1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #ifndef _CHART2_VSERIESPLOTTER_HXX
20 #define _CHART2_VSERIESPLOTTER_HXX
22 #include "PlotterBase.hxx"
23 #include "VDataSeries.hxx"
24 #include "LabelAlignment.hxx"
25 #include "MinimumAndMaximumSupplier.hxx"
26 #include "LegendEntryProvider.hxx"
27 #include "ExplicitCategoriesProvider.hxx"
28 #include <com/sun/star/chart2/XChartType.hpp>
29 #include <com/sun/star/drawing/Direction3D.hpp>
32 namespace com
{ namespace sun
{ namespace star
{
34 class XNumberFormatsSupplier
;
38 class XRegressionCurveCalculator
;
42 //.............................................................................
45 //.............................................................................
47 class NumberFormatterWrapper
;
49 class AxesNumberFormats
52 AxesNumberFormats() {};
54 void setFormat( sal_Int32 nFormatKey
, sal_Int32 nDimIndex
, sal_Int32 nAxisIndex
)
56 m_aNumberFormatMap
[tFullAxisIndex(nDimIndex
,nAxisIndex
)] = nFormatKey
;
58 sal_Int32
hasFormat( sal_Int32 nDimIndex
, sal_Int32 nAxisIndex
) const
60 return (m_aNumberFormatMap
.find(tFullAxisIndex(nDimIndex
,nAxisIndex
)) !=m_aNumberFormatMap
.end());
62 sal_Int32
getFormat( sal_Int32 nDimIndex
, sal_Int32 nAxisIndex
) const
64 tNumberFormatMap::const_iterator aIt
= m_aNumberFormatMap
.find(tFullAxisIndex(nDimIndex
,nAxisIndex
));
65 if( aIt
!=m_aNumberFormatMap
.end() )
71 typedef std::pair
< sal_Int32
, sal_Int32
> tFullAxisIndex
;
72 typedef std::map
< tFullAxisIndex
, sal_Int32
> tNumberFormatMap
;
73 tNumberFormatMap m_aNumberFormatMap
;
76 //-----------------------------------------------------------------------------
80 //enum StackType { STACK_NORMAL, STACK_NONE, STACK_BESIDES, STACK_ONTOP, STACK_BEHIND };
82 class VDataSeriesGroup
84 //a list of series that have the same CoordinateSystem
85 //they are used to be plotted maybe in a stacked manner by a plotter
89 VDataSeriesGroup( VDataSeries
* pSeries
);
90 virtual ~VDataSeriesGroup();
92 void addSeries( VDataSeries
* pSeries
);//takes ownership of pSeries
93 sal_Int32
getSeriesCount() const;
96 sal_Int32
getPointCount() const;
97 sal_Int32
getAttachedAxisIndexForFirstSeries() const;
99 void getMinimumAndMaximiumX( double& rfMinimum
, double& rfMaximum
) const;
100 void getMinimumAndMaximiumYInContinuousXRange( double& rfMinY
, double& rfMaxY
, double fMinX
, double fMaxX
, sal_Int32 nAxisIndex
) const;
102 void calculateYMinAndMaxForCategory( sal_Int32 nCategoryIndex
103 , bool bSeperateStackingForDifferentSigns
104 , double& rfMinimumY
, double& rfMaximumY
, sal_Int32 nAxisIndex
);
105 void calculateYMinAndMaxForCategoryRange( sal_Int32 nStartCategoryIndex
, sal_Int32 nEndCategoryIndex
106 , bool bSeperateStackingForDifferentSigns
107 , double& rfMinimumY
, double& rfMaximumY
, sal_Int32 nAxisIndex
);
109 ::std::vector
< VDataSeries
* > m_aSeriesVector
;
122 mutable bool m_bMaxPointCountDirty
;
123 mutable sal_Int32 m_nMaxPointCount
;
124 typedef std::map
< sal_Int32
, CachedYValues
> tCachedYValuesPerAxisIndexMap
;
125 mutable ::std::vector
< tCachedYValuesPerAxisIndexMap
> m_aListOfCachedYValues
;
128 class VSeriesPlotter
: public PlotterBase
, public MinimumAndMaximumSupplier
, public LegendEntryProvider
130 //-------------------------------------------------------------------------
132 //-------------------------------------------------------------------------
134 virtual ~VSeriesPlotter();
137 * A new series can be positioned relative to other series in a chart.
138 * This positioning has two dimensions. First a series can be placed
139 * next to each other on the category axis. This position is indicated by xSlot.
140 * Second a series can be stacked on top of another. This position is indicated by ySlot.
141 * The positions are counted from 0 on.
142 * xSlot < 0 : append the series to already existing x series
143 * xSlot > occupied : append the series to already existing x series
145 * If the xSlot is already occupied the given ySlot decides what should happen:
146 * ySlot < -1 : move all existing series in the xSlot to next slot
147 * ySlot == -1 : stack on top at given x position
148 * ySlot == already occupied : insert at given y and x position
149 * ySlot > occupied : stack on top at given x position
151 virtual void addSeries( VDataSeries
* pSeries
, sal_Int32 zSlot
= -1, sal_Int32 xSlot
= -1,sal_Int32 ySlot
= -1 );
153 /** a value <= 0 for a directions means that this direction can be stretched arbitrary
155 virtual ::com::sun::star::drawing::Direction3D
getPreferredDiagramAspectRatio() const;
156 virtual bool keepAspectRatio() const;
158 /** this enables you to handle series on the same x axis with different y axis
159 the property AttachedAxisIndex at a dataseries indicates which value scale is to use
160 (0==AttachedAxisIndex or a not set AttachedAxisIndex property indicates that this series should be scaled at the main y-axis;
161 1==AttachedAxisIndex indicates that the series should be scaled at the first secondary axis if there is any otherwise at the main y axis
163 The parameter nAxisIndex matches this DataSereis property 'AttachedAxisIndex'.
164 nAxisIndex must be greater than 0. nAxisIndex==1 referres to the first secondary axis.
168 virtual void addSecondaryValueScale( const ExplicitScaleData
& rScale
, sal_Int32 nAxisIndex
)
169 throw (::com::sun::star::uno::RuntimeException
);
171 //-------------------------------------------------------------------------
172 // MinimumAndMaximumSupplier
173 //-------------------------------------------------------------------------
175 virtual double getMinimumX();
176 virtual double getMaximumX();
178 virtual double getMinimumYInRange( double fMinimumX
, double fMaximumX
, sal_Int32 nAxisIndex
);
179 virtual double getMaximumYInRange( double fMinimumX
, double fMaximumX
, sal_Int32 nAxisIndex
);
181 virtual double getMinimumZ();
182 virtual double getMaximumZ();
184 virtual bool isExpandBorderToIncrementRhythm( sal_Int32 nDimensionIndex
);
185 virtual bool isExpandIfValuesCloseToBorder( sal_Int32 nDimensionIndex
);
186 virtual bool isExpandWideValuesToZero( sal_Int32 nDimensionIndex
);
187 virtual bool isExpandNarrowValuesTowardZero( sal_Int32 nDimensionIndex
);
188 virtual bool isSeperateStackingForDifferentSigns( sal_Int32 nDimensionIndex
);
190 virtual long calculateTimeResolutionOnXAxis();
191 virtual void setTimeResolutionOnXAxis( long nTimeResolution
, const Date
& rNullDate
);
195 void getMinimumAndMaximiumX( double& rfMinimum
, double& rfMaximum
) const;
196 void getMinimumAndMaximiumYInContinuousXRange( double& rfMinY
, double& rfMaxY
, double fMinX
, double fMaxX
, sal_Int32 nAxisIndex
) const;
198 //-------------------------------------------------------------------------
199 //-------------------------------------------------------------------------
201 virtual std::vector
< ViewLegendEntry
> createLegendEntries(
202 const ::com::sun::star::awt::Size
& rEntryKeyAspectRatio
,
203 ::com::sun::star::chart::ChartLegendExpansion eLegendExpansion
,
204 const ::com::sun::star::uno::Reference
<
205 ::com::sun::star::beans::XPropertySet
>& xTextProperties
,
206 const ::com::sun::star::uno::Reference
<
207 ::com::sun::star::drawing::XShapes
>& xTarget
,
208 const ::com::sun::star::uno::Reference
<
209 ::com::sun::star::lang::XMultiServiceFactory
>& xShapeFactory
,
210 const ::com::sun::star::uno::Reference
<
211 ::com::sun::star::uno::XComponentContext
>& xContext
215 virtual LegendSymbolStyle
getLegendSymbolStyle();
216 virtual com::sun::star::awt::Size
getPreferredLegendKeyAspectRatio();
218 virtual ::com::sun::star::uno::Any
getExplicitSymbol( const VDataSeries
& rSeries
, sal_Int32 nPointIndex
=-1/*-1 for series symbol*/ );
220 ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShape
> createLegendSymbolForSeries(
221 const ::com::sun::star::awt::Size
& rEntryKeyAspectRatio
222 , const VDataSeries
& rSeries
223 , const ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShapes
>& xTarget
224 , const ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XMultiServiceFactory
>& xShapeFactory
);
226 ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShape
> createLegendSymbolForPoint(
227 const ::com::sun::star::awt::Size
& rEntryKeyAspectRatio
228 , const VDataSeries
& rSeries
229 , sal_Int32 nPointIndex
230 , const ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShapes
>& xTarget
231 , const ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XMultiServiceFactory
>& xShapeFactory
);
233 virtual std::vector
< ViewLegendEntry
> createLegendEntriesForSeries(
234 const ::com::sun::star::awt::Size
& rEntryKeyAspectRatio
,
235 const VDataSeries
& rSeries
,
236 const ::com::sun::star::uno::Reference
<
237 ::com::sun::star::beans::XPropertySet
>& xTextProperties
,
238 const ::com::sun::star::uno::Reference
<
239 ::com::sun::star::drawing::XShapes
>& xTarget
,
240 const ::com::sun::star::uno::Reference
<
241 ::com::sun::star::lang::XMultiServiceFactory
>& xShapeFactory
,
242 const ::com::sun::star::uno::Reference
<
243 ::com::sun::star::uno::XComponentContext
>& xContext
246 ::std::vector
< VDataSeries
* > getAllSeries();
248 //-------------------------------------------------------------------------
249 //-------------------------------------------------------------------------
251 static VSeriesPlotter
* createSeriesPlotter( const ::com::sun::star::uno::Reference
<
252 ::com::sun::star::chart2::XChartType
>& xChartTypeModel
253 , sal_Int32 nDimensionCount
254 , bool bExcludingPositioning
= false /*for pie and donut charts labels and exploded segments are excluded from the given size*/);
256 sal_Int32
getPointCount() const;
258 void setNumberFormatsSupplier( const ::com::sun::star::uno::Reference
<
259 ::com::sun::star::util::XNumberFormatsSupplier
> & xNumFmtSupplier
);
260 void setAxesNumberFormats( const AxesNumberFormats
& rAxesNumberFormats
) { m_aAxesNumberFormats
= rAxesNumberFormats
; };
262 void setColorScheme( const ::com::sun::star::uno::Reference
<
263 ::com::sun::star::chart2::XColorScheme
>& xColorScheme
);
265 void setExplicitCategoriesProvider( ExplicitCategoriesProvider
* pExplicitCategoriesProvider
);
267 //get series names for the z axis labels
268 ::com::sun::star::uno::Sequence
< rtl::OUString
> getSeriesNames() const;
270 void setPageReferenceSize( const ::com::sun::star::awt::Size
& rPageRefSize
);
271 //better performance for big data
272 void setCoordinateSystemResolution( const ::com::sun::star::uno::Sequence
< sal_Int32
>& rCoordinateSystemResolution
);
273 bool PointsWereSkipped() const;
275 //return the depth for a logic 1
276 double getTransformedDepth() const;
278 void releaseShapes();
280 virtual void rearrangeLabelToAvoidOverlapIfRequested( const ::com::sun::star::awt::Size
& rPageSize
);
282 bool WantToPlotInFrontOfAxisLine();
283 virtual bool shouldSnapRectToUsedArea();
285 //-------------------------------------------------------------------------
286 //-------------------------------------------------------------------------
287 //-------------------------------------------------------------------------
289 //no default constructor
294 VSeriesPlotter( const ::com::sun::star::uno::Reference
<
295 ::com::sun::star::chart2::XChartType
>& xChartTypeModel
296 , sal_Int32 nDimensionCount
297 , bool bCategoryXAxis
=true );
299 ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShapes
>
300 getSeriesGroupShape( VDataSeries
* pDataSeries
301 , const::com::sun::star:: uno::Reference
<
302 ::com::sun::star::drawing::XShapes
>& xTarget
);
304 //the following group shapes will be created as children of SeriesGroupShape on demand
305 //they can be used to assure that some parts of a series shape are always in front of others (e.g. symbols in front of lines)
306 //parameter xTarget will be used as parent for the series group shape
307 ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShapes
>
308 getSeriesGroupShapeFrontChild( VDataSeries
* pDataSeries
309 , const::com::sun::star:: uno::Reference
<
310 ::com::sun::star::drawing::XShapes
>& xTarget
);
311 ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShapes
>
312 getSeriesGroupShapeBackChild( VDataSeries
* pDataSeries
313 , const::com::sun::star:: uno::Reference
<
314 ::com::sun::star::drawing::XShapes
>& xTarget
);
316 ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShapes
>
317 getLabelsGroupShape( VDataSeries
& rDataSeries
318 , const::com::sun::star:: uno::Reference
<
319 ::com::sun::star::drawing::XShapes
>& xTarget
);
321 ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShapes
>
322 getErrorBarsGroupShape( VDataSeries
& rDataSeries
323 , const::com::sun::star:: uno::Reference
<
324 ::com::sun::star::drawing::XShapes
>& xTarget
, bool bYError
);
326 ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShape
>
327 createDataLabel( const ::com::sun::star::uno::Reference
<
328 ::com::sun::star::drawing::XShapes
>& xTarget
329 , VDataSeries
& rDataSeries
330 , sal_Int32 nPointIndex
333 , const ::com::sun::star::awt::Point
& rScreenPosition2D
334 , LabelAlignment eAlignment
=LABEL_ALIGN_CENTER
335 , sal_Int32 nOffset
=0 );
337 ::rtl::OUString
getLabelTextForValue( VDataSeries
& rDataSeries
338 , sal_Int32 nPointIndex
340 , bool bAsPercentage
);
342 /** creates two T-shaped error bars in both directions (up/down or
343 left/right depending on the bVertical parameter)
348 @param xErrorBarProperties
349 the XPropertySet returned by the DataPoint-property "ErrorBarX" or
353 the index of the data point in rData for which the calculation is
357 for y-error bars this is true, for x-error-bars it is false.
359 virtual void createErrorBar(
360 const ::com::sun::star::uno::Reference
<
361 ::com::sun::star::drawing::XShapes
>& xTarget
362 , const ::com::sun::star::drawing::Position3D
& rPos
363 , const ::com::sun::star::uno::Reference
<
364 ::com::sun::star::beans::XPropertySet
> & xErrorBarProperties
365 , const VDataSeries
& rVDataSeries
368 , double* pfScaledLogicX
371 virtual void createErrorBar_X( const ::com::sun::star::drawing::Position3D
& rUnscaledLogicPosition
372 , VDataSeries
& rVDataSeries
, sal_Int32 nPointIndex
373 , const ::com::sun::star::uno::Reference
<
374 ::com::sun::star::drawing::XShapes
>& xTarget
375 , double* pfScaledLogicX
=0 );
377 virtual void createErrorBar_Y( const ::com::sun::star::drawing::Position3D
& rUnscaledLogicPosition
378 , VDataSeries
& rVDataSeries
, sal_Int32 nPointIndex
379 , const ::com::sun::star::uno::Reference
<
380 ::com::sun::star::drawing::XShapes
>& xTarget
381 , double* pfScaledLogicX
=0 );
383 virtual void createRegressionCurvesShapes( VDataSeries
& rVDataSeries
384 , const ::com::sun::star::uno::Reference
<
385 ::com::sun::star::drawing::XShapes
>& xTarget
386 , const ::com::sun::star::uno::Reference
<
387 ::com::sun::star::drawing::XShapes
>& xEquationTarget
388 , bool bMaySkipPointsInRegressionCalculation
);
390 virtual void createRegressionCurveEquationShapes( const ::rtl::OUString
& rEquationCID
391 , const ::com::sun::star::uno::Reference
<
392 ::com::sun::star::beans::XPropertySet
> & xEquationProperties
393 , const ::com::sun::star::uno::Reference
<
394 ::com::sun::star::drawing::XShapes
>& xEquationTarget
395 , const ::com::sun::star::uno::Reference
<
396 ::com::sun::star::chart2::XRegressionCurveCalculator
> & xRegressionCurveCalculator
397 , ::com::sun::star::awt::Point aDefaultPos
);
399 virtual void setMappedProperties(
400 const ::com::sun::star::uno::Reference
<
401 ::com::sun::star::drawing::XShape
>& xTarget
402 , const ::com::sun::star::uno::Reference
<
403 ::com::sun::star::beans::XPropertySet
>& xSource
404 , const tPropertyNameMap
& rMap
405 , tPropertyNameValueMap
* pOverwriteMap
=0 );
407 virtual PlottingPositionHelper
& getPlottingPositionHelper( sal_Int32 nAxisIndex
) const;//nAxisIndex indicates whether the position belongs to the main axis ( nAxisIndex==0 ) or secondary axis ( nAxisIndex==1 )
409 VDataSeries
* getFirstSeries() const;
412 PlottingPositionHelper
* m_pMainPosHelper
;
414 ::com::sun::star::uno::Reference
<
415 ::com::sun::star::chart2::XChartType
> m_xChartTypeModel
;
416 ::com::sun::star::uno::Reference
<
417 ::com::sun::star::beans::XPropertySet
> m_xChartTypeModelProps
;
419 ::std::vector
< ::std::vector
< VDataSeriesGroup
> > m_aZSlots
;
421 bool m_bCategoryXAxis
;//true->xvalues are indices (this would not be necessary if series for category chart wouldn't have x-values)
422 long m_nTimeResolution
;
425 ::std::auto_ptr
< NumberFormatterWrapper
> m_apNumberFormatterWrapper
;
426 AxesNumberFormats m_aAxesNumberFormats
;//direct numberformats on axes, if empty ask the data series instead
428 ::com::sun::star::uno::Reference
<
429 ::com::sun::star::chart2::XColorScheme
> m_xColorScheme
;
431 ExplicitCategoriesProvider
* m_pExplicitCategoriesProvider
;
433 //better performance for big data
434 ::com::sun::star::uno::Sequence
< sal_Int32
> m_aCoordinateSystemResolution
;
435 bool m_bPointsWereSkipped
;
438 typedef std::map
< sal_Int32
, ExplicitScaleData
> tSecondaryValueScales
;
439 tSecondaryValueScales m_aSecondaryValueScales
;
441 typedef std::map
< sal_Int32
, PlottingPositionHelper
* > tSecondaryPosHelperMap
;
442 mutable tSecondaryPosHelperMap m_aSecondaryPosHelperMap
;
443 ::com::sun::star::awt::Size m_aPageReferenceSize
;
446 //.............................................................................
448 //.............................................................................
451 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */