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>
diff --git a/chart2/source/view/charttypes/PieChart.cxx b/chart2/source/view/charttypes/PieChart.cxx
index a946616..9b14945 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: