chart2/qa/extras/chart2import.cxx                        |   21 +++
 chart2/qa/extras/data/xlsx/incorrect_label_position.xlsx |binary
 chart2/source/view/charttypes/PieChart.cxx               |  101 +++++++++------
 chart2/source/view/inc/VSeriesPlotter.hxx                |    2 
 4 files changed, 87 insertions(+), 37 deletions(-)

New commits:
commit f22b77f204e433004aeb5fc2885881c03a62aa70
Author:     Tünde Tóth <toth.tu...@nisz.hu>
AuthorDate: Wed Dec 16 11:29:48 2020 +0100
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Mon Dec 28 11:55:40 2020 +0100

    tdf#121281 pie chart: improve data label position
    
    to avoid chart distortion.
    
    Move the data label to inside the chart area when it
    goes outside the border.
    
    Change-Id: I78669ed601f28129944ac8f61c6478d386322b76
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/107829
    Tested-by: Jenkins
    Tested-by: László Németh <nem...@numbertext.org>
    Reviewed-by: László Németh <nem...@numbertext.org>

diff --git a/chart2/qa/extras/chart2import.cxx 
b/chart2/qa/extras/chart2import.cxx
index 9bb042fb6867..943cbd57ea99 100644
--- a/chart2/qa/extras/chart2import.cxx
+++ b/chart2/qa/extras/chart2import.cxx
@@ -171,6 +171,7 @@ public:
     void testTdf137734();
     void testTdf137874();
     void testTdfCustomShapePos();
+    void testTdf121281();
 
     CPPUNIT_TEST_SUITE(Chart2ImportTest);
     CPPUNIT_TEST(Fdo60083);
@@ -291,6 +292,7 @@ public:
     CPPUNIT_TEST(testTdf137734);
     CPPUNIT_TEST(testTdf137874);
     CPPUNIT_TEST(testTdfCustomShapePos);
+    CPPUNIT_TEST(testTdf121281);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -2802,6 +2804,25 @@ void Chart2ImportTest::testTdfCustomShapePos()
     }
 }
 
