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