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 : const ::std::vector< ExplicitScaleData >& getScales() const;
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 : ::basegfx::B3DHomMatrix getUnitCartesianToScene() const;
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 :
170 : virtual ::com::sun::star::drawing::Position3D
171 : transformLogicToScene( double fX, double fY, double fZ, bool bClip ) const SAL_OVERRIDE;
172 : virtual ::com::sun::star::drawing::Position3D
173 : transformScaledLogicToScene( double fX, double fY, double fZ, bool bClip ) const SAL_OVERRIDE;
174 : ::com::sun::star::drawing::Position3D
175 : transformAngleRadiusToScene( double fLogicValueOnAngleAxis, double fLogicValueOnRadiusAxis, double fLogicZ, bool bDoScaling=true ) const;
176 : ::com::sun::star::drawing::Position3D
177 : transformUnitCircleToScene( double fUnitAngleDegree, double fUnitRadius, double fLogicZ, bool bDoScaling=true ) const;
178 :
179 : using PlottingPositionHelper::transformScaledLogicToScene;
180 :
181 : double getOuterLogicRadius() const;
182 :
183 : inline bool isMathematicalOrientationAngle() const;
184 : inline bool isMathematicalOrientationRadius() const;
185 : public:
186 : //Offset for radius axis in absolute logic scaled values (1.0 == 1 category)
187 : double m_fRadiusOffset;
188 : //Offset for angle axis in real degree
189 : double m_fAngleDegreeOffset;
190 :
191 : private:
192 : ::basegfx::B3DHomMatrix m_aUnitCartesianToScene;
193 : NormalAxis m_eNormalAxis;
194 :
195 : ::basegfx::B3DHomMatrix impl_calculateMatrixUnitCartesianToScene( const ::basegfx::B3DHomMatrix& rMatrixScreenToScene ) const;
196 : };
197 :
198 0 : bool PolarPlottingPositionHelper::isMathematicalOrientationAngle() const
199 : {
200 0 : const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[1] : m_aScales[2];
201 0 : if( ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL==rScale.Orientation )
202 0 : return true;
203 0 : return false;
204 : }
205 266 : bool PolarPlottingPositionHelper::isMathematicalOrientationRadius() const
206 : {
207 266 : const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[0] : m_aScales[1];
208 266 : if( ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL==rScale.Orientation )
209 32 : return true;
210 234 : return false;
211 : }
212 :
213 : //better performance for big data
214 7951 : void PlottingPositionHelper::setCoordinateSystemResolution( const ::com::sun::star::uno::Sequence< sal_Int32 >& rCoordinateSystemResolution )
215 : {
216 7951 : m_nXResolution = 1000;
217 7951 : m_nYResolution = 1000;
218 7951 : m_nZResolution = 1000;
219 7951 : if( rCoordinateSystemResolution.getLength() > 0 )
220 7951 : m_nXResolution = rCoordinateSystemResolution[0];
221 7951 : if( rCoordinateSystemResolution.getLength() > 1 )
222 7951 : m_nYResolution = rCoordinateSystemResolution[1];
223 7951 : if( rCoordinateSystemResolution.getLength() > 2 )
224 201 : m_nZResolution = rCoordinateSystemResolution[2];
225 7951 : }
226 :
227 7808 : bool PlottingPositionHelper::isSameForGivenResolution( double fX, double fY, double fZ
228 : , double fX2, double fY2, double fZ2 /*these values are all expected tp be scaled already*/ )
229 : {
230 21513 : if( !::rtl::math::isFinite(fX) || !::rtl::math::isFinite(fY) || !::rtl::math::isFinite(fZ)
231 13705 : || !::rtl::math::isFinite(fX2) || !::rtl::math::isFinite(fY2) || !::rtl::math::isFinite(fZ2) )
232 1911 : return false;
233 :
234 5897 : double fScaledMinX = getLogicMinX();
235 5897 : double fScaledMinY = getLogicMinY();
236 5897 : double fScaledMinZ = getLogicMinZ();
237 5897 : double fScaledMaxX = getLogicMaxX();
238 5897 : double fScaledMaxY = getLogicMaxY();
239 5897 : double fScaledMaxZ = getLogicMaxZ();
240 :
241 5897 : doLogicScaling( &fScaledMinX, &fScaledMinY, &fScaledMinZ );
242 5897 : doLogicScaling( &fScaledMaxX, &fScaledMaxY, &fScaledMaxZ);
243 :
244 5897 : bool bSameX = ( static_cast<sal_Int32>(m_nXResolution*(fX - fScaledMinX)/(fScaledMaxX-fScaledMinX))
245 5897 : == static_cast<sal_Int32>(m_nXResolution*(fX2 - fScaledMinX)/(fScaledMaxX-fScaledMinX)) );
246 :
247 5897 : bool bSameY = ( static_cast<sal_Int32>(m_nYResolution*(fY - fScaledMinY)/(fScaledMaxY-fScaledMinY))
248 5897 : == static_cast<sal_Int32>(m_nYResolution*(fY2 - fScaledMinY)/(fScaledMaxY-fScaledMinY)) );
249 :
250 5897 : bool bSameZ = ( static_cast<sal_Int32>(m_nZResolution*(fZ - fScaledMinZ)/(fScaledMaxZ-fScaledMinZ))
251 5897 : == static_cast<sal_Int32>(m_nZResolution*(fZ2 - fScaledMinZ)/(fScaledMaxZ-fScaledMinZ)) );
252 :
253 5897 : return (bSameX && bSameY && bSameZ);
254 : }
255 :
256 10142 : bool PlottingPositionHelper::isStrongLowerRequested( sal_Int32 nDimensionIndex ) const
257 : {
258 10142 : if( m_aScales.empty() )
259 0 : return false;
260 10142 : if( 0==nDimensionIndex )
261 8568 : return m_bAllowShiftXAxisPos && m_aScales[nDimensionIndex].ShiftedCategoryPosition;
262 1574 : else if( 2==nDimensionIndex )
263 1574 : return m_bAllowShiftZAxisPos && m_aScales[nDimensionIndex].ShiftedCategoryPosition;
264 0 : return false;
265 : }
266 :
267 1660 : bool PlottingPositionHelper::isLogicVisible(
268 : double fX, double fY, double fZ ) const
269 : {
270 3363 : return fX >= m_aScales[0].Minimum && ( isStrongLowerRequested(0) ? fX < m_aScales[0].Maximum : fX <= m_aScales[0].Maximum )
271 1660 : && fY >= m_aScales[1].Minimum && fY <= m_aScales[1].Maximum
272 4894 : && fZ >= m_aScales[2].Minimum && ( isStrongLowerRequested(2) ? fZ < m_aScales[2].Maximum : fZ <= m_aScales[2].Maximum );
273 : }
274 :
275 77044 : void PlottingPositionHelper::doLogicScaling( double* pX, double* pY, double* pZ, bool bClip ) const
276 : {
277 77044 : if(bClip)
278 0 : this->clipLogicValues( pX,pY,pZ );
279 :
280 77044 : if(pX)
281 : {
282 53806 : if( m_aScales[0].Scaling.is())
283 1883 : *pX = m_aScales[0].Scaling->doScaling(*pX);
284 53806 : if( m_bAllowShiftXAxisPos && m_aScales[0].ShiftedCategoryPosition )
285 16873 : (*pX) += m_fScaledCategoryWidth/2.0;
286 : }
287 77044 : if(pY && m_aScales[1].Scaling.is())
288 63958 : *pY = m_aScales[1].Scaling->doScaling(*pY);
289 77044 : if(pZ)
290 : {
291 48491 : if( m_aScales[2].Scaling.is())
292 0 : *pZ = m_aScales[2].Scaling->doScaling(*pZ);
293 48491 : if( m_bAllowShiftZAxisPos && m_aScales[2].ShiftedCategoryPosition)
294 848 : (*pZ) += 0.5;
295 : }
296 77044 : }
297 :
298 145390 : void PlottingPositionHelper::doUnshiftedLogicScaling( double* pX, double* pY, double* pZ, bool bClip ) const
299 : {
300 145390 : if(bClip)
301 0 : this->clipLogicValues( pX,pY,pZ );
302 :
303 145390 : if(pX && m_aScales[0].Scaling.is())
304 3810 : *pX = m_aScales[0].Scaling->doScaling(*pX);
305 145390 : if(pY && m_aScales[1].Scaling.is())
306 139962 : *pY = m_aScales[1].Scaling->doScaling(*pY);
307 145390 : if(pZ && m_aScales[2].Scaling.is())
308 0 : *pZ = m_aScales[2].Scaling->doScaling(*pZ);
309 145390 : }
310 :
311 1116 : void PlottingPositionHelper::doLogicScaling( ::com::sun::star::drawing::Position3D& rPos, bool bClip ) const
312 : {
313 1116 : doLogicScaling( &rPos.PositionX, &rPos.PositionY, &rPos.PositionZ, bClip );
314 1116 : }
315 :
316 494 : void PlottingPositionHelper::clipLogicValues( double* pX, double* pY, double* pZ ) const
317 : {
318 494 : if(pX)
319 : {
320 354 : if( *pX < m_aScales[0].Minimum )
321 0 : *pX = m_aScales[0].Minimum;
322 354 : else if( *pX > m_aScales[0].Maximum )
323 0 : *pX = m_aScales[0].Maximum;
324 : }
325 494 : if(pY)
326 : {
327 494 : if( *pY < m_aScales[1].Minimum )
328 0 : *pY = m_aScales[1].Minimum;
329 494 : else if( *pY > m_aScales[1].Maximum )
330 0 : *pY = m_aScales[1].Maximum;
331 : }
332 494 : if(pZ)
333 : {
334 354 : if( *pZ < m_aScales[2].Minimum )
335 0 : *pZ = m_aScales[2].Minimum;
336 354 : else if( *pZ > m_aScales[2].Maximum )
337 0 : *pZ = m_aScales[2].Maximum;
338 : }
339 494 : }
340 :
341 6892 : inline bool PlottingPositionHelper::clipYRange( double& rMin, double& rMax ) const
342 : {
343 : //returns true if something remains
344 6892 : if( rMin > rMax )
345 : {
346 146 : double fHelp = rMin;
347 146 : rMin = rMax;
348 146 : rMax = fHelp;
349 : }
350 6892 : if( rMin > getLogicMaxY() )
351 0 : return false;
352 6892 : if( rMax < getLogicMinY() )
353 57 : return false;
354 6835 : if( rMin < getLogicMinY() )
355 1359 : rMin = getLogicMinY();
356 6835 : if( rMax > getLogicMaxY() )
357 0 : rMax = getLogicMaxY();
358 6835 : return true;
359 : }
360 :
361 111330 : inline double PlottingPositionHelper::getLogicMinX() const
362 : {
363 111330 : return m_aScales[0].Minimum;
364 : }
365 120640 : inline double PlottingPositionHelper::getLogicMinY() const
366 : {
367 120640 : return m_aScales[1].Minimum;
368 : }
369 94975 : inline double PlottingPositionHelper::getLogicMinZ() const
370 : {
371 94975 : return m_aScales[2].Minimum;
372 : }
373 :
374 126413 : inline double PlottingPositionHelper::getLogicMaxX() const
375 : {
376 126413 : return m_aScales[0].Maximum;
377 : }
378 126209 : inline double PlottingPositionHelper::getLogicMaxY() const
379 : {
380 126209 : return m_aScales[1].Maximum;
381 : }
382 95416 : inline double PlottingPositionHelper::getLogicMaxZ() const
383 : {
384 95416 : return m_aScales[2].Maximum;
385 : }
386 15107 : inline bool PlottingPositionHelper::isMathematicalOrientationX() const
387 : {
388 15107 : return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[0].Orientation;
389 : }
390 15259 : inline bool PlottingPositionHelper::isMathematicalOrientationY() const
391 : {
392 15259 : return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[1].Orientation;
393 : }
394 15107 : inline bool PlottingPositionHelper::isMathematicalOrientationZ() const
395 : {
396 15107 : return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[2].Orientation;
397 : }
398 30818 : inline bool PlottingPositionHelper::isSwapXAndY() const
399 : {
400 30818 : return m_bSwapXAndY;
401 : }
402 1927 : inline bool PlottingPositionHelper::maySkipPointsInRegressionCalculation() const
403 : {
404 1927 : return m_bMaySkipPointsInRegressionCalculation;
405 : }
406 :
407 : } //namespace chart
408 : #endif
409 :
410 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|