summaryrefslogtreecommitdiff
path: root/chart2
diff options
context:
space:
mode:
authorKurt Nordback <kurt.nordback@protonmail.com>2023-11-20 11:46:10 -0700
committerNoel Grandin <noel.grandin@collabora.co.uk>2024-02-18 07:33:18 +0100
commite1573deaf1b2ecd946d23a4ce623546c08036ec7 (patch)
tree03a94b8b7c626ef2d174f7050a69039769b59ecf /chart2
parent670de4eadcbb84394fd49c1c0c949dd35bd2303b (diff)
tdf#50934: Implement connector lines for pie-of-pie
Change-Id: Ifca083aa07b28d5c604382decaefedfe653ff8ab Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160731 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'chart2')
-rw-r--r--chart2/source/view/charttypes/PieChart.cxx83
1 files changed, 76 insertions, 7 deletions
diff --git a/chart2/source/view/charttypes/PieChart.cxx b/chart2/source/view/charttypes/PieChart.cxx
index a946616ea5fe..9b1494596598 100644
--- a/chart2/source/view/charttypes/PieChart.cxx
+++ b/chart2/source/view/charttypes/PieChart.cxx
@@ -928,20 +928,26 @@ void PieChart::createShapes()
createOneBar(SubPieType::RIGHT, aParam, xSeriesTarget,
xTextTarget, pSeries, pDataSrc, n3DRelativeHeight);
- // draw connecting lines
+ //
+ // Draw connecting lines
+ //
double xl0, xl1, yl0, yl1, x0, y0, x1, y1, y2, y3;
- if (m_aPosHelper.m_fAngleDegreeOffset < 90.0) {
+ // Get coordinates of "corners" of left composite wedge
+ sal_Int32 nEnd = pDataSrc->getNPoints(pSeries, SubPieType::LEFT);
+ double compFrac = pDataSrc->getData(pSeries, nEnd - 1,
+ SubPieType::LEFT) / aParam.mfLogicYSum;
+ if (compFrac < 0.5) {
xl0 = aParam.mfUnitCircleOuterRadius * m_fLeftScale *
- cos(m_aPosHelper.m_fAngleDegreeOffset * M_PI / 180) +
- m_fLeftShift;
+ cos(compFrac * M_PI) + m_fLeftShift;
yl0 = aParam.mfUnitCircleOuterRadius * m_fLeftScale *
- sin(m_aPosHelper.m_fAngleDegreeOffset * M_PI / 180);
+ sin(compFrac * M_PI);
} else {
xl0 = m_fLeftShift;
yl0 = aParam.mfUnitCircleOuterRadius * m_fLeftScale;
}
+ // Coordinates of bar top left corner
xl1 = m_fBarLeft;
yl1 = m_fFullBarHeight / 2;
@@ -974,12 +980,75 @@ void PieChart::createShapes()
break;
}
case PieChartSubType_PIE:
+ {
pDataSrc = &ofPieSrc;
createOneRing(SubPieType::LEFT, 0, aParam, xSeriesTarget,
xTextTarget, pSeries, pDataSrc, n3DRelativeHeight);
createOneRing(SubPieType::RIGHT, 0, aParam, xSeriesTarget,
xTextTarget, pSeries, pDataSrc, n3DRelativeHeight);
+
+ //
+ // Draw connecting lines
+ //
+ double xl0, xl1, yl0, yl1, x0, y0, x1, y1, y2, y3;
+
+ // Get coordinates of "corners" of left composite wedge
+ sal_Int32 nEnd = pDataSrc->getNPoints(pSeries, SubPieType::LEFT);
+ double compFrac = pDataSrc->getData(pSeries, nEnd - 1,
+ SubPieType::LEFT) / aParam.mfLogicYSum;
+ if (compFrac < 0.5) {
+ // Translated, per below
+ xl0 = aParam.mfUnitCircleOuterRadius * m_fLeftScale *
+ cos(compFrac * M_PI) + m_fLeftShift - m_fRightShift;
+ yl0 = aParam.mfUnitCircleOuterRadius * m_fLeftScale *
+ sin(compFrac * M_PI);
+ } else {
+ // Translated, per below
+ xl0 = m_fLeftShift - m_fRightShift;
+ yl0 = aParam.mfUnitCircleOuterRadius * m_fLeftScale;
+ }
+
+ // Compute tangent point on the right-hand circle of the line
+ // through (xl0, yl0). If we translate things so the right-hand
+ // circle is centered on the origin, then this point (x,y)
+ // satisfies these two equations, where r is the radius of the
+ // right-hand circle:
+ // (1) x^2 + y^2 = r^2
+ // (2) (y - yl0) / (x - xl0) = -x / y
+ const double r = aParam.mfUnitCircleOuterRadius * m_fRightScale;
+
+ xl1 = (r*r * xl0 + yl0 * r * sqrt(xl0*xl0 + yl0*yl0 - r*r)) /
+ (xl0*xl0 + yl0*yl0);
+ yl1 = sqrt(r*r - xl1*xl1);
+
+ // Now translate back to the coordinates we use
+ xl0 += m_fRightShift;
+ xl1 += m_fRightShift;
+
+ x0 = m_aPosHelper.transformUnitCircleToScene(0, xl0, 0).PositionX;
+ y0 = m_aPosHelper.transformUnitCircleToScene(90, yl0, 0).PositionY;
+ x1 = m_aPosHelper.transformUnitCircleToScene(0, xl1, 0).PositionX;
+ y1 = m_aPosHelper.transformUnitCircleToScene(90, yl1, 0).PositionY;
+ y2 = m_aPosHelper.transformUnitCircleToScene(90, -yl0, 0).PositionY;
+ y3 = m_aPosHelper.transformUnitCircleToScene(90, -yl1, 0).PositionY;
+
+ std::vector<std::vector<css::drawing::Position3D>> linePts;
+ linePts.resize(2);
+ linePts[0].push_back(css::drawing::Position3D(x0, y0, aParam.mfLogicZ));
+ linePts[0].push_back(css::drawing::Position3D(x1, y1, aParam.mfLogicZ));
+ linePts[1].push_back(css::drawing::Position3D(x0, y2, aParam.mfLogicZ));
+ linePts[1].push_back(css::drawing::Position3D(x1, y3, aParam.mfLogicZ));
+
+ VLineProperties aVLineProperties; // default black
+
+ //create line
+ rtl::Reference<SvxShapeGroupAnyD> xSeriesGroupShape_Shapes =
+ getSeriesGroupShape(pSeries, xSeriesTarget);
+ rtl::Reference<SvxShape> xShape = ShapeFactory::createLine2D(
+ xSeriesGroupShape_Shapes, linePts, &aVLineProperties);
+
break;
+ }
default:
assert(false); // this shouldn't happen
}
@@ -1104,9 +1173,9 @@ void PieChart::createOneRing([[maybe_unused]]enum SubPieType eType,
bConcentricExplosion);
// Handle coloring of the composite wedge
- sal_Int32 nEnd = pDataSrc->getNPoints(pSeries, eType);
const sal_Int32 nPropIdx = (
- eType == SubPieType::LEFT && nPointIndex == nEnd - 1 ?
+ eType == SubPieType::LEFT &&
+ nPointIndex == pDataSrc->getNPoints(pSeries, SubPieType::LEFT) - 1 ?
pSeries->getTotalPointCount() :
nPointIndex);
///point color: