LibreOffice Module chart2 (master) 1
Classes | Public Member Functions | Private Member Functions | Private Attributes | List of all members
chart::PieChart Class Reference

#include <PieChart.hxx>

Inheritance diagram for chart::PieChart:
[legend]
Collaboration diagram for chart::PieChart:
[legend]

Classes

struct  PieLabelInfo
 
struct  ShapeParam
 

Public Member Functions

 PieChart ()=delete
 
 PieChart (const rtl::Reference< ::chart::ChartType > &xChartTypeModel, sal_Int32 nDimensionCount, bool bExcludingPositioning)
 
virtual ~PieChart () override
 
virtual void createShapes () override
 This method creates all shapes needed for representing the pie chart. More...
 
virtual void rearrangeLabelToAvoidOverlapIfRequested (const css::awt::Size &rPageSize) override
 
virtual void setScales (std::vector< ExplicitScaleData > &&rScales, bool bSwapXAndYAxis) override
 
virtual void addSeries (std::unique_ptr< VDataSeries > pSeries, sal_Int32 zSlot, sal_Int32 xSlot, sal_Int32 ySlot) override
 A new series can be positioned relative to other series in a chart. More...
 
virtual css::drawing::Direction3D getPreferredDiagramAspectRatio () const override
 a value <= 0 for a directions means that this direction can be stretched arbitrary More...
 
virtual bool shouldSnapRectToUsedArea () override
 
virtual double getMinimumX () override
 
virtual double getMaximumX () override
 
virtual double getMinimumYInRange (double fMinimumX, double fMaximumX, sal_Int32 nAxisIndex) override
 
virtual double getMaximumYInRange (double fMinimumX, double fMaximumX, sal_Int32 nAxisIndex) override
 
virtual bool isExpandBorderToIncrementRhythm (sal_Int32 nDimensionIndex) override
 
virtual bool isExpandIfValuesCloseToBorder (sal_Int32 nDimensionIndex) override
 
virtual bool isExpandWideValuesToZero (sal_Int32 nDimensionIndex) override
 
virtual bool isExpandNarrowValuesTowardZero (sal_Int32 nDimensionIndex) override
 
virtual bool isSeparateStackingForDifferentSigns (sal_Int32 nDimensionIndex) override
 
- Public Member Functions inherited from chart::VSeriesPlotter
 VSeriesPlotter ()=delete
 
virtual ~VSeriesPlotter () override
 
virtual void addSeries (std::unique_ptr< VDataSeries > pSeries, sal_Int32 zSlot, sal_Int32 xSlot, sal_Int32 ySlot)
 A new series can be positioned relative to other series in a chart. More...
 
virtual css::drawing::Direction3D getPreferredDiagramAspectRatio () const
 a value <= 0 for a directions means that this direction can be stretched arbitrary More...
 
