Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / chart2 / source / view / inc / PlottingPositionHelper.hxx
blob74fc37cdea80919631fc236cf0c3bfc5ea41f8ac
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
19 #ifndef INCLUDED_CHART2_SOURCE_VIEW_INC_PLOTTINGPOSITIONHELPER_HXX
20 #define INCLUDED_CHART2_SOURCE_VIEW_INC_PLOTTINGPOSITIONHELPER_HXX
22 #include <chartview/ExplicitScaleValues.hxx>
24 #include <basegfx/range/b2drectangle.hxx>
25 #include <rtl/math.hxx>
26 #include <com/sun/star/drawing/Direction3D.hpp>
27 #include <com/sun/star/drawing/Position3D.hpp>
28 #include <basegfx/matrix/b3dhommatrix.hxx>
29 #include <com/sun/star/awt/Point.hpp>
30 #include <com/sun/star/uno/Sequence.hxx>
32 namespace com { namespace sun { namespace star { namespace chart2 { class XTransformation; } } } }
33 namespace com { namespace sun { namespace star { namespace drawing { class XShapes; } } } }
34 namespace com { namespace sun { namespace star { namespace drawing { struct HomogenMatrix; } } } }
35 namespace com { namespace sun { namespace star { namespace drawing { struct PolyPolygonShape3D; } } } }
37 namespace chart
40 class ShapeFactory;
42 class PlottingPositionHelper
44 public:
45 PlottingPositionHelper();
46 PlottingPositionHelper( const PlottingPositionHelper& rSource );
47 virtual ~PlottingPositionHelper();
49 virtual std::unique_ptr<PlottingPositionHelper> clone() const;
50 std::unique_ptr<PlottingPositionHelper> createSecondaryPosHelper( const ExplicitScaleData& rSecondaryScale );
52 virtual void setTransformationSceneToScreen( const css::drawing::HomogenMatrix& rMatrix);
54 virtual void setScales( const std::vector< ExplicitScaleData >& rScales, bool bSwapXAndYAxis );
55 const std::vector< ExplicitScaleData >& getScales() const { return m_aScales;}
57 //better performance for big data
58 inline void setCoordinateSystemResolution( const css::uno::Sequence< sal_Int32 >& rCoordinateSystemResolution );
59 inline bool isSameForGivenResolution( double fX, double fY, double fZ
60 , double fX2, double fY2, double fZ2 );
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 ) const;
65 inline void doUnshiftedLogicScaling( double* pX, double* pY, double* pZ ) 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;
70 inline void doLogicScaling( css::drawing::Position3D& rPos ) const;
72 virtual css::uno::Reference< css::chart2::XTransformation >
73 getTransformationScaledLogicToScene() const;
75 virtual css::drawing::Position3D
76 transformLogicToScene( double fX, double fY, double fZ, bool bClip ) const;
78 virtual css::drawing::Position3D
79 transformScaledLogicToScene( double fX, double fY, double fZ, bool bClip ) const;
81 void transformScaledLogicToScene( css::drawing::PolyPolygonShape3D& rPoly ) const;
83 static css::awt::Point transformSceneToScreenPosition(
84 const css::drawing::Position3D& rScenePosition3D
85 , const css::uno::Reference< css::drawing::XShapes >& xSceneTarget
86 , ShapeFactory* pShapeFactory, sal_Int32 nDimensionCount );
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;
95 inline bool isMathematicalOrientationX() const;
96 inline bool isMathematicalOrientationY() const;
97 inline bool isMathematicalOrientationZ() const;
99 ::basegfx::B2DRectangle getScaledLogicClipDoubleRect() const;
100 css::drawing::Direction3D getScaledLogicWidth() const;
102 inline bool isSwapXAndY() const;
104 bool isPercentY() const;
106 double getBaseValueY() const;
108 inline bool maySkipPointsInRegressionCalculation() const;
110 void setTimeResolution( long nTimeResolution, const Date& rNullDate );
111 virtual void setScaledCategoryWidth( double fScaledCategoryWidth );
112 void AllowShiftXAxisPos( bool bAllowShift );
113 void AllowShiftZAxisPos( bool bAllowShift );
115 protected: //member
116 std::vector< ExplicitScaleData > m_aScales;
117 ::basegfx::B3DHomMatrix m_aMatrixScreenToScene;
119 //this is calculated based on m_aScales and m_aMatrixScreenToScene
120 mutable css::uno::Reference< css::chart2::XTransformation > m_xTransformationLogicToScene;
122 bool m_bSwapXAndY;//e.g. true for bar chart and false for column chart
124 sal_Int32 m_nXResolution;
125 sal_Int32 m_nYResolution;
126 sal_Int32 m_nZResolution;
128 bool m_bMaySkipPointsInRegressionCalculation;
130 bool m_bDateAxis;
131 long m_nTimeResolution;
132 Date m_aNullDate;
134 double m_fScaledCategoryWidth;
135 bool m_bAllowShiftXAxisPos;
136 bool m_bAllowShiftZAxisPos;
139 class PolarPlottingPositionHelper : public PlottingPositionHelper
141 public:
142 PolarPlottingPositionHelper();
143 PolarPlottingPositionHelper( const PolarPlottingPositionHelper& rSource );
144 virtual ~PolarPlottingPositionHelper() override;
146 virtual std::unique_ptr<PlottingPositionHelper> clone() const override;
148 virtual void setTransformationSceneToScreen( const css::drawing::HomogenMatrix& rMatrix) override;
149 virtual void setScales( const std::vector< ExplicitScaleData >& rScales, bool bSwapXAndYAxis ) override;
151 const ::basegfx::B3DHomMatrix& getUnitCartesianToScene() const { return m_aUnitCartesianToScene;}
153 virtual css::uno::Reference< css::chart2::XTransformation >
154 getTransformationScaledLogicToScene() const override;
156 //the resulting values provided by the following 3 methods should be used
157 //for input to the transformation received with
158 //'getTransformationScaledLogicToScene'
160 /** Given a value in the radius axis scale range, it returns the normalized
161 * value.
163 double transformToRadius( double fLogicValueOnRadiusAxis, bool bDoScaling=true ) const;
165 /** Given a value in the angle axis scale range (e.g. [0,1] for pie charts)
166 * this method returns the related angle in degree.
168 double transformToAngleDegree( double fLogicValueOnAngleAxis, bool bDoScaling=true ) const;
170 /** Given 2 values in the angle axis scale range (e.g. [0,1] for pie charts)
171 * this method returns the angle between the 2 values keeping into account
172 * the correct axis orientation; (for instance, this method is used for
173 * computing the angle width of a pie slice).
175 double getWidthAngleDegree( double& fStartLogicValueOnAngleAxis, double& fEndLogicValueOnAngleAxis ) const;
177 virtual css::drawing::Position3D
178 transformLogicToScene( double fX, double fY, double fZ, bool bClip ) const override;
179 virtual css::drawing::Position3D
180 transformScaledLogicToScene( double fX, double fY, double fZ, bool bClip ) const override;
181 css::drawing::Position3D
182 transformAngleRadiusToScene( double fLogicValueOnAngleAxis, double fLogicValueOnRadiusAxis, double fLogicZ, bool bDoScaling=true ) const;
184 /** It returns the scene coordinates of the passed point: this point is
185 * described through a normalized cylindrical coordinate system.
186 * (For a pie chart the origin of the coordinate system is the pie center).
188 css::drawing::Position3D
189 transformUnitCircleToScene( double fUnitAngleDegree, double fUnitRadius, double fLogicZ ) const;
191 using PlottingPositionHelper::transformScaledLogicToScene;
193 double getOuterLogicRadius() const;
195 inline bool isMathematicalOrientationAngle() const;
196 inline bool isMathematicalOrientationRadius() const;
197 public:
198 ///m_bSwapXAndY (inherited): by default the X axis (scale[0]) represents
199 ///the angle axis and the Y axis (scale[1]) represents the radius axis;
200 ///when this parameter is true, the opposite happens (this is the case for
201 ///pie charts).
203 ///Offset for radius axis in absolute logic scaled values (1.0 == 1 category)
204 ///For a donut, it represents the non-normalized inner radius (see notes for
205 ///transformToRadius)
206 double m_fRadiusOffset;
207 ///Offset for angle axis in real degree.
208 ///For a pie it represents the angle offset at which the first slice have to
209 ///start;
210 double m_fAngleDegreeOffset;
212 private:
213 ::basegfx::B3DHomMatrix m_aUnitCartesianToScene;
215 ::basegfx::B3DHomMatrix impl_calculateMatrixUnitCartesianToScene( const ::basegfx::B3DHomMatrix& rMatrixScreenToScene ) const;
218 bool PolarPlottingPositionHelper::isMathematicalOrientationAngle() const
220 const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[1] : m_aScales[2];
221 if( css::chart2::AxisOrientation_MATHEMATICAL==rScale.Orientation )
222 return true;
223 return false;
225 bool PolarPlottingPositionHelper::isMathematicalOrientationRadius() const
227 const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[0] : m_aScales[1];
228 if( css::chart2::AxisOrientation_MATHEMATICAL==rScale.Orientation )
229 return true;
230 return false;
233 //better performance for big data
234 void PlottingPositionHelper::setCoordinateSystemResolution( const css::uno::Sequence< sal_Int32 >& rCoordinateSystemResolution )
236 m_nXResolution = 1000;
237 m_nYResolution = 1000;
238 m_nZResolution = 1000;
239 if( rCoordinateSystemResolution.getLength() > 0 )
240 m_nXResolution = rCoordinateSystemResolution[0];
241 if( rCoordinateSystemResolution.getLength() > 1 )
242 m_nYResolution = rCoordinateSystemResolution[1];
243 if( rCoordinateSystemResolution.getLength() > 2 )
244 m_nZResolution = rCoordinateSystemResolution[2];
247 bool PlottingPositionHelper::isSameForGivenResolution( double fX, double fY, double fZ
248 , double fX2, double fY2, double fZ2 /*these values are all expected tp be scaled already*/ )
250 if( !::rtl::math::isFinite(fX) || !::rtl::math::isFinite(fY) || !::rtl::math::isFinite(fZ)
251 || !::rtl::math::isFinite(fX2) || !::rtl::math::isFinite(fY2) || !::rtl::math::isFinite(fZ2) )
252 return false;
254 double fScaledMinX = getLogicMinX();
255 double fScaledMinY = getLogicMinY();
256 double fScaledMinZ = getLogicMinZ();
257 double fScaledMaxX = getLogicMaxX();
258 double fScaledMaxY = getLogicMaxY();
259 double fScaledMaxZ = getLogicMaxZ();
261 doLogicScaling( &fScaledMinX, &fScaledMinY, &fScaledMinZ );
262 doLogicScaling( &fScaledMaxX, &fScaledMaxY, &fScaledMaxZ);
264 bool bSameX = ( static_cast<sal_Int32>(m_nXResolution*(fX - fScaledMinX)/(fScaledMaxX-fScaledMinX))
265 == static_cast<sal_Int32>(m_nXResolution*(fX2 - fScaledMinX)/(fScaledMaxX-fScaledMinX)) );
267 bool bSameY = ( static_cast<sal_Int32>(m_nYResolution*(fY - fScaledMinY)/(fScaledMaxY-fScaledMinY))
268 == static_cast<sal_Int32>(m_nYResolution*(fY2 - fScaledMinY)/(fScaledMaxY-fScaledMinY)) );
270 bool bSameZ = ( static_cast<sal_Int32>(m_nZResolution*(fZ - fScaledMinZ)/(fScaledMaxZ-fScaledMinZ))
271 == static_cast<sal_Int32>(m_nZResolution*(fZ2 - fScaledMinZ)/(fScaledMaxZ-fScaledMinZ)) );
273 return (bSameX && bSameY && bSameZ);
276 bool PlottingPositionHelper::isStrongLowerRequested( sal_Int32 nDimensionIndex ) const
278 if( m_aScales.empty() )
279 return false;
280 if( 0==nDimensionIndex )
281 return m_bAllowShiftXAxisPos && m_aScales[nDimensionIndex].ShiftedCategoryPosition;
282 else if( 2==nDimensionIndex )
283 return m_bAllowShiftZAxisPos && m_aScales[nDimensionIndex].ShiftedCategoryPosition;
284 return false;
287 bool PlottingPositionHelper::isLogicVisible(
288 double fX, double fY, double fZ ) const
290 return fX >= m_aScales[0].Minimum && ( isStrongLowerRequested(0) ? fX < m_aScales[0].Maximum : fX <= m_aScales[0].Maximum )
291 && fY >= m_aScales[1].Minimum && fY <= m_aScales[1].Maximum
292 && fZ >= m_aScales[2].Minimum && ( isStrongLowerRequested(2) ? fZ < m_aScales[2].Maximum : fZ <= m_aScales[2].Maximum );
295 void PlottingPositionHelper::doLogicScaling( double* pX, double* pY, double* pZ ) const
297 if(pX)
299 if( m_aScales[0].Scaling.is())
300 *pX = m_aScales[0].Scaling->doScaling(*pX);
301 if( m_bAllowShiftXAxisPos && m_aScales[0].ShiftedCategoryPosition )
302 (*pX) += m_fScaledCategoryWidth/2.0;
304 if(pY && m_aScales[1].Scaling.is())
305 *pY = m_aScales[1].Scaling->doScaling(*pY);
306 if(pZ)
308 if( m_aScales[2].Scaling.is())
309 *pZ = m_aScales[2].Scaling->doScaling(*pZ);
310 if( m_bAllowShiftZAxisPos && m_aScales[2].ShiftedCategoryPosition)
311 (*pZ) += 0.5;
315 void PlottingPositionHelper::doUnshiftedLogicScaling( double* pX, double* pY, double* pZ ) const
317 if(pX && m_aScales[0].Scaling.is())
318 *pX = m_aScales[0].Scaling->doScaling(*pX);
319 if(pY && m_aScales[1].Scaling.is())
320 *pY = m_aScales[1].Scaling->doScaling(*pY);
321 if(pZ && m_aScales[2].Scaling.is())
322 *pZ = m_aScales[2].Scaling->doScaling(*pZ);
325 void PlottingPositionHelper::doLogicScaling( css::drawing::Position3D& rPos ) const
327 doLogicScaling( &rPos.PositionX, &rPos.PositionY, &rPos.PositionZ );
330 void PlottingPositionHelper::clipLogicValues( double* pX, double* pY, double* pZ ) const
332 if(pX)
334 if( *pX < m_aScales[0].Minimum )
335 *pX = m_aScales[0].Minimum;
336 else if( *pX > m_aScales[0].Maximum )
337 *pX = m_aScales[0].Maximum;
339 if(pY)
341 if( *pY < m_aScales[1].Minimum )
342 *pY = m_aScales[1].Minimum;
343 else if( *pY > m_aScales[1].Maximum )
344 *pY = m_aScales[1].Maximum;
346 if(pZ)
348 if( *pZ < m_aScales[2].Minimum )
349 *pZ = m_aScales[2].Minimum;
350 else if( *pZ > m_aScales[2].Maximum )
351 *pZ = m_aScales[2].Maximum;
355 inline bool PlottingPositionHelper::clipYRange( double& rMin, double& rMax ) const
357 //returns true if something remains
358 if( rMin > rMax )
360 double fHelp = rMin;
361 rMin = rMax;
362 rMax = fHelp;
364 if( rMin > getLogicMaxY() )
365 return false;
366 if( rMax < getLogicMinY() )
367 return false;
368 if( rMin < getLogicMinY() )
369 rMin = getLogicMinY();
370 if( rMax > getLogicMaxY() )
371 rMax = getLogicMaxY();
372 return true;
375 inline double PlottingPositionHelper::getLogicMinX() const
377 return m_aScales[0].Minimum;
379 inline double PlottingPositionHelper::getLogicMinY() const
381 return m_aScales[1].Minimum;
383 inline double PlottingPositionHelper::getLogicMinZ() const
385 return m_aScales[2].Minimum;
388 inline double PlottingPositionHelper::getLogicMaxX() const
390 return m_aScales[0].Maximum;
392 inline double PlottingPositionHelper::getLogicMaxY() const
394 return m_aScales[1].Maximum;
396 inline double PlottingPositionHelper::getLogicMaxZ() const
398 return m_aScales[2].Maximum;
400 inline bool PlottingPositionHelper::isMathematicalOrientationX() const
402 return css::chart2::AxisOrientation_MATHEMATICAL == m_aScales[0].Orientation;
404 inline bool PlottingPositionHelper::isMathematicalOrientationY() const
406 return css::chart2::AxisOrientation_MATHEMATICAL == m_aScales[1].Orientation;
408 inline bool PlottingPositionHelper::isMathematicalOrientationZ() const
410 return css::chart2::AxisOrientation_MATHEMATICAL == m_aScales[2].Orientation;
412 inline bool PlottingPositionHelper::isSwapXAndY() const
414 return m_bSwapXAndY;
416 inline bool PlottingPositionHelper::maySkipPointsInRegressionCalculation() const
418 return m_bMaySkipPointsInRegressionCalculation;
421 } //namespace chart
422 #endif
424 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */