Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
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/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
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 .
18 : : */
19 : : #ifndef _CHART2_VSERIESPLOTTER_HXX
20 : : #define _CHART2_VSERIESPLOTTER_HXX
21 : :
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>
30 : :
31 : :
32 : : namespace com { namespace sun { namespace star {
33 : : namespace util {
34 : : class XNumberFormatsSupplier;
35 : : }
36 : : namespace chart2 {
37 : : class XColorScheme;
38 : : class XRegressionCurveCalculator;
39 : : }
40 : : }}}
41 : :
42 : : //.............................................................................
43 : : namespace chart
44 : : {
45 : : //.............................................................................
46 : :
47 : : class NumberFormatterWrapper;
48 : :
49 : 2943 : class AxesNumberFormats
50 : : {
51 : : public:
52 : 1962 : AxesNumberFormats() {};
53 : :
54 : 1347 : void setFormat( sal_Int32 nFormatKey, sal_Int32 nDimIndex, sal_Int32 nAxisIndex )
55 : : {
56 [ + - ]: 1347 : m_aNumberFormatMap[tFullAxisIndex(nDimIndex,nAxisIndex)] = nFormatKey;
57 : 1347 : }
58 : 2191 : sal_Int32 hasFormat( sal_Int32 nDimIndex, sal_Int32 nAxisIndex ) const
59 : : {
60 [ + - ][ + - ]: 2191 : return (m_aNumberFormatMap.find(tFullAxisIndex(nDimIndex,nAxisIndex)) !=m_aNumberFormatMap.end());
[ + - ]
61 : : }
62 : 0 : sal_Int32 getFormat( sal_Int32 nDimIndex, sal_Int32 nAxisIndex ) const
63 : : {
64 [ # # ][ # # ]: 0 : tNumberFormatMap::const_iterator aIt = m_aNumberFormatMap.find(tFullAxisIndex(nDimIndex,nAxisIndex));
65 [ # # ][ # # ]: 0 : if( aIt !=m_aNumberFormatMap.end() )
66 [ # # ]: 0 : return aIt->second;
67 : 0 : return 0;
68 : : }
69 : :
70 : : private:
71 : : typedef std::pair< sal_Int32, sal_Int32 > tFullAxisIndex;
72 : : typedef std::map< tFullAxisIndex, sal_Int32 > tNumberFormatMap;
73 : : tNumberFormatMap m_aNumberFormatMap;
74 : : };
75 : :
76 : : //-----------------------------------------------------------------------------
77 : : /**
78 : : */
79 : :
80 : : //enum StackType { STACK_NORMAL, STACK_NONE, STACK_BESIDES, STACK_ONTOP, STACK_BEHIND };
81 : :
82 [ # # ][ + - ]: 13883 : class VDataSeriesGroup
83 : : {
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
86 : :
87 : : public:
88 : : VDataSeriesGroup();
89 : : VDataSeriesGroup( VDataSeries* pSeries );
90 : : virtual ~VDataSeriesGroup();
91 : :
92 : : void addSeries( VDataSeries* pSeries );//takes ownership of pSeries
93 : : sal_Int32 getSeriesCount() const;
94 : : void deleteSeries();
95 : :
96 : : sal_Int32 getPointCount() const;
97 : : sal_Int32 getAttachedAxisIndexForFirstSeries() const;
98 : :
99 : : void getMinimumAndMaximiumX( double& rfMinimum, double& rfMaximum ) const;
100 : : void getMinimumAndMaximiumYInContinuousXRange( double& rfMinY, double& rfMaxY, double fMinX, double fMaxX, sal_Int32 nAxisIndex ) const;
101 : :
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 );
108 : :
109 : : ::std::vector< VDataSeries* > m_aSeriesVector;
110 : :
111 : : private:
112 : : //cached values
113 : : struct CachedYValues
114 : : {
115 : : CachedYValues();
116 : :
117 : : bool m_bValuesDirty;
118 : : double m_fMinimumY;
119 : : double m_fMaximumY;
120 : : };
121 : :
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;
126 : : };
127 : :
128 : : class VSeriesPlotter : public PlotterBase, public MinimumAndMaximumSupplier, public LegendEntryProvider
129 : : {
130 : : //-------------------------------------------------------------------------
131 : : // public methods
132 : : //-------------------------------------------------------------------------
133 : : public:
134 : : virtual ~VSeriesPlotter();
135 : :
136 : : /*
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
144 : : *
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
150 : : */
151 : : virtual void addSeries( VDataSeries* pSeries, sal_Int32 zSlot = -1, sal_Int32 xSlot = -1,sal_Int32 ySlot = -1 );
152 : :
153 : : /** a value <= 0 for a directions means that this direction can be stretched arbitrary
154 : : */
155 : : virtual ::com::sun::star::drawing::Direction3D getPreferredDiagramAspectRatio() const;
156 : : virtual bool keepAspectRatio() const;
157 : :
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
162 : : and so on.
163 : : The parameter nAxisIndex matches this DataSereis property 'AttachedAxisIndex'.
164 : : nAxisIndex must be greater than 0. nAxisIndex==1 referres to the first secondary axis.
165 : : )
166 : : */
167 : :
168 : : virtual void addSecondaryValueScale( const ExplicitScaleData& rScale, sal_Int32 nAxisIndex )
169 : : throw (::com::sun::star::uno::RuntimeException);
170 : :
171 : : //-------------------------------------------------------------------------
172 : : // MinimumAndMaximumSupplier
173 : : //-------------------------------------------------------------------------
174 : :
175 : : virtual double getMinimumX();
176 : : virtual double getMaximumX();
177 : :
178 : : virtual double getMinimumYInRange( double fMinimumX, double fMaximumX, sal_Int32 nAxisIndex );
179 : : virtual double getMaximumYInRange( double fMinimumX, double fMaximumX, sal_Int32 nAxisIndex );
180 : :
181 : : virtual double getMinimumZ();
182 : : virtual double getMaximumZ();
183 : :
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 );
189 : :
190 : : virtual long calculateTimeResolutionOnXAxis();
191 : : virtual void setTimeResolutionOnXAxis( long nTimeResolution, const Date& rNullDate );
192 : :
193 : : //------
194 : :
195 : : void getMinimumAndMaximiumX( double& rfMinimum, double& rfMaximum ) const;
196 : : void getMinimumAndMaximiumYInContinuousXRange( double& rfMinY, double& rfMaxY, double fMinX, double fMaxX, sal_Int32 nAxisIndex ) const;
197 : :
198 : : //-------------------------------------------------------------------------
199 : : //-------------------------------------------------------------------------
200 : :
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
212 : : );
213 : :
214 : :
215 : : virtual LegendSymbolStyle getLegendSymbolStyle();
216 : : virtual com::sun::star::awt::Size getPreferredLegendKeyAspectRatio();
217 : :
218 : : virtual ::com::sun::star::uno::Any getExplicitSymbol( const VDataSeries& rSeries, sal_Int32 nPointIndex=-1/*-1 for series symbol*/ );
219 : :
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 );
225 : :
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 );
232 : :
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
244 : : );
245 : :
246 : : ::std::vector< VDataSeries* > getAllSeries();
247 : :
248 : : //-------------------------------------------------------------------------
249 : : //-------------------------------------------------------------------------
250 : :
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*/);
255 : :
256 : : sal_Int32 getPointCount() const;
257 : :
258 : : void setNumberFormatsSupplier( const ::com::sun::star::uno::Reference<
259 : : ::com::sun::star::util::XNumberFormatsSupplier > & xNumFmtSupplier );
260 : 981 : void setAxesNumberFormats( const AxesNumberFormats& rAxesNumberFormats ) { m_aAxesNumberFormats = rAxesNumberFormats; };
261 : :
262 : : void setColorScheme( const ::com::sun::star::uno::Reference<
263 : : ::com::sun::star::chart2::XColorScheme >& xColorScheme );
264 : :
265 : : void setExplicitCategoriesProvider( ExplicitCategoriesProvider* pExplicitCategoriesProvider );
266 : :
267 : : //get series names for the z axis labels
268 : : ::com::sun::star::uno::Sequence< rtl::OUString > getSeriesNames() const;
269 : :
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;
274 : :
275 : : //return the depth for a logic 1
276 : : double getTransformedDepth() const;
277 : :
278 : : void releaseShapes();
279 : :
280 : : virtual void rearrangeLabelToAvoidOverlapIfRequested( const ::com::sun::star::awt::Size& rPageSize );
281 : :
282 : : bool WantToPlotInFrontOfAxisLine();
283 : : virtual bool shouldSnapRectToUsedArea();
284 : :
285 : : //-------------------------------------------------------------------------
286 : : //-------------------------------------------------------------------------
287 : : //-------------------------------------------------------------------------
288 : : private: //methods
289 : : //no default constructor
290 : : VSeriesPlotter();
291 : :
292 : : protected: //methods
293 : :
294 : : VSeriesPlotter( const ::com::sun::star::uno::Reference<
295 : : ::com::sun::star::chart2::XChartType >& xChartTypeModel
296 : : , sal_Int32 nDimensionCount
297 : : , bool bCategoryXAxis=true );
298 : :
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 );
303 : :
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 );
315 : :
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 );
320 : :
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 );
325 : :
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
331 : : , double fValue
332 : : , double fSumValue
333 : : , const ::com::sun::star::awt::Point& rScreenPosition2D
334 : : , LabelAlignment eAlignment=LABEL_ALIGN_CENTER
335 : : , sal_Int32 nOffset=0 );
336 : :
337 : : ::rtl::OUString getLabelTextForValue( VDataSeries& rDataSeries
338 : : , sal_Int32 nPointIndex
339 : : , double fValue
340 : : , bool bAsPercentage );
341 : :
342 : : /** creates two T-shaped error bars in both directions (up/down or
343 : : left/right depending on the bVertical parameter)
344 : :
345 : : @param rPos
346 : : logic coordinates
347 : :
348 : : @param xErrorBarProperties
349 : : the XPropertySet returned by the DataPoint-property "ErrorBarX" or
350 : : "ErrorBarY".
351 : :
352 : : @param nIndex
353 : : the index of the data point in rData for which the calculation is
354 : : done.
355 : :
356 : : @param bVertical
357 : : for y-error bars this is true, for x-error-bars it is false.
358 : : */
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
366 : : , sal_Int32 nIndex
367 : : , bool bVertical
368 : : , double* pfScaledLogicX
369 : : );
370 : :
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 );
376 : :
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 );
382 : :
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 );
389 : :
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 );
398 : :
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 );
406 : :
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 )
408 : :
409 : : VDataSeries* getFirstSeries() const;
410 : :
411 : : protected: //member
412 : : PlottingPositionHelper* m_pMainPosHelper;
413 : :
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;
418 : :
419 : : ::std::vector< ::std::vector< VDataSeriesGroup > > m_aZSlots;
420 : :
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;
423 : : Date m_aNullDate;
424 : :
425 : : ::std::auto_ptr< NumberFormatterWrapper > m_apNumberFormatterWrapper;
426 : : AxesNumberFormats m_aAxesNumberFormats;//direct numberformats on axes, if empty ask the data series instead
427 : :
428 : : ::com::sun::star::uno::Reference<
429 : : ::com::sun::star::chart2::XColorScheme > m_xColorScheme;
430 : :
431 : : ExplicitCategoriesProvider* m_pExplicitCategoriesProvider;
432 : :
433 : : //better performance for big data
434 : : ::com::sun::star::uno::Sequence< sal_Int32 > m_aCoordinateSystemResolution;
435 : : bool m_bPointsWereSkipped;
436 : :
437 : : private: //member
438 : : typedef std::map< sal_Int32 , ExplicitScaleData > tSecondaryValueScales;
439 : : tSecondaryValueScales m_aSecondaryValueScales;
440 : :
441 : : typedef std::map< sal_Int32 , PlottingPositionHelper* > tSecondaryPosHelperMap;
442 : : mutable tSecondaryPosHelperMap m_aSecondaryPosHelperMap;
443 : : ::com::sun::star::awt::Size m_aPageReferenceSize;
444 : : };
445 : :
446 : : //.............................................................................
447 : : } //namespace chart
448 : : //.............................................................................
449 : : #endif
450 : :
451 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|