tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / chart2 / source / view / inc / PlottingPositionHelper.hxx
blobba2b6104bdc5b682b41d630a06368b8efb2f85fd
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 #pragma once
21 #include <sal/config.h>
23 #include <memory>
25 #include <chartview/ExplicitScaleValues.hxx>
27 #include <basegfx/range/b2drectangle.hxx>
28 #include <tools/long.hxx>
29 #include <com/sun/star/drawing/Direction3D.hpp>
30 #include <com/sun/star/drawing/Position3D.hpp>
31 #include <basegfx/matrix/b3dhommatrix.hxx>
32 #include <com/sun/star/awt/Point.hpp>
33 #include <com/sun/star/uno/Sequence.hxx>
34 #include <rtl/ref.hxx>
35 #include <svx/unoshape.hxx>
37 namespace com::sun::star::drawing { class XShapes; }
38 namespace com::sun::star::drawing { struct HomogenMatrix; }
39 namespace com::sun::star::drawing { struct PolyPolygonShape3D; }
41 namespace chart
44 class ShapeFactory;
46 /** allows the transformation of numeric values from one
47 coordinate-system into another. Values may be transformed using
48 any mapping.
49 This is a non-UNO variant of the css::chart2::XTransformation interface,
50 but using more efficient calling and returning types.
52 class XTransformation2
54 public:
55 virtual ~XTransformation2();
56 /** transforms the given input data tuple, given in the source
57 coordinate system, according to the internal transformation
58 rules, into a tuple of transformed coordinates in the
59 destination coordinate system.
61 <p>Note that both coordinate systems may have different
62 dimensions, e.g., if a transformation does simply a projection
63 into a lower-dimensional space.</p>
65 @param aValues a source tuple of data that is to be
66 transformed. The length of this sequence must be
67 equivalent to the dimension of the source coordinate
68 system.
70 @return the transformed data tuple. The length of this
71 sequence is equal to the dimension of the output
72 coordinate system.
74 @throws ::com::sun::star::lang::IllegalArgumentException
75 if the dimension of the input vector is not equal to the
76 dimension given in getSourceDimension().
78 virtual css::drawing::Position3D transform(
79 const css::drawing::Position3D& rSourceValues ) const = 0;
80 virtual css::drawing::Position3D transform(
81 const css::uno::Sequence< double >& rSourceValues ) const = 0;
85 class PlottingPositionHelper
87 public:
88 PlottingPositionHelper();
89 PlottingPositionHelper( const PlottingPositionHelper& rSource );
90 virtual ~PlottingPositionHelper();
92 virtual std::unique_ptr<PlottingPositionHelper> clone() const;
93 std::unique_ptr<PlottingPositionHelper> createSecondaryPosHelper( const ExplicitScaleData& rSecondaryScale );
95 virtual void setTransformationSceneToScreen( const css::drawing::HomogenMatrix& rMatrix);
97 virtual void setScales( std::vector< ExplicitScaleData >&& rScales, bool bSwapXAndYAxis );
98 const std::vector< ExplicitScaleData >& getScales() const { return m_aScales;}
100 //better performance for big data
101 inline void setCoordinateSystemResolution( const css::uno::Sequence< sal_Int32 >& rCoordinateSystemResolution );
102 inline bool isSameForGivenResolution( double fX, double fY, double fZ
103 , double fX2, double fY2, double fZ2 );
105 inline bool isStrongLowerRequested( sal_Int32 nDimensionIndex ) const;
106 inline bool isLogicVisible( double fX, double fY, double fZ ) const;
107 inline void doLogicScaling( double* pX, double* pY, double* pZ ) const;
108 inline void doUnshiftedLogicScaling( double* pX, double* pY, double* pZ ) const;
109 inline void clipLogicValues( double* pX, double* pY, double* pZ ) const;
110 void clipScaledLogicValues( double* pX, double* pY, double* pZ ) const;
111 inline bool clipYRange( double& rMin, double& rMax ) const;
113 inline void doLogicScaling( css::drawing::Position3D& rPos ) const;
115 virtual ::chart::XTransformation2*
116 getTransformationScaledLogicToScene() const;
118 virtual css::drawing::Position3D
119 transformLogicToScene( double fX, double fY, double fZ, bool bClip ) const;
121 virtual css::drawing::Position3D
122 transformScaledLogicToScene( double fX, double fY, double fZ, bool bClip ) const;
124 void transformScaledLogicToScene( css::drawing::PolyPolygonShape3D& rPoly ) const;
125 void transformScaledLogicToScene( std::vector<std::vector<css::drawing::Position3D>>& rPoly ) const;
127 static css::awt::Point transformSceneToScreenPosition(
128 const css::drawing::Position3D& rScenePosition3D
129 , const rtl::Reference<SvxShapeGroupAnyD>& xSceneTarget
130 , sal_Int32 nDimensionCount );
132 inline double getLogicMinX() const;
133 inline double getLogicMinY() const;
134 inline double getLogicMinZ() const;
135 inline double getLogicMaxX() const;
136 inline double getLogicMaxY() const;
137 inline double getLogicMaxZ() const;
139 inline bool isMathematicalOrientationX() const;
140 inline bool isMathematicalOrientationY() const;
141 inline bool isMathematicalOrientationZ() const;
143 ::basegfx::B2DRectangle getScaledLogicClipDoubleRect() const;
144 css::drawing::Direction3D getScaledLogicWidth() const;
146 inline bool isSwapXAndY() const;
148 bool isPercentY() const;
150 double getBaseValueY() const;
152 inline bool maySkipPointsInRegressionCalculation() const;
154 void setTimeResolution( tools::Long nTimeResolution, const Date& rNullDate );
155 virtual void setScaledCategoryWidth( double fScaledCategoryWidth );
156 void AllowShiftXAxisPos( bool bAllowShift );
157 void AllowShiftZAxisPos( bool bAllowShift );
159 protected: //member
160 std::vector< ExplicitScaleData > m_aScales;
161 ::basegfx::B3DHomMatrix m_aMatrixScreenToScene;
163 //this is calculated based on m_aScales and m_aMatrixScreenToScene
164 mutable std::unique_ptr< ::chart::XTransformation2 > m_xTransformationLogicToScene;
166 bool m_bSwapXAndY;//e.g. true for bar chart and false for column chart
168 sal_Int32 m_nXResolution;
169 sal_Int32 m_nYResolution;
170 sal_Int32 m_nZResolution;
172 bool m_bMaySkipPointsInRegressionCalculation;
174 bool m_bDateAxis;
175 tools::Long m_nTimeResolution;
176 Date m_aNullDate;
178 double m_fScaledCategoryWidth;
179 bool m_bAllowShiftXAxisPos;
180 bool m_bAllowShiftZAxisPos;
183 class PolarPlottingPositionHelper : public PlottingPositionHelper
185 public:
186 PolarPlottingPositionHelper();
187 PolarPlottingPositionHelper( const PolarPlottingPositionHelper& rSource );
188 virtual ~PolarPlottingPositionHelper() override;
190 virtual std::unique_ptr<PlottingPositionHelper> clone() const override;
192 virtual void setTransformationSceneToScreen( const css::drawing::HomogenMatrix& rMatrix) override;
193 virtual void setScales( std::vector< ExplicitScaleData >&& rScales, bool bSwapXAndYAxis ) override;
195 const ::basegfx::B3DHomMatrix& getUnitCartesianToScene() const { return m_aUnitCartesianToScene;}
197 virtual ::chart::XTransformation2*
198 getTransformationScaledLogicToScene() const override;
200 //the resulting values provided by the following 3 methods should be used
201 //for input to the transformation received with
202 //'getTransformationScaledLogicToScene'
204 /** Given a value in the radius axis scale range, it returns the normalized
205 * value.
207 double transformToRadius( double fLogicValueOnRadiusAxis, bool bDoScaling=true ) const;
209 /** Given a value in the angle axis scale range (e.g. [0,1] for pie charts)
210 * this method returns the related angle in degree.
212 double transformToAngleDegree( double fLogicValueOnAngleAxis, bool bDoScaling=true ) const;
214 /** Given 2 values in the angle axis scale range (e.g. [0,1] for pie charts)
215 * this method returns the angle between the 2 values keeping into account
216 * the correct axis orientation; (for instance, this method is used for
217 * computing the angle width of a pie slice).
219 double getWidthAngleDegree( double& fStartLogicValueOnAngleAxis, double& fEndLogicValueOnAngleAxis ) const;
221 virtual css::drawing::Position3D
222 transformLogicToScene( double fX, double fY, double fZ, bool bClip ) const override;
223 virtual css::drawing::Position3D
224 transformScaledLogicToScene( double fX, double fY, double fZ, bool bClip ) const override;
225 css::drawing::Position3D
226 transformAngleRadiusToScene( double fLogicValueOnAngleAxis, double fLogicValueOnRadiusAxis, double fLogicZ, bool bDoScaling=true ) const;
228 /** Return the scene coordinates of the passed point: this point is
229 * described through a normalized cylindrical coordinate system, with an
230 * optional offset.
231 * (For a standard pie chart the origin of the coordinate system is the
232 * pie center; for an of-pie chart the components of the aOffset
233 * parameter are not all zero).
235 css::drawing::Position3D
236 transformUnitCircleToScene( double fUnitAngleDegree
237 , double fUnitRadius, double fLogicZ
238 , const ::basegfx::B3DVector& aOffset = ::basegfx::B3DVector()) const;
240 using PlottingPositionHelper::transformScaledLogicToScene;
242 double getOuterLogicRadius() const;
244 inline bool isMathematicalOrientationAngle() const;
245 inline bool isMathematicalOrientationRadius() const;
246 public:
247 ///m_bSwapXAndY (inherited): by default the X axis (scale[0]) represents
248 ///the angle axis and the Y axis (scale[1]) represents the radius axis;
249 ///when this parameter is true, the opposite happens (this is the case for
250 ///pie charts).
252 ///Offset for radius axis in absolute logic scaled values (1.0 == 1 category)
253 ///For a donut, it represents the non-normalized inner radius (see notes for
254 ///transformToRadius)
255 double m_fRadiusOffset;
256 ///Offset for angle axis in real degree.
257 ///For a pie it represents the angle offset at which the first slice have to
258 ///start;
259 double m_fAngleDegreeOffset;
261 private:
262 ::basegfx::B3DHomMatrix m_aUnitCartesianToScene;
264 ::basegfx::B3DHomMatrix impl_calculateMatrixUnitCartesianToScene( const ::basegfx::B3DHomMatrix& rMatrixScreenToScene ) const;
267 bool PolarPlottingPositionHelper::isMathematicalOrientationAngle() const
269 const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[1] : m_aScales[2];
270 if( css::chart2::AxisOrientation_MATHEMATICAL==rScale.Orientation )
271 return true;
272 return false;
274 bool PolarPlottingPositionHelper::isMathematicalOrientationRadius() const
276 const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[0] : m_aScales[1];
277 if( css::chart2::AxisOrientation_MATHEMATICAL==rScale.Orientation )
278 return true;
279 return false;
282 //better performance for big data
283 void PlottingPositionHelper::setCoordinateSystemResolution( const css::uno::Sequence< sal_Int32 >& rCoordinateSystemResolution )
285 m_nXResolution = 1000;
286 m_nYResolution = 1000;
287 m_nZResolution = 1000;
288 if( rCoordinateSystemResolution.getLength() > 0 )
289 m_nXResolution = rCoordinateSystemResolution[0];
290 if( rCoordinateSystemResolution.getLength() > 1 )
291 m_nYResolution = rCoordinateSystemResolution[1];
292 if( rCoordinateSystemResolution.getLength() > 2 )
293 m_nZResolution = rCoordinateSystemResolution[2];
296 bool PlottingPositionHelper::isSameForGivenResolution( double fX, double fY, double fZ
297 , double fX2, double fY2, double fZ2 /*these values are all expected tp be scaled already*/ )
299 if( !std::isfinite(fX) || !std::isfinite(fY) || !std::isfinite(fZ)
300 || !std::isfinite(fX2) || !std::isfinite(fY2) || !std::isfinite(fZ2) )
301 return false;
303 double fScaledMinX = getLogicMinX();
304 double fScaledMinY = getLogicMinY();
305 double fScaledMinZ = getLogicMinZ();
306 double fScaledMaxX = getLogicMaxX();
307 double fScaledMaxY = getLogicMaxY();
308 double fScaledMaxZ = getLogicMaxZ();
310 doLogicScaling( &fScaledMinX, &fScaledMinY, &fScaledMinZ );
311 doLogicScaling( &fScaledMaxX, &fScaledMaxY, &fScaledMaxZ);
313 bool bSameX = ( static_cast<sal_Int32>(m_nXResolution*(fX - fScaledMinX)/(fScaledMaxX-fScaledMinX))
314 == static_cast<sal_Int32>(m_nXResolution*(fX2 - fScaledMinX)/(fScaledMaxX-fScaledMinX)) );
316 bool bSameY = ( static_cast<sal_Int32>(m_nYResolution*(fY - fScaledMinY)/(fScaledMaxY-fScaledMinY))
317 == static_cast<sal_Int32>(m_nYResolution*(fY2 - fScaledMinY)/(fScaledMaxY-fScaledMinY)) );
319 bool bSameZ = ( static_cast<sal_Int32>(m_nZResolution*(fZ - fScaledMinZ)/(fScaledMaxZ-fScaledMinZ))
320 == static_cast<sal_Int32>(m_nZResolution*(fZ2 - fScaledMinZ)/(fScaledMaxZ-fScaledMinZ)) );
322 return (bSameX && bSameY && bSameZ);
325 bool PlottingPositionHelper::isStrongLowerRequested( sal_Int32 nDimensionIndex ) const
327 if( m_aScales.empty() )
328 return false;
329 if( 0==nDimensionIndex )
330 return m_bAllowShiftXAxisPos && m_aScales[nDimensionIndex].m_bShiftedCategoryPosition;
331 else if( 2==nDimensionIndex )
332 return m_bAllowShiftZAxisPos && m_aScales[nDimensionIndex].m_bShiftedCategoryPosition;
333 return false;
336 bool PlottingPositionHelper::isLogicVisible(
337 double fX, double fY, double fZ ) const
339 return fX >= m_aScales[0].Minimum && ( isStrongLowerRequested(0) ? fX < m_aScales[0].Maximum : fX <= m_aScales[0].Maximum )
340 && fY >= m_aScales[1].Minimum && fY <= m_aScales[1].Maximum
341 && fZ >= m_aScales[2].Minimum && ( isStrongLowerRequested(2) ? fZ < m_aScales[2].Maximum : fZ <= m_aScales[2].Maximum );
344 void PlottingPositionHelper::doLogicScaling( double* pX, double* pY, double* pZ ) const
346 if(pX)
348 if( m_aScales[0].Scaling.is())
349 *pX = m_aScales[0].Scaling->doScaling(*pX);
350 if( m_bAllowShiftXAxisPos && m_aScales[0].m_bShiftedCategoryPosition )
351 (*pX) += m_fScaledCategoryWidth/2.0;
353 if(pY && m_aScales[1].Scaling.is())
354 *pY = m_aScales[1].Scaling->doScaling(*pY);
355 if(pZ)
357 if( m_aScales[2].Scaling.is())
358 *pZ = m_aScales[2].Scaling->doScaling(*pZ);
359 if( m_bAllowShiftZAxisPos && m_aScales[2].m_bShiftedCategoryPosition)
360 (*pZ) += 0.5;
364 void PlottingPositionHelper::doUnshiftedLogicScaling( double* pX, double* pY, double* pZ ) const
366 if(pX && m_aScales[0].Scaling.is())
367 *pX = m_aScales[0].Scaling->doScaling(*pX);
368 if(pY && m_aScales[1].Scaling.is())
369 *pY = m_aScales[1].Scaling->doScaling(*pY);
370 if(pZ && m_aScales[2].Scaling.is())
371 *pZ = m_aScales[2].Scaling->doScaling(*pZ);
374 void PlottingPositionHelper::doLogicScaling( css::drawing::Position3D& rPos ) const
376 doLogicScaling( &rPos.PositionX, &rPos.PositionY, &rPos.PositionZ );
379 void PlottingPositionHelper::clipLogicValues( double* pX, double* pY, double* pZ ) const
381 if(pX)
383 if( *pX < m_aScales[0].Minimum )
384 *pX = m_aScales[0].Minimum;
385 else if( *pX > m_aScales[0].Maximum )
386 *pX = m_aScales[0].Maximum;
388 if(pY)
390 if( *pY < m_aScales[1].Minimum )
391 *pY = m_aScales[1].Minimum;
392 else if( *pY > m_aScales[1].Maximum )
393 *pY = m_aScales[1].Maximum;
395 if(pZ)
397 if( *pZ < m_aScales[2].Minimum )
398 *pZ = m_aScales[2].Minimum;
399 else if( *pZ > m_aScales[2].Maximum )
400 *pZ = m_aScales[2].Maximum;
404 inline bool PlottingPositionHelper::clipYRange( double& rMin, double& rMax ) const
406 //returns true if something remains
407 if( rMin > rMax )
408 std::swap( rMin, rMax );
409 if( rMin > getLogicMaxY() )
410 return false;
411 if( rMax < getLogicMinY() )
412 return false;
413 if( rMin < getLogicMinY() )
414 rMin = getLogicMinY();
415 if( rMax > getLogicMaxY() )
416 rMax = getLogicMaxY();
417 return true;
420 inline double PlottingPositionHelper::getLogicMinX() const
422 return m_aScales[0].Minimum;
424 inline double PlottingPositionHelper::getLogicMinY() const
426 return m_aScales[1].Minimum;
428 inline double PlottingPositionHelper::getLogicMinZ() const
430 return m_aScales[2].Minimum;
433 inline double PlottingPositionHelper::getLogicMaxX() const
435 return m_aScales[0].Maximum;
437 inline double PlottingPositionHelper::getLogicMaxY() const
439 return m_aScales[1].Maximum;
441 inline double PlottingPositionHelper::getLogicMaxZ() const
443 return m_aScales[2].Maximum;
445 inline bool PlottingPositionHelper::isMathematicalOrientationX() const
447 return css::chart2::AxisOrientation_MATHEMATICAL == m_aScales[0].Orientation;
449 inline bool PlottingPositionHelper::isMathematicalOrientationY() const
451 return css::chart2::AxisOrientation_MATHEMATICAL == m_aScales[1].Orientation;
453 inline bool PlottingPositionHelper::isMathematicalOrientationZ() const
455 return css::chart2::AxisOrientation_MATHEMATICAL == m_aScales[2].Orientation;
457 inline bool PlottingPositionHelper::isSwapXAndY() const
459 return m_bSwapXAndY;
461 inline bool PlottingPositionHelper::maySkipPointsInRegressionCalculation() const
463 return m_bMaySkipPointsInRegressionCalculation;
466 } //namespace chart
468 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */