LibreOffice Module chart2 (master) 1
PlottingPositionHelper.hxx
Go to the documentation of this file.
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#pragma once
20
21#include <sal/config.h>
22
23#include <memory>
24
26
28#include <tools/long.hxx>
29#include <com/sun/star/drawing/Direction3D.hpp>
30#include <com/sun/star/drawing/Position3D.hpp>
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>
36
37namespace com::sun::star::drawing { class XShapes; }
38namespace com::sun::star::drawing { struct HomogenMatrix; }
39namespace com::sun::star::drawing { struct PolyPolygonShape3D; }
40
41namespace chart
42{
43
44class ShapeFactory;
45
53{
54public:
55 virtual ~XTransformation2();
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;
82};
83
84
86{
87public:
91
92 virtual std::unique_ptr<PlottingPositionHelper> clone() const;
93 std::unique_ptr<PlottingPositionHelper> createSecondaryPosHelper( const ExplicitScaleData& rSecondaryScale );
94
95 virtual void setTransformationSceneToScreen( const css::drawing::HomogenMatrix& rMatrix);
96
97 virtual void setScales( std::vector< ExplicitScaleData >&& rScales, bool bSwapXAndYAxis );
98 const std::vector< ExplicitScaleData >& getScales() const { return m_aScales;}
99
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 );
104
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;
112
113 inline void doLogicScaling( css::drawing::Position3D& rPos ) const;
114
115 virtual ::chart::XTransformation2*
117
118 virtual css::drawing::Position3D
119 transformLogicToScene( double fX, double fY, double fZ, bool bClip ) const;
120
121 virtual css::drawing::Position3D
122 transformScaledLogicToScene( double fX, double fY, double fZ, bool bClip ) const;
123
124 void transformScaledLogicToScene( css::drawing::PolyPolygonShape3D& rPoly ) const;
125 void transformScaledLogicToScene( std::vector<std::vector<css::drawing::Position3D>>& rPoly ) const;
126
127 static css::awt::Point transformSceneToScreenPosition(
128 const css::drawing::Position3D& rScenePosition3D
129 , const rtl::Reference<SvxShapeGroupAnyD>& xSceneTarget
130 , sal_Int32 nDimensionCount );
131
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;
138
139 inline bool isMathematicalOrientationX() const;
140 inline bool isMathematicalOrientationY() const;
141 inline bool isMathematicalOrientationZ() const;
142
144 css::drawing::Direction3D getScaledLogicWidth() const;
145
146 inline bool isSwapXAndY() const;
147
148 bool isPercentY() const;
149
150 double getBaseValueY() const;
151
152 inline bool maySkipPointsInRegressionCalculation() const;
153
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 );
158
159protected: //member
160 std::vector< ExplicitScaleData > m_aScales;
162
163 //this is calculated based on m_aScales and m_aMatrixScreenToScene
164 mutable std::unique_ptr< ::chart::XTransformation2 > m_xTransformationLogicToScene;
165
166 bool m_bSwapXAndY;//e.g. true for bar chart and false for column chart
167
168 sal_Int32 m_nXResolution;
169 sal_Int32 m_nYResolution;
170 sal_Int32 m_nZResolution;
171
173
177
181};
182
184{
185public:
188 virtual ~PolarPlottingPositionHelper() override;
189
190 virtual std::unique_ptr<PlottingPositionHelper> clone() const override;
191
192 virtual void setTransformationSceneToScreen( const css::drawing::HomogenMatrix& rMatrix) override;
193 virtual void setScales( std::vector< ExplicitScaleData >&& rScales, bool bSwapXAndYAxis ) override;
194
195 const ::basegfx::B3DHomMatrix& getUnitCartesianToScene() const { return m_aUnitCartesianToScene;}
196
197 virtual ::chart::XTransformation2*
199
200 //the resulting values provided by the following 3 methods should be used
201 //for input to the transformation received with
202 //'getTransformationScaledLogicToScene'
203
207 double transformToRadius( double fLogicValueOnRadiusAxis, bool bDoScaling=true ) const;
208
212 double transformToAngleDegree( double fLogicValueOnAngleAxis, bool bDoScaling=true ) const;
213
219 double getWidthAngleDegree( double& fStartLogicValueOnAngleAxis, double& fEndLogicValueOnAngleAxis ) const;
220
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;
227
232 css::drawing::Position3D
233 transformUnitCircleToScene( double fUnitAngleDegree, double fUnitRadius, double fLogicZ ) const;
234
236
237 double getOuterLogicRadius() const;
238
239 inline bool isMathematicalOrientationAngle() const;
240 inline bool isMathematicalOrientationRadius() const;
241public:
246
255
256private:
258
259 ::basegfx::B3DHomMatrix impl_calculateMatrixUnitCartesianToScene( const ::basegfx::B3DHomMatrix& rMatrixScreenToScene ) const;
260};
261
263{
264 const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[1] : m_aScales[2];
265 if( css::chart2::AxisOrientation_MATHEMATICAL==rScale.Orientation )
266 return true;
267 return false;
268}
270{
271 const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[0] : m_aScales[1];
272 if( css::chart2::AxisOrientation_MATHEMATICAL==rScale.Orientation )
273 return true;
274 return false;
275}
276
277//better performance for big data
278void PlottingPositionHelper::setCoordinateSystemResolution( const css::uno::Sequence< sal_Int32 >& rCoordinateSystemResolution )
279{
280 m_nXResolution = 1000;
281 m_nYResolution = 1000;
282 m_nZResolution = 1000;
283 if( rCoordinateSystemResolution.getLength() > 0 )
284 m_nXResolution = rCoordinateSystemResolution[0];
285 if( rCoordinateSystemResolution.getLength() > 1 )
286 m_nYResolution = rCoordinateSystemResolution[1];
287 if( rCoordinateSystemResolution.getLength() > 2 )
288 m_nZResolution = rCoordinateSystemResolution[2];
289}
290
291bool PlottingPositionHelper::isSameForGivenResolution( double fX, double fY, double fZ
292 , double fX2, double fY2, double fZ2 /*these values are all expected tp be scaled already*/ )
293{
294 if( !std::isfinite(fX) || !std::isfinite(fY) || !std::isfinite(fZ)
295 || !std::isfinite(fX2) || !std::isfinite(fY2) || !std::isfinite(fZ2) )
296 return false;
297
298 double fScaledMinX = getLogicMinX();
299 double fScaledMinY = getLogicMinY();
300 double fScaledMinZ = getLogicMinZ();
301 double fScaledMaxX = getLogicMaxX();
302 double fScaledMaxY = getLogicMaxY();
303 double fScaledMaxZ = getLogicMaxZ();
304
305 doLogicScaling( &fScaledMinX, &fScaledMinY, &fScaledMinZ );
306 doLogicScaling( &fScaledMaxX, &fScaledMaxY, &fScaledMaxZ);
307
308 bool bSameX = ( static_cast<sal_Int32>(m_nXResolution*(fX - fScaledMinX)/(fScaledMaxX-fScaledMinX))
309 == static_cast<sal_Int32>(m_nXResolution*(fX2 - fScaledMinX)/(fScaledMaxX-fScaledMinX)) );
310
311 bool bSameY = ( static_cast<sal_Int32>(m_nYResolution*(fY - fScaledMinY)/(fScaledMaxY-fScaledMinY))
312 == static_cast<sal_Int32>(m_nYResolution*(fY2 - fScaledMinY)/(fScaledMaxY-fScaledMinY)) );
313
314 bool bSameZ = ( static_cast<sal_Int32>(m_nZResolution*(fZ - fScaledMinZ)/(fScaledMaxZ-fScaledMinZ))
315 == static_cast<sal_Int32>(m_nZResolution*(fZ2 - fScaledMinZ)/(fScaledMaxZ-fScaledMinZ)) );
316
317 return (bSameX && bSameY && bSameZ);
318}
319
320bool PlottingPositionHelper::isStrongLowerRequested( sal_Int32 nDimensionIndex ) const
321{
322 if( m_aScales.empty() )
323 return false;
324 if( 0==nDimensionIndex )
325 return m_bAllowShiftXAxisPos && m_aScales[nDimensionIndex].m_bShiftedCategoryPosition;
326 else if( 2==nDimensionIndex )
327 return m_bAllowShiftZAxisPos && m_aScales[nDimensionIndex].m_bShiftedCategoryPosition;
328 return false;
329}
330
332 double fX, double fY, double fZ ) const
333{
334 return fX >= m_aScales[0].Minimum && ( isStrongLowerRequested(0) ? fX < m_aScales[0].Maximum : fX <= m_aScales[0].Maximum )
335 && fY >= m_aScales[1].Minimum && fY <= m_aScales[1].Maximum
336 && fZ >= m_aScales[2].Minimum && ( isStrongLowerRequested(2) ? fZ < m_aScales[2].Maximum : fZ <= m_aScales[2].Maximum );
337}
338
339void PlottingPositionHelper::doLogicScaling( double* pX, double* pY, double* pZ ) const
340{
341 if(pX)
342 {
343 if( m_aScales[0].Scaling.is())
344 *pX = m_aScales[0].Scaling->doScaling(*pX);
345 if( m_bAllowShiftXAxisPos && m_aScales[0].m_bShiftedCategoryPosition )
346 (*pX) += m_fScaledCategoryWidth/2.0;
347 }
348 if(pY && m_aScales[1].Scaling.is())
349 *pY = m_aScales[1].Scaling->doScaling(*pY);
350 if(pZ)
351 {
352 if( m_aScales[2].Scaling.is())
353 *pZ = m_aScales[2].Scaling->doScaling(*pZ);
354 if( m_bAllowShiftZAxisPos && m_aScales[2].m_bShiftedCategoryPosition)
355 (*pZ) += 0.5;
356 }
357}
358
359void PlottingPositionHelper::doUnshiftedLogicScaling( double* pX, double* pY, double* pZ ) const
360{
361 if(pX && m_aScales[0].Scaling.is())
362 *pX = m_aScales[0].Scaling->doScaling(*pX);
363 if(pY && m_aScales[1].Scaling.is())
364 *pY = m_aScales[1].Scaling->doScaling(*pY);
365 if(pZ && m_aScales[2].Scaling.is())
366 *pZ = m_aScales[2].Scaling->doScaling(*pZ);
367}
368
369void PlottingPositionHelper::doLogicScaling( css::drawing::Position3D& rPos ) const
370{
371 doLogicScaling( &rPos.PositionX, &rPos.PositionY, &rPos.PositionZ );
372}
373
374void PlottingPositionHelper::clipLogicValues( double* pX, double* pY, double* pZ ) const
375{
376 if(pX)
377 {
378 if( *pX < m_aScales[0].Minimum )
379 *pX = m_aScales[0].Minimum;
380 else if( *pX > m_aScales[0].Maximum )
381 *pX = m_aScales[0].Maximum;
382 }
383 if(pY)
384 {
385 if( *pY < m_aScales[1].Minimum )
386 *pY = m_aScales[1].Minimum;
387 else if( *pY > m_aScales[1].Maximum )
388 *pY = m_aScales[1].Maximum;
389 }
390 if(pZ)
391 {
392 if( *pZ < m_aScales[2].Minimum )
393 *pZ = m_aScales[2].Minimum;
394 else if( *pZ > m_aScales[2].Maximum )
395 *pZ = m_aScales[2].Maximum;
396 }
397}
398
399inline bool PlottingPositionHelper::clipYRange( double& rMin, double& rMax ) const
400{
401 //returns true if something remains
402 if( rMin > rMax )
403 std::swap( rMin, rMax );
404 if( rMin > getLogicMaxY() )
405 return false;
406 if( rMax < getLogicMinY() )
407 return false;
408 if( rMin < getLogicMinY() )
409 rMin = getLogicMinY();
410 if( rMax > getLogicMaxY() )
411 rMax = getLogicMaxY();
412 return true;
413}
414
416{
417 return m_aScales[0].Minimum;
418}
420{
421 return m_aScales[1].Minimum;
422}
424{
425 return m_aScales[2].Minimum;
426}
427
429{
430 return m_aScales[0].Maximum;
431}
433{
434 return m_aScales[1].Maximum;
435}
437{
438 return m_aScales[2].Maximum;
439}
441{
442 return css::chart2::AxisOrientation_MATHEMATICAL == m_aScales[0].Orientation;
443}
445{
446 return css::chart2::AxisOrientation_MATHEMATICAL == m_aScales[1].Orientation;
447}
449{
450 return css::chart2::AxisOrientation_MATHEMATICAL == m_aScales[2].Orientation;
451}
453{
454 return m_bSwapXAndY;
455}
457{
459}
460
461} //namespace chart
462
463/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool isStrongLowerRequested(sal_Int32 nDimensionIndex) const
virtual ::chart::XTransformation2 * getTransformationScaledLogicToScene() const
bool isSameForGivenResolution(double fX, double fY, double fZ, double fX2, double fY2, double fZ2)
css::drawing::Direction3D getScaledLogicWidth() const
::basegfx::B3DHomMatrix m_aMatrixScreenToScene
const std::vector< ExplicitScaleData > & getScales() const
virtual void setScales(std::vector< ExplicitScaleData > &&rScales, bool bSwapXAndYAxis)
void transformScaledLogicToScene(css::drawing::PolyPolygonShape3D &rPoly) const
virtual void setTransformationSceneToScreen(const css::drawing::HomogenMatrix &rMatrix)
static css::awt::Point transformSceneToScreenPosition(const css::drawing::Position3D &rScenePosition3D, const rtl::Reference< SvxShapeGroupAnyD > &xSceneTarget, sal_Int32 nDimensionCount)
bool clipYRange(double &rMin, double &rMax) const
void AllowShiftZAxisPos(bool bAllowShift)
void clipScaledLogicValues(double *pX, double *pY, double *pZ) const
void setCoordinateSystemResolution(const css::uno::Sequence< sal_Int32 > &rCoordinateSystemResolution)
std::vector< ExplicitScaleData > m_aScales
::basegfx::B2DRectangle getScaledLogicClipDoubleRect() const
bool isLogicVisible(double fX, double fY, double fZ) const
void AllowShiftXAxisPos(bool bAllowShift)
virtual std::unique_ptr< PlottingPositionHelper > clone() const
void doUnshiftedLogicScaling(double *pX, double *pY, double *pZ) const
virtual css::drawing::Position3D transformLogicToScene(double fX, double fY, double fZ, bool bClip) const
virtual void setScaledCategoryWidth(double fScaledCategoryWidth)
void doLogicScaling(double *pX, double *pY, double *pZ) const
virtual css::drawing::Position3D transformScaledLogicToScene(double fX, double fY, double fZ, bool bClip) const
std::unique_ptr< ::chart::XTransformation2 > m_xTransformationLogicToScene
void setTimeResolution(tools::Long nTimeResolution, const Date &rNullDate)
void clipLogicValues(double *pX, double *pY, double *pZ) const
std::unique_ptr< PlottingPositionHelper > createSecondaryPosHelper(const ExplicitScaleData &rSecondaryScale)
double transformToAngleDegree(double fLogicValueOnAngleAxis, bool bDoScaling=true) const
Given a value in the angle axis scale range (e.g.
css::drawing::Position3D transformUnitCircleToScene(double fUnitAngleDegree, double fUnitRadius, double fLogicZ) const
It returns the scene coordinates of the passed point: this point is described through a normalized cy...
::basegfx::B3DHomMatrix impl_calculateMatrixUnitCartesianToScene(const ::basegfx::B3DHomMatrix &rMatrixScreenToScene) const
const ::basegfx::B3DHomMatrix & getUnitCartesianToScene() const
virtual std::unique_ptr< PlottingPositionHelper > clone() const override
virtual ::chart::XTransformation2 * getTransformationScaledLogicToScene() const override
double m_fAngleDegreeOffset
Offset for angle axis in real degree.
virtual void setTransformationSceneToScreen(const css::drawing::HomogenMatrix &rMatrix) override
css::drawing::Position3D transformAngleRadiusToScene(double fLogicValueOnAngleAxis, double fLogicValueOnRadiusAxis, double fLogicZ, bool bDoScaling=true) const
virtual void setScales(std::vector< ExplicitScaleData > &&rScales, bool bSwapXAndYAxis) override
virtual css::drawing::Position3D transformScaledLogicToScene(double fX, double fY, double fZ, bool bClip) const override
double getWidthAngleDegree(double &fStartLogicValueOnAngleAxis, double &fEndLogicValueOnAngleAxis) const
Given 2 values in the angle axis scale range (e.g.
double transformToRadius(double fLogicValueOnRadiusAxis, bool bDoScaling=true) const
Given a value in the radius axis scale range, it returns the normalized value.
double m_fRadiusOffset
m_bSwapXAndY (inherited): by default the X axis (scale[0]) represents the angle axis and the Y axis (...
virtual css::drawing::Position3D transformLogicToScene(double fX, double fY, double fZ, bool bClip) const override
allows the transformation of numeric values from one coordinate-system into another.
virtual css::drawing::Position3D transform(const css::drawing::Position3D &rSourceValues) const =0
transforms the given input data tuple, given in the source coordinate system, according to the intern...
virtual css::drawing::Position3D transform(const css::uno::Sequence< double > &rSourceValues) const =0
long Long
This structure contains the explicit values for a scale like Minimum and Maximum.
css::chart2::AxisOrientation Orientation