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 123 : class AxesNumberFormats
50 : {
51 : public:
52 82 : AxesNumberFormats() {};
53 :
54 41 : void setFormat( sal_Int32 nFormatKey, sal_Int32 nDimIndex, sal_Int32 nAxisIndex )
55 : {
56 41 : m_aNumberFormatMap[tFullAxisIndex(nDimIndex,nAxisIndex)] = nFormatKey;
57 41 : }
58 0 : sal_Int32 hasFormat( sal_Int32 nDimIndex, sal_Int32 nAxisIndex ) const
59 : {
60 0 : 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 533 : 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 41 : 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: */
|