diff options
author | Kurt Nordback <kurt.nordback@protonmail.com> | 2023-11-20 11:46:10 -0700 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2024-02-18 07:33:18 +0100 |
commit | e1573deaf1b2ecd946d23a4ce623546c08036ec7 (patch) | |
tree | 03a94b8b7c626ef2d174f7050a69039769b59ecf /chart2 | |
parent | 670de4eadcbb84394fd49c1c0c949dd35bd2303b (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.cxx | 83 |
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: |