1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 _CHART2_PLOTTINGPOSITIONHELPER_HXX
20 #define _CHART2_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 //.............................................................................
38 //.............................................................................
42 class PlottingPositionHelper
45 PlottingPositionHelper();
46 PlottingPositionHelper( const PlottingPositionHelper
& rSource
);
47 virtual ~PlottingPositionHelper();
49 virtual PlottingPositionHelper
* clone() const;
50 virtual PlottingPositionHelper
* createSecondaryPosHelper( const ExplicitScaleData
& rSecondaryScale
);
52 virtual void setTransformationSceneToScreen( const ::com::sun::star::drawing::HomogenMatrix
& rMatrix
);
54 virtual void setScales( const ::std::vector
< ExplicitScaleData
>& rScales
, bool bSwapXAndYAxis
);
55 const ::std::vector
< ExplicitScaleData
>& getScales() const;
57 //better performance for big data
58 inline void setCoordinateSystemResolution( const ::com::sun::star::uno::Sequence
< sal_Int32
>& rCoordinateSystemResolution
);
59 inline bool isSameForGivenResolution( double fX
, double fY
, double fZ
60 , double fX2
, double fY2
, double fZ2
);
62 inline bool isStrongLowerRequested( sal_Int32 nDimensionIndex
) const;
63 inline bool isLogicVisible( double fX
, double fY
, double fZ
) const;
64 inline void doLogicScaling( double* pX
, double* pY
, double* pZ
, bool bClip
=false ) const;
65 inline void doUnshiftedLogicScaling( double* pX
, double* pY
, double* pZ
, bool bClip
=false ) const;
66 inline void clipLogicValues( double* pX
, double* pY
, double* pZ
) const;
67 void clipScaledLogicValues( double* pX
, double* pY
, double* pZ
) const;
68 inline bool clipYRange( double& rMin
, double& rMax
) const;
70 inline void doLogicScaling( ::com::sun::star::drawing::Position3D
& rPos
, bool bClip
=false ) const;
72 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::chart2::XTransformation
>
73 getTransformationScaledLogicToScene() const;
75 virtual ::com::sun::star::drawing::Position3D
76 transformLogicToScene( double fX
, double fY
, double fZ
, bool bClip
) const;
78 virtual ::com::sun::star::drawing::Position3D
79 transformScaledLogicToScene( double fX
, double fY
, double fZ
, bool bClip
) const;
81 void transformScaledLogicToScene( ::com::sun::star::drawing::PolyPolygonShape3D
& rPoly
) const;
83 static com::sun::star::awt::Point
transformSceneToScreenPosition(
84 const com::sun::star::drawing::Position3D
& rScenePosition3D
85 , const com::sun::star::uno::Reference
< com::sun::star::drawing::XShapes
>& xSceneTarget
86 , ShapeFactory
* pShapeFactory
, sal_Int32 nDimensionCount
);
88 inline double getLogicMinX() const;
89 inline double getLogicMinY() const;
90 inline double getLogicMinZ() const;
91 inline double getLogicMaxX() const;
92 inline double getLogicMaxY() const;
93 inline double getLogicMaxZ() const;
95 inline bool isMathematicalOrientationX() const;
96 inline bool isMathematicalOrientationY() const;
97 inline bool isMathematicalOrientationZ() const;
99 ::basegfx::B2DRectangle
getScaledLogicClipDoubleRect() const;
100 ::com::sun::star::drawing::Direction3D
getScaledLogicWidth() const;
102 inline bool isSwapXAndY() const;
104 bool isPercentY() const;
106 double getBaseValueY() const;
108 inline bool maySkipPointsInRegressionCalculation() const;
110 void setTimeResolution( long nTimeResolution
, const Date
& rNullDate
);
111 virtual void setScaledCategoryWidth( double fScaledCategoryWidth
);
112 void AllowShiftXAxisPos( bool bAllowShift
);
113 void AllowShiftZAxisPos( bool bAllowShift
);
116 ::std::vector
< ExplicitScaleData
> m_aScales
;
117 ::basegfx::B3DHomMatrix m_aMatrixScreenToScene
;
119 //this is calculated based on m_aScales and m_aMatrixScreenToScene
120 mutable ::com::sun::star::uno::Reference
<
121 ::com::sun::star::chart2::XTransformation
> m_xTransformationLogicToScene
;
123 bool m_bSwapXAndY
;//e.g. true for bar chart and false for column chart
125 sal_Int32 m_nXResolution
;
126 sal_Int32 m_nYResolution
;
127 sal_Int32 m_nZResolution
;
129 bool m_bMaySkipPointsInRegressionCalculation
;
132 long m_nTimeResolution
;
135 double m_fScaledCategoryWidth
;
136 bool m_bAllowShiftXAxisPos
;
137 bool m_bAllowShiftZAxisPos
;
140 //describes which axis of the drawinglayer scene or sreen axis are the normal axis
148 class PolarPlottingPositionHelper
: public PlottingPositionHelper
151 PolarPlottingPositionHelper( NormalAxis eNormalAxis
=NormalAxis_Z
);
152 PolarPlottingPositionHelper( const PolarPlottingPositionHelper
& rSource
);
153 virtual ~PolarPlottingPositionHelper();
155 virtual PlottingPositionHelper
* clone() const;
157 virtual void setTransformationSceneToScreen( const ::com::sun::star::drawing::HomogenMatrix
& rMatrix
);
158 virtual void setScales( const std::vector
< ExplicitScaleData
>& rScales
, bool bSwapXAndYAxis
);
160 ::basegfx::B3DHomMatrix
getUnitCartesianToScene() const;
162 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::chart2::XTransformation
>
163 getTransformationScaledLogicToScene() const;
165 //the resulting values should be used for input to the transformation
166 //received with 'getTransformationScaledLogicToScene'
167 double transformToRadius( double fLogicValueOnRadiusAxis
, bool bDoScaling
=true ) const;
168 double transformToAngleDegree( double fLogicValueOnAngleAxis
, bool bDoScaling
=true ) const;
169 double getWidthAngleDegree( double& fStartLogicValueOnAngleAxis
, double& fEndLogicValueOnAngleAxis
) const;
172 virtual ::com::sun::star::drawing::Position3D
173 transformLogicToScene( double fX
, double fY
, double fZ
, bool bClip
) const;
174 virtual ::com::sun::star::drawing::Position3D
175 transformScaledLogicToScene( double fX
, double fY
, double fZ
, bool bClip
) const;
176 ::com::sun::star::drawing::Position3D
177 transformAngleRadiusToScene( double fLogicValueOnAngleAxis
, double fLogicValueOnRadiusAxis
, double fLogicZ
, bool bDoScaling
=true ) const;
178 ::com::sun::star::drawing::Position3D
179 transformUnitCircleToScene( double fUnitAngleDegree
, double fUnitRadius
, double fLogicZ
, bool bDoScaling
=true ) const;
181 using PlottingPositionHelper::transformScaledLogicToScene
;
183 double getOuterLogicRadius() const;
185 inline bool isMathematicalOrientationAngle() const;
186 inline bool isMathematicalOrientationRadius() const;
188 //Offset for radius axis in absolute logic scaled values (1.0 == 1 category)
189 double m_fRadiusOffset
;
190 //Offset for angle axis in real degree
191 double m_fAngleDegreeOffset
;
194 ::basegfx::B3DHomMatrix m_aUnitCartesianToScene
;
195 NormalAxis m_eNormalAxis
;
197 ::basegfx::B3DHomMatrix
impl_calculateMatrixUnitCartesianToScene( const ::basegfx::B3DHomMatrix
& rMatrixScreenToScene
) const;
200 bool PolarPlottingPositionHelper::isMathematicalOrientationAngle() const
202 const ExplicitScaleData
& rScale
= m_bSwapXAndY
? m_aScales
[1] : m_aScales
[2];
203 if( ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL
==rScale
.Orientation
)
207 bool PolarPlottingPositionHelper::isMathematicalOrientationRadius() const
209 const ExplicitScaleData
& rScale
= m_bSwapXAndY
? m_aScales
[0] : m_aScales
[1];
210 if( ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL
==rScale
.Orientation
)
215 //better performance for big data
216 void PlottingPositionHelper::setCoordinateSystemResolution( const ::com::sun::star::uno::Sequence
< sal_Int32
>& rCoordinateSystemResolution
)
218 m_nXResolution
= 1000;
219 m_nYResolution
= 1000;
220 m_nZResolution
= 1000;
221 if( rCoordinateSystemResolution
.getLength() > 0 )
222 m_nXResolution
= rCoordinateSystemResolution
[0];
223 if( rCoordinateSystemResolution
.getLength() > 1 )
224 m_nYResolution
= rCoordinateSystemResolution
[1];
225 if( rCoordinateSystemResolution
.getLength() > 2 )
226 m_nZResolution
= rCoordinateSystemResolution
[2];
229 bool PlottingPositionHelper::isSameForGivenResolution( double fX
, double fY
, double fZ
230 , double fX2
, double fY2
, double fZ2
/*these values are all expected tp be scaled already*/ )
232 if( !::rtl::math::isFinite(fX
) || !::rtl::math::isFinite(fY
) || !::rtl::math::isFinite(fZ
)
233 || !::rtl::math::isFinite(fX2
) || !::rtl::math::isFinite(fY2
) || !::rtl::math::isFinite(fZ2
) )
236 double fScaledMinX
= getLogicMinX();
237 double fScaledMinY
= getLogicMinY();
238 double fScaledMinZ
= getLogicMinZ();
239 double fScaledMaxX
= getLogicMaxX();
240 double fScaledMaxY
= getLogicMaxY();
241 double fScaledMaxZ
= getLogicMaxZ();
243 doLogicScaling( &fScaledMinX
, &fScaledMinY
, &fScaledMinZ
);
244 doLogicScaling( &fScaledMaxX
, &fScaledMaxY
, &fScaledMaxZ
);
246 bool bSameX
= ( static_cast<sal_Int32
>(m_nXResolution
*(fX
- fScaledMinX
)/(fScaledMaxX
-fScaledMinX
))
247 == static_cast<sal_Int32
>(m_nXResolution
*(fX2
- fScaledMinX
)/(fScaledMaxX
-fScaledMinX
)) );
249 bool bSameY
= ( static_cast<sal_Int32
>(m_nYResolution
*(fY
- fScaledMinY
)/(fScaledMaxY
-fScaledMinY
))
250 == static_cast<sal_Int32
>(m_nYResolution
*(fY2
- fScaledMinY
)/(fScaledMaxY
-fScaledMinY
)) );
252 bool bSameZ
= ( static_cast<sal_Int32
>(m_nZResolution
*(fZ
- fScaledMinZ
)/(fScaledMaxZ
-fScaledMinZ
))
253 == static_cast<sal_Int32
>(m_nZResolution
*(fZ2
- fScaledMinZ
)/(fScaledMaxZ
-fScaledMinZ
)) );
255 return (bSameX
&& bSameY
&& bSameZ
);
258 bool PlottingPositionHelper::isStrongLowerRequested( sal_Int32 nDimensionIndex
) const
260 if( m_aScales
.empty() )
262 if( 0==nDimensionIndex
)
263 return m_bAllowShiftXAxisPos
&& m_aScales
[nDimensionIndex
].ShiftedCategoryPosition
;
264 else if( 2==nDimensionIndex
)
265 return m_bAllowShiftZAxisPos
&& m_aScales
[nDimensionIndex
].ShiftedCategoryPosition
;
269 bool PlottingPositionHelper::isLogicVisible(
270 double fX
, double fY
, double fZ
) const
272 return fX
>= m_aScales
[0].Minimum
&& ( isStrongLowerRequested(0) ? fX
< m_aScales
[0].Maximum
: fX
<= m_aScales
[0].Maximum
)
273 && fY
>= m_aScales
[1].Minimum
&& fY
<= m_aScales
[1].Maximum
274 && fZ
>= m_aScales
[2].Minimum
&& ( isStrongLowerRequested(2) ? fZ
< m_aScales
[2].Maximum
: fZ
<= m_aScales
[2].Maximum
);
277 void PlottingPositionHelper::doLogicScaling( double* pX
, double* pY
, double* pZ
, bool bClip
) const
280 this->clipLogicValues( pX
,pY
,pZ
);
284 if( m_aScales
[0].Scaling
.is())
285 *pX
= m_aScales
[0].Scaling
->doScaling(*pX
);
286 if( m_bAllowShiftXAxisPos
&& m_aScales
[0].ShiftedCategoryPosition
)
287 (*pX
) += m_fScaledCategoryWidth
/2.0;
289 if(pY
&& m_aScales
[1].Scaling
.is())
290 *pY
= m_aScales
[1].Scaling
->doScaling(*pY
);
293 if( m_aScales
[2].Scaling
.is())
294 *pZ
= m_aScales
[2].Scaling
->doScaling(*pZ
);
295 if( m_bAllowShiftZAxisPos
&& m_aScales
[2].ShiftedCategoryPosition
)
300 void PlottingPositionHelper::doUnshiftedLogicScaling( double* pX
, double* pY
, double* pZ
, bool bClip
) const
303 this->clipLogicValues( pX
,pY
,pZ
);
305 if(pX
&& m_aScales
[0].Scaling
.is())
306 *pX
= m_aScales
[0].Scaling
->doScaling(*pX
);
307 if(pY
&& m_aScales
[1].Scaling
.is())
308 *pY
= m_aScales
[1].Scaling
->doScaling(*pY
);
309 if(pZ
&& m_aScales
[2].Scaling
.is())
310 *pZ
= m_aScales
[2].Scaling
->doScaling(*pZ
);
313 void PlottingPositionHelper::doLogicScaling( ::com::sun::star::drawing::Position3D
& rPos
, bool bClip
) const
315 doLogicScaling( &rPos
.PositionX
, &rPos
.PositionY
, &rPos
.PositionZ
, bClip
);
318 void PlottingPositionHelper::clipLogicValues( double* pX
, double* pY
, double* pZ
) const
322 if( *pX
< m_aScales
[0].Minimum
)
323 *pX
= m_aScales
[0].Minimum
;
324 else if( *pX
> m_aScales
[0].Maximum
)
325 *pX
= m_aScales
[0].Maximum
;
329 if( *pY
< m_aScales
[1].Minimum
)
330 *pY
= m_aScales
[1].Minimum
;
331 else if( *pY
> m_aScales
[1].Maximum
)
332 *pY
= m_aScales
[1].Maximum
;
336 if( *pZ
< m_aScales
[2].Minimum
)
337 *pZ
= m_aScales
[2].Minimum
;
338 else if( *pZ
> m_aScales
[2].Maximum
)
339 *pZ
= m_aScales
[2].Maximum
;
343 inline bool PlottingPositionHelper::clipYRange( double& rMin
, double& rMax
) const
345 //returns true if something remains
352 if( rMin
> getLogicMaxY() )
354 if( rMax
< getLogicMinY() )
356 if( rMin
< getLogicMinY() )
357 rMin
= getLogicMinY();
358 if( rMax
> getLogicMaxY() )
359 rMax
= getLogicMaxY();
363 inline double PlottingPositionHelper::getLogicMinX() const
365 return m_aScales
[0].Minimum
;
367 inline double PlottingPositionHelper::getLogicMinY() const
369 return m_aScales
[1].Minimum
;
371 inline double PlottingPositionHelper::getLogicMinZ() const
373 return m_aScales
[2].Minimum
;
376 inline double PlottingPositionHelper::getLogicMaxX() const
378 return m_aScales
[0].Maximum
;
380 inline double PlottingPositionHelper::getLogicMaxY() const
382 return m_aScales
[1].Maximum
;
384 inline double PlottingPositionHelper::getLogicMaxZ() const
386 return m_aScales
[2].Maximum
;
388 inline bool PlottingPositionHelper::isMathematicalOrientationX() const
390 return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL
== m_aScales
[0].Orientation
;
392 inline bool PlottingPositionHelper::isMathematicalOrientationY() const
394 return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL
== m_aScales
[1].Orientation
;
396 inline bool PlottingPositionHelper::isMathematicalOrientationZ() const
398 return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL
== m_aScales
[2].Orientation
;
400 inline bool PlottingPositionHelper::isSwapXAndY() const
404 inline bool PlottingPositionHelper::maySkipPointsInRegressionCalculation() const
406 return m_bMaySkipPointsInRegressionCalculation
;
409 //.............................................................................
411 //.............................................................................
414 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */