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