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 INCLUDED_CHART2_SOURCE_VIEW_INC_PLOTTINGPOSITIONHELPER_HXX
20 : #define INCLUDED_CHART2_SOURCE_VIEW_INC_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 : namespace chart
36 : {
37 :
38 : class AbstractShapeFactory;
39 :
40 : class PlottingPositionHelper
41 : {
42 : public:
43 : PlottingPositionHelper();
44 : PlottingPositionHelper( const PlottingPositionHelper& rSource );
45 : virtual ~PlottingPositionHelper();
46 :
47 : virtual PlottingPositionHelper* clone() const;
48 : virtual PlottingPositionHelper* createSecondaryPosHelper( const ExplicitScaleData& rSecondaryScale );
49 :
50 : virtual void setTransformationSceneToScreen( const ::com::sun::star::drawing::HomogenMatrix& rMatrix);
51 :
52 : virtual void setScales( const ::std::vector< ExplicitScaleData >& rScales, bool bSwapXAndYAxis );
53 94 : const ::std::vector< ExplicitScaleData >& getScales() const { return m_aScales;}
54 :
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 );
59 :
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;
67 :
68 : inline void doLogicScaling( ::com::sun::star::drawing::Position3D& rPos, bool bClip=false ) const;
69 :
70 : virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTransformation >
71 : getTransformationScaledLogicToScene() const;
72 :
73 : virtual ::com::sun::star::drawing::Position3D
74 : transformLogicToScene( double fX, double fY, double fZ, bool bClip ) const;
75 :
76 : virtual ::com::sun::star::drawing::Position3D
77 : transformScaledLogicToScene( double fX, double fY, double fZ, bool bClip ) const;
78 :
79 : void transformScaledLogicToScene( ::com::sun::star::drawing::PolyPolygonShape3D& rPoly ) const;
80 :
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 );
85 :
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;
92 :
93 : inline bool isMathematicalOrientationX() const;
94 : inline bool isMathematicalOrientationY() const;
95 : inline bool isMathematicalOrientationZ() const;
96 :
97 : ::basegfx::B2DRectangle getScaledLogicClipDoubleRect() const;
98 : ::com::sun::star::drawing::Direction3D getScaledLogicWidth() const;
99 :
100 : inline bool isSwapXAndY() const;
101 :
102 : bool isPercentY() const;
103 :
104 : double getBaseValueY() const;
105 :
106 : inline bool maySkipPointsInRegressionCalculation() const;
107 :
108 : void setTimeResolution( long nTimeResolution, const Date& rNullDate );
109 : virtual void setScaledCategoryWidth( double fScaledCategoryWidth );
110 : void AllowShiftXAxisPos( bool bAllowShift );
111 : void AllowShiftZAxisPos( bool bAllowShift );
112 :
113 : protected: //member
114 : ::std::vector< ExplicitScaleData > m_aScales;
115 : ::basegfx::B3DHomMatrix m_aMatrixScreenToScene;
116 :
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;
120 :
121 : bool m_bSwapXAndY;//e.g. true for bar chart and false for column chart
122 :
123 : sal_Int32 m_nXResolution;
124 : sal_Int32 m_nYResolution;
125 : sal_Int32 m_nZResolution;
126 :
127 : bool m_bMaySkipPointsInRegressionCalculation;
128 :
129 : bool m_bDateAxis;
130 : long m_nTimeResolution;
131 : Date m_aNullDate;
132 :
133 : double m_fScaledCategoryWidth;
134 : bool m_bAllowShiftXAxisPos;
135 : bool m_bAllowShiftZAxisPos;
136 : };
137 :
138 : //describes which axis of the drawinglayer scene or sreen axis are the normal axis
139 : enum NormalAxis
140 : {
141 : NormalAxis_X
142 : , NormalAxis_Y
143 : , NormalAxis_Z
144 : };
145 :
146 : class PolarPlottingPositionHelper : public PlottingPositionHelper
147 : {
148 : public:
149 : PolarPlottingPositionHelper( NormalAxis eNormalAxis=NormalAxis_Z );
150 : PolarPlottingPositionHelper( const PolarPlottingPositionHelper& rSource );
151 : virtual ~PolarPlottingPositionHelper();
152 :
153 : virtual PlottingPositionHelper* clone() const SAL_OVERRIDE;
154 :
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;
157 :
158 152 : ::basegfx::B3DHomMatrix getUnitCartesianToScene() const { return m_aUnitCartesianToScene;}
159 :
160 : virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTransformation >
161 : getTransformationScaledLogicToScene() const SAL_OVERRIDE;
162 :
163 : //the resulting values should be used for input to the transformation
164 : //received with 'getTransformationScaledLogicToScene'
165 : double transformToRadius( double fLogicValueOnRadiusAxis, bool bDoScaling=true ) const;
166 : double transformToAngleDegree( double fLogicValueOnAngleAxis, bool bDoScaling=true ) const;
167 : double getWidthAngleDegree( double& fStartLogicValueOnAngleAxis, double& fEndLogicValueOnAngleAxis ) const;
168 :
169 : virtual ::com::sun::star::drawing::Position3D
170 : transformLogicToScene( double fX, double fY, double fZ, bool bClip ) const SAL_OVERRIDE;
171 : virtual ::com::sun::star::drawing::Position3D
172 : transformScaledLogicToScene( double fX, double fY, double fZ, bool bClip ) const SAL_OVERRIDE;
173 : ::com::sun::star::drawing::Position3D
174 : transformAngleRadiusToScene( double fLogicValueOnAngleAxis, double fLogicValueOnRadiusAxis, double fLogicZ, bool bDoScaling=true ) const;
175 : ::com::sun::star::drawing::Position3D
176 : transformUnitCircleToScene( double fUnitAngleDegree, double fUnitRadius, double fLogicZ, bool bDoScaling=true ) const;
177 :
178 : using PlottingPositionHelper::transformScaledLogicToScene;
179 :
180 : double getOuterLogicRadius() const;
181 :
182 : inline bool isMathematicalOrientationAngle() const;
183 : inline bool isMathematicalOrientationRadius() const;
184 : public:
185 : //Offset for radius axis in absolute logic scaled values (1.0 == 1 category)
186 : double m_fRadiusOffset;
187 : //Offset for angle axis in real degree
188 : double m_fAngleDegreeOffset;
189 :
190 : private:
191 : ::basegfx::B3DHomMatrix m_aUnitCartesianToScene;
192 : NormalAxis m_eNormalAxis;
193 :
194 : ::basegfx::B3DHomMatrix impl_calculateMatrixUnitCartesianToScene( const ::basegfx::B3DHomMatrix& rMatrixScreenToScene ) const;
195 : };
196 :
197 0 : bool PolarPlottingPositionHelper::isMathematicalOrientationAngle() const
198 : {
199 0 : const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[1] : m_aScales[2];
200 0 : if( ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL==rScale.Orientation )
201 0 : return true;
202 0 : return false;
203 : }
204 344 : bool PolarPlottingPositionHelper::isMathematicalOrientationRadius() const
205 : {
206 344 : const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[0] : m_aScales[1];
207 344 : if( ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL==rScale.Orientation )
208 164 : return true;
209 180 : return false;
210 : }
211 :
212 : //better performance for big data
213 7681 : void PlottingPositionHelper::setCoordinateSystemResolution( const ::com::sun::star::uno::Sequence< sal_Int32 >& rCoordinateSystemResolution )
214 : {
215 7681 : m_nXResolution = 1000;
216 7681 : m_nYResolution = 1000;
217 7681 : m_nZResolution = 1000;
218 7681 : if( rCoordinateSystemResolution.getLength() > 0 )
219 7681 : m_nXResolution = rCoordinateSystemResolution[0];
220 7681 : if( rCoordinateSystemResolution.getLength() > 1 )
221 7681 : m_nYResolution = rCoordinateSystemResolution[1];
222 7681 : if( rCoordinateSystemResolution.getLength() > 2 )
223 849 : m_nZResolution = rCoordinateSystemResolution[2];
224 7681 : }
225 :
226 7624 : bool PlottingPositionHelper::isSameForGivenResolution( double fX, double fY, double fZ
227 : , double fX2, double fY2, double fZ2 /*these values are all expected tp be scaled already*/ )
228 : {
229 21183 : if( !::rtl::math::isFinite(fX) || !::rtl::math::isFinite(fY) || !::rtl::math::isFinite(fZ)
230 13559 : || !::rtl::math::isFinite(fX2) || !::rtl::math::isFinite(fY2) || !::rtl::math::isFinite(fZ2) )
231 1689 : return false;
232 :
233 5935 : double fScaledMinX = getLogicMinX();
234 5935 : double fScaledMinY = getLogicMinY();
235 5935 : double fScaledMinZ = getLogicMinZ();
236 5935 : double fScaledMaxX = getLogicMaxX();
237 5935 : double fScaledMaxY = getLogicMaxY();
238 5935 : double fScaledMaxZ = getLogicMaxZ();
239 :
240 5935 : doLogicScaling( &fScaledMinX, &fScaledMinY, &fScaledMinZ );
241 5935 : doLogicScaling( &fScaledMaxX, &fScaledMaxY, &fScaledMaxZ);
242 :
243 5935 : bool bSameX = ( static_cast<sal_Int32>(m_nXResolution*(fX - fScaledMinX)/(fScaledMaxX-fScaledMinX))
244 5935 : == static_cast<sal_Int32>(m_nXResolution*(fX2 - fScaledMinX)/(fScaledMaxX-fScaledMinX)) );
245 :
246 5935 : bool bSameY = ( static_cast<sal_Int32>(m_nYResolution*(fY - fScaledMinY)/(fScaledMaxY-fScaledMinY))
247 5935 : == static_cast<sal_Int32>(m_nYResolution*(fY2 - fScaledMinY)/(fScaledMaxY-fScaledMinY)) );
248 :
249 5935 : bool bSameZ = ( static_cast<sal_Int32>(m_nZResolution*(fZ - fScaledMinZ)/(fScaledMaxZ-fScaledMinZ))
250 5935 : == static_cast<sal_Int32>(m_nZResolution*(fZ2 - fScaledMinZ)/(fScaledMaxZ-fScaledMinZ)) );
251 :
252 5935 : return (bSameX && bSameY && bSameZ);
253 : }
254 :
255 11991 : bool PlottingPositionHelper::isStrongLowerRequested( sal_Int32 nDimensionIndex ) const
256 : {
257 11991 : if( m_aScales.empty() )
258 0 : return false;
259 11991 : if( 0==nDimensionIndex )
260 8764 : return m_bAllowShiftXAxisPos && m_aScales[nDimensionIndex].ShiftedCategoryPosition;
261 3227 : else if( 2==nDimensionIndex )
262 3227 : return m_bAllowShiftZAxisPos && m_aScales[nDimensionIndex].ShiftedCategoryPosition;
263 0 : return false;
264 : }
265 :
266 3552 : bool PlottingPositionHelper::isLogicVisible(
267 : double fX, double fY, double fZ ) const
268 : {
269 7191 : return fX >= m_aScales[0].Minimum && ( isStrongLowerRequested(0) ? fX < m_aScales[0].Maximum : fX <= m_aScales[0].Maximum )
270 3552 : && fY >= m_aScales[1].Minimum && fY <= m_aScales[1].Maximum
271 10331 : && fZ >= m_aScales[2].Minimum && ( isStrongLowerRequested(2) ? fZ < m_aScales[2].Maximum : fZ <= m_aScales[2].Maximum );
272 : }
273 :
274 75033 : void PlottingPositionHelper::doLogicScaling( double* pX, double* pY, double* pZ, bool bClip ) const
275 : {
276 75033 : if(bClip)
277 0 : this->clipLogicValues( pX,pY,pZ );
278 :
279 75033 : if(pX)
280 : {
281 53937 : if( m_aScales[0].Scaling.is())
282 4952 : *pX = m_aScales[0].Scaling->doScaling(*pX);
283 53937 : if( m_bAllowShiftXAxisPos && m_aScales[0].ShiftedCategoryPosition )
284 12741 : (*pX) += m_fScaledCategoryWidth/2.0;
285 : }
286 75033 : if(pY && m_aScales[1].Scaling.is())
287 62008 : *pY = m_aScales[1].Scaling->doScaling(*pY);
288 75033 : if(pZ)
289 : {
290 52990 : if( m_aScales[2].Scaling.is())
291 0 : *pZ = m_aScales[2].Scaling->doScaling(*pZ);
292 52990 : if( m_bAllowShiftZAxisPos && m_aScales[2].ShiftedCategoryPosition)
293 4320 : (*pZ) += 0.5;
294 : }
295 75033 : }
296 :
297 125916 : void PlottingPositionHelper::doUnshiftedLogicScaling( double* pX, double* pY, double* pZ, bool bClip ) const
298 : {
299 125916 : if(bClip)
300 0 : this->clipLogicValues( pX,pY,pZ );
301 :
302 125916 : if(pX && m_aScales[0].Scaling.is())
303 9808 : *pX = m_aScales[0].Scaling->doScaling(*pX);
304 125916 : if(pY && m_aScales[1].Scaling.is())
305 122622 : *pY = m_aScales[1].Scaling->doScaling(*pY);
306 125916 : if(pZ && m_aScales[2].Scaling.is())
307 0 : *pZ = m_aScales[2].Scaling->doScaling(*pZ);
308 125916 : }
309 :
310 2615 : void PlottingPositionHelper::doLogicScaling( ::com::sun::star::drawing::Position3D& rPos, bool bClip ) const
311 : {
312 2615 : doLogicScaling( &rPos.PositionX, &rPos.PositionY, &rPos.PositionZ, bClip );
313 2615 : }
314 :
315 676 : void PlottingPositionHelper::clipLogicValues( double* pX, double* pY, double* pZ ) const
316 : {
317 676 : if(pX)
318 : {
319 456 : if( *pX < m_aScales[0].Minimum )
320 0 : *pX = m_aScales[0].Minimum;
321 456 : else if( *pX > m_aScales[0].Maximum )
322 0 : *pX = m_aScales[0].Maximum;
323 : }
324 676 : if(pY)
325 : {
326 676 : if( *pY < m_aScales[1].Minimum )
327 0 : *pY = m_aScales[1].Minimum;
328 676 : else if( *pY > m_aScales[1].Maximum )
329 0 : *pY = m_aScales[1].Maximum;
330 : }
331 676 : if(pZ)
332 : {
333 456 : if( *pZ < m_aScales[2].Minimum )
334 0 : *pZ = m_aScales[2].Minimum;
335 456 : else if( *pZ > m_aScales[2].Maximum )
336 0 : *pZ = m_aScales[2].Maximum;
337 : }
338 676 : }
339 :
340 5180 : inline bool PlottingPositionHelper::clipYRange( double& rMin, double& rMax ) const
341 : {
342 : //returns true if something remains
343 5180 : if( rMin > rMax )
344 : {
345 270 : double fHelp = rMin;
346 270 : rMin = rMax;
347 270 : rMax = fHelp;
348 : }
349 5180 : if( rMin > getLogicMaxY() )
350 0 : return false;
351 5180 : if( rMax < getLogicMinY() )
352 114 : return false;
353 5066 : if( rMin < getLogicMinY() )
354 954 : rMin = getLogicMinY();
355 5066 : if( rMax > getLogicMaxY() )
356 0 : rMax = getLogicMaxY();
357 5066 : return true;
358 : }
359 :
360 89886 : inline double PlottingPositionHelper::getLogicMinX() const
361 : {
362 89886 : return m_aScales[0].Minimum;
363 : }
364 94947 : inline double PlottingPositionHelper::getLogicMinY() const
365 : {
366 94947 : return m_aScales[1].Minimum;
367 : }
368 85367 : inline double PlottingPositionHelper::getLogicMinZ() const
369 : {
370 85367 : return m_aScales[2].Minimum;
371 : }
372 :
373 102358 : inline double PlottingPositionHelper::getLogicMaxX() const
374 : {
375 102358 : return m_aScales[0].Maximum;
376 : }
377 100283 : inline double PlottingPositionHelper::getLogicMaxY() const
378 : {
379 100283 : return m_aScales[1].Maximum;
380 : }
381 86131 : inline double PlottingPositionHelper::getLogicMaxZ() const
382 : {
383 86131 : return m_aScales[2].Maximum;
384 : }
385 13813 : inline bool PlottingPositionHelper::isMathematicalOrientationX() const
386 : {
387 13813 : return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[0].Orientation;
388 : }
389 13926 : inline bool PlottingPositionHelper::isMathematicalOrientationY() const
390 : {
391 13926 : return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[1].Orientation;
392 : }
393 13813 : inline bool PlottingPositionHelper::isMathematicalOrientationZ() const
394 : {
395 13813 : return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[2].Orientation;
396 : }
397 29458 : inline bool PlottingPositionHelper::isSwapXAndY() const
398 : {
399 29458 : return m_bSwapXAndY;
400 : }
401 1721 : inline bool PlottingPositionHelper::maySkipPointsInRegressionCalculation() const
402 : {
403 1721 : return m_bMaySkipPointsInRegressionCalculation;
404 : }
405 :
406 : } //namespace chart
407 : #endif
408 :
409 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|