+void Chart2ImportTest::testTdf121281()
+{
+    load("/chart2/qa/extras/data/xlsx/", "incorrect_label_position.xlsx");
+    Reference<chart::XChartDocument> xChartDoc(getChartDocFromSheet(0, 
mxComponent),
+                                               UNO_QUERY_THROW);
+    Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(xChartDoc, 
UNO_QUERY_THROW);
+    Reference<drawing::XDrawPage> xDrawPage(xDrawPageSupplier->getDrawPage(), 
UNO_SET_THROW);
+    Reference<drawing::XShapes> xShapes(xDrawPage->getByIndex(0), 
UNO_QUERY_THROW);
+    Reference<drawing::XShape> xDataPointLabel(
+        getShapeByName(xShapes,
+                       
"CID/MultiClick/CID/D=0:CS=0:CT=0:Series=0:DataLabels=:DataLabel=0"),
+        UNO_SET_THROW);
+
+    CPPUNIT_ASSERT(xDataPointLabel.is());
+    awt::Point aLabelPosition = xDataPointLabel->getPosition();
+    // This failed, if the data label flowed out of the chart area.
+    CPPUNIT_ASSERT_GREATEREQUAL(static_cast<sal_Int32>(0), aLabelPosition.Y);
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Chart2ImportTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/chart2/qa/extras/data/xlsx/incorrect_label_position.xlsx 
b/chart2/qa/extras/data/xlsx/incorrect_label_position.xlsx
new file mode 100644
index 000000000000..4f133b558116
Binary files /dev/null and 
b/chart2/qa/extras/data/xlsx/incorrect_label_position.xlsx differ
diff --git a/chart2/source/view/charttypes/PieChart.cxx 
b/chart2/source/view/charttypes/PieChart.cxx
index 3b61cb9c46e3..e77a7964ee71 100644
--- a/chart2/source/view/charttypes/PieChart.cxx
+++ b/chart2/source/view/charttypes/PieChart.cxx
@@ -468,49 +468,78 @@ void PieChart::createTextLabelShape(
     }
 
     bool bShowLeaderLine = rSeries.getPropertiesOfSeries()
-                                        
->getPropertyValue("ShowCustomLeaderLines")
-                                        .get<sal_Bool>();
-    if (m_bPieLabelsAllowToMove && rSeries.isLabelCustomPos(nPointIndex) && 
bShowLeaderLine)
+                                   ->getPropertyValue("ShowCustomLeaderLines")
+                                   .get<sal_Bool>();
+    if (m_bPieLabelsAllowToMove)
     {
-        sal_Int32 nX1 = aPieLabelInfo.aOuterPosition.getX();
-        sal_Int32 nY1 = aPieLabelInfo.aOuterPosition.getY();
-        sal_Int32 nX2 = nX1;
-        sal_Int32 nY2 = nY1;
         ::basegfx::B2IRectangle 
aRect(lcl_getRect(aPieLabelInfo.xLabelGroupShape));
-        if (nX1 < aRect.getMinX())
-            nX2 = aRect.getMinX();
-        else if (nX1 > aRect.getMaxX())
-            nX2 = aRect.getMaxX();
-
-        if (nY1 < aRect.getMinY())
-            nY2 = aRect.getMinY();
-        else if (nY1 > aRect.getMaxY())
-            nY2 = aRect.getMaxY();
+        sal_Int32 nPageWidth = m_aPageReferenceSize.Width;
+        sal_Int32 nPageHeight = m_aPageReferenceSize.Height;
+
+        // the data label should be inside the chart area
+        awt::Point aShapePos = aPieLabelInfo.xLabelGroupShape->getPosition();
+        if (aRect.getMinX() < 0)
+            aPieLabelInfo.xLabelGroupShape->setPosition(
+                awt::Point(aShapePos.X - aRect.getMinX(), aShapePos.Y));
+        if (aRect.getMinY() < 0)
+            aPieLabelInfo.xLabelGroupShape->setPosition(
+                awt::Point(aShapePos.X, aShapePos.Y - aRect.getMinY()));
+        if (aRect.getMaxX() > nPageWidth)
+            aPieLabelInfo.xLabelGroupShape->setPosition(
+                awt::Point(aShapePos.X - (aRect.getMaxX() - nPageWidth), 
aShapePos.Y));
+        if (aRect.getMaxY() > nPageHeight)
+            aPieLabelInfo.xLabelGroupShape->setPosition(
+                awt::Point(aShapePos.X, aShapePos.Y - (aRect.getMaxY() - 
nPageHeight)));
+
+        if (rSeries.isLabelCustomPos(nPointIndex) && bShowLeaderLine)
+        {
+            sal_Int32 nX1 = aPieLabelInfo.aOuterPosition.getX();
+            sal_Int32 nY1 = aPieLabelInfo.aOuterPosition.getY();
+            sal_Int32 nX2 = nX1;
+            sal_Int32 nY2 = nY1;
+            if (nX1 < aRect.getMinX())
+                nX2 = aRect.getMinX();
+            else if (nX1 > aRect.getMaxX())
+                nX2 = aRect.getMaxX();
 
-        sal_Int32 nSquaredDistanceFromOrigin
-            = (nX2 - aOrigin.X) * (nX2 - aOrigin.X) + (nY2 - aOrigin.Y) * (nY2 
- aOrigin.Y);
+            if (nY1 < aRect.getMinY())
+                nY2 = aRect.getMinY();
+            else if (nY1 > aRect.getMaxY())
+                nY2 = aRect.getMaxY();
 
-        // tdf#138018 Don't show leader line when custom positioned data label 
is inside pie chart
-        if (nSquaredDistanceFromOrigin > fSquaredPieRadius)
-        {
-            drawing::PointSequenceSequence aPoints(1);
-            aPoints[0].realloc(2);
-            aPoints[0][0].X = nX1;
-            aPoints[0][0].Y = nY1;
-            aPoints[0][1].X = nX2;
-            aPoints[0][1].Y = nY2;
+            sal_Int32 nSquaredDistanceFromOrigin
+                = (nX2 - aOrigin.X) * (nX2 - aOrigin.X) + (nY2 - aOrigin.Y) * 
(nY2 - aOrigin.Y);
 
-            uno::Reference<beans::XPropertySet> 
xProp(aPieLabelInfo.xTextShape, uno::UNO_QUERY);
-            VLineProperties aVLineProperties;
-            if (xProp.is())
+            // tdf#138018 Don't show leader line when custom positioned data 
label is inside pie chart
+            if (nSquaredDistanceFromOrigin > fSquaredPieRadius)
             {
-                sal_Int32 nColor = 0;
-                xProp->getPropertyValue("CharColor") >>= nColor;
-                //automatic font color does not work for lines -> fallback to 
black
-                if (nColor != -1)
-                    aVLineProperties.Color <<= nColor;
+                //when the line is very short compared to the page size don't 
create one
+                ::basegfx::B2DVector aLength(nX1 - nX2, nY1 - nY2);
+                double fPageDiagonaleLength = sqrt(double(nPageWidth) * 
double(nPageWidth)
+                                                   + double(nPageHeight) * 
double(nPageHeight));
+                if ((aLength.getLength() / fPageDiagonaleLength) >= 0.01)
+                {
+                    drawing::PointSequenceSequence aPoints(1);
+                    aPoints[0].realloc(2);
+                    aPoints[0][0].X = nX1;
+                    aPoints[0][0].Y = nY1;
+                    aPoints[0][1].X = nX2;
+                    aPoints[0][1].Y = nY2;
+
+                    uno::Reference<beans::XPropertySet> 
xProp(aPieLabelInfo.xTextShape,
+                                                              uno::UNO_QUERY);
+                    VLineProperties aVLineProperties;
+                    if (xProp.is())
+                    {
+                        sal_Int32 nColor = 0;
+                        xProp->getPropertyValue("CharColor") >>= nColor;
+                        //automatic font color does not work for lines -> 
fallback to black
+                        if (nColor != -1)
+                            aVLineProperties.Color <<= nColor;
+                    }
+                    m_pShapeFactory->createLine2D(xTextTarget, aPoints, 
&aVLineProperties);
+                }
             }
-            m_pShapeFactory->createLine2D(xTextTarget, aPoints, 
&aVLineProperties);
         }
     }
 
diff --git a/chart2/source/view/inc/VSeriesPlotter.hxx 
b/chart2/source/view/inc/VSeriesPlotter.hxx
index 7632ff586633..a824ff14c77b 100644
--- a/chart2/source/view/inc/VSeriesPlotter.hxx
+++ b/chart2/source/view/inc/VSeriesPlotter.hxx
@@ -426,6 +426,7 @@ protected:
     bool m_bPointsWereSkipped;
     bool m_bPieLabelsAllowToMove;
     basegfx::B2IRectangle m_aAvailableOuterRect;
+    css::awt::Size m_aPageReferenceSize;
 
 private:
     typedef std::map< sal_Int32 , ExplicitScaleData > tSecondaryValueScales;
@@ -433,7 +434,6 @@ private:
 
     typedef std::map< sal_Int32 , std::unique_ptr<PlottingPositionHelper> > 
tSecondaryPosHelperMap;
     mutable tSecondaryPosHelperMap   m_aSecondaryPosHelperMap;
-    css::awt::Size      m_aPageReferenceSize;
 };
 
 } //namespace chart
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to