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:
parent
17b0eb43ac
commit
a91ac466e2
5 changed files with 64 additions and 73 deletions
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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: */
|
||||
|
|
|
@ -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>
|
||||
|
|
BIN
sw/qa/extras/layout/data/tdf137116.docx
Normal file
BIN
sw/qa/extras/layout/data/tdf137116.docx
Normal file
Binary file not shown.
|
@ -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");
|
||||
|
|
Loading…
Reference in a new issue