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 0 : bool PolarPlottingPositionHelper::isMathematicalOrientationRadius() const
208 : {
209 0 : const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[0] : m_aScales[1];
210 0 : if( ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL==rScale.Orientation )
211 0 : return true;
212 0 : return false;
213 : }
214 :
215 : //better performance for big data
216 492 : void PlottingPositionHelper::setCoordinateSystemResolution( const ::com::sun::star::uno::Sequence< sal_Int32 >& rCoordinateSystemResolution )
217 : {
218 492 : m_nXResolution = 1000;
219 492 : m_nYResolution = 1000;
220 492 : m_nZResolution = 1000;
221 492 : if( rCoordinateSystemResolution.getLength() > 0 )
222 492 : m_nXResolution = rCoordinateSystemResolution[0];
223 492 : if( rCoordinateSystemResolution.getLength() > 1 )
224 492 : m_nYResolution = rCoordinateSystemResolution[1];
225 492 : if( rCoordinateSystemResolution.getLength() > 2 )
226 0 : m_nZResolution = rCoordinateSystemResolution[2];
227 492 : }
228 :
229 492 : 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 1599 : if( !::rtl::math::isFinite(fX) || !::rtl::math::isFinite(fY) || !::rtl::math::isFinite(fZ)
233 1107 : || !::rtl::math::isFinite(fX2) || !::rtl::math::isFinite(fY2) || !::rtl::math::isFinite(fZ2) )
234 123 : return false;
235 :
236 369 : double fScaledMinX = getLogicMinX();
237 369 : double fScaledMinY = getLogicMinY();
238 369 : double fScaledMinZ = getLogicMinZ();
239 369 : double fScaledMaxX = getLogicMaxX();
240 369 : double fScaledMaxY = getLogicMaxY();
241 369 : double fScaledMaxZ = getLogicMaxZ();
242 :
243 369 : doLogicScaling( &fScaledMinX, &fScaledMinY, &fScaledMinZ );
244 369 : doLogicScaling( &fScaledMaxX, &fScaledMaxY, &fScaledMaxZ);
245 :
246 : bool bSameX = ( static_cast<sal_Int32>(m_nXResolution*(fX - fScaledMinX)/(fScaledMaxX-fScaledMinX))
247 369 : == 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 369 : == 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 369 : == static_cast<sal_Int32>(m_nZResolution*(fZ2 - fScaledMinZ)/(fScaledMaxZ-fScaledMinZ)) );
254 :
255 369 : return (bSameX && bSameY && bSameZ);
256 : }
257 :
258 492 : bool PlottingPositionHelper::isStrongLowerRequested( sal_Int32 nDimensionIndex ) const
259 : {
260 492 : if( m_aScales.empty() )
261 0 : return false;
262 492 : if( 0==nDimensionIndex )
263 492 : return m_bAllowShiftXAxisPos && m_aScales[nDimensionIndex].ShiftedCategoryPosition;
264 0 : else if( 2==nDimensionIndex )
265 0 : return m_bAllowShiftZAxisPos && m_aScales[nDimensionIndex].ShiftedCategoryPosition;
266 0 : return false;
267 : }
268 :
269 0 : bool PlottingPositionHelper::isLogicVisible(
270 : double fX, double fY, double fZ ) const
271 : {
272 0 : return fX >= m_aScales[0].Minimum && ( isStrongLowerRequested(0) ? fX < m_aScales[0].Maximum : fX <= m_aScales[0].Maximum )
273 0 : && fY >= m_aScales[1].Minimum && fY <= m_aScales[1].Maximum
274 0 : && fZ >= m_aScales[2].Minimum && ( isStrongLowerRequested(2) ? fZ < m_aScales[2].Maximum : fZ <= m_aScales[2].Maximum );
275 : }
276 :
277 4920 : void PlottingPositionHelper::doLogicScaling( double* pX, double* pY, double* pZ, bool bClip ) const
278 : {
279 4920 : if(bClip)
280 0 : this->clipLogicValues( pX,pY,pZ );
281 :
282 4920 : if(pX)
283 : {
284 3444 : if( m_aScales[0].Scaling.is())
285 0 : *pX = m_aScales[0].Scaling->doScaling(*pX);
286 3444 : if( m_bAllowShiftXAxisPos && m_aScales[0].ShiftedCategoryPosition )
287 1230 : (*pX) += m_fScaledCategoryWidth/2.0;
288 : }
289 4920 : if(pY && m_aScales[1].Scaling.is())
290 4428 : *pY = m_aScales[1].Scaling->doScaling(*pY);
291 4920 : if(pZ)
292 : {
293 2952 : if( m_aScales[2].Scaling.is())
294 0 : *pZ = m_aScales[2].Scaling->doScaling(*pZ);
295 2952 : if( m_bAllowShiftZAxisPos && m_aScales[2].ShiftedCategoryPosition)
296 0 : (*pZ) += 0.5;
297 : }
298 4920 : }
299 :
300 10168 : void PlottingPositionHelper::doUnshiftedLogicScaling( double* pX, double* pY, double* pZ, bool bClip ) const
301 : {
302 10168 : if(bClip)
303 0 : this->clipLogicValues( pX,pY,pZ );
304 :
305 10168 : if(pX && m_aScales[0].Scaling.is())
306 0 : *pX = m_aScales[0].Scaling->doScaling(*pX);
307 10168 : if(pY && m_aScales[1].Scaling.is())
308 10168 : *pY = m_aScales[1].Scaling->doScaling(*pY);
309 10168 : if(pZ && m_aScales[2].Scaling.is())
310 0 : *pZ = m_aScales[2].Scaling->doScaling(*pZ);
311 10168 : }
312 :
313 0 : void PlottingPositionHelper::doLogicScaling( ::com::sun::star::drawing::Position3D& rPos, bool bClip ) const
314 : {
315 0 : doLogicScaling( &rPos.PositionX, &rPos.PositionY, &rPos.PositionZ, bClip );
316 0 : }
317 :
318 0 : void PlottingPositionHelper::clipLogicValues( double* pX, double* pY, double* pZ ) const
319 : {
320 0 : if(pX)
321 : {
322 0 : if( *pX < m_aScales[0].Minimum )
323 0 : *pX = m_aScales[0].Minimum;
324 0 : else if( *pX > m_aScales[0].Maximum )
325 0 : *pX = m_aScales[0].Maximum;
326 : }
327 0 : if(pY)
328 : {
329 0 : if( *pY < m_aScales[1].Minimum )
330 0 : *pY = m_aScales[1].Minimum;
331 0 : else if( *pY > m_aScales[1].Maximum )
332 0 : *pY = m_aScales[1].Maximum;
333 : }
334 0 : if(pZ)
335 : {
336 0 : if( *pZ < m_aScales[2].Minimum )
337 0 : *pZ = m_aScales[2].Minimum;
338 0 : else if( *pZ > m_aScales[2].Maximum )
339 0 : *pZ = m_aScales[2].Maximum;
340 : }
341 0 : }
342 :
343 492 : inline bool PlottingPositionHelper::clipYRange( double& rMin, double& rMax ) const
344 : {
345 : //returns true if something remains
346 492 : if( rMin > rMax )
347 : {
348 0 : double fHelp = rMin;
349 0 : rMin = rMax;
350 0 : rMax = fHelp;
351 : }
352 492 : if( rMin > getLogicMaxY() )
353 0 : return false;
354 492 : if( rMax < getLogicMinY() )
355 0 : return false;
356 492 : if( rMin < getLogicMinY() )
357 0 : rMin = getLogicMinY();
358 492 : if( rMax > getLogicMaxY() )
359 0 : rMax = getLogicMaxY();
360 492 : return true;
361 : }
362 :
363 7954 : inline double PlottingPositionHelper::getLogicMinX() const
364 : {
365 7954 : return m_aScales[0].Minimum;
366 : }
367 8323 : inline double PlottingPositionHelper::getLogicMinY() const
368 : {
369 8323 : return m_aScales[1].Minimum;
370 : }
371 6560 : inline double PlottingPositionHelper::getLogicMinZ() const
372 : {
373 6560 : return m_aScales[2].Minimum;
374 : }
375 :
376 8979 : inline double PlottingPositionHelper::getLogicMaxX() const
377 : {
378 8979 : return m_aScales[0].Maximum;
379 : }
380 8856 : inline double PlottingPositionHelper::getLogicMaxY() const
381 : {
382 8856 : return m_aScales[1].Maximum;
383 : }
384 6560 : inline double PlottingPositionHelper::getLogicMaxZ() const
385 : {
386 6560 : return m_aScales[2].Maximum;
387 : }
388 1107 : inline bool PlottingPositionHelper::isMathematicalOrientationX() const
389 : {
390 1107 : return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[0].Orientation;
391 : }
392 1107 : inline bool PlottingPositionHelper::isMathematicalOrientationY() const
393 : {
394 1107 : return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[1].Orientation;
395 : }
396 1107 : inline bool PlottingPositionHelper::isMathematicalOrientationZ() const
397 : {
398 1107 : return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[2].Orientation;
399 : }
400 2173 : inline bool PlottingPositionHelper::isSwapXAndY() const
401 : {
402 2173 : return m_bSwapXAndY;
403 : }
404 123 : inline bool PlottingPositionHelper::maySkipPointsInRegressionCalculation() const
405 : {
406 123 : return m_bMaySkipPointsInRegressionCalculation;
407 : }
408 :
409 : //.............................................................................
410 : } //namespace chart
411 : //.............................................................................
412 : #endif
413 :
414 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|