chart2/source/view/charttypes/PieChart.cxx           |  167 ++++++++++++++-----
 chart2/source/view/charttypes/PieChart.hxx           |   18 +-
 chart2/source/view/inc/PlottingPositionHelper.hxx    |   13 +
 chart2/source/view/inc/PolarLabelPositionHelper.hxx  |    3 
 chart2/source/view/main/PlottingPositionHelper.cxx   |    7 
 chart2/source/view/main/PolarLabelPositionHelper.cxx |   15 +
 6 files changed, 168 insertions(+), 55 deletions(-)

New commits:
commit d0092c5627f3dc2db33846e3b81ce19780372529
Author:     Kurt Nordback <kurt.nordb...@protonmail.com>
AuthorDate: Wed Jun 26 06:27:12 2024 -0600
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Sat Aug 17 08:19:39 2024 +0200

    tdf#161230 - Pie-of-pie and bar-of-pie chart data labels are misaligned
    
    Implementing label support for of-pie charts. This involves using the 
existing
    pie label code with an added horizontal shift, and adding special (simple)
    handling for the bars in bar-of-pie. This also fixes tdf#161228
    
    Change-Id: Ifc7c1f28548caf216aba5c7dc411d05a0c9d8726
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169566
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>
    Tested-by: Jenkins

