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 INCLUDED_CHART2_SOURCE_VIEW_INC_VSERIESPLOTTER_HXX
20 : #define INCLUDED_CHART2_SOURCE_VIEW_INC_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 : namespace com { namespace sun { namespace star {
32 : namespace util {
33 : class XNumberFormatsSupplier;
34 : }
35 : namespace chart2 {
36 : class XColorScheme;
37 : class XRegressionCurveCalculator;
38 : }
39 : }}}
40 :
41 : namespace chart {
42 :
43 : class NumberFormatterWrapper;
44 :
45 0 : class AxesNumberFormats
46 : {
47 : public:
48 0 : AxesNumberFormats() {};
49 :
50 0 : void setFormat( sal_Int32 nFormatKey, sal_Int32 nDimIndex, sal_Int32 nAxisIndex )
51 : {
52 0 : m_aNumberFormatMap[tFullAxisIndex(nDimIndex,nAxisIndex)] = nFormatKey;
53 0 : }
54 0 : bool hasFormat( sal_Int32 nDimIndex, sal_Int32 nAxisIndex ) const
55 : {
56 0 : return (m_aNumberFormatMap.find(tFullAxisIndex(nDimIndex,nAxisIndex)) !=m_aNumberFormatMap.end());
57 : }
58 0 : sal_Int32 getFormat( sal_Int32 nDimIndex, sal_Int32 nAxisIndex ) const
59 : {
60 0 : tNumberFormatMap::const_iterator aIt = m_aNumberFormatMap.find(tFullAxisIndex(nDimIndex,nAxisIndex));
61 0 : if( aIt !=m_aNumberFormatMap.end() )
62 0 : return aIt->second;
63 0 : return 0;
64 : }
65 :
66 : private:
67 : typedef std::pair< sal_Int32, sal_Int32 > tFullAxisIndex;
68 : typedef std::map< tFullAxisIndex, sal_Int32 > tNumberFormatMap;
69 : tNumberFormatMap m_aNumberFormatMap;
70 : };
71 :
72 : /**
73 : * A list of series that have the same CoordinateSystem. They are used to be
74 : * plotted maybe in a stacked manner by a plotter.
75 : */
76 0 : class VDataSeriesGroup SAL_FINAL
77 : {
78 : public:
79 : VDataSeriesGroup();
80 : VDataSeriesGroup( VDataSeries* pSeries );
81 : ~VDataSeriesGroup();
82 :
83 : void addSeries( VDataSeries* pSeries );//takes ownership of pSeries
84 : sal_Int32 getSeriesCount() const;
85 : void deleteSeries();
86 :
87 : sal_Int32 getPointCount() const;
88 : sal_Int32 getAttachedAxisIndexForFirstSeries() const;
89 :
90 : void getMinimumAndMaximiumX( double& rfMinimum, double& rfMaximum ) const;
91 : void getMinimumAndMaximiumYInContinuousXRange( double& rfMinY, double& rfMaxY, double fMinX, double fMaxX, sal_Int32 nAxisIndex ) const;
92 :
93 : void calculateYMinAndMaxForCategory( sal_Int32 nCategoryIndex
94 : , bool bSeparateStackingForDifferentSigns
95 : , double& rfMinimumY, double& rfMaximumY, sal_Int32 nAxisIndex );
96 : void calculateYMinAndMaxForCategoryRange( sal_Int32 nStartCategoryIndex, sal_Int32 nEndCategoryIndex
97 : , bool bSeparateStackingForDifferentSigns
98 : , double& rfMinimumY, double& rfMaximumY, sal_Int32 nAxisIndex );
99 :
100 : ::std::vector< VDataSeries* > m_aSeriesVector;
101 :
102 : private:
103 : //cached values
104 : struct CachedYValues
105 : {
106 : CachedYValues();
107 :
108 : bool m_bValuesDirty;
109 : double m_fMinimumY;
110 : double m_fMaximumY;
111 : };
112 :
113 : mutable bool m_bMaxPointCountDirty;
114 : mutable sal_Int32 m_nMaxPointCount;
115 : typedef std::map< sal_Int32, CachedYValues > tCachedYValuesPerAxisIndexMap;
116 : mutable ::std::vector< tCachedYValuesPerAxisIndexMap > m_aListOfCachedYValues;
117 : };
118 :
119 : class VSeriesPlotter : public PlotterBase, public MinimumAndMaximumSupplier, public LegendEntryProvider
120 : {
121 : public:
122 : virtual ~VSeriesPlotter();
123 :
124 : /*
125 : * A new series can be positioned relative to other series in a chart.
126 : * This positioning has two dimensions. First a series can be placed
127 : * next to each other on the category axis. This position is indicated by xSlot.
128 : * Second a series can be stacked on top of another. This position is indicated by ySlot.
129 : * The positions are counted from 0 on.
130 : * xSlot < 0 : append the series to already existing x series
131 : * xSlot > occupied : append the series to already existing x series
132 : *
133 : * If the xSlot is already occupied the given ySlot decides what should happen:
134 : * ySlot < -1 : move all existing series in the xSlot to next slot
135 : * ySlot == -1 : stack on top at given x position
136 : * ySlot == already occupied : insert at given y and x position
137 : * ySlot > occupied : stack on top at given x position
138 : */
139 : virtual void addSeries( VDataSeries* pSeries, sal_Int32 zSlot = -1, sal_Int32 xSlot = -1,sal_Int32 ySlot = -1 );
140 :
141 : /** a value <= 0 for a directions means that this direction can be stretched arbitrary
142 : */
143 : virtual ::com::sun::star::drawing::Direction3D getPreferredDiagramAspectRatio() const;
144 : virtual bool keepAspectRatio() const;
145 :
146 : /** this enables you to handle series on the same x axis with different y axis
147 : the property AttachedAxisIndex at a dataseries indicates which value scale is to use
148 : (0==AttachedAxisIndex or a not set AttachedAxisIndex property indicates that this series should be scaled at the main y-axis;
149 : 1==AttachedAxisIndex indicates that the series should be scaled at the first secondary axis if there is any otherwise at the main y axis
150 : and so on.
151 : The parameter nAxisIndex matches this DataSereis property 'AttachedAxisIndex'.
152 : nAxisIndex must be greater than 0. nAxisIndex==1 referres to the first secondary axis.
153 : )
154 : */
155 :
156 : virtual void addSecondaryValueScale( const ExplicitScaleData& rScale, sal_Int32 nAxisIndex )
157 : throw (::com::sun::star::uno::RuntimeException);
158 :
159 : // MinimumAndMaximumSupplier
160 :
161 : virtual double getMinimumX() SAL_OVERRIDE;
162 : virtual double getMaximumX() SAL_OVERRIDE;
163 :
164 : virtual double getMinimumYInRange( double fMinimumX, double fMaximumX, sal_Int32 nAxisIndex ) SAL_OVERRIDE;
165 : virtual double getMaximumYInRange( double fMinimumX, double fMaximumX, sal_Int32 nAxisIndex ) SAL_OVERRIDE;
166 :
167 : virtual double getMinimumZ() SAL_OVERRIDE;
168 : virtual double getMaximumZ() SAL_OVERRIDE;
169 :
170 : virtual bool isExpandBorderToIncrementRhythm( sal_Int32 nDimensionIndex ) SAL_OVERRIDE;
171 : virtual bool isExpandIfValuesCloseToBorder( sal_Int32 nDimensionIndex ) SAL_OVERRIDE;
172 : virtual bool isExpandWideValuesToZero( sal_Int32 nDimensionIndex ) SAL_OVERRIDE;
173 : virtual bool isExpandNarrowValuesTowardZero( sal_Int32 nDimensionIndex ) SAL_OVERRIDE;
174 : virtual bool isSeparateStackingForDifferentSigns( sal_Int32 nDimensionIndex ) SAL_OVERRIDE;
175 :
176 : virtual long calculateTimeResolutionOnXAxis() SAL_OVERRIDE;
177 : virtual void setTimeResolutionOnXAxis( long nTimeResolution, const Date& rNullDate ) SAL_OVERRIDE;
178 :
179 : void getMinimumAndMaximiumX( double& rfMinimum, double& rfMaximum ) const;
180 : void getMinimumAndMaximiumYInContinuousXRange( double& rfMinY, double& rfMaxY, double fMinX, double fMaxX, sal_Int32 nAxisIndex ) const;
181 :
182 : virtual std::vector< ViewLegendEntry > createLegendEntries(
183 : const ::com::sun::star::awt::Size& rEntryKeyAspectRatio,
184 : ::com::sun::star::chart::ChartLegendExpansion eLegendExpansion,
185 : const ::com::sun::star::uno::Reference<
186 : ::com::sun::star::beans::XPropertySet >& xTextProperties,
187 : const ::com::sun::star::uno::Reference<
188 : ::com::sun::star::drawing::XShapes >& xTarget,
189 : const ::com::sun::star::uno::Reference<
190 : ::com::sun::star::lang::XMultiServiceFactory >& xShapeFactory,
191 : const ::com::sun::star::uno::Reference<
192 : ::com::sun::star::uno::XComponentContext >& xContext
193 : ) SAL_OVERRIDE;
194 :
195 : virtual LegendSymbolStyle getLegendSymbolStyle();
196 : virtual com::sun::star::awt::Size getPreferredLegendKeyAspectRatio() SAL_OVERRIDE;
197 :
198 : virtual ::com::sun::star::uno::Any getExplicitSymbol( const VDataSeries& rSeries, sal_Int32 nPointIndex=-1/*-1 for series symbol*/ );
199 :
200 : ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > createLegendSymbolForSeries(
201 : const ::com::sun::star::awt::Size& rEntryKeyAspectRatio
202 : , const VDataSeries& rSeries
203 : , const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget
204 : , const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xShapeFactory );
205 :
206 : ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > createLegendSymbolForPoint(
207 : const ::com::sun::star::awt::Size& rEntryKeyAspectRatio
208 : , const VDataSeries& rSeries
209 : , sal_Int32 nPointIndex
210 : , const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget
211 : , const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xShapeFactory );
212 :
213 : virtual std::vector< ViewLegendEntry > createLegendEntriesForSeries(
214 : const ::com::sun::star::awt::Size& rEntryKeyAspectRatio,
215 : const VDataSeries& rSeries,
216 : const ::com::sun::star::uno::Reference<
217 : ::com::sun::star::beans::XPropertySet >& xTextProperties,
218 : const ::com::sun::star::uno::Reference<
219 : ::com::sun::star::drawing::XShapes >& xTarget,
220 : const ::com::sun::star::uno::Reference<
221 : ::com::sun::star::lang::XMultiServiceFactory >& xShapeFactory,
222 : const ::com::sun::star::uno::Reference<
223 : ::com::sun::star::uno::XComponentContext >& xContext
224 : );
225 :
226 : ::std::vector< VDataSeries* > getAllSeries();
227 :
228 : static VSeriesPlotter* createSeriesPlotter( const ::com::sun::star::uno::Reference<
229 : ::com::sun::star::chart2::XChartType >& xChartTypeModel
230 : , sal_Int32 nDimensionCount
231 : , bool bExcludingPositioning = false /*for pie and donut charts labels and exploded segments are excluded from the given size*/);
232 :
233 : sal_Int32 getPointCount() const;
234 :
235 : void setNumberFormatsSupplier( const ::com::sun::star::uno::Reference<
236 : ::com::sun::star::util::XNumberFormatsSupplier > & xNumFmtSupplier );
237 0 : void setAxesNumberFormats( const AxesNumberFormats& rAxesNumberFormats ) { m_aAxesNumberFormats = rAxesNumberFormats; };
238 :
239 : void setColorScheme( const ::com::sun::star::uno::Reference<
240 : ::com::sun::star::chart2::XColorScheme >& xColorScheme );
241 :
242 : void setExplicitCategoriesProvider( ExplicitCategoriesProvider* pExplicitCategoriesProvider );
243 :
244 : //get series names for the z axis labels
245 : ::com::sun::star::uno::Sequence< OUString > getSeriesNames() const;
246 :
247 : void setPageReferenceSize( const ::com::sun::star::awt::Size & rPageRefSize );
248 : //better performance for big data
249 : void setCoordinateSystemResolution( const ::com::sun::star::uno::Sequence< sal_Int32 >& rCoordinateSystemResolution );
250 : bool PointsWereSkipped() const;
251 :
252 : //return the depth for a logic 1
253 : double getTransformedDepth() const;
254 :
255 : void releaseShapes();
256 :
257 : virtual void rearrangeLabelToAvoidOverlapIfRequested( const ::com::sun::star::awt::Size& rPageSize );
258 :
259 : bool WantToPlotInFrontOfAxisLine();
260 : virtual bool shouldSnapRectToUsedArea();
261 :
262 : private:
263 : //no default constructor
264 : VSeriesPlotter();
265 :
266 : protected:
267 :
268 : VSeriesPlotter( const ::com::sun::star::uno::Reference<
269 : ::com::sun::star::chart2::XChartType >& xChartTypeModel
270 : , sal_Int32 nDimensionCount
271 : , bool bCategoryXAxis=true );
272 :
273 : ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >
274 : getSeriesGroupShape( VDataSeries* pDataSeries
275 : , const::com::sun::star:: uno::Reference<
276 : ::com::sun::star::drawing::XShapes >& xTarget );
277 :
278 : //the following group shapes will be created as children of SeriesGroupShape on demand
279 : //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)
280 : //parameter xTarget will be used as parent for the series group shape
281 : ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >
282 : getSeriesGroupShapeFrontChild( VDataSeries* pDataSeries
283 : , const::com::sun::star:: uno::Reference<
284 : ::com::sun::star::drawing::XShapes >& xTarget );
285 : ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >
286 : getSeriesGroupShapeBackChild( VDataSeries* pDataSeries
287 : , const::com::sun::star:: uno::Reference<
288 : ::com::sun::star::drawing::XShapes >& xTarget );
289 :
290 : ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >
291 : getLabelsGroupShape( VDataSeries& rDataSeries
292 : , const::com::sun::star:: uno::Reference<
293 : ::com::sun::star::drawing::XShapes >& xTarget );
294 :
295 : ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >
296 : getErrorBarsGroupShape( VDataSeries& rDataSeries
297 : , const::com::sun::star:: uno::Reference<
298 : ::com::sun::star::drawing::XShapes >& xTarget, bool bYError );
299 :
300 : ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
301 : createDataLabel( const ::com::sun::star::uno::Reference<
302 : ::com::sun::star::drawing::XShapes >& xTarget
303 : , VDataSeries& rDataSeries
304 : , sal_Int32 nPointIndex
305 : , double fValue
306 : , double fSumValue
307 : , const ::com::sun::star::awt::Point& rScreenPosition2D
308 : , LabelAlignment eAlignment=LABEL_ALIGN_CENTER
309 : , sal_Int32 nOffset=0 );
310 :
311 : OUString getLabelTextForValue( VDataSeries& rDataSeries
312 : , sal_Int32 nPointIndex
313 : , double fValue
314 : , bool bAsPercentage );
315 :
316 : /** creates two T-shaped error bars in both directions (up/down or
317 : left/right depending on the bVertical parameter)
318 :
319 : @param rPos
320 : logic coordinates
321 :
322 : @param xErrorBarProperties
323 : the XPropertySet returned by the DataPoint-property "ErrorBarX" or
324 : "ErrorBarY".
325 :
326 : @param nIndex
327 : the index of the data point in rData for which the calculation is
328 : done.
329 :
330 : @param bVertical
331 : for y-error bars this is true, for x-error-bars it is false.
332 : */
333 : virtual void createErrorBar(
334 : const ::com::sun::star::uno::Reference<
335 : ::com::sun::star::drawing::XShapes >& xTarget
336 : , const ::com::sun::star::drawing::Position3D & rPos
337 : , const ::com::sun::star::uno::Reference<
338 : ::com::sun::star::beans::XPropertySet > & xErrorBarProperties
339 : , const VDataSeries& rVDataSeries
340 : , sal_Int32 nIndex
341 : , bool bVertical
342 : , double* pfScaledLogicX
343 : );
344 :
345 : virtual void createErrorBar_X( const ::com::sun::star::drawing::Position3D& rUnscaledLogicPosition
346 : , VDataSeries& rVDataSeries, sal_Int32 nPointIndex
347 : , const ::com::sun::star::uno::Reference<
348 : ::com::sun::star::drawing::XShapes >& xTarget
349 : , double* pfScaledLogicX=0 );
350 :
351 : virtual void createErrorBar_Y( const ::com::sun::star::drawing::Position3D& rUnscaledLogicPosition
352 : , VDataSeries& rVDataSeries, sal_Int32 nPointIndex
353 : , const ::com::sun::star::uno::Reference<
354 : ::com::sun::star::drawing::XShapes >& xTarget
355 : , double* pfScaledLogicX=0 );
356 :
357 : virtual void createRegressionCurvesShapes( VDataSeries& rVDataSeries
358 : , const ::com::sun::star::uno::Reference<
359 : ::com::sun::star::drawing::XShapes >& xTarget
360 : , const ::com::sun::star::uno::Reference<
361 : ::com::sun::star::drawing::XShapes >& xEquationTarget
362 : , bool bMaySkipPointsInRegressionCalculation );
363 :
364 : virtual void createRegressionCurveEquationShapes( const OUString & rEquationCID
365 : , const ::com::sun::star::uno::Reference<
366 : ::com::sun::star::beans::XPropertySet > & xEquationProperties
367 : , const ::com::sun::star::uno::Reference<
368 : ::com::sun::star::drawing::XShapes >& xEquationTarget
369 : , const ::com::sun::star::uno::Reference<
370 : ::com::sun::star::chart2::XRegressionCurveCalculator > & xRegressionCurveCalculator
371 : , ::com::sun::star::awt::Point aDefaultPos );
372 :
373 : virtual void setMappedProperties(
374 : const ::com::sun::star::uno::Reference<
375 : ::com::sun::star::drawing::XShape >& xTarget
376 : , const ::com::sun::star::uno::Reference<
377 : ::com::sun::star::beans::XPropertySet >& xSource
378 : , const tPropertyNameMap& rMap
379 : , tPropertyNameValueMap* pOverwriteMap=0 );
380 :
381 : virtual PlottingPositionHelper& getPlottingPositionHelper( sal_Int32 nAxisIndex ) const;//nAxisIndex indicates whether the position belongs to the main axis ( nAxisIndex==0 ) or secondary axis ( nAxisIndex==1 )
382 :
383 : VDataSeries* getFirstSeries() const;
384 :
385 : protected:
386 : PlottingPositionHelper* m_pMainPosHelper;
387 :
388 : ::com::sun::star::uno::Reference<
389 : ::com::sun::star::chart2::XChartType > m_xChartTypeModel;
390 : ::com::sun::star::uno::Reference<
391 : ::com::sun::star::beans::XPropertySet > m_xChartTypeModelProps;
392 :
393 : ::std::vector< ::std::vector< VDataSeriesGroup > > m_aZSlots;
394 :
395 : bool m_bCategoryXAxis;//true->xvalues are indices (this would not be necessary if series for category chart wouldn't have x-values)
396 : long m_nTimeResolution;
397 : Date m_aNullDate;
398 :
399 : boost::scoped_ptr< NumberFormatterWrapper > m_apNumberFormatterWrapper;
400 : AxesNumberFormats m_aAxesNumberFormats;//direct numberformats on axes, if empty ask the data series instead
401 :
402 : ::com::sun::star::uno::Reference<
403 : ::com::sun::star::chart2::XColorScheme > m_xColorScheme;
404 :
405 : ExplicitCategoriesProvider* m_pExplicitCategoriesProvider;
406 :
407 : //better performance for big data
408 : ::com::sun::star::uno::Sequence< sal_Int32 > m_aCoordinateSystemResolution;
409 : bool m_bPointsWereSkipped;
410 :
411 : private:
412 : typedef std::map< sal_Int32 , ExplicitScaleData > tSecondaryValueScales;
413 : tSecondaryValueScales m_aSecondaryValueScales;
414 :
415 : typedef std::map< sal_Int32 , PlottingPositionHelper* > tSecondaryPosHelperMap;
416 : mutable tSecondaryPosHelperMap m_aSecondaryPosHelperMap;
417 : ::com::sun::star::awt::Size m_aPageReferenceSize;
418 : };
419 :
420 : } //namespace chart
421 : #endif
422 :
423 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|