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