diff options
Diffstat (limited to 'chart2/source/view/inc/PlottingPositionHelper.hxx')
-rw-r--r-- | chart2/source/view/inc/PlottingPositionHelper.hxx | 406 |
1 files changed, 406 insertions, 0 deletions
diff --git a/chart2/source/view/inc/PlottingPositionHelper.hxx b/chart2/source/view/inc/PlottingPositionHelper.hxx new file mode 100644 index 000000000000..a1f16883b779 --- /dev/null +++ b/chart2/source/view/inc/PlottingPositionHelper.hxx @@ -0,0 +1,406 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _CHART2_PLOTTINGPOSITIONHELPER_HXX +#define _CHART2_PLOTTINGPOSITIONHELPER_HXX + +#include "LabelAlignment.hxx" +#include <basegfx/range/b2drectangle.hxx> +#include <rtl/math.hxx> +#include <com/sun/star/chart2/ExplicitScaleData.hpp> +#include <com/sun/star/chart2/XTransformation.hpp> +#include <com/sun/star/drawing/Direction3D.hpp> +#include <com/sun/star/drawing/HomogenMatrix.hpp> +#include <com/sun/star/drawing/PolyPolygonShape3D.hpp> +#include <com/sun/star/drawing/Position3D.hpp> +#include <com/sun/star/drawing/XShapes.hpp> +#include <basegfx/matrix/b3dhommatrix.hxx> + +/* +//for WeakImplHelper1 +#include <cppuhelper/implbase1.hxx> +*/ +//............................................................................. +namespace chart +{ +//............................................................................. + +class ShapeFactory; + +//----------------------------------------------------------------------------- +/** +*/ + +class PlottingPositionHelper +{ +public: + PlottingPositionHelper(); + PlottingPositionHelper( const PlottingPositionHelper& rSource ); + virtual ~PlottingPositionHelper(); + + virtual PlottingPositionHelper* clone() const; + virtual PlottingPositionHelper* createSecondaryPosHelper( const ::com::sun::star::chart2::ExplicitScaleData& rSecondaryScale ); + + virtual void setTransformationSceneToScreen( const ::com::sun::star::drawing::HomogenMatrix& rMatrix); + + virtual void setScales( const ::com::sun::star::uno::Sequence< + ::com::sun::star::chart2::ExplicitScaleData >& rScales + , sal_Bool bSwapXAndYAxis ); + const ::com::sun::star::uno::Sequence< + ::com::sun::star::chart2::ExplicitScaleData >& getScales() const; + + //better performance for big data + inline void setCoordinateSystemResolution( const ::com::sun::star::uno::Sequence< sal_Int32 >& rCoordinateSystemResolution ); + inline bool isSameForGivenResolution( double fX, double fY, double fZ + , double fX2, double fY2, double fZ2 ); + + inline bool isLogicVisible( double fX, double fY, double fZ ) const; + inline void doLogicScaling( double* pX, double* pY, double* pZ, bool bClip=false ) const; + inline void clipLogicValues( double* pX, double* pY, double* pZ ) const; + void clipScaledLogicValues( double* pX, double* pY, double* pZ ) const; + inline bool clipYRange( double& rMin, double& rMax ) const; + + inline void doLogicScaling( ::com::sun::star::drawing::Position3D& rPos, bool bClip=false ) const; + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTransformation > + getTransformationScaledLogicToScene() const; + + virtual ::com::sun::star::drawing::Position3D + transformLogicToScene( double fX, double fY, double fZ, bool bClip ) const; + + virtual ::com::sun::star::drawing::Position3D + transformScaledLogicToScene( double fX, double fY, double fZ, bool bClip ) const; + + void transformScaledLogicToScene( ::com::sun::star::drawing::PolyPolygonShape3D& rPoly ) const; + + static com::sun::star::awt::Point transformSceneToScreenPosition( + const com::sun::star::drawing::Position3D& rScenePosition3D + , const com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >& xSceneTarget + , ShapeFactory* pShapeFactory, sal_Int32 nDimensionCount ); + + inline double getLogicMinX() const; + inline double getLogicMinY() const; + inline double getLogicMinZ() const; + inline double getLogicMaxX() const; + inline double getLogicMaxY() const; + inline double getLogicMaxZ() const; + + inline bool isMathematicalOrientationX() const; + inline bool isMathematicalOrientationY() const; + inline bool isMathematicalOrientationZ() const; + + ::basegfx::B2DRectangle getScaledLogicClipDoubleRect() const; + ::com::sun::star::drawing::Direction3D getScaledLogicWidth() const; + + inline bool isSwapXAndY() const; + + bool isPercentY() const; + + double getBaseValueY() const; + + inline bool maySkipPointsInRegressionCalculation() const; + +protected: //member + ::com::sun::star::uno::Sequence< + ::com::sun::star::chart2::ExplicitScaleData > m_aScales; + ::basegfx::B3DHomMatrix m_aMatrixScreenToScene; + + //this is calculated based on m_aScales and m_aMatrixScreenToScene + mutable ::com::sun::star::uno::Reference< + ::com::sun::star::chart2::XTransformation > m_xTransformationLogicToScene; + + bool m_bSwapXAndY;//e.g. true for bar chart and false for column chart + + sal_Int32 m_nXResolution; + sal_Int32 m_nYResolution; + sal_Int32 m_nZResolution; + + bool m_bMaySkipPointsInRegressionCalculation; +}; + +//describes wich axis of the drawinglayer scene or sreen axis are the normal axis +enum NormalAxis +{ + NormalAxis_X + , NormalAxis_Y + , NormalAxis_Z +}; + +class PolarPlottingPositionHelper : public PlottingPositionHelper + /* + , public ::cppu::WeakImplHelper1< + ::com::sun::star::chart2::XTransformation > + */ +{ +public: + PolarPlottingPositionHelper( NormalAxis eNormalAxis=NormalAxis_Z ); + PolarPlottingPositionHelper( const PolarPlottingPositionHelper& rSource ); + virtual ~PolarPlottingPositionHelper(); + + virtual PlottingPositionHelper* clone() const; + + virtual void setTransformationSceneToScreen( const ::com::sun::star::drawing::HomogenMatrix& rMatrix); + virtual void setScales( const ::com::sun::star::uno::Sequence< + ::com::sun::star::chart2::ExplicitScaleData >& rScales + , sal_Bool bSwapXAndYAxis ); + + ::basegfx::B3DHomMatrix getUnitCartesianToScene() const; + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTransformation > + getTransformationScaledLogicToScene() const; + + //the resulting values should be used for input to the transformation + //received with 'getTransformationScaledLogicToScene' + double transformToRadius( double fLogicValueOnRadiusAxis, bool bDoScaling=true ) const; + double transformToAngleDegree( double fLogicValueOnAngleAxis, bool bDoScaling=true ) const; + double getWidthAngleDegree( double& fStartLogicValueOnAngleAxis, double& fEndLogicValueOnAngleAxis ) const; + // + + virtual ::com::sun::star::drawing::Position3D + transformLogicToScene( double fX, double fY, double fZ, bool bClip ) const; + virtual ::com::sun::star::drawing::Position3D + transformScaledLogicToScene( double fX, double fY, double fZ, bool bClip ) const; + ::com::sun::star::drawing::Position3D + transformAngleRadiusToScene( double fLogicValueOnAngleAxis, double fLogicValueOnRadiusAxis, double fLogicZ, bool bDoScaling=true ) const; + ::com::sun::star::drawing::Position3D + transformUnitCircleToScene( double fUnitAngleDegree, double fUnitRadius, double fLogicZ, bool bDoScaling=true ) const; + + using PlottingPositionHelper::transformScaledLogicToScene; + +#ifdef NOTYET + double getInnerLogicRadius() const; +#endif + double getOuterLogicRadius() const; + + inline bool isMathematicalOrientationAngle() const; + inline bool isMathematicalOrientationRadius() const; + + /* + // ____ XTransformation ____ + /// @see ::com::sun::star::chart2::XTransformation + virtual ::com::sun::star::uno::Sequence< double > SAL_CALL transform( + const ::com::sun::star::uno::Sequence< double >& rSourceValues ) + throw (::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::uno::RuntimeException); + /// @see ::com::sun::star::chart2::XTransformation + virtual sal_Int32 SAL_CALL getSourceDimension() + throw (::com::sun::star::uno::RuntimeException); + /// @see ::com::sun::star::chart2::XTransformation + virtual sal_Int32 SAL_CALL getTargetDimension() + throw (::com::sun::star::uno::RuntimeException); + */ +public: + //Offset for radius axis in absolute logic scaled values (1.0 == 1 category) + double m_fRadiusOffset; + //Offset for angle axis in real degree + double m_fAngleDegreeOffset; + +private: + ::basegfx::B3DHomMatrix m_aUnitCartesianToScene; + NormalAxis m_eNormalAxis; + + ::basegfx::B3DHomMatrix impl_calculateMatrixUnitCartesianToScene( const ::basegfx::B3DHomMatrix& rMatrixScreenToScene ) const; +}; + +bool PolarPlottingPositionHelper::isMathematicalOrientationAngle() const +{ + const ::com::sun::star::chart2::ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[1] : m_aScales[2]; + if( ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL==rScale.Orientation ) + return true; + return false; +} +bool PolarPlottingPositionHelper::isMathematicalOrientationRadius() const +{ + const ::com::sun::star::chart2::ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[0] : m_aScales[1]; + if( ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL==rScale.Orientation ) + return true; + return false; +} + +//better performance for big data +void PlottingPositionHelper::setCoordinateSystemResolution( const ::com::sun::star::uno::Sequence< sal_Int32 >& rCoordinateSystemResolution ) +{ + m_nXResolution = 1000; + m_nYResolution = 1000; + m_nZResolution = 1000; + if( rCoordinateSystemResolution.getLength() > 0 ) + m_nXResolution = rCoordinateSystemResolution[0]; + if( rCoordinateSystemResolution.getLength() > 1 ) + m_nYResolution = rCoordinateSystemResolution[1]; + if( rCoordinateSystemResolution.getLength() > 2 ) + m_nZResolution = rCoordinateSystemResolution[2]; +} + +bool PlottingPositionHelper::isSameForGivenResolution( double fX, double fY, double fZ + , double fX2, double fY2, double fZ2 /*these values are all expected tp be scaled already*/ ) +{ + if( !::rtl::math::isFinite(fX) || !::rtl::math::isFinite(fY) || !::rtl::math::isFinite(fZ) + || !::rtl::math::isFinite(fX2) || !::rtl::math::isFinite(fY2) || !::rtl::math::isFinite(fZ2) ) + return false; + + double fScaledMinX = getLogicMinX(); + double fScaledMinY = getLogicMinY(); + double fScaledMinZ = getLogicMinZ(); + double fScaledMaxX = getLogicMaxX(); + double fScaledMaxY = getLogicMaxY(); + double fScaledMaxZ = getLogicMaxZ(); + + doLogicScaling( &fScaledMinX, &fScaledMinY, &fScaledMinZ ); + doLogicScaling( &fScaledMaxX, &fScaledMaxY, &fScaledMaxZ); + + bool bSameX = ( static_cast<sal_Int32>(m_nXResolution*(fX - fScaledMinX)/(fScaledMaxX-fScaledMinX)) + == static_cast<sal_Int32>(m_nXResolution*(fX2 - fScaledMinX)/(fScaledMaxX-fScaledMinX)) ); + + bool bSameY = ( static_cast<sal_Int32>(m_nYResolution*(fY - fScaledMinY)/(fScaledMaxY-fScaledMinY)) + == static_cast<sal_Int32>(m_nYResolution*(fY2 - fScaledMinY)/(fScaledMaxY-fScaledMinY)) ); + + bool bSameZ = ( static_cast<sal_Int32>(m_nZResolution*(fZ - fScaledMinZ)/(fScaledMaxZ-fScaledMinZ)) + == static_cast<sal_Int32>(m_nZResolution*(fZ2 - fScaledMinZ)/(fScaledMaxZ-fScaledMinZ)) ); + + return (bSameX && bSameY && bSameZ); +} + +bool PlottingPositionHelper::isLogicVisible( + double fX, double fY, double fZ ) const +{ + return fX >= m_aScales[0].Minimum && fX <= m_aScales[0].Maximum + && fY >= m_aScales[1].Minimum && fY <= m_aScales[1].Maximum + && fZ >= m_aScales[2].Minimum && fZ <= m_aScales[2].Maximum; +} + +void PlottingPositionHelper::doLogicScaling( double* pX, double* pY, double* pZ, bool bClip ) const +{ + if(bClip) + this->clipLogicValues( pX,pY,pZ ); + + if(pX && m_aScales[0].Scaling.is()) + *pX = m_aScales[0].Scaling->doScaling(*pX); + if(pY && m_aScales[1].Scaling.is()) + *pY = m_aScales[1].Scaling->doScaling(*pY); + if(pZ && m_aScales[2].Scaling.is()) + *pZ = m_aScales[2].Scaling->doScaling(*pZ); +} + +void PlottingPositionHelper::doLogicScaling( ::com::sun::star::drawing::Position3D& rPos, bool bClip ) const +{ + doLogicScaling( &rPos.PositionX, &rPos.PositionY, &rPos.PositionZ, bClip ); +} + +void PlottingPositionHelper::clipLogicValues( double* pX, double* pY, double* pZ ) const +{ + if(pX) + { + if( *pX < m_aScales[0].Minimum ) + *pX = m_aScales[0].Minimum; + else if( *pX > m_aScales[0].Maximum ) + *pX = m_aScales[0].Maximum; + } + if(pY) + { + if( *pY < m_aScales[1].Minimum ) + *pY = m_aScales[1].Minimum; + else if( *pY > m_aScales[1].Maximum ) + *pY = m_aScales[1].Maximum; + } + if(pZ) + { + if( *pZ < m_aScales[2].Minimum ) + *pZ = m_aScales[2].Minimum; + else if( *pZ > m_aScales[2].Maximum ) + *pZ = m_aScales[2].Maximum; + } +} + +inline bool PlottingPositionHelper::clipYRange( double& rMin, double& rMax ) const +{ + //returns true if something remains + if( rMin > rMax ) + { + double fHelp = rMin; + rMin = rMax; + rMax = fHelp; + } + if( rMin > getLogicMaxY() ) + return false; + if( rMax < getLogicMinY() ) + return false; + if( rMin < getLogicMinY() ) + rMin = getLogicMinY(); + if( rMax > getLogicMaxY() ) + rMax = getLogicMaxY(); + return true; +} + +inline double PlottingPositionHelper::getLogicMinX() const +{ + return m_aScales[0].Minimum; +} +inline double PlottingPositionHelper::getLogicMinY() const +{ + return m_aScales[1].Minimum; +} +inline double PlottingPositionHelper::getLogicMinZ() const +{ + return m_aScales[2].Minimum; +} + +inline double PlottingPositionHelper::getLogicMaxX() const +{ + return m_aScales[0].Maximum; +} +inline double PlottingPositionHelper::getLogicMaxY() const +{ + return m_aScales[1].Maximum; +} +inline double PlottingPositionHelper::getLogicMaxZ() const +{ + return m_aScales[2].Maximum; +} +inline bool PlottingPositionHelper::isMathematicalOrientationX() const +{ + return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[0].Orientation; +} +inline bool PlottingPositionHelper::isMathematicalOrientationY() const +{ + return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[1].Orientation; +} +inline bool PlottingPositionHelper::isMathematicalOrientationZ() const +{ + return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[2].Orientation; +} +inline bool PlottingPositionHelper::isSwapXAndY() const +{ + return m_bSwapXAndY; +} +inline bool PlottingPositionHelper::maySkipPointsInRegressionCalculation() const +{ + return m_bMaySkipPointsInRegressionCalculation; +} + +//............................................................................. +} //namespace chart +//............................................................................. +#endif |