fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / chart2 / source / view / inc / PlottingPositionHelper.hxx
blob4e6e64d8e38c0ac74037b6c46c94dcf72b37cbdf
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
19 #ifndef INCLUDED_CHART2_SOURCE_VIEW_INC_PLOTTINGPOSITIONHELPER_HXX
20 #define INCLUDED_CHART2_SOURCE_VIEW_INC_PLOTTINGPOSITIONHELPER_HXX
22 #include "LabelAlignment.hxx"
23 #include "chartview/ExplicitScaleValues.hxx"
25 #include <basegfx/range/b2drectangle.hxx>
26 #include <rtl/math.hxx>
27 #include <com/sun/star/chart2/XTransformation.hpp>
28 #include <com/sun/star/drawing/Direction3D.hpp>
29 #include <com/sun/star/drawing/HomogenMatrix.hpp>
30 #include <com/sun/star/drawing/PolyPolygonShape3D.hpp>
31 #include <com/sun/star/drawing/Position3D.hpp>
32 #include <com/sun/star/drawing/XShapes.hpp>
33 #include <basegfx/matrix/b3dhommatrix.hxx>
35 namespace chart
38 class AbstractShapeFactory;
40 class PlottingPositionHelper
42 public:
43 PlottingPositionHelper();
44 PlottingPositionHelper( const PlottingPositionHelper& rSource );
45 virtual ~PlottingPositionHelper();
47 virtual PlottingPositionHelper* clone() const;
48 PlottingPositionHelper* createSecondaryPosHelper( const ExplicitScaleData& rSecondaryScale );
50 virtual void setTransformationSceneToScreen( const ::com::sun::star::drawing::HomogenMatrix& rMatrix);
52 virtual void setScales( const ::std::vector< ExplicitScaleData >& rScales, bool bSwapXAndYAxis );
53 const ::std::vector< ExplicitScaleData >& getScales() const { return m_aScales;}
55 //better performance for big data
56 inline void setCoordinateSystemResolution( const ::com::sun::star::uno::Sequence< sal_Int32 >& rCoordinateSystemResolution );
57 inline bool isSameForGivenResolution( double fX, double fY, double fZ
58 , double fX2, double fY2, double fZ2 );
60 inline bool isStrongLowerRequested( sal_Int32 nDimensionIndex ) const;
61 inline bool isLogicVisible( double fX, double fY, double fZ ) const;
62 inline void doLogicScaling( double* pX, double* pY, double* pZ, bool bClip=false ) const;
63 inline void doUnshiftedLogicScaling( double* pX, double* pY, double* pZ, bool bClip=false ) const;
64 inline void clipLogicValues( double* pX, double* pY, double* pZ ) const;
65 void clipScaledLogicValues( double* pX, double* pY, double* pZ ) const;
66 inline bool clipYRange( double& rMin, double& rMax ) const;
68 inline void doLogicScaling( ::com::sun::star::drawing::Position3D& rPos, bool bClip=false ) const;
70 virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTransformation >
71 getTransformationScaledLogicToScene() const;
73 virtual ::com::sun::star::drawing::Position3D
74 transformLogicToScene( double fX, double fY, double fZ, bool bClip ) const;
76 virtual ::com::sun::star::drawing::Position3D
77 transformScaledLogicToScene( double fX, double fY, double fZ, bool bClip ) const;
79 void transformScaledLogicToScene( ::com::sun::star::drawing::PolyPolygonShape3D& rPoly ) const;
81 static com::sun::star::awt::Point transformSceneToScreenPosition(
82 const com::sun::star::drawing::Position3D& rScenePosition3D
83 , const com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >& xSceneTarget
84 , AbstractShapeFactory* pShapeFactory, sal_Int32 nDimensionCount );
86 inline double getLogicMinX() const;
87 inline double getLogicMinY() const;
88 inline double getLogicMinZ() const;
89 inline double getLogicMaxX() const;
90 inline double getLogicMaxY() const;
91 inline double getLogicMaxZ() const;
93 inline bool isMathematicalOrientationX() const;
94 inline bool isMathematicalOrientationY() const;
95 inline bool isMathematicalOrientationZ() const;
97 ::basegfx::B2DRectangle getScaledLogicClipDoubleRect() const;
98 ::com::sun::star::drawing::Direction3D getScaledLogicWidth() const;
100 inline bool isSwapXAndY() const;
102 bool isPercentY() const;
104 double getBaseValueY() const;
106 inline bool maySkipPointsInRegressionCalculation() const;
108 void setTimeResolution( long nTimeResolution, const Date& rNullDate );
109 virtual void setScaledCategoryWidth( double fScaledCategoryWidth );
110 void AllowShiftXAxisPos( bool bAllowShift );
111 void AllowShiftZAxisPos( bool bAllowShift );
113 protected: //member
114 ::std::vector< ExplicitScaleData > m_aScales;
115 ::basegfx::B3DHomMatrix m_aMatrixScreenToScene;
117 //this is calculated based on m_aScales and m_aMatrixScreenToScene
118 mutable ::com::sun::star::uno::Reference<
119 ::com::sun::star::chart2::XTransformation > m_xTransformationLogicToScene;
121 bool m_bSwapXAndY;//e.g. true for bar chart and false for column chart
123 sal_Int32 m_nXResolution;
124 sal_Int32 m_nYResolution;
125 sal_Int32 m_nZResolution;
127 bool m_bMaySkipPointsInRegressionCalculation;
129 bool m_bDateAxis;
130 long m_nTimeResolution;
131 Date m_aNullDate;
133 double m_fScaledCategoryWidth;
134 bool m_bAllowShiftXAxisPos;
135 bool m_bAllowShiftZAxisPos;
138 //describes which axis of the drawinglayer scene or sreen axis are the normal axis
139 enum NormalAxis
141 NormalAxis_X
142 , NormalAxis_Y
143 , NormalAxis_Z
146 class PolarPlottingPositionHelper : public PlottingPositionHelper
148 public:
149 PolarPlottingPositionHelper( NormalAxis eNormalAxis=NormalAxis_Z );
150 PolarPlottingPositionHelper( const PolarPlottingPositionHelper& rSource );
151 virtual ~PolarPlottingPositionHelper();
153 virtual PlottingPositionHelper* clone() const SAL_OVERRIDE;
155 virtual void setTransformationSceneToScreen( const ::com::sun::star::drawing::HomogenMatrix& rMatrix) SAL_OVERRIDE;
156 virtual void setScales( const std::vector< ExplicitScaleData >& rScales, bool bSwapXAndYAxis ) SAL_OVERRIDE;
158 ::basegfx::B3DHomMatrix getUnitCartesianToScene() const { return m_aUnitCartesianToScene;}
160 virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTransformation >
161 getTransformationScaledLogicToScene() const SAL_OVERRIDE;
163 //the resulting values provided by the following 3 methods should be used
164 //for input to the transformation received with
165 //'getTransformationScaledLogicToScene'
167 /** Given a value in the radius axis scale range, it returns the normalized
168 * value.
170 double transformToRadius( double fLogicValueOnRadiusAxis, bool bDoScaling=true ) const;
172 /** Given a value in the angle axis scale range (e.g. [0,1] for pie charts)
173 * this method returns the related angle in degree.
175 double transformToAngleDegree( double fLogicValueOnAngleAxis, bool bDoScaling=true ) const;
177 /** Given 2 values in the angle axis scale range (e.g. [0,1] for pie charts)
178 * this method returns the angle between the 2 values keeping into account
179 * the correct axis orientation; (for instance, this method is used for
180 * computing the angle width of a pie slice).
182 double getWidthAngleDegree( double& fStartLogicValueOnAngleAxis, double& fEndLogicValueOnAngleAxis ) const;
184 virtual ::com::sun::star::drawing::Position3D
185 transformLogicToScene( double fX, double fY, double fZ, bool bClip ) const SAL_OVERRIDE;
186 virtual ::com::sun::star::drawing::Position3D
187 transformScaledLogicToScene( double fX, double fY, double fZ, bool bClip ) const SAL_OVERRIDE;
188 ::com::sun::star::drawing::Position3D
189 transformAngleRadiusToScene( double fLogicValueOnAngleAxis, double fLogicValueOnRadiusAxis, double fLogicZ, bool bDoScaling=true ) const;
191 /** It returns the scene coordinates of the passed point: this point is
192 * described through a normalized cylindrical coordinate system.
193 * (For a pie chart the origin of the coordinate system is the pie center).
195 ::com::sun::star::drawing::Position3D
196 transformUnitCircleToScene( double fUnitAngleDegree, double fUnitRadius, double fLogicZ, bool bDoScaling=true ) const;
198 using PlottingPositionHelper::transformScaledLogicToScene;
200 double getOuterLogicRadius() const;
202 inline bool isMathematicalOrientationAngle() const;
203 inline bool isMathematicalOrientationRadius() const;
204 public:
205 ///m_bSwapXAndY (inherited): by default the X axis (scale[0]) represents
206 ///the angle axis and the Y axis (scale[1]) represents the radius axis;
207 ///when this parameter is true, the opposite happens (this is the case for
208 ///pie charts).
210 ///Offset for radius axis in absolute logic scaled values (1.0 == 1 category)
211 ///For a donut, it represents the non-normalized inner radius (see notes for
212 ///transformToRadius)
213 double m_fRadiusOffset;
214 ///Offset for angle axis in real degree.
215 ///For a pie it represents the angle offset at which the first slice have to
216 ///start;
217 double m_fAngleDegreeOffset;
219 private:
220 ::basegfx::B3DHomMatrix m_aUnitCartesianToScene;
221 NormalAxis m_eNormalAxis;
223 ::basegfx::B3DHomMatrix impl_calculateMatrixUnitCartesianToScene( const ::basegfx::B3DHomMatrix& rMatrixScreenToScene ) const;
226 bool PolarPlottingPositionHelper::isMathematicalOrientationAngle() const
228 const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[1] : m_aScales[2];
229 if( ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL==rScale.Orientation )
230 return true;
231 return false;
233 bool PolarPlottingPositionHelper::isMathematicalOrientationRadius() const
235 const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[0] : m_aScales[1];
236 if( ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL==rScale.Orientation )
237 return true;
238 return false;
241 //better performance for big data
242 void PlottingPositionHelper::setCoordinateSystemResolution( const ::com::sun::star::uno::Sequence< sal_Int32 >& rCoordinateSystemResolution )
244 m_nXResolution = 1000;
245 m_nYResolution = 1000;
246 m_nZResolution = 1000;
247 if( rCoordinateSystemResolution.getLength() > 0 )
248 m_nXResolution = rCoordinateSystemResolution[0];
249 if( rCoordinateSystemResolution.getLength() > 1 )
250 m_nYResolution = rCoordinateSystemResolution[1];
251 if( rCoordinateSystemResolution.getLength() > 2 )
252 m_nZResolution = rCoordinateSystemResolution[2];
255 bool PlottingPositionHelper::isSameForGivenResolution( double fX, double fY, double fZ
256 , double fX2, double fY2, double fZ2 /*these values are all expected tp be scaled already*/ )
258 if( !::rtl::math::isFinite(fX) || !::rtl::math::isFinite(fY) || !::rtl::math::isFinite(fZ)
259 || !::rtl::math::isFinite(fX2) || !::rtl::math::isFinite(fY2) || !::rtl::math::isFinite(fZ2) )
260 return false;
262 double fScaledMinX = getLogicMinX();
263 double fScaledMinY = getLogicMinY();
264 double fScaledMinZ = getLogicMinZ();
265 double fScaledMaxX = getLogicMaxX();
266 double fScaledMaxY = getLogicMaxY();
267 double fScaledMaxZ = getLogicMaxZ();
269 doLogicScaling( &fScaledMinX, &fScaledMinY, &fScaledMinZ );
270 doLogicScaling( &fScaledMaxX, &fScaledMaxY, &fScaledMaxZ);
272 bool bSameX = ( static_cast<sal_Int32>(m_nXResolution*(fX - fScaledMinX)/(fScaledMaxX-fScaledMinX))
273 == static_cast<sal_Int32>(m_nXResolution*(fX2 - fScaledMinX)/(fScaledMaxX-fScaledMinX)) );
275 bool bSameY = ( static_cast<sal_Int32>(m_nYResolution*(fY - fScaledMinY)/(fScaledMaxY-fScaledMinY))
276 == static_cast<sal_Int32>(m_nYResolution*(fY2 - fScaledMinY)/(fScaledMaxY-fScaledMinY)) );
278 bool bSameZ = ( static_cast<sal_Int32>(m_nZResolution*(fZ - fScaledMinZ)/(fScaledMaxZ-fScaledMinZ))
279 == static_cast<sal_Int32>(m_nZResolution*(fZ2 - fScaledMinZ)/(fScaledMaxZ-fScaledMinZ)) );
281 return (bSameX && bSameY && bSameZ);
284 bool PlottingPositionHelper::isStrongLowerRequested( sal_Int32 nDimensionIndex ) const
286 if( m_aScales.empty() )
287 return false;
288 if( 0==nDimensionIndex )
289 return m_bAllowShiftXAxisPos && m_aScales[nDimensionIndex].ShiftedCategoryPosition;
290 else if( 2==nDimensionIndex )
291 return m_bAllowShiftZAxisPos && m_aScales[nDimensionIndex].ShiftedCategoryPosition;
292 return false;
295 bool PlottingPositionHelper::isLogicVisible(
296 double fX, double fY, double fZ ) const
298 return fX >= m_aScales[0].Minimum && ( isStrongLowerRequested(0) ? fX < m_aScales[0].Maximum : fX <= m_aScales[0].Maximum )
299 && fY >= m_aScales[1].Minimum && fY <= m_aScales[1].Maximum
300 && fZ >= m_aScales[2].Minimum && ( isStrongLowerRequested(2) ? fZ < m_aScales[2].Maximum : fZ <= m_aScales[2].Maximum );
303 void PlottingPositionHelper::doLogicScaling( double* pX, double* pY, double* pZ, bool bClip ) const
305 if(bClip)
306 this->clipLogicValues( pX,pY,pZ );
308 if(pX)
310 if( m_aScales[0].Scaling.is())
311 *pX = m_aScales[0].Scaling->doScaling(*pX);
312 if( m_bAllowShiftXAxisPos && m_aScales[0].ShiftedCategoryPosition )
313 (*pX) += m_fScaledCategoryWidth/2.0;
315 if(pY && m_aScales[1].Scaling.is())
316 *pY = m_aScales[1].Scaling->doScaling(*pY);
317 if(pZ)
319 if( m_aScales[2].Scaling.is())
320 *pZ = m_aScales[2].Scaling->doScaling(*pZ);
321 if( m_bAllowShiftZAxisPos && m_aScales[2].ShiftedCategoryPosition)
322 (*pZ) += 0.5;
326 void PlottingPositionHelper::doUnshiftedLogicScaling( double* pX, double* pY, double* pZ, bool bClip ) const
328 if(bClip)
329 this->clipLogicValues( pX,pY,pZ );
331 if(pX && m_aScales[0].Scaling.is())
332 *pX = m_aScales[0].Scaling->doScaling(*pX);
333 if(pY && m_aScales[1].Scaling.is())
334 *pY = m_aScales[1].Scaling->doScaling(*pY);
335 if(pZ && m_aScales[2].Scaling.is())
336 *pZ = m_aScales[2].Scaling->doScaling(*pZ);
339 void PlottingPositionHelper::doLogicScaling( ::com::sun::star::drawing::Position3D& rPos, bool bClip ) const
341 doLogicScaling( &rPos.PositionX, &rPos.PositionY, &rPos.PositionZ, bClip );
344 void PlottingPositionHelper::clipLogicValues( double* pX, double* pY, double* pZ ) const
346 if(pX)
348 if( *pX < m_aScales[0].Minimum )
349 *pX = m_aScales[0].Minimum;
350 else if( *pX > m_aScales[0].Maximum )
351 *pX = m_aScales[0].Maximum;
353 if(pY)
355 if( *pY < m_aScales[1].Minimum )
356 *pY = m_aScales[1].Minimum;
357 else if( *pY > m_aScales[1].Maximum )
358 *pY = m_aScales[1].Maximum;
360 if(pZ)
362 if( *pZ < m_aScales[2].Minimum )
363 *pZ = m_aScales[2].Minimum;
364 else if( *pZ > m_aScales[2].Maximum )
365 *pZ = m_aScales[2].Maximum;
369 inline bool PlottingPositionHelper::clipYRange( double& rMin, double& rMax ) const
371 //returns true if something remains
372 if( rMin > rMax )
374 double fHelp = rMin;
375 rMin = rMax;
376 rMax = fHelp;
378 if( rMin > getLogicMaxY() )
379 return false;
380 if( rMax < getLogicMinY() )
381 return false;
382 if( rMin < getLogicMinY() )
383 rMin = getLogicMinY();
384 if( rMax > getLogicMaxY() )
385 rMax = getLogicMaxY();
386 return true;
389 inline double PlottingPositionHelper::getLogicMinX() const
391 return m_aScales[0].Minimum;
393 inline double PlottingPositionHelper::getLogicMinY() const
395 return m_aScales[1].Minimum;
397 inline double PlottingPositionHelper::getLogicMinZ() const
399 return m_aScales[2].Minimum;
402 inline double PlottingPositionHelper::getLogicMaxX() const
404 return m_aScales[0].Maximum;
406 inline double PlottingPositionHelper::getLogicMaxY() const
408 return m_aScales[1].Maximum;
410 inline double PlottingPositionHelper::getLogicMaxZ() const
412 return m_aScales[2].Maximum;
414 inline bool PlottingPositionHelper::isMathematicalOrientationX() const
416 return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[0].Orientation;
418 inline bool PlottingPositionHelper::isMathematicalOrientationY() const
420 return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[1].Orientation;
422 inline bool PlottingPositionHelper::isMathematicalOrientationZ() const
424 return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[2].Orientation;
426 inline bool PlottingPositionHelper::isSwapXAndY() const
428 return m_bSwapXAndY;
430 inline bool PlottingPositionHelper::maySkipPointsInRegressionCalculation() const
432 return m_bMaySkipPointsInRegressionCalculation;
435 } //namespace chart
436 #endif
438 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */