summaryrefslogtreecommitdiff
path: root/chart2
diff options
context:
space:
mode:
authorTünde Tóth <toth.tunde@nisz.hu>2020-12-16 11:29:48 +0100
committerLászló Németh <nemeth@numbertext.org>2020-12-28 11:55:40 +0100
commitf22b77f204e433004aeb5fc2885881c03a62aa70 (patch)
tree862351744f9d245e1b004ceefcb188227a89d478 /chart2
parentbd51df8e4e267cdad369af402bb243cb3ed222f1 (diff)
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 <nemeth@numbertext.org> Reviewed-by: László Németh <nemeth@numbertext.org>
Diffstat (limited to 'chart2')
-rw-r--r--chart2/qa/extras/chart2import.cxx21
-rw-r--r--chart2/qa/extras/data/xlsx/incorrect_label_position.xlsxbin0 -> 14112 bytes
-rw-r--r--chart2/source/view/charttypes/PieChart.cxx101
-rw-r--r--chart2/source/view/inc/VSeriesPlotter.hxx2
4 files changed, 87 insertions, 37 deletions
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
--- /dev/null
+++ b/chart2/qa/extras/data/xlsx/incorrect_label_position.xlsx
Binary files 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