diff options
-rw-r--r-- | chart2/qa/extras/chart2import.cxx | 25 | ||||
-rw-r--r-- | chart2/qa/extras/data/xlsx/tdf136752.xlsx | bin | 0 -> 11909 bytes | |||
-rw-r--r-- | chart2/source/view/charttypes/PieChart.cxx | 68 | ||||
-rw-r--r-- | chart2/source/view/charttypes/PieChart.hxx | 6 |
4 files changed, 75 insertions, 24 deletions
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 Binary files differnew file mode 100644 index 000000000000..05fad58cfff5 --- /dev/null +++ b/chart2/qa/extras/data/xlsx/tdf136752.xlsx 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> |