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 3222 : class AxesNumberFormats
46 : {
47 : public:
48 2148 : AxesNumberFormats() {};
49 :
50 1700 : void setFormat( sal_Int32 nFormatKey, sal_Int32 nDimIndex, sal_Int32 nAxisIndex )
51 : {
52 1700 : m_aNumberFormatMap[tFullAxisIndex(nDimIndex,nAxisIndex)] = nFormatKey;
53 1700 : }
54 1260 : bool hasFormat( sal_Int32 nDimIndex, sal_Int32 nAxisIndex ) const
55 : {
56 1260 : return (m_aNumberFormatMap.find(tFullAxisIndex(nDimIndex,nAxisIndex)) !=m_aNumberFormatMap.end());
57 : }
58 156 : sal_Int32 getFormat( sal_Int32 nDimIndex, sal_Int32 nAxisIndex ) const
59 : {
60 156 : tNumberFormatMap::const_iterator aIt = m_aNumberFormatMap.find(tFullAxisIndex(nDimIndex,nAxisIndex));
61 156 : if( aIt !=m_aNumberFormatMap.end() )
62 156 : 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 13593 : 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 : 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 :
183 : // Methods for handling legends and legend entries.
184 :
185 : virtual std::vector< ViewLegendEntry > createLegendEntries(
186 : const ::com::sun::star::awt::Size& rEntryKeyAspectRatio,
187 : ::com::sun::star::chart::ChartLegendExpansion eLegendExpansion,
188 : const ::com::sun::star::uno::Reference<
189 : ::com::sun::star::beans::XPropertySet >& xTextProperties,
190 : const ::com::sun::star::uno::Reference<
191 : ::com::sun::star::drawing::XShapes >& xTarget,
192 : const ::com::sun::star::uno::Reference<
193 : ::com::sun::star::lang::XMultiServiceFactory >& xShapeFactory,
194 : const ::com::sun::star::uno::Reference<
195 : ::com::sun::star::uno::XComponentContext >& xContext
196 : ) SAL_OVERRIDE;
197 :
198 : virtual LegendSymbolStyle getLegendSymbolStyle();
199 : virtual com::sun::star::awt::Size getPreferredLegendKeyAspectRatio() SAL_OVERRIDE;
200 :
201 : virtual ::com::sun::star::uno::Any getExplicitSymbol( const VDataSeries& rSeries, sal_Int32 nPointIndex=-1/*-1 for series symbol*/ );
202 :
203 : ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > createLegendSymbolForSeries(
204 : const ::com::sun::star::awt::Size& rEntryKeyAspectRatio
205 : , const VDataSeries& rSeries
206 : , const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget
207 : , const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xShapeFactory );
208 :
209 : ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > createLegendSymbolForPoint(
210 : const ::com::sun::star::awt::Size& rEntryKeyAspectRatio
211 : , const VDataSeries& rSeries
212 : , sal_Int32 nPointIndex
213 : , const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget
214 : , const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xShapeFactory );
215 :
216 : std::vector< ViewLegendEntry > createLegendEntriesForSeries(
217 : const ::com::sun::star::awt::Size& rEntryKeyAspectRatio,
218 : const VDataSeries& rSeries,
219 : const ::com::sun::star::uno::Reference<
220 : ::com::sun::star::beans::XPropertySet >& xTextProperties,
221 : const ::com::sun::star::uno::Reference<
222 : ::com::sun::star::drawing::XShapes >& xTarget,
223 : const ::com::sun::star::uno::Reference<
224 : ::com::sun::star::lang::XMultiServiceFactory >& xShapeFactory,
225 : const ::com::sun::star::uno::Reference<
226 : ::com::sun::star::uno::XComponentContext >& xContext
227 : );
228 :
229 : ::std::vector< VDataSeries* > getAllSeries();
230 :
231 : // This method creates a series plotter of the requested type; e.g. : return new PieChart ....
232 : static VSeriesPlotter* createSeriesPlotter( const ::com::sun::star::uno::Reference<
233 : ::com::sun::star::chart2::XChartType >& xChartTypeModel
234 : , sal_Int32 nDimensionCount
235 : , bool bExcludingPositioning = false /*for pie and donut charts labels and exploded segments are excluded from the given size*/);
236 :
237 : sal_Int32 getPointCount() const;
238 :
239 : // Methods for number formats and color schemes
240 :
241 : void setNumberFormatsSupplier( const ::com::sun::star::uno::Reference<
242 : ::com::sun::star::util::XNumberFormatsSupplier > & xNumFmtSupplier );
243 1074 : void setAxesNumberFormats( const AxesNumberFormats& rAxesNumberFormats ) { m_aAxesNumberFormats = rAxesNumberFormats; };
244 :
245 : void setColorScheme( const ::com::sun::star::uno::Reference<
246 : ::com::sun::star::chart2::XColorScheme >& xColorScheme );
247 :
248 : void setExplicitCategoriesProvider( ExplicitCategoriesProvider* pExplicitCategoriesProvider );
249 :
250 : //get series names for the z axis labels
251 : ::com::sun::star::uno::Sequence< OUString > getSeriesNames() const;
252 :
253 : void setPageReferenceSize( const ::com::sun::star::awt::Size & rPageRefSize );
254 : //better performance for big data
255 : void setCoordinateSystemResolution( const ::com::sun::star::uno::Sequence< sal_Int32 >& rCoordinateSystemResolution );
256 1111 : bool PointsWereSkipped() const { return m_bPointsWereSkipped;}
257 :
258 : //return the depth for a logic 1
259 : double getTransformedDepth() const;
260 :
261 : void releaseShapes();
262 :
263 : virtual void rearrangeLabelToAvoidOverlapIfRequested( const ::com::sun::star::awt::Size& rPageSize );
264 :
265 : bool WantToPlotInFrontOfAxisLine();
266 : virtual bool shouldSnapRectToUsedArea();
267 :
268 : private:
269 : //no default constructor
270 : VSeriesPlotter();
271 :
272 : protected:
273 :
274 : VSeriesPlotter( const ::com::sun::star::uno::Reference<
275 : ::com::sun::star::chart2::XChartType >& xChartTypeModel
276 : , sal_Int32 nDimensionCount
277 : , bool bCategoryXAxis=true );
278 :
279 : // Methods for group shapes.
280 :
281 : ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >
282 : getSeriesGroupShape( VDataSeries* pDataSeries
283 : , const::com::sun::star:: uno::Reference<
284 : ::com::sun::star::drawing::XShapes >& xTarget );
285 :
286 : //the following group shapes will be created as children of SeriesGroupShape on demand
287 : //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)
288 : //parameter xTarget will be used as parent for the series group shape
289 : ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >
290 : getSeriesGroupShapeFrontChild( VDataSeries* pDataSeries
291 : , const::com::sun::star:: uno::Reference<
292 : ::com::sun::star::drawing::XShapes >& xTarget );
293 : ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >
294 : getSeriesGroupShapeBackChild( VDataSeries* pDataSeries
295 : , const::com::sun::star:: uno::Reference<
296 : ::com::sun::star::drawing::XShapes >& xTarget );
297 :
298 : /// This method creates a 2D group shape for containing all text shapes
299 : /// needed for this series; the group is added to the text target;
300 : ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >
301 : getLabelsGroupShape( VDataSeries& rDataSeries
302 : , const::com::sun::star:: uno::Reference<
303 : ::com::sun::star::drawing::XShapes >& xTarget );
304 :
305 : ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >
306 : getErrorBarsGroupShape( VDataSeries& rDataSeries
307 : , const::com::sun::star:: uno::Reference<
308 : ::com::sun::star::drawing::XShapes >& xTarget, bool bYError );
309 :
310 : /** This method creates a text shape for a label related to a data point
311 : * and append it to the root text shape group (xTarget).
312 : *
313 : * @param xTarget
314 : * the main root text shape group.
315 : * @param rDataSeries
316 : * the data series, the data point belongs to.
317 : * @param nPointIndex
318 : * the index of the data point the label is related to.
319 : * @param fValue
320 : * the value of the data point.
321 : * @param fSumValue
322 : * the sum of all data point values in the data series.
323 : * @param rScreenPosition2D
324 : * the anchor point position for the label.
325 : * @param eAlignment
326 : * the required alignment of the label.
327 : * @param offset
328 : * an optional offset depending on the label alignment.
329 : *
330 : * @return
331 : * a reference to the created text shape.
332 : */
333 : ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
334 : createDataLabel( const ::com::sun::star::uno::Reference<
335 : ::com::sun::star::drawing::XShapes >& xTarget
336 : , VDataSeries& rDataSeries
337 : , sal_Int32 nPointIndex
338 : , double fValue
339 : , double fSumValue
340 : , const ::com::sun::star::awt::Point& rScreenPosition2D
341 : , LabelAlignment eAlignment=LABEL_ALIGN_CENTER
342 : , sal_Int32 nOffset=0 );
343 :
344 : /// This method returns a text string representation of the passed numeric
345 : /// value by exploiting a NumberFormatterWrapper object.
346 : OUString getLabelTextForValue( VDataSeries& rDataSeries
347 : , sal_Int32 nPointIndex
348 : , double fValue
349 : , bool bAsPercentage );
350 :
351 : /** creates two T-shaped error bars in both directions (up/down or
352 : left/right depending on the bVertical parameter)
353 :
354 : @param rPos
355 : logic coordinates
356 :
357 : @param xErrorBarProperties
358 : the XPropertySet returned by the DataPoint-property "ErrorBarX" or
359 : "ErrorBarY".
360 :
361 : @param nIndex
362 : the index of the data point in rData for which the calculation is
363 : done.
364 :
365 : @param bVertical
366 : for y-error bars this is true, for x-error-bars it is false.
367 : */
368 : void createErrorBar(
369 : const ::com::sun::star::uno::Reference<
370 : ::com::sun::star::drawing::XShapes >& xTarget
371 : , const ::com::sun::star::drawing::Position3D & rPos
372 : , const ::com::sun::star::uno::Reference<
373 : ::com::sun::star::beans::XPropertySet > & xErrorBarProperties
374 : , const VDataSeries& rVDataSeries
375 : , sal_Int32 nIndex
376 : , bool bVertical
377 : , double* pfScaledLogicX
378 : );
379 :
380 : void createErrorBar_X( const ::com::sun::star::drawing::Position3D& rUnscaledLogicPosition
381 : , VDataSeries& rVDataSeries, sal_Int32 nPointIndex
382 : , const ::com::sun::star::uno::Reference<
383 : ::com::sun::star::drawing::XShapes >& xTarget
384 : , double* pfScaledLogicX=0 );
385 :
386 : void createErrorBar_Y( const ::com::sun::star::drawing::Position3D& rUnscaledLogicPosition
387 : , VDataSeries& rVDataSeries, sal_Int32 nPointIndex
388 : , const ::com::sun::star::uno::Reference<
389 : ::com::sun::star::drawing::XShapes >& xTarget
390 : , double* pfScaledLogicX=0 );
391 :
392 : void createRegressionCurvesShapes( VDataSeries& rVDataSeries
393 : , const ::com::sun::star::uno::Reference<
394 : ::com::sun::star::drawing::XShapes >& xTarget
395 : , const ::com::sun::star::uno::Reference<
396 : ::com::sun::star::drawing::XShapes >& xEquationTarget
397 : , bool bMaySkipPointsInRegressionCalculation );
398 :
399 : void createRegressionCurveEquationShapes( const OUString & rEquationCID
400 : , const ::com::sun::star::uno::Reference<
401 : ::com::sun::star::beans::XPropertySet > & xEquationProperties
402 : , const ::com::sun::star::uno::Reference<
403 : ::com::sun::star::drawing::XShapes >& xEquationTarget
404 : , const ::com::sun::star::uno::Reference<
405 : ::com::sun::star::chart2::XRegressionCurveCalculator > & xRegressionCurveCalculator
406 : , ::com::sun::star::awt::Point aDefaultPos );
407 :
408 : static void setMappedProperties(
409 : const ::com::sun::star::uno::Reference<
410 : ::com::sun::star::drawing::XShape >& xTarget
411 : , const ::com::sun::star::uno::Reference<
412 : ::com::sun::star::beans::XPropertySet >& xSource
413 : , const tPropertyNameMap& rMap
414 : , tPropertyNameValueMap* pOverwriteMap=0 );
415 :
416 : virtual PlottingPositionHelper& getPlottingPositionHelper( sal_Int32 nAxisIndex ) const;//nAxisIndex indicates whether the position belongs to the main axis ( nAxisIndex==0 ) or secondary axis ( nAxisIndex==1 )
417 :
418 : VDataSeries* getFirstSeries() const;
419 :
420 : protected:
421 : PlottingPositionHelper* m_pMainPosHelper;
422 :
423 : ::com::sun::star::uno::Reference<
424 : ::com::sun::star::chart2::XChartType > m_xChartTypeModel;
425 : ::com::sun::star::uno::Reference<
426 : ::com::sun::star::beans::XPropertySet > m_xChartTypeModelProps;
427 :
428 : ::std::vector< ::std::vector< VDataSeriesGroup > > m_aZSlots;
429 :
430 : bool m_bCategoryXAxis;//true->xvalues are indices (this would not be necessary if series for category chart wouldn't have x-values)
431 : long m_nTimeResolution;
432 : Date m_aNullDate;
433 :
434 : boost::scoped_ptr< NumberFormatterWrapper > m_apNumberFormatterWrapper;
435 : AxesNumberFormats m_aAxesNumberFormats;//direct numberformats on axes, if empty ask the data series instead
436 :
437 : ::com::sun::star::uno::Reference<
438 : ::com::sun::star::chart2::XColorScheme > m_xColorScheme;
439 :
440 : ExplicitCategoriesProvider* m_pExplicitCategoriesProvider;
441 :
442 : //better performance for big data
443 : ::com::sun::star::uno::Sequence< sal_Int32 > m_aCoordinateSystemResolution;
444 : bool m_bPointsWereSkipped;
445 :
446 : private:
447 : typedef std::map< sal_Int32 , ExplicitScaleData > tSecondaryValueScales;
448 : tSecondaryValueScales m_aSecondaryValueScales;
449 :
450 : typedef std::map< sal_Int32 , PlottingPositionHelper* > tSecondaryPosHelperMap;
451 : mutable tSecondaryPosHelperMap m_aSecondaryPosHelperMap;
452 : ::com::sun::star::awt::Size m_aPageReferenceSize;
453 : };
454 :
455 : } //namespace chart
456 : #endif
457 :
458 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|