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