tdf#137116 pie chart: improve BestFit position of data labels

Regression from commit: 2e1a1054a4
(tdf#136752 pie chart: improve data label position)

Change-Id: I66943684957a220c81db7f928fbb47700b78d012
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103610
Tested-by: Jenkins
Tested-by: László Németh <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
This commit is contained in:
Tünde Tóth 2020-09-29 13:32:40 +02:00 committed by László Németh
parent 17b0eb43ac
commit a91ac466e2
5 changed files with 64 additions and 73 deletions

View file

@ -2579,8 +2579,8 @@ void Chart2ImportTest::testTdf134225()
awt::Point aLabelPosition2 = xDataPointLabel2->getPosition();
// Check the distance between the position of the 1st data point label and the second one
CPPUNIT_ASSERT_DOUBLES_EQUAL(1800, sal_Int32(aLabelPosition2.X - aLabelPosition1.X), 30);
CPPUNIT_ASSERT_DOUBLES_EQUAL(2123, sal_Int32(aLabelPosition2.Y - aLabelPosition1.Y), 30);
CPPUNIT_ASSERT_DOUBLES_EQUAL(1669, sal_Int32(aLabelPosition2.X - aLabelPosition1.X), 30);
CPPUNIT_ASSERT_DOUBLES_EQUAL(2166, sal_Int32(aLabelPosition2.Y - aLabelPosition1.Y), 30);
#endif
}

View file

@ -389,26 +389,51 @@ void PieChart::createTextLabelShape(
* 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())
if (!performLabelBestFitInnerPlacement(rParam, aPieLabelInfo))
{
double fAngleDegree
= rParam.mfUnitCircleStartAngleDegree + rParam.mfUnitCircleWidthAngleDegree / 2.0;
while (fAngleDegree > 360.0)
fAngleDegree -= 360.0;
while (fAngleDegree < 0.0)
fAngleDegree += 360.0;
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 * (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());
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);
}
nScreenValueOffsetInRadiusDirection = (m_nDimension != 3) ? 150 : 0;
aScreenPosition2D
= aPolarPosHelper.getLabelScreenPositionAndAlignmentForUnitCircleValues(
eAlignment, css::chart::DataLabelPlacement::OUTSIDE,
rParam.mfUnitCircleStartAngleDegree,
rParam.mfUnitCircleWidthAngleDegree, rParam.mfUnitCircleInnerRadius,
rParam.mfUnitCircleOuterRadius, rParam.mfLogicZ + 0.5, 0);
aPieLabelInfo.aFirstPosition
= basegfx::B2IVector(aScreenPosition2D.X, aScreenPosition2D.Y);
//add a scaling independent Offset if requested
if (nScreenValueOffsetInRadiusDirection != 0)
{
basegfx::B2IVector aDirection(aScreenPosition2D.X - aOrigin.X,
aScreenPosition2D.Y - aOrigin.Y);
aDirection.setLength(nScreenValueOffsetInRadiusDirection);
aScreenPosition2D.X += aDirection.getX();
aScreenPosition2D.Y += aDirection.getY();
}
nTextMaximumFrameWidth = ceil(fTextMaximumFrameWidth);
uno::Reference<drawing::XShapes> xShapes(xChild->getParent(), uno::UNO_QUERY);
xShapes->remove(aPieLabelInfo.xTextShape);
aPieLabelInfo.xTextShape
@ -420,7 +445,6 @@ void PieChart::createTextLabelShape(
return;
aPieLabelInfo.xLabelGroupShape.set(xChild->getParent(), uno::UNO_QUERY);
performLabelBestFitOuterPlacement(rParam, aPieLabelInfo);
}
}
@ -1608,57 +1632,6 @@ bool PieChart::performLabelBestFitInnerPlacement(ShapeParam& rShapeParam, PieLab
return true;
}
void PieChart::performLabelBestFitOuterPlacement(ShapeParam& rShapeParam,
PieLabelInfo const& rPieLabelInfo)
{
awt::Point aOldPos(rPieLabelInfo.xLabelGroupShape->getPosition());
basegfx::B2IVector aTranslationVector = rPieLabelInfo.aFirstPosition - rPieLabelInfo.aOrigin;
awt::Point aScreenPosition2D(aOldPos.X + aTranslationVector.getX(),
aOldPos.Y + aTranslationVector.getY());
double fAngleDegree
= rShapeParam.mfUnitCircleStartAngleDegree + rShapeParam.mfUnitCircleWidthAngleDegree / 2.0;
::basegfx::B2IRectangle aBb(lcl_getRect(rPieLabelInfo.xLabelGroupShape));
double fLabelWidth = aBb.getWidth();
double fLabelHeight = aBb.getHeight();
while (fAngleDegree > 360.0)
fAngleDegree -= 360.0;
while (fAngleDegree < 0.0)
fAngleDegree += 360.0;
if (fAngleDegree <= 22.5 || fAngleDegree >= 337.5)
aScreenPosition2D.X += fLabelWidth / 2;
else if (fAngleDegree < 67.5)
{
aScreenPosition2D.X += fLabelWidth / 2;
aScreenPosition2D.Y -= fLabelHeight / 2;
}
else if (fAngleDegree < 112.5)
aScreenPosition2D.Y -= fLabelHeight / 2;
else if (fAngleDegree <= 157.5)
{
aScreenPosition2D.X -= fLabelWidth / 2;
aScreenPosition2D.Y -= fLabelHeight / 2;
}
else if (fAngleDegree <= 202.5)
aScreenPosition2D.X -= fLabelWidth / 2;
else if (fAngleDegree < 247.5)
{
aScreenPosition2D.X -= fLabelWidth / 2;
aScreenPosition2D.Y += fLabelHeight / 2;
}
else if (fAngleDegree < 292.5)
aScreenPosition2D.Y += fLabelHeight / 2;
else
{
aScreenPosition2D.X += fLabelWidth / 2;
aScreenPosition2D.Y += fLabelHeight / 2;
}
rPieLabelInfo.xLabelGroupShape->setPosition(aScreenPosition2D);
}
} //namespace chart
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View file

@ -107,8 +107,6 @@ struct PieLabelInfo;
bool performLabelBestFitInnerPlacement( ShapeParam& rShapeParam
, PieLabelInfo const & rPieLabelInfo );
static void performLabelBestFitOuterPlacement( ShapeParam& rShapeParam
, PieLabelInfo const & rPieLabelInfo );
private: //member
std::unique_ptr<PiePositionHelper>

Binary file not shown.

View file

@ -2923,6 +2923,26 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf134866)
pXmlDoc, "/metafile/push[1]/push[1]/push[1]/push[4]/push[1]/textarray[2]/text", "100%");
}
CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf137116)
{
SwDoc* pDoc = createDoc("tdf137116.docx");
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);
sal_Int32 nX2 = getXPath(pXmlDoc, "//textarray[2]", "x").toInt32(); // second data label
sal_Int32 nX4 = getXPath(pXmlDoc, "//textarray[4]", "x").toInt32(); // fourth data label
// Without the accompanying fix in place, this test would have failed with:
// - Expected: 694
// - Actual : -225
// - Delta : 100
// i.e. the second data label appeared inside the pie slice.
CPPUNIT_ASSERT_DOUBLES_EQUAL(694, nX2 - nX4, 100);
}
CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf130031)
{
SwDoc* pDoc = createDoc("tdf130031.docx");