diff --git a/chart2/source/view/charttypes/PieChart.cxx 
b/chart2/source/view/charttypes/PieChart.cxx
index 2db56c84a5bd..4bda2129817d 100644
--- a/chart2/source/view/charttypes/PieChart.cxx
+++ b/chart2/source/view/charttypes/PieChart.cxx
@@ -313,14 +313,14 @@ rtl::Reference<SvxShape> PieChart::createDataPoint(
                 aOrigin = m_aPosHelper.transformUnitCircleToScene(0, 0, 
rParam.mfLogicZ);
                 aNewOrigin = m_aPosHelper.transformUnitCircleToScene(180, 
0.75, rParam.mfLogicZ);
                 aOffset = aNewOrigin - aOrigin;
-                fExplodedOuterRadius *= 2.0/3;
+                fExplodedOuterRadius *= m_fLeftScale;
                 break;
             case SubPieType::RIGHT:
                 // Draw the sub-pie for pie-of-pie much smaller and to the 
right
                 aOrigin = m_aPosHelper.transformUnitCircleToScene(0, 0, 
rParam.mfLogicZ);
                 aNewOrigin = m_aPosHelper.transformUnitCircleToScene(0, 0.75, 
rParam.mfLogicZ);
                 aOffset = aNewOrigin - aOrigin;
-                fExplodedOuterRadius *= 1.0/3;
+                fExplodedOuterRadius *= m_fRightScale;
                 break;
             case SubPieType::NONE:
             default:
@@ -357,31 +357,13 @@ rtl::Reference<SvxShape> PieChart::createBarDataPoint(
         const ShapeParam& rParam,
         double fBarSegBottom, double fBarSegTop)
 {
-    drawing::Position3D aP0, aP1;
-
     // Draw the bar for bar-of-pie small and to the right. Width and
     // position are hard-coded for now.
 
-#if 0
-    aP0 = cartesianPosHelper.transformLogicToScene(0.75, fBarSegBottom,
-            rParam.mfLogicZ, false);
-    aP1 = cartesianPosHelper.transformLogicToScene(1.25, fBarSegTop,
-            rParam.mfLogicZ, false);
-#else
-    double x0 = m_aPosHelper.transformUnitCircleToScene(0, 0.75, 0).PositionX;
-    double x1 = m_aPosHelper.transformUnitCircleToScene(0, 1.25, 0).PositionX;
-    double y0 = m_aPosHelper.transformUnitCircleToScene(
-            90, fBarSegBottom, 0).PositionY;
-    double y1 = m_aPosHelper.transformUnitCircleToScene(
-            90, fBarSegTop, 0).PositionY;
-
-    aP0 = drawing::Position3D(x0, y0, rParam.mfLogicZ);
-    aP1 = drawing::Position3D(x1, y1, rParam.mfLogicZ);
-#endif
+    css::awt::Point aPos;
+    css::awt::Size aSz;
 
-    const css::awt::Point aPos(aP0.PositionX, aP1.PositionY);
-    const css::awt::Size aSz(fabs(aP0.PositionX - aP1.PositionX),
-            fabs(aP0.PositionY - aP1.PositionY));
+    getBarRect(&aPos, &aSz, fBarSegBottom, fBarSegTop, rParam);
 
     const tNameSequence emptyNameSeq;
     const tAnySequence emptyValSeq;
@@ -395,9 +377,28 @@ rtl::Reference<SvxShape> PieChart::createBarDataPoint(
     return xShape;
 }
 
+void PieChart::getBarRect(css::awt::Point *pPos, css::awt::Size *pSz,
+        double fBarBottom, double fBarTop, const ShapeParam& rParam) const
+{
+    double x0 = m_aPosHelper.transformUnitCircleToScene(0, m_fBarLeft, 
0).PositionX;
+    double x1 = m_aPosHelper.transformUnitCircleToScene(0, m_fBarRight, 
0).PositionX;
+    double y0 = m_aPosHelper.transformUnitCircleToScene(
+            90, fBarBottom, 0).PositionY;
+    double y1 = m_aPosHelper.transformUnitCircleToScene(
+            90, fBarTop, 0).PositionY;
+
+    drawing::Position3D aP0(x0, y0, rParam.mfLogicZ);
+    drawing::Position3D aP1(x1, y1, rParam.mfLogicZ);
+
+    *pPos = css::awt::Point(aP0.PositionX, aP1.PositionY);
+    *pSz = css::awt::Size(fabs(aP0.PositionX - aP1.PositionX),
+            fabs(aP0.PositionY - aP1.PositionY));
+}
+
 void PieChart::createTextLabelShape(
     const rtl::Reference<SvxShapeGroupAnyD>& xTextTarget,
-    VDataSeries& rSeries, sal_Int32 nPointIndex, ShapeParam& rParam )
+    VDataSeries& rSeries, sal_Int32 nPointIndex, ShapeParam& rParam ,
+    enum SubPieType eType)
 {
     if (!rSeries.getDataPointLabelIfLabel(nPointIndex))
         // There is no text label for this data point.  Nothing to do.
@@ -449,6 +450,24 @@ void PieChart::createTextLabelShape(
     else if( nLabelPlacement == css::chart::DataLabelPlacement::INSIDE )
         nScreenValueOffsetInRadiusDirection = (m_nDimension!=3) ? -150 : 
0;//todo maybe calculate this font height dependent
 
+    double fRadiusScale;
+    double fXShift;
+    switch (eType) {
+    case SubPieType::LEFT:
+        fRadiusScale = m_fLeftScale;
+        fXShift = m_fLeftShift;
+        break;
+    case SubPieType::RIGHT:
+        fRadiusScale = m_fRightScale;
+        fXShift = m_fRightShift;
+        break;
+    default:
+        fRadiusScale = 1.0;
+        fXShift = 0;
+    }
+
+    ::basegfx::B3DVector aShift(fXShift, 0, 0);
+
     ///the scene position of the label anchor point is calculated (see notes 
for
     
///`PolarLabelPositionHelper::getLabelScreenPositionAndAlignmentForUnitCircleValues`),
     ///and immediately transformed into the screen position.
@@ -456,12 +475,15 @@ void PieChart::createTextLabelShape(
     awt::Point aScreenPosition2D(
         
aPolarPosHelper.getLabelScreenPositionAndAlignmentForUnitCircleValues(eAlignment,
 nLabelPlacement
         , rParam.mfUnitCircleStartAngleDegree, 
rParam.mfUnitCircleWidthAngleDegree
-        , rParam.mfUnitCircleInnerRadius, rParam.mfUnitCircleOuterRadius, 
rParam.mfLogicZ+0.5, 0 ));
+        , rParam.mfUnitCircleInnerRadius, rParam.mfUnitCircleOuterRadius * 
fRadiusScale
+        , rParam.mfLogicZ+0.5, 0, aShift));
 
     ///the screen position of the pie/donut center is calculated.
     PieLabelInfo aPieLabelInfo;
     aPieLabelInfo.aFirstPosition = basegfx::B2IVector( aScreenPosition2D.X, 
aScreenPosition2D.Y );
-    awt::Point aOrigin( aPolarPosHelper.transformSceneToScreenPosition( 
m_aPosHelper.transformUnitCircleToScene( 0.0, 0.0, rParam.mfLogicZ+1.0 ) ) );
+    awt::Point aOrigin( aPolarPosHelper.transformSceneToScreenPosition(
+                m_aPosHelper.transformUnitCircleToScene( 0.0, 0.0,
+                    rParam.mfLogicZ+1.0, aShift ) ) );
     aPieLabelInfo.aOrigin = basegfx::B2IVector( aOrigin.X, aOrigin.Y );
 
     ///add a scaling independent Offset if requested
@@ -477,8 +499,9 @@ void PieChart::createTextLabelShape(
     awt::Point aOuterCirclePoint = 
PlottingPositionHelper::transformSceneToScreenPosition(
             m_aPosHelper.transformUnitCircleToScene(
                     0,
-                    rParam.mfUnitCircleOuterRadius,
-                    0 ),
+                    rParam.mfUnitCircleOuterRadius * fRadiusScale,
+                    0 ,
+                    aShift),
             m_xLogicTarget, m_nDimension );
     basegfx::B2IVector aRadiusVector(
             aOuterCirclePoint.X - aPieLabelInfo.aOrigin.getX(),
@@ -493,7 +516,8 @@ void PieChart::createTextLabelShape(
     // aOuterPosition: slice midpoint on the circumference,
     // which is where an outside/custom label would be connected
     awt::Point aOuterPosition = 
PlottingPositionHelper::transformSceneToScreenPosition(
-        m_aPosHelper.transformUnitCircleToScene(fAngleDegree, 
rParam.mfUnitCircleOuterRadius, 0),
+        m_aPosHelper.transformUnitCircleToScene(fAngleDegree,
+            rParam.mfUnitCircleOuterRadius * fRadiusScale, 0, aShift),
         m_xLogicTarget, m_nDimension);
     aPieLabelInfo.aOuterPosition = basegfx::B2IVector(aOuterPosition.X, 
aOuterPosition.Y);
 
@@ -579,7 +603,8 @@ void PieChart::createTextLabelShape(
          *       is crucial (and currently lacking)!
          * TODO: * change bestFit to treat the width as a max width, and 
reduce if beneficial
          */
-        if (!performLabelBestFitInnerPlacement(rParam, aPieLabelInfo))
+        if (!performLabelBestFitInnerPlacement(rParam, aPieLabelInfo,
+                    fRadiusScale, aShift))
         {
             if (m_aAvailableOuterRect.getWidth())
             {
@@ -620,7 +645,8 @@ void PieChart::createTextLabelShape(
                     eAlignment, css::chart::DataLabelPlacement::OUTSIDE,
                     rParam.mfUnitCircleStartAngleDegree,
                     rParam.mfUnitCircleWidthAngleDegree, 
rParam.mfUnitCircleInnerRadius,
-                    rParam.mfUnitCircleOuterRadius, rParam.mfLogicZ + 0.5, 0);
+                    rParam.mfUnitCircleOuterRadius * fRadiusScale,
+                    rParam.mfLogicZ + 0.5, 0, aShift);
             aPieLabelInfo.aFirstPosition
                 = basegfx::B2IVector(aScreenPosition2D.X, aScreenPosition2D.Y);
 
@@ -726,6 +752,58 @@ void PieChart::createTextLabelShape(
     m_aLabelInfoList.push_back(aPieLabelInfo);
 }
 
+// Put labels in one bar of a bar-of-pie chart. This is quite basic and doesn't
+// deal with the possibility of the bar being too small for the label text.
+void PieChart::createBarLabelShape(
+    const rtl::Reference<SvxShapeGroupAnyD>& xTextTarget,
+    VDataSeries& rSeries, sal_Int32 nPointIndex, double fBarBottom,
+    double fBarTop, ShapeParam& rParam)
+{
+    if (!rSeries.getDataPointLabelIfLabel(nPointIndex))
+        // There is no text label for this data point.  Nothing to do.
+        return;
+
+    // Ignore the label placement specification, and just center all labels
+    const LabelAlignment eAlignment(LABEL_ALIGN_CENTER);
+
+    css::awt::Point aPos;
+    css::awt::Size aSz;
+
+    getBarRect(&aPos, &aSz, fBarBottom, fBarTop, rParam);
+
+    // The screen position of the label anchor point is the center of the bar
+    awt::Point aScreenPosition2D(
+            aPos.X + aSz.Width/2.0,
+            aPos.Y + aSz.Height/2.0);
+
+    const double fTextMaximumFrameWidth = 0.8 * (m_fBarRight - m_fBarLeft);
+    const sal_Int32 nTextMaximumFrameWidth = ceil(fTextMaximumFrameWidth);
+
+    ///the text shape for the label is created
+    PieLabelInfo aPieLabelInfo;
+    const double nVal = rSeries.getYValue(nPointIndex);
+    aPieLabelInfo.xTextShape = createDataLabel(
+        xTextTarget, rSeries, nPointIndex, nVal, rParam.mfLogicYSum,
+        aScreenPosition2D, eAlignment, 0, nTextMaximumFrameWidth);
+
+    ///a new `PieLabelInfo` instance is initialized with all the info related 
to
+    ///the current label in order to simplify later label position 
rearrangement;
+    rtl::Reference< SvxShape > xChild = aPieLabelInfo.xTextShape;
+
+    ///text shape could be empty; in that case there is no need to add label 
info
+    if( !xChild.is() )
+        return;
+
+    aPieLabelInfo.xLabelGroupShape = 
dynamic_cast<SvxShapeGroupAnyD*>(xChild->getParent().get());
+    aPieLabelInfo.fValue = nVal;
+    aPieLabelInfo.bMovementAllowed = false;
+    aPieLabelInfo.bMoved = false;
+    aPieLabelInfo.xTextTarget = xTextTarget;
+    aPieLabelInfo.bShowLeaderLine = false;
+
+    m_aLabelInfoList.push_back(aPieLabelInfo);
+}
+
 void PieChart::addSeries( std::unique_ptr<VDataSeries> pSeries, sal_Int32 /* 
zSlot */, sal_Int32 /* xSlot */, sal_Int32 /* ySlot */ )
 {
     VSeriesPlotter::addSeries( std::move(pSeries), 0, -1, 0 );
@@ -1269,8 +1347,11 @@ void PieChart::createOneRing(
                 }
             }
 
-            ///create label
-            createTextLabelShape(xTextTarget, *pSeries, nPropIdx, aParam);
+            ///create label, *except* for composite wedge
+            if (!(eType == SubPieType::LEFT && nPointIndex == 
pDataSrc->getNPoints(pSeries,
+                    SubPieType::LEFT) - 1)) {
+                createTextLabelShape(xTextTarget, *pSeries, nPropIdx, aParam, 
eType);
+            }
 
             if(!bDoExplode)
             {
@@ -1383,7 +1464,8 @@ void PieChart::createOneBar(
         }
 
         ///create label
-        createTextLabelShape(xTextTarget, *pSeries, nPropIdx, aParam);
+        createBarLabelShape(xTextTarget, *pSeries, nPropIdx, fBarBottom,
+                fBarTop, aParam);
 
         ShapeFactory::setShapeName( xPointShape,
                 ObjectIdentifier::createPointCID( pSeries->getPointCID_Stub(),
@@ -1879,7 +1961,9 @@ void PieChart::rearrangeLabelToAvoidOverlapIfRequested( 
const awt::Size& rPageSi
  *   4. the top edge when 225 < alpha < 315.
  *
  **/
-bool PieChart::performLabelBestFitInnerPlacement(ShapeParam& rShapeParam, 
PieLabelInfo const & rPieLabelInfo)
+bool PieChart::performLabelBestFitInnerPlacement(ShapeParam& rShapeParam,
+        PieLabelInfo const & rPieLabelInfo, double fRadiusScale,
+        const ::basegfx::B3DVector& aShift)
 {
     SAL_INFO( "chart2.pie.label.bestfit.inside",
               "** PieChart::performLabelBestFitInnerPlacement invoked **" );
@@ -1892,12 +1976,13 @@ bool 
PieChart::performLabelBestFitInnerPlacement(ShapeParam& rShapeParam, PieLab
 
     // get the middle point of the arc representing the pie slice border
     double fLogicZ = rShapeParam.mfLogicZ + 1.0;
-    awt::Point aMiddleArcPoint = 
PlottingPositionHelper::transformSceneToScreenPosition(
-            m_aPosHelper.transformUnitCircleToScene(
+    drawing::Position3D aUnitCirclePt = 
m_aPosHelper.transformUnitCircleToScene(
                     fBisectingRayAngleDeg,
-                    rShapeParam.mfUnitCircleOuterRadius,
-                    fLogicZ ),
-            m_xLogicTarget, m_nDimension );
+                    rShapeParam.mfUnitCircleOuterRadius * fRadiusScale,
+                    fLogicZ,
+                    aShift);
+    awt::Point aMiddleArcPoint = 
PlottingPositionHelper::transformSceneToScreenPosition(
+            aUnitCirclePt, m_xLogicTarget, m_nDimension );
 
     // compute the pie radius
     basegfx::B2IVector aPieCenter = rPieLabelInfo.aOrigin;
@@ -1910,7 +1995,7 @@ bool 
PieChart::performLabelBestFitInnerPlacement(ShapeParam& rShapeParam, PieLab
     // the bb is moved as much as possible near to the border of the pie,
     // anyway a small offset from the border is present (0.025 * pie radius)
     const double fPieBorderOffset = 0.025;
-    fPieRadius = fPieRadius - fPieRadius * fPieBorderOffset;
+    fPieRadius *= (1 - fPieBorderOffset);
 
     SAL_INFO( "chart2.pie.label.bestfit.inside",
               "    pie sector:" );
diff --git a/chart2/source/view/charttypes/PieChart.hxx 
b/chart2/source/view/charttypes/PieChart.hxx
index 6f29ea7e894c..c5cb1e535cc8 100644
--- a/chart2/source/view/charttypes/PieChart.hxx
+++ b/chart2/source/view/charttypes/PieChart.hxx
@@ -186,7 +186,15 @@ private: //methods
      */
     void createTextLabelShape(
         const rtl::Reference<SvxShapeGroupAnyD>& xTextTarget,
-        VDataSeries& rSeries, sal_Int32 nPointIndex, ShapeParam& rParam );
+        VDataSeries& rSeries, sal_Int32 nPointIndex, ShapeParam& rParam ,
+        enum SubPieType eType );
+
+    /** Same as createTextLabelShape(), but for bar-of-pie bar charts.
+     */
+    void createBarLabelShape(
+        const rtl::Reference<SvxShapeGroupAnyD>& xTextTarget,
+        VDataSeries& rSeries, sal_Int32 nPointIndex,
+        double fBarBottom, double fBarTop, ShapeParam& rParam);
 
     /** This method sets `m_fMaxOffset` to the maximum `Offset` property and
      *  returns it. There is a `Offset` property for each entry in a data
@@ -209,7 +217,9 @@ struct PieLabelInfo;
                                 , const css::awt::Size& rPageSize );
 
     bool                performLabelBestFitInnerPlacement( ShapeParam& 
rShapeParam
-                                , PieLabelInfo const & rPieLabelInfo );
+                                , PieLabelInfo const & rPieLabelInfo
+                                , double fRadiusScale
+                                , const ::basegfx::B3DVector& aShift);
 
     // A standalone pie, one pie in a pie-of-pie, or one ring of a donut
     void                createOneRing([[maybe_unused]]enum SubPieType eType
@@ -231,6 +241,9 @@ struct PieLabelInfo;
             const PieDataSrcBase *pDataSrc,
             sal_Int32 n3DRelativeHeight);
 
+    void getBarRect(css::awt::Point *pPos, css::awt::Size *pSz,
+            double fBarBottom, double fBarTop, const ShapeParam& rParam) const;
+
     // Determine left endpoints of connecting lines. These will terminate 
either
     // at the corners of the composite wedge (if the wedge is small enough), or
     // tangent to the left pie circle (if the wedge is larger). The endpoints
@@ -262,6 +275,7 @@ private: //member
     bool                  m_bUseRings;
     bool                  m_bSizeExcludesLabelsAndExplodedSegments;
     ::css::chart2::PieChartSubType m_eSubType;
+    // Number of entries in an of-pie composite wedge
     sal_Int32             m_nCompositeSize;
 
     struct PieLabelInfo
diff --git a/chart2/source/view/inc/PlottingPositionHelper.hxx 
b/chart2/source/view/inc/PlottingPositionHelper.hxx
index 916668dd6c14..ba2b6104bdc5 100644
--- a/chart2/source/view/inc/PlottingPositionHelper.hxx
+++ b/chart2/source/view/inc/PlottingPositionHelper.hxx
@@ -225,12 +225,17 @@ public:
     css::drawing::Position3D
             transformAngleRadiusToScene( double fLogicValueOnAngleAxis, double 
fLogicValueOnRadiusAxis, double fLogicZ, bool bDoScaling=true ) const;
 
-    /** It returns the scene coordinates of the passed point: this point is
-     *  described through a normalized cylindrical coordinate system.
-     *  (For a pie chart the origin of the coordinate system is the pie 
center).
+    /** Return the scene coordinates of the passed point: this point is
+     *  described through a normalized cylindrical coordinate system, with an
+     *  optional offset.
+     *  (For a standard pie chart the origin of the coordinate system is the
+     *  pie center; for an of-pie chart the components of the aOffset
+     *  parameter are not all zero).
      */
     css::drawing::Position3D
-            transformUnitCircleToScene( double fUnitAngleDegree, double 
fUnitRadius, double fLogicZ ) const;
+            transformUnitCircleToScene( double fUnitAngleDegree
+                    , double fUnitRadius, double fLogicZ
+                    , const ::basegfx::B3DVector& aOffset = 
::basegfx::B3DVector()) const;
 
     using PlottingPositionHelper::transformScaledLogicToScene;
 
diff --git a/chart2/source/view/inc/PolarLabelPositionHelper.hxx 
b/chart2/source/view/inc/PolarLabelPositionHelper.hxx
index 84f4ff1dc83c..c980495f68c8 100644
--- a/chart2/source/view/inc/PolarLabelPositionHelper.hxx
+++ b/chart2/source/view/inc/PolarLabelPositionHelper.hxx
@@ -59,7 +59,8 @@ public:
                         , double fUnitCircleStartAngleDegree, double 
fUnitCircleWidthAngleDegree
                         , double fUnitCircleInnerRadius, double 
fUnitCircleOuterRadius
                         , double fLogicZ
-                        , sal_Int32 nScreenValueOffsetInRadiusDirection ) 
const;
+                        , sal_Int32 nScreenValueOffsetInRadiusDirection
+                        , const ::basegfx::B3DVector& aOffset = 
::basegfx::B3DVector()) const;
 
 private:
     PolarPlottingPositionHelper*    m_pPosHelper;
diff --git a/chart2/source/view/main/PlottingPositionHelper.cxx 
b/chart2/source/view/main/PlottingPositionHelper.cxx
index dfbf38bbd90e..0f8c223537b2 100644
--- a/chart2/source/view/main/PlottingPositionHelper.cxx
+++ b/chart2/source/view/main/PlottingPositionHelper.cxx
@@ -622,8 +622,10 @@ drawing::Position3D 
PolarPlottingPositionHelper::transformScaledLogicToScene( do
     double fLogicValueOnRadiusAxis = m_bSwapXAndY ? fX : fY;
     return transformAngleRadiusToScene( fLogicValueOnAngleAxis, 
fLogicValueOnRadiusAxis, fZ, false );
 }
-drawing::Position3D PolarPlottingPositionHelper::transformUnitCircleToScene( 
double fUnitAngleDegree, double fUnitRadius
-                                                                            , 
double fLogicZ ) const
+drawing::Position3D PolarPlottingPositionHelper::transformUnitCircleToScene(
+        double fUnitAngleDegree, double fUnitRadius,
+        double fLogicZ ,
+        const ::basegfx::B3DVector& aOffset) const
 {
     double fAnglePi = basegfx::deg2rad(fUnitAngleDegree);
 
@@ -633,6 +635,7 @@ drawing::Position3D 
PolarPlottingPositionHelper::transformUnitCircleToScene( dou
 
     //!! applying matrix to vector does ignore translation, so it is important 
to use a B3DPoint here instead of B3DVector
     ::basegfx::B3DPoint aPoint(fX,fY,fZ);
+    aPoint += aOffset;
     ::basegfx::B3DPoint aRet = m_aUnitCartesianToScene * aPoint;
     return B3DPointToPosition3D(aRet);
 }
diff --git a/chart2/source/view/main/PolarLabelPositionHelper.cxx 
b/chart2/source/view/main/PolarLabelPositionHelper.cxx
index 44070603c75a..5662f8639f08 100644
--- a/chart2/source/view/main/PolarLabelPositionHelper.cxx
+++ b/chart2/source/view/main/PolarLabelPositionHelper.cxx
@@ -17,6 +17,7 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include <BaseGFXHelper.hxx>
 #include <PolarLabelPositionHelper.hxx>
 #include <PlottingPositionHelper.hxx>
 #include <basegfx/vector/b2dvector.hxx>
@@ -62,7 +63,8 @@ awt::Point 
PolarLabelPositionHelper::getLabelScreenPositionAndAlignmentForUnitCi
         , double fUnitCircleStartAngleDegree, double 
fUnitCircleWidthAngleDegree
         , double fUnitCircleInnerRadius, double fUnitCircleOuterRadius
         , double fLogicZ
-        , sal_Int32 nScreenValueOffsetInRadiusDirection ) const
+        , sal_Int32 nScreenValueOffsetInRadiusDirection
+        , const ::basegfx::B3DVector& aOffset) const
 {
     bool bCenter = (nLabelPlacement != css::chart::DataLabelPlacement::OUTSIDE)
                 && (nLabelPlacement != css::chart::DataLabelPlacement::INSIDE);
@@ -75,7 +77,8 @@ awt::Point 
PolarLabelPositionHelper::getLabelScreenPositionAndAlignmentForUnitCi
         fRadius = fUnitCircleInnerRadius + 
(fUnitCircleOuterRadius-fUnitCircleInnerRadius)/2.0 ;
 
     awt::Point aRet( transformSceneToScreenPosition(
-        m_pPosHelper->transformUnitCircleToScene( fAngleDegree, fRadius, 
fLogicZ+0.5 ) ) );
+        m_pPosHelper->transformUnitCircleToScene( fAngleDegree, fRadius,
+            fLogicZ+0.5, aOffset ) ) );
 
     if(m_nDimensionCount==3 && nLabelPlacement == 
css::chart::DataLabelPlacement::OUTSIDE)
     {
@@ -83,10 +86,11 @@ awt::Point 
PolarLabelPositionHelper::getLabelScreenPositionAndAlignmentForUnitCi
         //take the farthest point to put the label to
 
         awt::Point aP0( transformSceneToScreenPosition(
-            m_pPosHelper->transformUnitCircleToScene( 0, 0, fLogicZ ) ) );
+            m_pPosHelper->transformUnitCircleToScene( 0, 0, fLogicZ, aOffset ) 
) );
         awt::Point aP1(aRet);
         awt::Point aP2( transformSceneToScreenPosition(
-            m_pPosHelper->transformUnitCircleToScene( fAngleDegree, fRadius, 
fLogicZ-0.5 ) ) );
+            m_pPosHelper->transformUnitCircleToScene( fAngleDegree, fRadius,
+                fLogicZ-0.5, aOffset ) ) );
 
         ::basegfx::B2DVector aV0( aP0.X, aP0.Y );
         ::basegfx::B2DVector aV1( aP1.X, aP1.Y );
@@ -142,7 +146,8 @@ awt::Point 
PolarLabelPositionHelper::getLabelScreenPositionAndAlignmentForUnitCi
     if( nScreenValueOffsetInRadiusDirection != 0)
     {
         awt::Point aOrigin( transformSceneToScreenPosition(
-            m_pPosHelper->transformUnitCircleToScene( 0.0, 0.0, fLogicZ+0.5 ) 
) );
+            m_pPosHelper->transformUnitCircleToScene( 0.0, 0.0, fLogicZ+0.5,
+                aOffset ) ) );
         basegfx::B2IVector aDirection( aRet.X- aOrigin.X, aRet.Y- aOrigin.Y );
         aDirection.setLength(nScreenValueOffsetInRadiusDirection);
         aRet.X += aDirection.getX();

Reply via email to