void addSecondaryValueScale (const ExplicitScaleData &rScale, sal_Int32 nAxisIndex)
 this enables you to handle series on the same x axis with different y axis the property AttachedAxisIndex at a dataseries indicates which value scale is to use (0==AttachedAxisIndex or a not set AttachedAxisIndex property indicates that this series should be scaled at the main y-axis; 1==AttachedAxisIndex indicates that the series should be scaled at the first secondary axis if there is any otherwise at the main y axis and so on. More...
 
virtual double getMinimumX () override
 
virtual double getMaximumX () override
 
virtual double getMinimumYInRange (double fMinimumX, double fMaximumX, sal_Int32 nAxisIndex) override
 
virtual double getMaximumYInRange (double fMinimumX, double fMaximumX, sal_Int32 nAxisIndex) override
 
virtual double getMinimumZ () override
 
virtual double getMaximumZ () override
 
virtual bool isExpandBorderToIncrementRhythm (sal_Int32 nDimensionIndex) override
 
virtual bool isExpandIfValuesCloseToBorder (sal_Int32 nDimensionIndex) override
 
virtual bool isExpandWideValuesToZero (sal_Int32 nDimensionIndex) override
 
virtual bool isExpandNarrowValuesTowardZero (sal_Int32 nDimensionIndex) override
 
virtual bool isSeparateStackingForDifferentSigns (sal_Int32 nDimensionIndex) override
 
virtual tools::Long calculateTimeResolutionOnXAxis () override
 
virtual void setTimeResolutionOnXAxis (tools::Long nTimeResolution, const Date &rNullDate) override
 
void getMinimumAndMaximumX (double &rfMinimum, double &rfMaximum) const
 
void getMinimumAndMaximumYInContinuousXRange (double &rfMinY, double &rfMaxY, double fMinX, double fMaxX, sal_Int32 nAxisIndex) const
 
virtual std::vector< ViewLegendEntrycreateLegendEntries (const css::awt::Size &rEntryKeyAspectRatio, css::chart2::LegendPosition eLegendPosition, const css::uno::Reference< css::beans::XPropertySet > &xTextProperties, const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const css::uno::Reference< css::uno::XComponentContext > &xContext, ChartModel &rModel) override
 
virtual LegendSymbolStyle getLegendSymbolStyle ()
 
virtual css::awt::Size getPreferredLegendKeyAspectRatio () override
 
virtual css::uno::Any getExplicitSymbol (const VDataSeries &rSeries, sal_Int32 nPointIndex)
 
rtl::Reference< SvxShapeGroupcreateLegendSymbolForSeries (const css::awt::Size &rEntryKeyAspectRatio, const VDataSeries &rSeries, const rtl::Reference< SvxShapeGroupAnyD > &xTarget)
 
rtl::Reference< SvxShapeGroupcreateLegendSymbolForPoint (const css::awt::Size &rEntryKeyAspectRatio, const VDataSeries &rSeries, sal_Int32 nPointIndex, const rtl::Reference< SvxShapeGroupAnyD > &xTarget)
 
std::vector< ViewLegendEntrycreateLegendEntriesForSeries (const css::awt::Size &rEntryKeyAspectRatio, const VDataSeries &rSeries, const css::uno::Reference< css::beans::XPropertySet > &xTextProperties, const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const css::uno::Reference< css::uno::XComponentContext > &xContext)
 
std::vector< ViewLegendSymbolcreateSymbols (const css::awt::Size &rEntryKeyAspectRatio, const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const css::uno::Reference< css::uno::XComponentContext > &xContext)
 
std::vector< ViewLegendSymbolcreateSymbolsForSeries (const css::awt::Size &rEntryKeyAspectRatio, const VDataSeries &rSeries, const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const css::uno::Reference< css::uno::XComponentContext > &xContext)
 
std::vector< VDataSeries * > getAllSeries ()
 
std::vector< VDataSeries const * > getAllSeries () const
 
sal_Int32 getPointCount () const
 
void setNumberFormatsSupplier (const css::uno::Reference< css::util::XNumberFormatsSupplier > &xNumFmtSupplier)
 
void setColorScheme (const css::uno::Reference< css::chart2::XColorScheme > &xColorScheme)
 
void setExplicitCategoriesProvider (ExplicitCategoriesProvider *pExplicitCategoriesProvider)
 
ExplicitCategoriesProvidergetExplicitCategoriesProvider ()
 
css::uno::Sequence< OUString > getSeriesNames () const
 
css::uno::Sequence< OUString > getAllSeriesNames () const
 
void setPageReferenceSize (const css::awt::Size &rPageRefSize)
 
void setCoordinateSystemResolution (const css::uno::Sequence< sal_Int32 > &rCoordinateSystemResolution)
 
bool PointsWereSkipped () const
 
void setPieLabelsAllowToMove (bool bIsPieOrDonut)
 
void setAvailableOuterRect (const basegfx::B2IRectangle &aAvailableOuterRect)
 
double getTransformedDepth () const
 
void releaseShapes ()
 
virtual void rearrangeLabelToAvoidOverlapIfRequested (const css::awt::Size &rPageSize)
 
bool WantToPlotInFrontOfAxisLine ()
 
virtual bool shouldSnapRectToUsedArea ()
 
OUString getLabelTextForValue (VDataSeries const &rDataSeries, sal_Int32 nPointIndex, double fValue, bool bAsPercentage)
 This method returns a text string representation of the passed numeric value by exploiting a NumberFormatterWrapper object. More...
 
- Public Member Functions inherited from chart::PlotterBase
 PlotterBase (sal_Int32 nDimension)
 
virtual ~PlotterBase ()
 
virtual void initPlotter (const rtl::Reference< SvxShapeGroupAnyD > &xLogicTarget, const rtl::Reference< SvxShapeGroupAnyD > &xFinalTarget, const OUString &rCID)
 
virtual void setScales (std::vector< ExplicitScaleData > &&rScales, bool bSwapXAndYAxis)
 
virtual void setTransformationSceneToScreen (const css::drawing::HomogenMatrix &rMatrix)
 
virtual void createShapes ()=0
 
virtual double getMinimumX ()=0
 
virtual double getMaximumX ()=0
 
virtual double getMinimumYInRange (double fMinimumX, double fMaximumX, sal_Int32 nAxisIndex)=0
 
virtual double getMaximumYInRange (double fMinimumX, double fMaximumX, sal_Int32 nAxisIndex)=0
 
virtual double getMinimumZ ()=0
 
virtual double getMaximumZ ()=0
 
virtual bool isExpandBorderToIncrementRhythm (sal_Int32 nDimensionIndex)=0
 
virtual bool isExpandIfValuesCloseToBorder (sal_Int32 nDimensionIndex)=0
 
virtual bool isExpandWideValuesToZero (sal_Int32 nDimensionIndex)=0
 
virtual bool isExpandNarrowValuesTowardZero (sal_Int32 nDimensionIndex)=0
 
virtual bool isSeparateStackingForDifferentSigns (sal_Int32 nDimensionIndex)=0
 
virtual tools::Long calculateTimeResolutionOnXAxis ()=0
 
virtual void setTimeResolutionOnXAxis (tools::Long nTimeResolution, const Date &rNullDate)=0
 
virtual css::awt::Size getPreferredLegendKeyAspectRatio ()=0
 
virtual std::vector< ViewLegendEntrycreateLegendEntries (const css::awt::Size &rEntryKeyAspectRatio, css::chart2::LegendPosition eLegendPosition, const css::uno::Reference< css::beans::XPropertySet > &xTextProperties, const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const css::uno::Reference< css::uno::XComponentContext > &xContext, ChartModel &rModel)=0
 

Private Member Functions

rtl::Reference< SvxShapecreateDataPoint (const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const css::uno::Reference< css::beans::XPropertySet > &xObjectProperties, const ShapeParam &rParam, const sal_Int32 nPointCount, const bool bConcentricExplosion)
 
void createTextLabelShape (const rtl::Reference< SvxShapeGroupAnyD > &xTextTarget, VDataSeries &rSeries, sal_Int32 nPointIndex, ShapeParam &rParam)
 This method creates a text shape for a label of a data point. More...
 
double getMaxOffset ()
 This method sets m_fMaxOffset to the maximum Offset property and returns it. More...
 
bool detectLabelOverlapsAndMove (const css::awt::Size &rPageSize)
 
void resetLabelPositionsToPreviousState ()
 
bool tryMoveLabels (PieLabelInfo const *pFirstBorder, PieLabelInfo const *pSecondBorder, PieLabelInfo *pCenter, bool bSingleCenter, bool &rbAlternativeMoveDirection, const css::awt::Size &rPageSize)
 Try to remove all overlaps that occur in the list of labels going from pFirstBorder to pSecondBorder More...
 
bool performLabelBestFitInnerPlacement (ShapeParam &rShapeParam, PieLabelInfo const &rPieLabelInfo)
 Handle the placement of the label in the best fit case: the routine try to place the label inside the related pie slice, in case of success it returns true else returns false. More...
 

Private Attributes

std::unique_ptr< PiePositionHelperm_pPosHelper
 
bool m_bUseRings
 
bool m_bSizeExcludesLabelsAndExplodedSegments
 
std::vector< PieLabelInfom_aLabelInfoList
 
double m_fMaxOffset
 

Additional Inherited Members

- Static Public Member Functions inherited from chart::VSeriesPlotter
static VSeriesPlottercreateSeriesPlotter (const rtl::Reference< ::chart::ChartType > &xChartTypeModel, sal_Int32 nDimensionCount, bool bExcludingPositioning)
 
- Static Public Member Functions inherited from chart::PlotterBase
static bool isValidPosition (const css::drawing::Position3D &rPos)
 
- Protected Member Functions inherited from chart::VSeriesPlotter
 VSeriesPlotter (rtl::Reference< ::chart::ChartType > xChartTypeModel, sal_Int32 nDimensionCount, bool bCategoryXAxis=true)
 
rtl::Reference< SvxShapeGroupAnyDgetSeriesGroupShape (VDataSeries *pDataSeries, const rtl::Reference< SvxShapeGroupAnyD > &xTarget)
 
rtl::Reference< SvxShapeGroupAnyDgetSeriesGroupShapeFrontChild (VDataSeries *pDataSeries, const rtl::Reference< SvxShapeGroupAnyD > &xTarget)
 
rtl::Reference< SvxShapeGroupAnyDgetSeriesGroupShapeBackChild (VDataSeries *pDataSeries, const rtl::Reference< SvxShapeGroupAnyD > &xTarget)
 
rtl::Reference< SvxShapeGroupAnyDgetErrorBarsGroupShape (VDataSeries &rDataSeries, const rtl::Reference< SvxShapeGroupAnyD > &xTarget, bool bYError)
 
rtl::Reference< SvxShapeTextcreateDataLabel (const rtl::Reference< SvxShapeGroupAnyD > &xTarget, VDataSeries &rDataSeries, sal_Int32 nPointIndex, double fValue, double fSumValue, const css::awt::Point &rScreenPosition2D, LabelAlignment eAlignment, sal_Int32 nOffset=0, sal_Int32 nTextWidth=0)
 This method creates a text shape for a label related to a data point and append it to the root text shape group (xTarget). More...
 
void createErrorBar (const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const css::drawing::Position3D &rPos, const css::uno::Reference< css::beans::XPropertySet > &xErrorBarProperties, const VDataSeries &rVDataSeries, sal_Int32 nIndex, bool bVertical, const double *pfScaledLogicX)
 creates two T-shaped error bars in both directions (up/down or left/right depending on the bVertical parameter) More...
 
void createErrorRectangle (const css::drawing::Position3D &rUnscaledLogicPosition, VDataSeries &rVDataSeries, sal_Int32 nIndex, const rtl::Reference< SvxShapeGroupAnyD > &rTarget, bool bUseXErrorData, bool bUseYErrorData)
 
void createErrorBar_X (const css::drawing::Position3D &rUnscaledLogicPosition, VDataSeries &rVDataSeries, sal_Int32 nPointIndex, const rtl::Reference< SvxShapeGroupAnyD > &xTarget)
 
void createErrorBar_Y (const css::drawing::Position3D &rUnscaledLogicPosition, VDataSeries &rVDataSeries, sal_Int32 nPointIndex, const rtl::Reference< SvxShapeGroupAnyD > &xTarget, double const *pfScaledLogicX)
 
void createRegressionCurvesShapes (VDataSeries const &rVDataSeries, const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const rtl::Reference< SvxShapeGroupAnyD > &xEquationTarget, bool bMaySkipPointsInRegressionCalculation)
 
void createRegressionCurveEquationShapes (const OUString &rEquationCID, const css::uno::Reference< css::beans::XPropertySet > &xEquationProperties, const rtl::Reference< SvxShapeGroupAnyD > &xEquationTarget, const css::uno::Reference< css::chart2::XRegressionCurveCalculator > &xRegressionCurveCalculator, css::awt::Point aDefaultPos)
 
virtual PlottingPositionHelpergetPlottingPositionHelper (sal_Int32 nAxisIndex) const
 
VDataSeriesgetFirstSeries () const
 
OUString getCategoryName (sal_Int32 nPointIndex) const
 
- Protected Member Functions inherited from chart::PlotterBase
rtl::Reference< SvxShapeGroupAnyDcreateGroupShape (const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const OUString &rName=OUString())
 
- Protected Member Functions inherited from chart::MinimumAndMaximumSupplier
 ~MinimumAndMaximumSupplier ()
 
- Protected Member Functions inherited from chart::LegendEntryProvider
 ~LegendEntryProvider ()
 
- Static Protected Member Functions inherited from chart::VSeriesPlotter
static rtl::Reference< SvxShapeGroupgetLabelsGroupShape (VDataSeries &rDataSeries, const rtl::Reference< SvxShapeGroupAnyD > &xTarget)
 This method creates a 2D group shape for containing all text shapes needed for this series; the group is added to the text target;. More...
 
static void addErrorBorder (const css::drawing::Position3D &rPos0, const css::drawing::Position3D &rPos1, const rtl::Reference< SvxShapeGroupAnyD > &rTarget, const css::uno::Reference< css::beans::XPropertySet > &rErrorBorderProp)
 
- Protected Attributes inherited from chart::VSeriesPlotter
PlottingPositionHelperm_pMainPosHelper
 
rtl::Reference< ::chart::ChartTypem_xChartTypeModel
 
std::vector< std::vector< VDataSeriesGroup > > m_aZSlots
 
bool m_bCategoryXAxis
 
tools::Long m_nTimeResolution
 
Date m_aNullDate
 
std::unique_ptr< NumberFormatterWrapperm_apNumberFormatterWrapper
 
css::uno::Reference< css::chart2::XColorScheme > m_xColorScheme
 
ExplicitCategoriesProviderm_pExplicitCategoriesProvider
 
css::uno::Sequence< sal_Int32 > m_aCoordinateSystemResolution
 
bool m_bPointsWereSkipped
 
bool m_bPieLabelsAllowToMove
 
basegfx::B2IRectangle m_aAvailableOuterRect
 
css::awt::Size m_aPageReferenceSize
 
- Protected Attributes inherited from chart::PlotterBase
rtl::Reference< SvxShapeGroupAnyDm_xLogicTarget
 
rtl::Reference< SvxShapeGroupAnyDm_xFinalTarget
 
OUString m_aCID
 
const sal_Int32 m_nDimension
 
PlottingPositionHelperm_pPosHelper
 

Detailed Description

Definition at line 31 of file PieChart.hxx.

Constructor & Destructor Documentation

◆ PieChart() [1/2]

chart::PieChart::PieChart ( )
delete

◆ PieChart() [2/2]

chart::PieChart::PieChart ( const rtl::Reference< ::chart::ChartType > &  xChartTypeModel,
sal_Int32  nDimensionCount,
bool  bExcludingPositioning 
)

◆ ~PieChart()

chart::PieChart::~PieChart ( )
overridevirtual

Definition at line 227 of file PieChart.cxx.

Member Function Documentation

◆ addSeries()

void chart::PieChart::addSeries ( std::unique_ptr< VDataSeries pSeries,
sal_Int32  zSlot,
sal_Int32  xSlot,
sal_Int32  ySlot 
)
overridevirtual

A new series can be positioned relative to other series in a chart.

This positioning has two dimensions. First a series can be placed next to each other on the category axis. This position is indicated by xSlot. Second a series can be stacked on top of another. This position is indicated by ySlot. The positions are counted from 0 on. xSlot < 0 : append the series to already existing x series xSlot > occupied : append the series to already existing x series

If the xSlot is already occupied the given ySlot decides what should happen: ySlot < -1 : move all existing series in the xSlot to next slot ySlot == -1 : stack on top at given x position ySlot == already occupied : insert at given y and x position ySlot > occupied : stack on top at given x position

Reimplemented from chart::VSeriesPlotter.

Definition at line 573 of file PieChart.cxx.

References chart::VSeriesPlotter::addSeries().

◆ createDataPoint()

rtl::Reference< SvxShape > chart::PieChart::createDataPoint ( const rtl::Reference< SvxShapeGroupAnyD > &  xTarget,
const css::uno::Reference< css::beans::XPropertySet > &  xObjectProperties,
const ShapeParam rParam,
const sal_Int32  nPointCount,
const bool  bConcentricExplosion 
)
private

◆ createShapes()

void chart::PieChart::createShapes ( )
overridevirtual

This method creates all shapes needed for representing the pie chart.

a ZSlot is a vector< vector< VDataSeriesGroup > >. There is only one ZSlot: m_aZSlots[0] which has a number of elements equal to the total number of data series (in fact, even if m_aZSlots[0][i] is an object of type VDataSeriesGroup, in the current implementation, there is only one data series in each data series group).

m_xLogicTarget is where the group of all data series shapes (e.g. a pie slice) is added (xSeriesTarget);

m_xFinalTarget is where the group of all text shapes (labels) is added (xTextTarget).

both have been already created and added to the same root shape ( a member of a VDiagram object); this initialization occurs in ChartView::impl_createDiagramAndContent.

the text labels should be always on top of the other series shapes therefore create an own group for the texts to move them to front (because the text group is created after the series group the texts are displayed on top)

pay attention that the m_bSwapXAndY parameter used by the polar plotting position helper is always set to true for pie/donut charts (see PieChart::setScales). This fact causes that createShapes expects that the radius axis scale is the one with index 0 and the angle axis scale is the one with index 1.

m_bUseRings == true if chart type is donut, == false if chart type is pie; if the chart is of donut type we have as many rings as many data series, else we have a single ring (a pie) representing the first data series; for what I can see the radius axis orientation is always reversed and the angle axis orientation is always non-reversed; the radius axis scale range is [0.5, number of rings + 0.5 + max_offset], the angle axis scale range is [0, 1]. The max_offset parameter is used for exploded pie chart and its value is 0.5.

the explodeable ring is the first one except when the radius axis orientation is reversed (always!?) and we are dealing with a donut: in such a case the explodeable ring is the last one.

iterate over each xslot, that is on each data series (there is only one data series in each data series group!); note that if the chart type is a pie the loop iterates only over the first data series (m_bUseRings||fSlotX<0.5)

The angle degree offset is set by the same property of the data series. Counter-clockwise offset from the 3 o'clock position.

iterate through all points to get the sum of all entries of the current data series

iterate through all points to create shapes

compute the maximum relative distance offset of the current slice from the pie center it is worth noting that after the first invocation the maximum offset value is cached, so it is evaluated only once per each call to createShapes

compute the outer and the inner radius for the current ring slice

collect data point information (logic coordinates, style ):

note that the explode percentage is set to the Offset property of the current data series entry only for slices belonging to the outer ring

see notes for PolarPlottingPositionHelper methods transform to unit circle:

create data point

point color:

create label

enable dragging of outer segments

Implements chart::PlotterBase.

Definition at line 671 of file PieChart.cxx.

References createDataPoint(), chart::ShapeFactory::createGroup2D(), chart::PlotterBase::createGroupShape(), chart::ObjectIdentifier::createPieSegmentDragParameterString(), chart::ObjectIdentifier::createPointCID(), chart::ObjectIdentifier::createSeriesSubObjectStub(), createTextLabelShape(), getMaxOffset(), chart::ObjectIdentifier::getPieSegmentDragMethodServiceName(), chart::VDataSeries::getPointCID_Stub(), chart::VDataSeries::getPropertiesOfPoint(), chart::VSeriesPlotter::getSeriesGroupShape(), chart::VDataSeries::getSeriesParticle(), chart::VDataSeries::getStartingAngle(), chart::VDataSeries::getTotalPointCount(), chart::VSeriesPlotter::getTransformedDepth(), chart::VDataSeries::getValueByProperty(), chart::VDataSeries::getYValue(), chart::VDataSeries::hasPointOwnColor(), chart::VDataSeries::hasPropertyMapping(), m_aLabelInfoList, chart::VSeriesPlotter::m_aZSlots, m_bUseRings, m_fMaxOffset, chart::PlotterBase::m_nDimension, m_pPosHelper, chart::VSeriesPlotter::m_xChartTypeModel, chart::VSeriesPlotter::m_xColorScheme, chart::PlotterBase::m_xFinalTarget, chart::PlotterBase::m_xLogicTarget, chart::PieChart::ShapeParam::mfDepth, chart::PieChart::ShapeParam::mfExplodePercentage, chart::PieChart::ShapeParam::mfLogicYSum, chart::PieChart::ShapeParam::mfLogicZ, chart::PieChart::ShapeParam::mfUnitCircleInnerRadius, chart::PieChart::ShapeParam::mfUnitCircleOuterRadius, chart::PieChart::ShapeParam::mfUnitCircleStartAngleDegree, chart::PieChart::ShapeParam::mfUnitCircleWidthAngleDegree, chart::OBJECTTYPE_DATA_POINT, chart::PROP_PIECHARTTYPE_3DRELATIVEHEIGHT, chart::ShapeFactory::setShapeName(), TOOLS_WARN_EXCEPTION, and chart::PlottingPositionHelper::transformSceneToScreenPosition().

◆ createTextLabelShape()

void chart::PieChart::createTextLabelShape ( const rtl::Reference< SvxShapeGroupAnyD > &  xTextTarget,
VDataSeries rSeries,
sal_Int32  nPointIndex,
ShapeParam rParam 
)
private

This method creates a text shape for a label of a data point.

Parameters
xTextTargetwhere to append the new created text shape.
rSeriesthe data series, the data point belongs to.
nPointIndexthe index of the data point the label is related to.
rParamShapeParam object.

by using the mfExplodePercentage parameter a normalized offset is added to both normalized radii. (See notes for PolarPlottingPositionHelper::transformToRadius, especially example 3, and related comments).

get the required label placement type. Available placements are AVOID_OVERLAP, CENTER, OUTSIDE and INSIDE;

when the placement is of AVOID_OVERLAP type a later rearrangement of the label position is allowed; the createTextLabelShape treats the AVOID_OVERLAP as if it was of CENTER type;

for OUTSIDE (INSIDE) label placements an offset of 150 (-150), in the radius direction, is added to the final screen position of the label anchor point. This is required in order to ensure that the label is completely outside (inside) the related slice. Indeed this value should depend on the font height; pay attention: 150 is not a big offset, in fact the screen position coordinates for label anchor points are in the 10000-20000 range, hence these are coordinates of a virtual screen and 150 is a small value;

the scene position of the label anchor point is calculated (see notes for PolarLabelPositionHelper::getLabelScreenPositionAndAlignmentForUnitCircleValues), and immediately transformed into the screen position.

the screen position of the pie/donut center is calculated.

add a scaling independent Offset if requested

the text shape for the label is created

a new PieLabelInfo instance is initialized with all the info related to the current label in order to simplify later label position rearrangement;

text shape could be empty; in that case there is no need to add label info

Handle the placement of the label in the best fit case. First off the routine try to place the label inside the related pie slice, if this is not possible the label is placed outside.

Definition at line 316 of file PieChart.cxx.

References aDirection, chart::PieChart::PieLabelInfo::aFirstPosition, chart::PieChart::PieLabelInfo::aOrigin, chart::PieChart::PieLabelInfo::aOuterPosition, chart::PieChart::PieLabelInfo::bMoved, chart::PieChart::PieLabelInfo::bMovementAllowed, chart::PieChart::PieLabelInfo::bShowLeaderLine, chart::VLineProperties::Color, chart::VSeriesPlotter::createDataLabel(), chart::ShapeFactory::createLine2D(), chart::PieChart::PieLabelInfo::fValue, chart::VDataSeries::getDataPointLabelIfLabel(), chart::VDataSeries::getLabelPlacement(), chart::PolarLabelPositionHelper::getLabelScreenPositionAndAlignmentForUnitCircleValues(), basegfx::B2DVector::getLength(), basegfx::Range2D< typename TYPE, typename TRAITS >::getMaxX(), basegfx::Range2D< typename TYPE, typename TRAITS >::getMaxY(), basegfx::Range2D< typename TYPE, typename TRAITS >::getMinX(), basegfx::Range2D< typename TYPE, typename TRAITS >::getMinY(), chart::VDataSeries::getModel(), basegfx::Range2D< typename TYPE, typename TRAITS >::getWidth(), basegfx::Tuple2D< typename TYPE >::getX(), basegfx::Tuple2D< typename TYPE >::getY(), chart::VDataSeries::getYValue(), chart::VDataSeries::isLabelCustomPos(), chart::LABEL_ALIGN_CENTER, chart::VSeriesPlotter::m_aAvailableOuterRect, m_aLabelInfoList, chart::VSeriesPlotter::m_aPageReferenceSize, chart::VSeriesPlotter::m_bPieLabelsAllowToMove, m_bUseRings, chart::PlotterBase::m_nDimension, m_pPosHelper, chart::VSeriesPlotter::m_xChartTypeModel, chart::PlotterBase::m_xLogicTarget, chart::PieChart::ShapeParam::mfExplodePercentage, chart::PieChart::ShapeParam::mfLogicYSum, chart::PieChart::ShapeParam::mfLogicZ, chart::PieChart::ShapeParam::mfUnitCircleInnerRadius, chart::PieChart::ShapeParam::mfUnitCircleOuterRadius, chart::PieChart::ShapeParam::mfUnitCircleStartAngleDegree, chart::PieChart::ShapeParam::mfUnitCircleWidthAngleDegree, performLabelBestFitInnerPlacement(), chart::DataSeriesProperties::PROP_DATASERIES_SHOW_CUSTOM_LEADERLINES, basegfx::B2IVector::scalar(), chart::LabelPositionHelper::transformSceneToScreenPosition(), chart::PlottingPositionHelper::transformSceneToScreenPosition(), chart::PieChart::PieLabelInfo::xLabelGroupShape, chart::PieChart::PieLabelInfo::xTextShape, and chart::PieChart::PieLabelInfo::xTextTarget.

Referenced by createShapes().

◆ detectLabelOverlapsAndMove()

bool chart::PieChart::detectLabelOverlapsAndMove ( const css::awt::Size &  rPageSize)
private

the routine tries to individuate a chain of overlapping labels and assigns the first and the last of them to pFirstBorder and pSecondBorder; this result is achieved by performing two consecutive while loop.

find borders of a group of overlapping labels

a first while loop is started on the collection of PieLabelInfo objects; the bounding box of each label is checked for overlap against the bounding box of the previous and of the next label; when an overlap is found bOverlapFound is set to true, however the iteration is break only if the overlap occurs against only the next label and not against the previous label: so we exit from the loop whenever an overlap occurs except when the loop initial label overlaps with the previous one;

in case we found a label (pFirstBorder) which overlaps with the next label and not with the previous label a second while loop is started with pFirstBorder as initial label; one more time the bounding box of each label is checked for overlap against the bounding box of the previous and of the next label, however this time we exit from the loop only if the current label overlaps with the previous one but does not with the next one (the opposite of what is required in the former loop); in case such a label is found it is assigned to pSecondBorder and the iteration is stopped; so in case there is a chain of overlapping labels we end up having the first label of the chain pointed by pFirstBorder and the last label of the chain pointed by pSecondBorder;

when two labels satisfying the required conditions are not found (pFirstBorder == 0 || pSecondBorder == 0) but still an overlap occurs (bOverlapFound == true) we are in the situation where each label overlaps with both the previous and the next one; so pFirstBorder is set to point to the last PieLabelInfo object in the collection and pSecondBorder is set to point to the first one;

the total number of labels that made up the chain is calculated and used for getting a pointer to the central label (pCenter);

the current position of each label in the collection is saved in PieLabelInfo.aPreviousPosition, so that it is possible to undo the label move action if it is needed; the undo action is provided by the PieChart::resetLabelPositionsToPreviousState method.

the PieChart::tryMoveLabels method is invoked with rbAlternativeMoveDirection boolean parameter set to false, such a method tries to remove all overlaps that occur in the list of labels going from pFirstBorder to pSecondBorder; if the PieChart::tryMoveLabels returns true no further action is performed, however it is worth noting that it does not mean that all overlap issues have been surely fixed, but only that all moved labels are at least completely inside the page document; when PieChart::tryMoveLabels returns false, it means that the attempt to fix one of the overlap issues caused that a label has been moved (partially) outside the page document (anyway the PieChart::tryMoveLabels method takes care to restore the position of all labels to their initial position, and to set the rbAlternativeMoveDirection in/out parameter to true); in such a case a second invocation of PieChart::tryMoveLabels is performed (and this time the rbAlternativeMoveDirection boolean parameter is true) and independently by what the PieChart::tryMoveLabels method returns no further action is performed; (see notes for PieChart::tryMoveLabels);

in both cases (one or two invocations of PieChart::tryMoveLabels) the detectLabelOverlapsAndMove method ends returning true.

Definition at line 1003 of file PieChart.cxx.

References chart::PieChart::PieLabelInfo::aPreviousPosition, basegfx::Range2D< typename TYPE, typename TRAITS >::intersect(), basegfx::Range2D< typename TYPE, typename TRAITS >::isEmpty(), m_aLabelInfoList, chart::PieChart::PieLabelInfo::pNext, chart::PieChart::PieLabelInfo::pPrevious, tryMoveLabels(), and chart::PieChart::PieLabelInfo::xLabelGroupShape.

Referenced by rearrangeLabelToAvoidOverlapIfRequested().

◆ getMaximumX()

double chart::PieChart::getMaximumX ( )
overridevirtual

Reimplemented from chart::VSeriesPlotter.

Definition at line 629 of file PieChart.cxx.

References getMaxOffset(), chart::VSeriesPlotter::m_aZSlots, and m_bUseRings.

◆ getMaximumYInRange()

double chart::PieChart::getMaximumYInRange ( double  fMinimumX,
double  fMaximumX,
sal_Int32  nAxisIndex 
)
overridevirtual

Reimplemented from chart::VSeriesPlotter.

Definition at line 641 of file PieChart.cxx.

◆ getMaxOffset()

double chart::PieChart::getMaxOffset ( )
private

This method sets m_fMaxOffset to the maximum Offset property and returns it.

There is a Offset property for each entry in a data series, moreover there exists a shared Offset property attached to the whole data series. The Offset property represents the relative distance offset of a slice from the pie center. The shared property is used for exploded pie chart, while the property attached to single data series entries is used for manual dragging of a slice. m_fMaxOffset is used by PiePositionHelper::getInnerAndOuterRadius. Note that only the Offset properties of the first (x slot) data series and its entries are utilized for computing the maximum offset.

Definition at line 582 of file PieChart.cxx.

References chart::VDataSeries::getModel(), chart::VDataSeries::getPropertiesOfPoint(), chart::VSeriesPlotter::m_aZSlots, m_bSizeExcludesLabelsAndExplodedSegments, m_fMaxOffset, and chart::DataSeriesProperties::PROP_DATASERIES_ATTRIBUTED_DATA_POINTS.

Referenced by createShapes(), and getMaximumX().

◆ getMinimumX()

double chart::PieChart::getMinimumX ( )
overridevirtual

Reimplemented from chart::VSeriesPlotter.

Definition at line 578 of file PieChart.cxx.

◆ getMinimumYInRange()

double chart::PieChart::getMinimumYInRange ( double  fMinimumX,
double  fMaximumX,
sal_Int32  nAxisIndex 
)
overridevirtual

Reimplemented from chart::VSeriesPlotter.

Definition at line 636 of file PieChart.cxx.

◆ getPreferredDiagramAspectRatio()

drawing::Direction3D chart::PieChart::getPreferredDiagramAspectRatio ( ) const
overridevirtual

a value <= 0 for a directions means that this direction can be stretched arbitrary

Reimplemented from chart::VSeriesPlotter.

Definition at line 237 of file PieChart.cxx.

References chart::PlotterBase::m_nDimension.

◆ isExpandBorderToIncrementRhythm()

bool chart::PieChart::isExpandBorderToIncrementRhythm ( sal_Int32  nDimensionIndex)
overridevirtual

Reimplemented from chart::VSeriesPlotter.

Definition at line 646 of file PieChart.cxx.

◆ isExpandIfValuesCloseToBorder()

bool chart::PieChart::isExpandIfValuesCloseToBorder ( sal_Int32  nDimensionIndex)
overridevirtual

Reimplemented from chart::VSeriesPlotter.

Definition at line 651 of file PieChart.cxx.

◆ isExpandNarrowValuesTowardZero()

bool chart::PieChart::isExpandNarrowValuesTowardZero ( sal_Int32  nDimensionIndex)
overridevirtual

Reimplemented from chart::VSeriesPlotter.

Definition at line 661 of file PieChart.cxx.

◆ isExpandWideValuesToZero()

bool chart::PieChart::isExpandWideValuesToZero ( sal_Int32  nDimensionIndex)
overridevirtual

Reimplemented from chart::VSeriesPlotter.

Definition at line 656 of file PieChart.cxx.

◆ isSeparateStackingForDifferentSigns()

bool chart::PieChart::isSeparateStackingForDifferentSigns ( sal_Int32  nDimensionIndex)
overridevirtual

Reimplemented from chart::VSeriesPlotter.

Definition at line 666 of file PieChart.cxx.

◆ performLabelBestFitInnerPlacement()

bool chart::PieChart::performLabelBestFitInnerPlacement ( ShapeParam rShapeParam,
PieLabelInfo const &  rPieLabelInfo 
)
private

Handle the placement of the label in the best fit case: the routine try to place the label inside the related pie slice, in case of success it returns true else returns false.

Notation: C: the pie center s: the bisector ray of the current pie slice alpha: the angle between the horizontal axis and the bisector ray s N: the vertex of the label b.b. which is nearest to C F: the vertex of the label b.b. not adjacent to N; F lies on the pie border P, Q: the intersection points between the label b.b. and the bisector ray s; P is the one at minimum distance respect with C e: the edge of the label b.b. where P lies (the nearest edge to C) M: the vertex of e that is not N G: the vertex of the label b.b. which is adjacent to N and that is not M beta: the angle MPF theta: the angle CPF

| | /s | / | / | G _________________________/____________________________ F | | /Q ..| | | / . . | | | / . . | | | / . . | | | / . . | | | / . . | | | / d. . | | | / . . | | | / . . | | | / . . | | | / . . | | | / . . | | | / . . | | | / . \ beta . | | |__________/.____|_______.____________________________| | N /P / . M | /___/theta . | / . | / . r | / . | / . | / . | / . | / . | / . | / . | / . | /. alpha __|/__|_____________________________________________________________ |C |

When alpha = 45k (k integer) s crosses the label b.b. at N exactly. In such a case the nearest edge e is defined as the edge having N as the start vertex and that is covered in the counterclockwise direction when we move from N to the adjacent vertex.

The nearest vertex N is:

  1. the bottom left vertex when 0 < alpha < 90
  2. the bottom right vertex when 90 < alpha < 180
  3. the top right vertex when 180 < alpha < 270
  4. the top left vertex when 270 < alpha < 360.

The nearest edge e is:

  1. the left edge when −45 < alpha < 45
  2. the bottom edge when 45 < alpha <135
  3. the right edge when 135 < alpha < 225
  4. the top edge when 225 < alpha < 315.

Definition at line 1411 of file PieChart.cxx.

References aDirection, chart::PieChart::PieLabelInfo::aFirstPosition, basegfx::B2DVector::angle(), chart::PieChart::PieLabelInfo::aOrigin, basegfx::deg2rad(), basegfx::Tuple2D< typename TYPE >::get(), basegfx::Range2D< typename TYPE, typename TRAITS >::getHeight(), basegfx::Range2D< typename TYPE, typename TRAITS >::getWidth(), basegfx::Tuple2D< typename TYPE >::getX(), basegfx::Tuple2D< typename TYPE >::getY(), chart::PlotterBase::m_nDimension, m_pPosHelper, chart::PlotterBase::m_xLogicTarget, chart::PieChart::ShapeParam::mfLogicZ, chart::PieChart::ShapeParam::mfUnitCircleOuterRadius, chart::PieChart::ShapeParam::mfUnitCircleStartAngleDegree, chart::PieChart::ShapeParam::mfUnitCircleWidthAngleDegree, nIndex, NormAngle360(), basegfx::rad2deg(), SAL_INFO, basegfx::B2IVector::scalar(), basegfx::Tuple2D< typename TYPE >::set(), basegfx::B2DVector::setLength(), basegfx::Tuple2D< typename TYPE >::setX(), basegfx::Tuple2D< typename TYPE >::setY(), chart::PlottingPositionHelper::transformSceneToScreenPosition(), basegfx::X, chart::PieChart::PieLabelInfo::xLabelGroupShape, and basegfx::Y.

Referenced by createTextLabelShape().

◆ rearrangeLabelToAvoidOverlapIfRequested()

void chart::PieChart::rearrangeLabelToAvoidOverlapIfRequested ( const css::awt::Size &  rPageSize)
overridevirtual

this method is invoked by ChartView::impl_createDiagramAndContent for pie and donut charts after text label creation; it tries to rearrange labels only when the label placement type is AVOID_OVERLAP.

check whether there are any labels that should be moved

initialize next and previous member of PieLabelInfo objects

detect overlaps and move

create connection lines for the moved labels

Reimplemented from chart::VSeriesPlotter.

Definition at line 1248 of file PieChart.cxx.

References chart::VLineProperties::Color, chart::ShapeFactory::createLine2D(), detectLabelOverlapsAndMove(), basegfx::B2DVector::getLength(), basegfx::Range2D< typename TYPE, typename TRAITS >::getMaxX(), basegfx::Range2D< typename TYPE, typename TRAITS >::getMaxY(), basegfx::Range2D< typename TYPE, typename TRAITS >::getMinX(), basegfx::Range2D< typename TYPE, typename TRAITS >::getMinY(), m_aLabelInfoList, chart::PieChart::PieLabelInfo::pNext, and chart::PieChart::PieLabelInfo::pPrevious.

◆ resetLabelPositionsToPreviousState()

void chart::PieChart::resetLabelPositionsToPreviousState ( )
private

Definition at line 997 of file PieChart.cxx.

References m_aLabelInfoList.

Referenced by tryMoveLabels().

◆ setScales()

void chart::PieChart::setScales ( std::vector< ExplicitScaleData > &&  rScales,
bool  bSwapXAndYAxis 
)
overridevirtual

Reimplemented from chart::PlotterBase.

Definition at line 231 of file PieChart.cxx.

References chart::PlotterBase::m_nDimension, and m_pPosHelper.

◆ shouldSnapRectToUsedArea()

bool chart::PieChart::shouldSnapRectToUsedArea ( )
overridevirtual

Reimplemented from chart::VSeriesPlotter.

Definition at line 244 of file PieChart.cxx.

◆ tryMoveLabels()

bool chart::PieChart::tryMoveLabels ( PieLabelInfo const *  pFirstBorder,
PieLabelInfo const *  pSecondBorder,
PieLabelInfo pCenter,
bool  bSingleCenter,
bool &  rbAlternativeMoveDirection,
const css::awt::Size &  rPageSize 
)
private

Try to remove all overlaps that occur in the list of labels going from pFirstBorder to pSecondBorder

two loops are performed simultaneously: the outer loop iterates on PieLabelInfo objects in the list starting from the central element (pCenter) and moving forward until the last element (pSecondBorder); the inner loop starts from the previous element of pCenter and moves forward until the current PieLabelInfo object of the outer loop is reached

on the current PieLabelInfo object of the outer loop the moveAwayFrom method is invoked by passing the current PieLabelInfo object of the inner loop as argument.

so each label going from the central one to the last one is checked for overlapping against all previous labels (that comes after the central label) and in case the overlap occurs the moveAwayFrom method tries to fix the issue; if moveAwayFrom returns true (pay attention: that does not mean that the overlap issue has been surely fixed but only that the moved label is at least completely inside the page document: see notes on PieChart::PieLabelInfo::moveAwayFrom), the inner loop starts a new iteration else the rbAlternativeMoveDirection boolean parameter is tested: if it is false the parameter is set to true, the position of all labels is restored to the initial one (through the PieChart::resetLabelPositionsToPreviousState method) and the method ends by returning false, else the inner loop starts a new iteration step; so when rbAlternativeMoveDirection is true the method goes on trying to fix left overlap issues even if the last moveAwayFrom invocation has moved a label in a position that it is not completely inside the page document

if the method does not return before ending the first pair of loops, a second pair of simultaneous loops is performed in the opposite direction (respect with the previous case): the outer loop iterates on PieLabelInfo objects in the list starting from the central element (pCenter) and moving backward until the first element (pFirstBorder); the inner loop starts from the next element of pCenter and moves backward until the current PieLabelInfo object of the outer loop is reached

like in the previous case on the current PieLabelInfo object of the outer loop the moveAwayFrom method is invoked by passing the current PieLabelInfo object of the inner loop as argument

so each label going from the central one to the first one is checked for overlapping on all subsequent labels (that come before the central label) and in case the overlap occurs the moveAwayFrom method tries to fix the issue. The subsequent actions performed after the invocation moveAwayFrom are the same detailed above for the first pair of loops

Definition at line 1152 of file PieChart.cxx.

References m_pPosHelper, chart::PieChart::PieLabelInfo::moveAwayFrom(), chart::PieChart::PieLabelInfo::pNext, chart::PieChart::PieLabelInfo::pPrevious, and resetLabelPositionsToPreviousState().

Referenced by detectLabelOverlapsAndMove().

Member Data Documentation

◆ m_aLabelInfoList

std::vector< PieLabelInfo > chart::PieChart::m_aLabelInfoList
private

◆ m_bSizeExcludesLabelsAndExplodedSegments

bool chart::PieChart::m_bSizeExcludesLabelsAndExplodedSegments
private

Definition at line 116 of file PieChart.hxx.

Referenced by getMaxOffset().

◆ m_bUseRings

bool chart::PieChart::m_bUseRings
private

Definition at line 115 of file PieChart.hxx.

Referenced by createShapes(), createTextLabelShape(), and getMaximumX().

◆ m_fMaxOffset

double chart::PieChart::m_fMaxOffset
private

Definition at line 141 of file PieChart.hxx.

Referenced by createShapes(), and getMaxOffset().

◆ m_pPosHelper

std::unique_ptr<PiePositionHelper> chart::PieChart::m_pPosHelper
private

The documentation for this class was generated from the following files: