diff options
author | Tünde Tóth <toth.tunde@nisz.hu> | 2020-10-16 08:57:53 +0200 |
---|---|---|
committer | László Németh <nemeth@numbertext.org> | 2020-10-19 13:00:50 +0200 |
commit | 657ea0d1250624312e104f9acfb6a04a3ba4cce3 (patch) | |
tree | bcdae605c3f2bf9d9bd8cd3cc92c16e0e8df13e1 | |
parent | 2646023729dd16c1a613fac7e8e6a37828d7a404 (diff) |
tdf#134121 pie chart: add leader lines
to data labels with custom position.
See commit 769433ad93040bc81f06672c8a2c01e2b76fece3
(tdf#90749 chart: add leader lines to custom data label positions)
Change-Id: If5d912cc04993e59bd5ab93b644ea49ba8642b49
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104410
Tested-by: László Németh <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
-rw-r--r-- | chart2/source/view/charttypes/PieChart.cxx | 117 | ||||
-rw-r--r-- | chart2/source/view/charttypes/PieChart.hxx | 2 | ||||
-rw-r--r-- | sw/qa/extras/layout/data/piechart_leaderline.odt | bin | 0 -> 15625 bytes | |||
-rw-r--r-- | sw/qa/extras/layout/layout2.cxx | 15 |
4 files changed, 94 insertions, 40 deletions
diff --git a/chart2/source/view/charttypes/PieChart.cxx b/chart2/source/view/charttypes/PieChart.cxx index 55eb67037b9a..9b7279599f8b 100644 --- a/chart2/source/view/charttypes/PieChart.cxx +++ b/chart2/source/view/charttypes/PieChart.cxx @@ -102,6 +102,29 @@ struct PieChart::ShapeParam mfDepth(0.0) {} }; +namespace +{ +::basegfx::B2IRectangle lcl_getRect(const uno::Reference<drawing::XShape>& xShape) +{ + ::basegfx::B2IRectangle aRect; + if (xShape.is()) + aRect = BaseGFXHelper::makeRectangle(xShape->getPosition(), xShape->getSize()); + return aRect; +} + +bool lcl_isInsidePage(const awt::Point& rPos, const awt::Size& rSize, const awt::Size& rPageSize) +{ + if (rPos.X < 0 || rPos.Y < 0) + return false; + if ((rPos.X + rSize.Width) > rPageSize.Width) + return false; + if ((rPos.Y + rSize.Height) > rPageSize.Height) + return false; + return true; +} + +} //end anonymous namespace + class PiePositionHelper : public PolarPlottingPositionHelper { public: @@ -349,17 +372,22 @@ void PieChart::createTextLabelShape( aOuterCirclePoint.Y - aPieLabelInfo.aOrigin.getY() ); double fSquaredPieRadius = aRadiusVector.scalar(aRadiusVector); double fPieRadius = sqrt( fSquaredPieRadius ); + double fAngleDegree + = rParam.mfUnitCircleStartAngleDegree + rParam.mfUnitCircleWidthAngleDegree / 2.0; + while (fAngleDegree > 360.0) + fAngleDegree -= 360.0; + while (fAngleDegree < 0.0) + fAngleDegree += 360.0; + + awt::Point aOuterPosition = PlottingPositionHelper::transformSceneToScreenPosition( + m_pPosHelper->transformUnitCircleToScene(fAngleDegree, rParam.mfUnitCircleOuterRadius, 0), + m_xLogicTarget, m_pShapeFactory, m_nDimension); + aPieLabelInfo.aOuterPosition = basegfx::B2IVector(aOuterPosition.X, aOuterPosition.Y); // set the maximum text width to be used when text wrapping is enabled double fTextMaximumFrameWidth = 0.8 * fPieRadius; if( nLabelPlacement == css::chart::DataLabelPlacement::OUTSIDE && 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 = m_aAvailableOuterRect.getMaxX() - aPieLabelInfo.aFirstPosition.getX(); else if (fAngleDegree < 112.5 || fAngleDegree >= 247.5) @@ -396,13 +424,6 @@ void PieChart::createTextLabelShape( { if (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 @@ -451,10 +472,50 @@ void PieChart::createTextLabelShape( } } + bool bShowLeaderLine = rSeries.getPropertiesOfSeries() + ->getPropertyValue("ShowCustomLeaderLines") + .get<sal_Bool>(); + if (m_bPieLabelsAllowToMove && rSeries.isLabelCustomPos(nPointIndex) && bShowLeaderLine) + { + 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(); + + 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; + if (nColor != -1) //automatic font color does not work for lines -> fallback to black + aVLineProperties.Color <<= nColor; + } + m_pShapeFactory->createLine2D(xTextTarget, aPoints, &aVLineProperties); + } + aPieLabelInfo.fValue = nVal; aPieLabelInfo.bMovementAllowed = bMovementAllowed; aPieLabelInfo.bMoved = false; aPieLabelInfo.xTextTarget = xTextTarget; + aPieLabelInfo.bShowLeaderLine = bShowLeaderLine && !rSeries.isLabelCustomPos(nPointIndex); m_aLabelInfoList.push_back(aPieLabelInfo); } @@ -800,30 +861,6 @@ void PieChart::createShapes() }//next x slot } -namespace -{ - -::basegfx::B2IRectangle lcl_getRect( const uno::Reference< drawing::XShape >& xShape ) -{ - ::basegfx::B2IRectangle aRect; - if( xShape.is() ) - aRect = BaseGFXHelper::makeRectangle(xShape->getPosition(),xShape->getSize() ); - return aRect; -} - -bool lcl_isInsidePage( const awt::Point& rPos, const awt::Size& rSize, const awt::Size& rPageSize ) -{ - if( rPos.X < 0 || rPos.Y < 0 ) - return false; - if( (rPos.X + rSize.Width) > rPageSize.Width ) - return false; - if( (rPos.Y + rSize.Height) > rPageSize.Height ) - return false; - return true; -} - -}//end anonymous namespace - PieChart::PieLabelInfo::PieLabelInfo() : aFirstPosition(), aOrigin(), fValue(0.0) , bMovementAllowed(false), bMoved(false), pPrevious(nullptr),pNext(nullptr) @@ -1206,10 +1243,10 @@ void PieChart::rearrangeLabelToAvoidOverlapIfRequested( const awt::Size& rPageSi VLineProperties aVLineProperties; for (auto const& labelInfo : m_aLabelInfoList) { - if( labelInfo.bMoved ) + if( labelInfo.bMoved && labelInfo.bShowLeaderLine ) { - sal_Int32 nX1 = labelInfo.aFirstPosition.getX(); - sal_Int32 nY1 = labelInfo.aFirstPosition.getY(); + sal_Int32 nX1 = labelInfo.aOuterPosition.getX(); + sal_Int32 nY1 = labelInfo.aOuterPosition.getY(); sal_Int32 nX2 = nX1; sal_Int32 nY2 = nY1; ::basegfx::B2IRectangle aRect( lcl_getRect( labelInfo.xLabelGroupShape ) ); diff --git a/chart2/source/view/charttypes/PieChart.hxx b/chart2/source/view/charttypes/PieChart.hxx index 73d40d06bbfa..d4dd0255af6a 100644 --- a/chart2/source/view/charttypes/PieChart.hxx +++ b/chart2/source/view/charttypes/PieChart.hxx @@ -123,10 +123,12 @@ private: //member css::uno::Reference< css::drawing::XShape > xTextShape; css::uno::Reference< css::drawing::XShape > xLabelGroupShape; ::basegfx::B2IVector aFirstPosition; + ::basegfx::B2IVector aOuterPosition; ::basegfx::B2IVector aOrigin; double fValue; bool bMovementAllowed; bool bMoved; + bool bShowLeaderLine; css::uno::Reference< css::drawing::XShapes > xTextTarget; PieLabelInfo* pPrevious; PieLabelInfo* pNext; diff --git a/sw/qa/extras/layout/data/piechart_leaderline.odt b/sw/qa/extras/layout/data/piechart_leaderline.odt Binary files differnew file mode 100644 index 000000000000..77c61a691eb1 --- /dev/null +++ b/sw/qa/extras/layout/data/piechart_leaderline.odt diff --git a/sw/qa/extras/layout/layout2.cxx b/sw/qa/extras/layout/layout2.cxx index f0bb71e9b9f5..1107f3cff20e 100644 --- a/sw/qa/extras/layout/layout2.cxx +++ b/sw/qa/extras/layout/layout2.cxx @@ -878,6 +878,21 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf130242) CPPUNIT_ASSERT_DOUBLES_EQUAL(3018, nY, 50); } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf134121) +{ + SwDoc* pDoc = createDoc("piechart_leaderline.odt"); + SwDocShell* pShell = pDoc->GetDocShell(); + + // Dump the rendering of the first page as an XML file. + std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile(); + MetafileXmlDump dumper; + xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile); + CPPUNIT_ASSERT(pXmlDoc); + + // Check the custom leader line on pie chart. + assertXPath(pXmlDoc, "//polyline", 1); +} + CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf130380) { SwDoc* pDoc = createDoc("tdf130380.docx"); |