summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chart2/qa/extras/chart2dump/reference/piecharttest/donut_chart.txt10
-rw-r--r--chart2/source/view/charttypes/PieChart.cxx60
-rw-r--r--chart2/source/view/charttypes/PieChart.hxx4
3 files changed, 55 insertions, 19 deletions
diff --git a/chart2/qa/extras/chart2dump/reference/piecharttest/donut_chart.txt b/chart2/qa/extras/chart2dump/reference/piecharttest/donut_chart.txt
index b2dfd33295a2..c1af41103de5 100644
--- a/chart2/qa/extras/chart2dump/reference/piecharttest/donut_chart.txt
+++ b/chart2/qa/extras/chart2dump/reference/piecharttest/donut_chart.txt
@@ -35,15 +35,15 @@
16728590
/// /D=0:CS=0:CT=0:Series=0:Point=2
// aSlicePosition.X
-8909
+9033
// aSlicePosition.Y
-4532
+4635
// aSliceSize.Height
-4689
+4659
// aSliceSize.Width
-2544
+2458
// aSliceTransformation
-2544;0;8909;0;4689;4532;0;0;1
+2458;0;9033;0;4659;4635;0;0;1
// static_cast<sal_Int32>(aSliceFillStyle)
1
// static_cast<sal_Int32>(aSliceFillColor)
diff --git a/chart2/source/view/charttypes/PieChart.cxx b/chart2/source/view/charttypes/PieChart.cxx
index 806bc468414c..a81428c24c15 100644
--- a/chart2/source/view/charttypes/PieChart.cxx
+++ b/chart2/source/view/charttypes/PieChart.cxx
@@ -246,17 +246,47 @@ bool PieChart::shouldSnapRectToUsedArea()
rtl::Reference<SvxShape> PieChart::createDataPoint(
const rtl::Reference<SvxShapeGroupAnyD>& xTarget,
const uno::Reference<beans::XPropertySet>& xObjectProperties,
- const ShapeParam& rParam )
+ const ShapeParam& rParam,
+ const sal_Int32 nPointCount,
+ const bool bConcentricExplosion)
{
//transform position:
drawing::Direction3D aOffset;
- if (rParam.mfExplodePercentage != 0.0)
- {
- double fAngle = rParam.mfUnitCircleStartAngleDegree + rParam.mfUnitCircleWidthAngleDegree/2.0;
- double fRadius = (rParam.mfUnitCircleOuterRadius-rParam.mfUnitCircleInnerRadius)*rParam.mfExplodePercentage;
- drawing::Position3D aOrigin = m_pPosHelper->transformUnitCircleToScene(0, 0, rParam.mfLogicZ);
- drawing::Position3D aNewOrigin = m_pPosHelper->transformUnitCircleToScene(fAngle, fRadius, rParam.mfLogicZ);
- aOffset = aNewOrigin - aOrigin;
+ double fExplodedInnerRadius = rParam.mfUnitCircleInnerRadius;
+ double fExplodedOuterRadius = rParam.mfUnitCircleOuterRadius;
+ double fStartAngle = rParam.mfUnitCircleStartAngleDegree;
+ double fWidthAngle = rParam.mfUnitCircleWidthAngleDegree;
+
+ if (rParam.mfExplodePercentage != 0.0) {
+ double fRadius = (fExplodedOuterRadius-fExplodedInnerRadius)*rParam.mfExplodePercentage;
+
+ if (bConcentricExplosion) {
+
+ // For concentric explosion, increase the radius but retain the original
+ // arc length of all ring segments together. This results in a gap
+ // that's evenly divided among all segments, assuming they all have
+ // the same explosion percentage
+ assert(fExplodedInnerRadius >= 0 && fExplodedOuterRadius > 0);
+ double fAngleRatio = (fExplodedInnerRadius + fExplodedOuterRadius) /
+ (fExplodedInnerRadius + fExplodedOuterRadius + 2 * fRadius);
+
+ assert(nPointCount > 0);
+ double fAngleGap = 360 * (1.0 - fAngleRatio) / nPointCount;
+ fStartAngle += fAngleGap / 2;
+ fWidthAngle -= fAngleGap;
+
+ fExplodedInnerRadius += fRadius;
+ fExplodedOuterRadius += fRadius;
+
+ } else {
+ // For the non-concentric explosion case, keep the original radius
+ // but shift the circle origin
+ double fAngle = fStartAngle + fWidthAngle/2.0;
+
+ drawing::Position3D aOrigin = m_pPosHelper->transformUnitCircleToScene(0, 0, rParam.mfLogicZ);
+ drawing::Position3D aNewOrigin = m_pPosHelper->transformUnitCircleToScene(fAngle, fRadius, rParam.mfLogicZ);
+ aOffset = aNewOrigin - aOrigin;
+ }
}
//create point
@@ -264,16 +294,16 @@ rtl::Reference<SvxShape> PieChart::createDataPoint(
if(m_nDimension==3)
{
xShape = ShapeFactory::createPieSegment( xTarget
- , rParam.mfUnitCircleStartAngleDegree, rParam.mfUnitCircleWidthAngleDegree
- , rParam.mfUnitCircleInnerRadius, rParam.mfUnitCircleOuterRadius
+ , fStartAngle, fWidthAngle
+ , fExplodedInnerRadius, fExplodedOuterRadius
, aOffset, B3DHomMatrixToHomogenMatrix( m_pPosHelper->getUnitCartesianToScene() )
, rParam.mfDepth );
}
else
{
xShape = ShapeFactory::createPieSegment2D( xTarget
- , rParam.mfUnitCircleStartAngleDegree, rParam.mfUnitCircleWidthAngleDegree
- , rParam.mfUnitCircleInnerRadius, rParam.mfUnitCircleOuterRadius
+ , fStartAngle, fWidthAngle
+ , fExplodedInnerRadius, fExplodedOuterRadius
, aOffset, B3DHomMatrixToHomogenMatrix( m_pPosHelper->getUnitCartesianToScene() ) );
}
PropertyMapper::setMappedProperties( *xShape, xObjectProperties, PropertyMapper::getPropertyNameMapForFilledSeriesProperties() );
@@ -808,9 +838,13 @@ void PieChart::createShapes()
///create data point
aParam.mfLogicZ = -1.0; // For 3D pie chart label position
+
+ // Do concentric explosion if it's a donut chart with more than one series
+ const bool bConcentricExplosion = m_bUseRings && (m_aZSlots.front().size() > 1);
rtl::Reference<SvxShape> xPointShape =
createDataPoint(
- xSeriesGroupShape_Shapes, xPointProperties, aParam);
+ xSeriesGroupShape_Shapes, xPointProperties, aParam, nPointCount,
+ bConcentricExplosion);
///point color:
if (!pSeries->hasPointOwnColor(nPointIndex) && m_xColorScheme.is())
diff --git a/chart2/source/view/charttypes/PieChart.hxx b/chart2/source/view/charttypes/PieChart.hxx
index c990cc6e4a13..9a5b7fb4c9d6 100644
--- a/chart2/source/view/charttypes/PieChart.hxx
+++ b/chart2/source/view/charttypes/PieChart.hxx
@@ -67,7 +67,9 @@ private: //methods
createDataPoint(
const rtl::Reference<SvxShapeGroupAnyD>& xTarget,
const css::uno::Reference<css::beans::XPropertySet>& xObjectProperties,
- const ShapeParam& rParam );
+ const ShapeParam& rParam,
+ const sal_Int32 nPointCount,
+ const bool bConcentricExplosion);
/** This method creates a text shape for a label of a data point.
*