/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ #ifndef _CHART2_VSERIESPLOTTER_HXX #define _CHART2_VSERIESPLOTTER_HXX #include "PlotterBase.hxx" #include "VDataSeries.hxx" #include "LabelAlignment.hxx" #include "MinimumAndMaximumSupplier.hxx" #include "LegendEntryProvider.hxx" #include "ExplicitCategoriesProvider.hxx" #include #include namespace com { namespace sun { namespace star { namespace util { class XNumberFormatsSupplier; } namespace chart2 { class XColorScheme; class XRegressionCurveCalculator; } }}} //............................................................................. namespace chart { //............................................................................. class NumberFormatterWrapper; class AxesNumberFormats { public: AxesNumberFormats() {}; void setFormat( sal_Int32 nFormatKey, sal_Int32 nDimIndex, sal_Int32 nAxisIndex ) { m_aNumberFormatMap[tFullAxisIndex(nDimIndex,nAxisIndex)] = nFormatKey; } sal_Int32 hasFormat( sal_Int32 nDimIndex, sal_Int32 nAxisIndex ) const { return (m_aNumberFormatMap.find(tFullAxisIndex(nDimIndex,nAxisIndex)) !=m_aNumberFormatMap.end()); } sal_Int32 getFormat( sal_Int32 nDimIndex, sal_Int32 nAxisIndex ) const { tNumberFormatMap::const_iterator aIt = m_aNumberFormatMap.find(tFullAxisIndex(nDimIndex,nAxisIndex)); if( aIt !=m_aNumberFormatMap.end() ) return aIt->second; return 0; } private: typedef std::pair< sal_Int32, sal_Int32 > tFullAxisIndex; typedef std::map< tFullAxisIndex, sal_Int32 > tNumberFormatMap; tNumberFormatMap m_aNumberFormatMap; }; //----------------------------------------------------------------------------- /** */ //enum StackType { STACK_NORMAL, STACK_NONE, STACK_BESIDES, STACK_ONTOP, STACK_BEHIND }; class VDataSeriesGroup { //a list of series that have the same CoordinateSystem //they are used to be plotted maybe in a stacked manner by a plotter public: VDataSeriesGroup(); VDataSeriesGroup( VDataSeries* pSeries ); virtual ~VDataSeriesGroup(); void addSeries( VDataSeries* pSeries );//takes ownership of pSeries sal_Int32 getSeriesCount() const; void deleteSeries(); sal_Int32 getPointCount() const; sal_Int32 getAttachedAxisIndexForFirstSeries() const; void getMinimumAndMaximiumX( double& rfMinimum, double& rfMaximum ) const; void getMinimumAndMaximiumYInContinuousXRange( double& rfMinY, double& rfMaxY, double fMinX, double fMaxX, sal_Int32 nAxisIndex ) const; void calculateYMinAndMaxForCategory( sal_Int32 nCategoryIndex , bool bSeperateStackingForDifferentSigns , double& rfMinimumY, double& rfMaximumY, sal_Int32 nAxisIndex ); void calculateYMinAndMaxForCategoryRange( sal_Int32 nStartCategoryIndex, sal_Int32 nEndCategoryIndex , bool bSeperateStackingForDifferentSigns , double& rfMinimumY, double& rfMaximumY, sal_Int32 nAxisIndex ); ::std::vector< VDataSeries* > m_aSeriesVector; private: //cached values struct CachedYValues { CachedYValues(); bool m_bValuesDirty; double m_fMinimumY; double m_fMaximumY; }; mutable bool m_bMaxPointCountDirty; mutable sal_Int32 m_nMaxPointCount; typedef std::map< sal_Int32, CachedYValues > tCachedYValuesPerAxisIndexMap; mutable ::std::vector< tCachedYValuesPerAxisIndexMap > m_aListOfCachedYValues; }; class VSeriesPlotter : public PlotterBase, public MinimumAndMaximumSupplier, public LegendEntryProvider { //------------------------------------------------------------------------- // public methods //------------------------------------------------------------------------- public: virtual ~VSeriesPlotter(); /* * A new series can be positioned relative to other series in a chart. * This positioning has two dimensions. First a series can be placed * next to each other on the category axis. This position is indicated by xSlot. * Second a series can be stacked on top of another. This position is indicated by ySlot. * The positions are counted from 0 on. * xSlot < 0 : append the series to already existing x series * xSlot > occupied : append the series to already existing x series * * If the xSlot is already occupied the given ySlot decides what should happen: * ySlot < -1 : move all existing series in the xSlot to next slot * ySlot == -1 : stack on top at given x position * ySlot == already occupied : insert at given y and x position * ySlot > occupied : stack on top at given x position */ virtual void addSeries( VDataSeries* pSeries, sal_Int32 zSlot = -1, sal_Int32 xSlot = -1,sal_Int32 ySlot = -1 ); /** a value <= 0 for a directions means that this direction can be stretched arbitrary */ virtual ::com::sun::star::drawing::Direction3D getPreferredDiagramAspectRatio() const; virtual bool keepAspectRatio() const; /** this enables you to handle series on the same x axis with different y axis the property AttachedAxisIndex at a dataseries indicates which value scale is to use (0==AttachedAxisIndex or a not set AttachedAxisIndex property indicates that this series should be scaled at the main y-axis; 1==AttachedAxisIndex indicates that the series should be scaled at the first secondary axis if there is any otherwise at the main y axis and so on. The parameter nAxisIndex matches this DataSereis property 'AttachedAxisIndex'. nAxisIndex must be greater than 0. nAxisIndex==1 referres to the first secondary axis. ) */ virtual void addSecondaryValueScale( const ExplicitScaleData& rScale, sal_Int32 nAxisIndex ) throw (::com::sun::star::uno::RuntimeException); //------------------------------------------------------------------------- // MinimumAndMaximumSupplier //------------------------------------------------------------------------- virtual double getMinimumX(); virtual double getMaximumX(); virtual double getMinimumYInRange( double fMinimumX, double fMaximumX, sal_Int32 nAxisIndex ); virtual double getMaximumYInRange( double fMinimumX, double fMaximumX, sal_Int32 nAxisIndex ); virtual double getMinimumZ(); virtual double getMaximumZ(); virtual bool isExpandBorderToIncrementRhythm( sal_Int32 nDimensionIndex ); virtual bool isExpandIfValuesCloseToBorder( sal_Int32 nDimensionIndex ); virtual bool isExpandWideValuesToZero( sal_Int32 nDimensionIndex ); virtual bool isExpandNarrowValuesTowardZero( sal_Int32 nDimensionIndex ); virtual bool isSeperateStackingForDifferentSigns( sal_Int32 nDimensionIndex ); virtual long calculateTimeResolutionOnXAxis(); virtual void setTimeResolutionOnXAxis( long nTimeResolution, const Date& rNullDate ); //------ void getMinimumAndMaximiumX( double& rfMinimum, double& rfMaximum ) const; void getMinimumAndMaximiumYInContinuousXRange( double& rfMinY, double& rfMaxY, double fMinX, double fMaxX, sal_Int32 nAxisIndex ) const; //------------------------------------------------------------------------- //------------------------------------------------------------------------- virtual std::vector< ViewLegendEntry > createLegendEntries( const ::com::sun::star::awt::Size& rEntryKeyAspectRatio, ::com::sun::star::chart::ChartLegendExpansion eLegendExpansion, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xTextProperties, const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget, const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xShapeFactory, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& xContext ); virtual LegendSymbolStyle getLegendSymbolStyle(); virtual com::sun::star::awt::Size getPreferredLegendKeyAspectRatio(); virtual ::com::sun::star::uno::Any getExplicitSymbol( const VDataSeries& rSeries, sal_Int32 nPointIndex=-1/*-1 for series symbol*/ ); ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > createLegendSymbolForSeries( const ::com::sun::star::awt::Size& rEntryKeyAspectRatio , const VDataSeries& rSeries , const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget , const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xShapeFactory ); ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > createLegendSymbolForPoint( const ::com::sun::star::awt::Size& rEntryKeyAspectRatio , const VDataSeries& rSeries , sal_Int32 nPointIndex , const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget , const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xShapeFactory ); virtual std::vector< ViewLegendEntry > createLegendEntriesForSeries( const ::com::sun::star::awt::Size& rEntryKeyAspectRatio, const VDataSeries& rSeries, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xTextProperties, const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget, const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xShapeFactory, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& xContext ); ::std::vector< VDataSeries* > getAllSeries(); //------------------------------------------------------------------------- //------------------------------------------------------------------------- static VSeriesPlotter* createSeriesPlotter( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartTypeModel , sal_Int32 nDimensionCount , bool bExcludingPositioning = false /*for pie and donut charts labels and exploded segments are excluded from the given size*/); sal_Int32 getPointCount() const; void setNumberFormatsSupplier( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > & xNumFmtSupplier ); void setAxesNumberFormats( const AxesNumberFormats& rAxesNumberFormats ) { m_aAxesNumberFormats = rAxesNumberFormats; }; void setColorScheme( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XColorScheme >& xColorScheme ); void setExplicitCategoriesProvider( ExplicitCategoriesProvider* pExplicitCategoriesProvider ); //get series names for the z axis labels ::com::sun::star::uno::Sequence< rtl::OUString > getSeriesNames() const; void setPageReferenceSize( const ::com::sun::star::awt::Size & rPageRefSize ); //better performance for big data void setCoordinateSystemResolution( const ::com::sun::star::uno::Sequence< sal_Int32 >& rCoordinateSystemResolution ); bool PointsWereSkipped() const; //return the depth for a logic 1 double getTransformedDepth() const; void releaseShapes(); virtual void rearrangeLabelToAvoidOverlapIfRequested( const ::com::sun::star::awt::Size& rPageSize ); bool WantToPlotInFrontOfAxisLine(); virtual bool shouldSnapRectToUsedArea(); //------------------------------------------------------------------------- //------------------------------------------------------------------------- //------------------------------------------------------------------------- private: //methods //no default constructor VSeriesPlotter(); protected: //methods VSeriesPlotter( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartTypeModel , sal_Int32 nDimensionCount , bool bCategoryXAxis=true ); ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes > getSeriesGroupShape( VDataSeries* pDataSeries , const::com::sun::star:: uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget ); //the following group shapes will be created as children of SeriesGroupShape on demand //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) //parameter xTarget will be used as parent for the series group shape ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes > getSeriesGroupShapeFrontChild( VDataSeries* pDataSeries , const::com::sun::star:: uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget ); ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes > getSeriesGroupShapeBackChild( VDataSeries* pDataSeries , const::com::sun::star:: uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget ); ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes > getLabelsGroupShape( VDataSeries& rDataSeries , const::com::sun::star:: uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget ); ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes > getErrorBarsGroupShape( VDataSeries& rDataSeries , const::com::sun::star:: uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget ); ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > createDataLabel( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget , VDataSeries& rDataSeries , sal_Int32 nPointIndex , double fValue , double fSumValue , const ::com::sun::star::awt::Point& rScreenPosition2D , LabelAlignment eAlignment=LABEL_ALIGN_CENTER , sal_Int32 nOffset=0 ); ::rtl::OUString getLabelTextForValue( VDataSeries& rDataSeries , sal_Int32 nPointIndex , double fValue , bool bAsPercentage ); /** creates two T-shaped error bars in both directions (up/down or left/right depending on the bVertical parameter) @param rPos logic coordinates @param xErrorBarProperties the XPropertySet returned by the DataPoint-property "ErrorBarX" or "ErrorBarY". @param nIndex the index of the data point in rData for which the calculation is done. @param bVertical for y-error bars this is true, for x-error-bars it is false. */ virtual void createErrorBar( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget , const ::com::sun::star::drawing::Position3D & rPos , const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & xErrorBarProperties , const VDataSeries& rVDataSeries , sal_Int32 nIndex , bool bVertical , double* pfScaledLogicX ); virtual void createErrorBar_Y( const ::com::sun::star::drawing::Position3D& rUnscaledLogicPosition , VDataSeries& rVDataSeries, sal_Int32 nPointIndex , const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget , double* pfScaledLogicX=0 ); virtual void createRegressionCurvesShapes( VDataSeries& rVDataSeries , const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget , const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xEquationTarget , bool bMaySkipPointsInRegressionCalculation ); virtual void createRegressionCurveEquationShapes( const ::rtl::OUString & rEquationCID , const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & xEquationProperties , const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xEquationTarget , const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XRegressionCurveCalculator > & xRegressionCurveCalculator , ::com::sun::star::awt::Point aDefaultPos ); virtual void setMappedProperties( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& xTarget , const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xSource , const tPropertyNameMap& rMap , tPropertyNameValueMap* pOverwriteMap=0 ); virtual PlottingPositionHelper& getPlottingPositionHelper( sal_Int32 nAxisIndex ) const;//nAxisIndex indicates wether the position belongs to the main axis ( nAxisIndex==0 ) or secondary axis ( nAxisIndex==1 ) VDataSeries* getFirstSeries() const; protected: //member PlottingPositionHelper* m_pMainPosHelper; ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType > m_xChartTypeModel; ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > m_xChartTypeModelProps; ::std::vector< ::std::vector< VDataSeriesGroup > > m_aZSlots; bool m_bCategoryXAxis;//true->xvalues are indices (this would not be necessary if series for category chart wouldn't have x-values) long m_nTimeResolution; Date m_aNullDate; ::std::auto_ptr< NumberFormatterWrapper > m_apNumberFormatterWrapper; AxesNumberFormats m_aAxesNumberFormats;//direct numberformats on axes, if empty ask the data series instead ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XColorScheme > m_xColorScheme; ExplicitCategoriesProvider* m_pExplicitCategoriesProvider; //better performance for big data ::com::sun::star::uno::Sequence< sal_Int32 > m_aCoordinateSystemResolution; bool m_bPointsWereSkipped; private: //member typedef std::map< sal_Int32 , ExplicitScaleData > tSecondaryValueScales; tSecondaryValueScales m_aSecondaryValueScales; typedef std::map< sal_Int32 , PlottingPositionHelper* > tSecondaryPosHelperMap; mutable tSecondaryPosHelperMap m_aSecondaryPosHelperMap; ::com::sun::star::awt::Size m_aPageReferenceSize; }; //............................................................................. } //namespace chart //............................................................................. #endif