Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
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/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
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 .
18 : : */
19 : : #ifndef _CHART2_PLOTTINGPOSITIONHELPER_HXX
20 : : #define _CHART2_PLOTTINGPOSITIONHELPER_HXX
21 : :
22 : : #include "LabelAlignment.hxx"
23 : : #include "chartview/ExplicitScaleValues.hxx"
24 : :
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>
34 : :
35 : : //.............................................................................
36 : : namespace chart
37 : : {
38 : : //.............................................................................
39 : :
40 : : class ShapeFactory;
41 : :
42 : : class PlottingPositionHelper
43 : : {
44 : : public:
45 : : PlottingPositionHelper();
46 : : PlottingPositionHelper( const PlottingPositionHelper& rSource );
47 : : virtual ~PlottingPositionHelper();
48 : :
49 : : virtual PlottingPositionHelper* clone() const;
50 : : virtual PlottingPositionHelper* createSecondaryPosHelper( const ExplicitScaleData& rSecondaryScale );
51 : :
52 : : virtual void setTransformationSceneToScreen( const ::com::sun::star::drawing::HomogenMatrix& rMatrix);
53 : :
54 : : virtual void setScales( const ::std::vector< ExplicitScaleData >& rScales, bool bSwapXAndYAxis );
55 : : const ::std::vector< ExplicitScaleData >& getScales() const;
56 : :
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 );
61 : :
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;
69 : :
70 : : inline void doLogicScaling( ::com::sun::star::drawing::Position3D& rPos, bool bClip=false ) const;
71 : :
72 : : virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTransformation >
73 : : getTransformationScaledLogicToScene() const;
74 : :
75 : : virtual ::com::sun::star::drawing::Position3D
76 : : transformLogicToScene( double fX, double fY, double fZ, bool bClip ) const;
77 : :
78 : : virtual ::com::sun::star::drawing::Position3D
79 : : transformScaledLogicToScene( double fX, double fY, double fZ, bool bClip ) const;
80 : :
81 : : void transformScaledLogicToScene( ::com::sun::star::drawing::PolyPolygonShape3D& rPoly ) const;
82 : :
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 );
87 : :
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;
94 : :
95 : : inline bool isMathematicalOrientationX() const;
96 : : inline bool isMathematicalOrientationY() const;
97 : : inline bool isMathematicalOrientationZ() const;
98 : :
99 : : ::basegfx::B2DRectangle getScaledLogicClipDoubleRect() const;
100 : : ::com::sun::star::drawing::Direction3D getScaledLogicWidth() const;
101 : :
102 : : inline bool isSwapXAndY() const;
103 : :
104 : : bool isPercentY() const;
105 : :
106 : : double getBaseValueY() const;
107 : :
108 : : inline bool maySkipPointsInRegressionCalculation() const;
109 : :
110 : : void setTimeResolution( long nTimeResolution, const Date& rNullDate );
111 : : virtual void setScaledCategoryWidth( double fScaledCategoryWidth );
112 : : void AllowShiftXAxisPos( bool bAllowShift );
113 : : void AllowShiftZAxisPos( bool bAllowShift );
114 : :
115 : : protected: //member
116 : : ::std::vector< ExplicitScaleData > m_aScales;
117 : : ::basegfx::B3DHomMatrix m_aMatrixScreenToScene;
118 : :
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;
122 : :
123 : : bool m_bSwapXAndY;//e.g. true for bar chart and false for column chart
124 : :
125 : : sal_Int32 m_nXResolution;
126 : : sal_Int32 m_nYResolution;
127 : : sal_Int32 m_nZResolution;
128 : :
129 : : bool m_bMaySkipPointsInRegressionCalculation;
130 : :
131 : : bool m_bDateAxis;
132 : : long m_nTimeResolution;
133 : : Date m_aNullDate;
134 : :
135 : : double m_fScaledCategoryWidth;
136 : : bool m_bAllowShiftXAxisPos;
137 : : bool m_bAllowShiftZAxisPos;
138 : : };
139 : :
140 : : //describes wich axis of the drawinglayer scene or sreen axis are the normal axis
141 : : enum NormalAxis
142 : : {
143 : : NormalAxis_X
144 : : , NormalAxis_Y
145 : : , NormalAxis_Z
146 : : };
147 : :
148 : : class PolarPlottingPositionHelper : public PlottingPositionHelper
149 : : {
150 : : public:
151 : : PolarPlottingPositionHelper( NormalAxis eNormalAxis=NormalAxis_Z );
152 : : PolarPlottingPositionHelper( const PolarPlottingPositionHelper& rSource );
153 : : virtual ~PolarPlottingPositionHelper();
154 : :
155 : : virtual PlottingPositionHelper* clone() const;
156 : :
157 : : virtual void setTransformationSceneToScreen( const ::com::sun::star::drawing::HomogenMatrix& rMatrix);
158 : : virtual void setScales( const std::vector< ExplicitScaleData >& rScales, bool bSwapXAndYAxis );
159 : :
160 : : ::basegfx::B3DHomMatrix getUnitCartesianToScene() const;
161 : :
162 : : virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTransformation >
163 : : getTransformationScaledLogicToScene() const;
164 : :
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;
170 : : //
171 : :
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;
180 : :
181 : : using PlottingPositionHelper::transformScaledLogicToScene;
182 : :
183 : : double getOuterLogicRadius() const;
184 : :
185 : : inline bool isMathematicalOrientationAngle() const;
186 : : inline bool isMathematicalOrientationRadius() const;
187 : : public:
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;
192 : :
193 : : private:
194 : : ::basegfx::B3DHomMatrix m_aUnitCartesianToScene;
195 : : NormalAxis m_eNormalAxis;
196 : :
197 : : ::basegfx::B3DHomMatrix impl_calculateMatrixUnitCartesianToScene( const ::basegfx::B3DHomMatrix& rMatrixScreenToScene ) const;
198 : : };
199 : :
200 : 0 : bool PolarPlottingPositionHelper::isMathematicalOrientationAngle() const
201 : : {
202 [ # # ]: 0 : const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[1] : m_aScales[2];
203 [ # # ]: 0 : if( ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL==rScale.Orientation )
204 : 0 : return true;
205 : 0 : return false;
206 : : }
207 : 342 : bool PolarPlottingPositionHelper::isMathematicalOrientationRadius() const
208 : : {
209 [ + - ]: 342 : const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[0] : m_aScales[1];
210 [ - + ]: 342 : if( ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL==rScale.Orientation )
211 : 0 : return true;
212 : 342 : return false;
213 : : }
214 : :
215 : : //better performance for big data
216 : 13507 : void PlottingPositionHelper::setCoordinateSystemResolution( const ::com::sun::star::uno::Sequence< sal_Int32 >& rCoordinateSystemResolution )
217 : : {
218 : 13507 : m_nXResolution = 1000;
219 : 13507 : m_nYResolution = 1000;
220 : 13507 : m_nZResolution = 1000;
221 [ + - ]: 13507 : if( rCoordinateSystemResolution.getLength() > 0 )
222 : 13507 : m_nXResolution = rCoordinateSystemResolution[0];
223 [ + - ]: 13507 : if( rCoordinateSystemResolution.getLength() > 1 )
224 : 13507 : m_nYResolution = rCoordinateSystemResolution[1];
225 [ + + ]: 13507 : if( rCoordinateSystemResolution.getLength() > 2 )
226 : 465 : m_nZResolution = rCoordinateSystemResolution[2];
227 : 13507 : }
228 : :
229 : 13263 : 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*/ )
231 : : {
232 [ + + ][ + - ]: 43758 : if( !::rtl::math::isFinite(fX) || !::rtl::math::isFinite(fY) || !::rtl::math::isFinite(fZ)
[ + - + -
+ - - + ]
[ + + ]
233 : 30495 : || !::rtl::math::isFinite(fX2) || !::rtl::math::isFinite(fY2) || !::rtl::math::isFinite(fZ2) )
234 : 3098 : return false;
235 : :
236 [ + - ]: 10165 : double fScaledMinX = getLogicMinX();
237 [ + - ]: 10165 : double fScaledMinY = getLogicMinY();
238 [ + - ]: 10165 : double fScaledMinZ = getLogicMinZ();
239 [ + - ]: 10165 : double fScaledMaxX = getLogicMaxX();
240 [ + - ]: 10165 : double fScaledMaxY = getLogicMaxY();
241 [ + - ]: 10165 : double fScaledMaxZ = getLogicMaxZ();
242 : :
243 [ + - ]: 10165 : doLogicScaling( &fScaledMinX, &fScaledMinY, &fScaledMinZ );
244 [ + - ]: 10165 : doLogicScaling( &fScaledMaxX, &fScaledMaxY, &fScaledMaxZ);
245 : :
246 : : bool bSameX = ( static_cast<sal_Int32>(m_nXResolution*(fX - fScaledMinX)/(fScaledMaxX-fScaledMinX))
247 : 10165 : == static_cast<sal_Int32>(m_nXResolution*(fX2 - fScaledMinX)/(fScaledMaxX-fScaledMinX)) );
248 : :
249 : : bool bSameY = ( static_cast<sal_Int32>(m_nYResolution*(fY - fScaledMinY)/(fScaledMaxY-fScaledMinY))
250 : 10165 : == static_cast<sal_Int32>(m_nYResolution*(fY2 - fScaledMinY)/(fScaledMaxY-fScaledMinY)) );
251 : :
252 : : bool bSameZ = ( static_cast<sal_Int32>(m_nZResolution*(fZ - fScaledMinZ)/(fScaledMaxZ-fScaledMinZ))
253 : 10165 : == static_cast<sal_Int32>(m_nZResolution*(fZ2 - fScaledMinZ)/(fScaledMaxZ-fScaledMinZ)) );
254 : :
255 [ - + ][ # # ]: 13263 : return (bSameX && bSameY && bSameZ);
[ # # ]
256 : : }
257 : :
258 : 17923 : bool PlottingPositionHelper::isStrongLowerRequested( sal_Int32 nDimensionIndex ) const
259 : : {
260 [ - + ]: 17923 : if( m_aScales.empty() )
261 : 0 : return false;
262 [ + + ]: 17923 : if( 0==nDimensionIndex )
263 [ + - ][ + + ]: 14678 : return m_bAllowShiftXAxisPos && m_aScales[nDimensionIndex].ShiftedCategoryPosition;
264 [ + - ]: 3245 : else if( 2==nDimensionIndex )
265 [ + - ][ + + ]: 3245 : return m_bAllowShiftZAxisPos && m_aScales[nDimensionIndex].ShiftedCategoryPosition;
266 : 17923 : return false;
267 : : }
268 : :
269 : 3573 : bool PlottingPositionHelper::isLogicVisible(
270 : : double fX, double fY, double fZ ) const
271 : : {
272 : 10719 : return fX >= m_aScales[0].Minimum && ( isStrongLowerRequested(0) ? fX < m_aScales[0].Maximum : fX <= m_aScales[0].Maximum )
273 : 6976 : && fY >= m_aScales[1].Minimum && fY <= m_aScales[1].Maximum
274 [ + - ][ + + ]: 17695 : && fZ >= m_aScales[2].Minimum && ( isStrongLowerRequested(2) ? fZ < m_aScales[2].Maximum : fZ <= m_aScales[2].Maximum );
[ + - ][ + - ]
[ + - + +
+ - + - +
+ + + ]
275 : : }
276 : :
277 : 127593 : void PlottingPositionHelper::doLogicScaling( double* pX, double* pY, double* pZ, bool bClip ) const
278 : : {
279 [ - + ]: 127593 : if(bClip)
280 : 0 : this->clipLogicValues( pX,pY,pZ );
281 : :
282 [ + + ]: 127593 : if(pX)
283 : : {
284 [ - + ]: 88424 : if( m_aScales[0].Scaling.is())
285 : 0 : *pX = m_aScales[0].Scaling->doScaling(*pX);
286 [ + + ][ + + ]: 88424 : if( m_bAllowShiftXAxisPos && m_aScales[0].ShiftedCategoryPosition )
[ + + ]
287 : 27017 : (*pX) += m_fScaledCategoryWidth/2.0;
288 : : }
289 [ + + ][ + + ]: 127593 : if(pY && m_aScales[1].Scaling.is())
[ + + ]
290 : 102899 : *pY = m_aScales[1].Scaling->doScaling(*pY);
291 [ + + ]: 127593 : if(pZ)
292 : : {
293 [ - + ]: 81862 : if( m_aScales[2].Scaling.is())
294 : 0 : *pZ = m_aScales[2].Scaling->doScaling(*pZ);
295 [ + + ][ + + ]: 81862 : if( m_bAllowShiftZAxisPos && m_aScales[2].ShiftedCategoryPosition)
[ + + ]
296 : 2656 : (*pZ) += 0.5;
297 : : }
298 : 127593 : }
299 : :
300 : 234014 : void PlottingPositionHelper::doUnshiftedLogicScaling( double* pX, double* pY, double* pZ, bool bClip ) const
301 : : {
302 [ - + ]: 234014 : if(bClip)
303 : 0 : this->clipLogicValues( pX,pY,pZ );
304 : :
305 [ + - ][ - + ]: 234014 : if(pX && m_aScales[0].Scaling.is())
[ - + ]
306 : 0 : *pX = m_aScales[0].Scaling->doScaling(*pX);
307 [ + - ][ + + ]: 234014 : if(pY && m_aScales[1].Scaling.is())
[ + + ]
308 : 219866 : *pY = m_aScales[1].Scaling->doScaling(*pY);
309 [ + - ][ - + ]: 234014 : if(pZ && m_aScales[2].Scaling.is())
[ - + ]
310 : 0 : *pZ = m_aScales[2].Scaling->doScaling(*pZ);
311 : 234014 : }
312 : :
313 : 2538 : void PlottingPositionHelper::doLogicScaling( ::com::sun::star::drawing::Position3D& rPos, bool bClip ) const
314 : : {
315 : 2538 : doLogicScaling( &rPos.PositionX, &rPos.PositionY, &rPos.PositionZ, bClip );
316 : 2538 : }
317 : :
318 : 696 : void PlottingPositionHelper::clipLogicValues( double* pX, double* pY, double* pZ ) const
319 : : {
320 [ + + ]: 696 : if(pX)
321 : : {
322 [ - + ]: 456 : if( *pX < m_aScales[0].Minimum )
323 : 0 : *pX = m_aScales[0].Minimum;
324 [ - + ]: 456 : else if( *pX > m_aScales[0].Maximum )
325 : 0 : *pX = m_aScales[0].Maximum;
326 : : }
327 [ + - ]: 696 : if(pY)
328 : : {
329 [ - + ]: 696 : if( *pY < m_aScales[1].Minimum )
330 : 0 : *pY = m_aScales[1].Minimum;
331 [ - + ]: 696 : else if( *pY > m_aScales[1].Maximum )
332 : 0 : *pY = m_aScales[1].Maximum;
333 : : }
334 [ + + ]: 696 : if(pZ)
335 : : {
336 [ - + ]: 456 : if( *pZ < m_aScales[2].Minimum )
337 : 0 : *pZ = m_aScales[2].Minimum;
338 [ - + ]: 456 : else if( *pZ > m_aScales[2].Maximum )
339 : 0 : *pZ = m_aScales[2].Maximum;
340 : : }
341 : 696 : }
342 : :
343 : 11089 : inline bool PlottingPositionHelper::clipYRange( double& rMin, double& rMax ) const
344 : : {
345 : : //returns true if something remains
346 [ + + ]: 11089 : if( rMin > rMax )
347 : : {
348 : 190 : double fHelp = rMin;
349 : 190 : rMin = rMax;
350 : 190 : rMax = fHelp;
351 : : }
352 [ - + ]: 11089 : if( rMin > getLogicMaxY() )
353 : 0 : return false;
354 [ + + ]: 11089 : if( rMax < getLogicMinY() )
355 : 120 : return false;
356 [ + + ]: 10969 : if( rMin < getLogicMinY() )
357 : 2616 : rMin = getLogicMinY();
358 [ - + ]: 10969 : if( rMax > getLogicMaxY() )
359 : 0 : rMax = getLogicMaxY();
360 : 11089 : return true;
361 : : }
362 : :
363 : 181133 : inline double PlottingPositionHelper::getLogicMinX() const
364 : : {
365 : 181133 : return m_aScales[0].Minimum;
366 : : }
367 : 194155 : inline double PlottingPositionHelper::getLogicMinY() const
368 : : {
369 : 194155 : return m_aScales[1].Minimum;
370 : : }
371 : 153555 : inline double PlottingPositionHelper::getLogicMinZ() const
372 : : {
373 : 153555 : return m_aScales[2].Minimum;
374 : : }
375 : :
376 : 205198 : inline double PlottingPositionHelper::getLogicMaxX() const
377 : : {
378 : 205198 : return m_aScales[0].Maximum;
379 : : }
380 : 202074 : inline double PlottingPositionHelper::getLogicMaxY() const
381 : : {
382 : 202074 : return m_aScales[1].Maximum;
383 : : }
384 : 154158 : inline double PlottingPositionHelper::getLogicMaxZ() const
385 : : {
386 : 154158 : return m_aScales[2].Maximum;
387 : : }
388 : 23643 : inline bool PlottingPositionHelper::isMathematicalOrientationX() const
389 : : {
390 : 23643 : return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[0].Orientation;
391 : : }
392 : 23887 : inline bool PlottingPositionHelper::isMathematicalOrientationY() const
393 : : {
394 : 23887 : return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[1].Orientation;
395 : : }
396 : 23643 : inline bool PlottingPositionHelper::isMathematicalOrientationZ() const
397 : : {
398 : 23643 : return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[2].Orientation;
399 : : }
400 : 49080 : inline bool PlottingPositionHelper::isSwapXAndY() const
401 : : {
402 : 49080 : return m_bSwapXAndY;
403 : : }
404 : 3129 : inline bool PlottingPositionHelper::maySkipPointsInRegressionCalculation() const
405 : : {
406 : 3129 : return m_bMaySkipPointsInRegressionCalculation;
407 : : }
408 : :
409 : : //.............................................................................
410 : : } //namespace chart
411 : : //.............................................................................
412 : : #endif
413 : :
414 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|