chart2/qa/extras/chart2import.cxx          |   25 +++++++++-
 chart2/qa/extras/data/xlsx/tdf136752.xlsx  |binary
 chart2/source/view/charttypes/PieChart.cxx |   68 ++++++++++++++++++++---------
 chart2/source/view/charttypes/PieChart.hxx |    6 +-
 4 files changed, 75 insertions(+), 24 deletions(-)

New commits:
commit 2e1a1054a4a98415057e72269ace9db075d3b191
Author:     Tünde Tóth <toth.tu...@nisz.hu>
AuthorDate: Tue Sep 15 14:27:57 2020 +0200
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Wed Sep 23 10:29:50 2020 +0200

    tdf#136752 pie chart: improve data label position
    
    to avoid chart distortion.
    
    Set the maximum text width of data point label shape based
    to the 80% of the remaining space, when text wrapping is enabled
    and the label placement is AVOID_OVERLAP.
    
    Change-Id: I174089ec62df3aa21b5d1f26f74d475945d83684
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102744
    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 fe0a2c48231e..6097a8a0388f 100644
--- a/chart2/qa/extras/chart2import.cxx
+++ b/chart2/qa/extras/chart2import.cxx
@@ -165,6 +165,7 @@ public:
     void testTdf136105();
     void testTdf91250();
     void testTdf134111();
+    void testTdf136752();
 
     CPPUNIT_TEST_SUITE(Chart2ImportTest);
     CPPUNIT_TEST(Fdo60083);
@@ -278,6 +279,7 @@ public:
     CPPUNIT_TEST(testTdf136105);
     CPPUNIT_TEST(testTdf91250);
     CPPUNIT_TEST(testTdf134111);
+    CPPUNIT_TEST(testTdf136752);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -2550,8 +2552,8 @@ void Chart2ImportTest::testTdf133376()
     CPPUNIT_ASSERT(xDataPointLabel.is());
     // Check the position of the 3rd data point label, which is out from the 
pie slice
     awt::Point aLabelPosition = xDataPointLabel->getPosition();
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(482, aLabelPosition.X, 30);
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(5427, aLabelPosition.Y, 30);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(349, aLabelPosition.X, 30);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(5480, aLabelPosition.Y, 30);
 }
 
 void Chart2ImportTest::testTdf134225()
@@ -2658,6 +2660,25 @@ void Chart2ImportTest::testTdf134111()
     CPPUNIT_ASSERT(bTextBreak);
 }
 
+void Chart2ImportTest::testTdf136752()
+{
+    load("/chart2/qa/extras/data/xlsx/", "tdf136752.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());
+    // Check the position of the 1st data point label, which is out from the 
pie slice
+    awt::Point aLabelPosition = xDataPointLabel->getPosition();
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(8675, aLabelPosition.X, 500);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(1458, aLabelPosition.Y, 500);
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Chart2ImportTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/chart2/qa/extras/data/xlsx/tdf136752.xlsx 
b/chart2/qa/extras/data/xlsx/tdf136752.xlsx
new file mode 100644
index 000000000000..05fad58cfff5
Binary files /dev/null and b/chart2/qa/extras/data/xlsx/tdf136752.xlsx differ
diff --git a/chart2/source/view/charttypes/PieChart.cxx 
b/chart2/source/view/charttypes/PieChart.cxx
index 000a3f4a8a90..e2dd04f6c645 100644
--- a/chart2/source/view/charttypes/PieChart.cxx
+++ b/chart2/source/view/charttypes/PieChart.cxx
@@ -32,6 +32,7 @@
 
 #include <com/sun/star/container/XChild.hpp>
 #include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <rtl/math.hxx>
 #include <sal/log.hxx>
@@ -382,16 +383,52 @@ void PieChart::createTextLabelShape(
 
     aPieLabelInfo.xLabelGroupShape.set( xChild->getParent(), uno::UNO_QUERY );
 
+    if (bMovementAllowed && !m_bUseRings)
+    {
+        /** Handle the placement of the label in the best fit case.
+         *  First off the routine try to place the label inside the related 
pie slice,
+         *  if this is not possible the label is placed outside.
+         */
+        if (!performLabelBestFitInnerPlacement(rParam, aPieLabelInfo)
+            && m_aAvailableOuterRect.getWidth())
+        {
+            double fAngleDegree
+                = rParam.mfUnitCircleStartAngleDegree + 
rParam.mfUnitCircleWidthAngleDegree / 2.0;
+            while (fAngleDegree > 360.0)
+                fAngleDegree -= 360.0;
+            while (fAngleDegree < 0.0)
+                fAngleDegree += 360.0;
+
+            if (fAngleDegree < 67.5 || fAngleDegree >= 292.5)
+                fTextMaximumFrameWidth
+                    = 0.8 * (m_aAvailableOuterRect.getMaxX() - 
aPieLabelInfo.aFirstPosition.getX());
+            else if (fAngleDegree < 112.5 || fAngleDegree >= 247.5)
+                fTextMaximumFrameWidth = 0.8 * 
m_aAvailableOuterRect.getWidth();
+            else
+                fTextMaximumFrameWidth
+                    = 0.8 * (aPieLabelInfo.aFirstPosition.getX() - 
m_aAvailableOuterRect.getMinX());
+
+            nTextMaximumFrameWidth = ceil(fTextMaximumFrameWidth);
+            uno::Reference<drawing::XShapes> xShapes(xChild->getParent(), 
uno::UNO_QUERY);
+            xShapes->remove(aPieLabelInfo.xTextShape);
+            aPieLabelInfo.xTextShape
+                = createDataLabel(xTextTarget, rSeries, nPointIndex, nVal, 
rParam.mfLogicYSum,
+                                  aScreenPosition2D, eAlignment, 0, 
nTextMaximumFrameWidth);
+            xChild.clear();
+            
xChild.set(uno::Reference<container::XChild>(aPieLabelInfo.xTextShape, 
uno::UNO_QUERY));
+            if (!xChild.is())
+                return;
+
+            aPieLabelInfo.xLabelGroupShape.set(xChild->getParent(), 
uno::UNO_QUERY);
+            performLabelBestFitOuterPlacement(rParam, aPieLabelInfo);
+        }
+    }
+
     aPieLabelInfo.fValue = nVal;
     aPieLabelInfo.bMovementAllowed = bMovementAllowed;
-    aPieLabelInfo.bMoved= false;
+    aPieLabelInfo.bMoved = false;
     aPieLabelInfo.xTextTarget = xTextTarget;
 
-    if (bMovementAllowed)
-    {
-        performLabelBestFit(rParam, aPieLabelInfo);
-    }
-
     m_aLabelInfoList.push_back(aPieLabelInfo);
 }
 
@@ -1571,25 +1608,16 @@ bool 
PieChart::performLabelBestFitInnerPlacement(ShapeParam& rShapeParam, PieLab
     return true;
 }
 
-/** Handle the placement of the label in the best fit case.
- *  First off the routine try to place the label inside the related pie slice,
- *  if this is not possible the label is placed outside.
- */
-void PieChart::performLabelBestFit(ShapeParam& rShapeParam, PieLabelInfo const 
& rPieLabelInfo)
+void PieChart::performLabelBestFitOuterPlacement(ShapeParam& rShapeParam,
+                                                 PieLabelInfo const& 
rPieLabelInfo)
 {
-    if( m_bUseRings )
-        return;
-
-    if( performLabelBestFitInnerPlacement(rShapeParam, rPieLabelInfo) )
-        return;
-
-    // If it does not fit inside, let's put it outside
     awt::Point aOldPos(rPieLabelInfo.xLabelGroupShape->getPosition());
     basegfx::B2IVector aTranslationVector = rPieLabelInfo.aFirstPosition - 
rPieLabelInfo.aOrigin;
     awt::Point aScreenPosition2D(aOldPos.X + aTranslationVector.getX(),
-        aOldPos.Y + aTranslationVector.getY());
+                                 aOldPos.Y + aTranslationVector.getY());
 
-    double fAngleDegree = rShapeParam.mfUnitCircleStartAngleDegree + 
rShapeParam.mfUnitCircleWidthAngleDegree / 2.0;
+    double fAngleDegree
+        = rShapeParam.mfUnitCircleStartAngleDegree + 
rShapeParam.mfUnitCircleWidthAngleDegree / 2.0;
     ::basegfx::B2IRectangle aBb(lcl_getRect(rPieLabelInfo.xLabelGroupShape));
     double fLabelWidth = aBb.getWidth();
     double fLabelHeight = aBb.getHeight();
diff --git a/chart2/source/view/charttypes/PieChart.hxx 
b/chart2/source/view/charttypes/PieChart.hxx
index 97a8a3ba2e81..41e5d3f25648 100644
--- a/chart2/source/view/charttypes/PieChart.hxx
+++ b/chart2/source/view/charttypes/PieChart.hxx
@@ -105,8 +105,10 @@ struct PieLabelInfo;
                                 , PieLabelInfo* pCenter, bool bSingleCenter, 
bool& rbAlternativeMoveDirection
                                 , const css::awt::Size& rPageSize );
 
-    bool                performLabelBestFitInnerPlacement(ShapeParam& 
rShapeParam, PieLabelInfo const & rPieLabelInfo);
-    void                performLabelBestFit(ShapeParam& rShapeParam, 
PieLabelInfo const & rPieLabelInfo);
+    bool                performLabelBestFitInnerPlacement( ShapeParam& 
rShapeParam
+                                , PieLabelInfo const & rPieLabelInfo );
+    static void         performLabelBestFitOuterPlacement( ShapeParam& 
rShapeParam
+                                , PieLabelInfo const & rPieLabelInfo );
 
 private: //member
     std::unique_ptr<PiePositionHelper>
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to