summaryrefslogtreecommitdiff
path: root/chart2/source/view/charttypes
diff options
context:
space:
mode:
authorTünde Tóth <toth.tunde@nisz.hu>2020-09-15 14:27:57 +0200
committerLászló Németh <nemeth@numbertext.org>2020-09-23 10:29:50 +0200
commit2e1a1054a4a98415057e72269ace9db075d3b191 (patch)
tree2efc134cab3432a01441b3c91e95b5e3db8134f8 /chart2/source/view/charttypes
parent4f2daa1cc683a3e3abbca6e15aa168add414eeff (diff)
tdf#136752 pie chart: improve data label position
to avoid chart distortion. Set the maximum text width of data point label shape based to the 80% of the remaining space, when text wrapping is enabled and the label placement is AVOID_OVERLAP. Change-Id: I174089ec62df3aa21b5d1f26f74d475945d83684 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102744 Tested-by: László Németh <nemeth@numbertext.org> Reviewed-by: László Németh <nemeth@numbertext.org>
Diffstat (limited to 'chart2/source/view/charttypes')
-rw-r--r--chart2/source/view/charttypes/PieChart.cxx68
-rw-r--r--chart2/source/view/charttypes/PieChart.hxx6
2 files changed, 52 insertions, 22 deletions
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>