1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 #ifndef _CHART2_PLOTTINGPOSITIONHELPER_HXX 24 #define _CHART2_PLOTTINGPOSITIONHELPER_HXX 25 26 #include "LabelAlignment.hxx" 27 #include "chartview/ExplicitScaleValues.hxx" 28 29 #include <basegfx/range/b2drectangle.hxx> 30 #include <rtl/math.hxx> 31 #include <com/sun/star/chart2/XTransformation.hpp> 32 #include <com/sun/star/drawing/Direction3D.hpp> 33 #include <com/sun/star/drawing/HomogenMatrix.hpp> 34 #include <com/sun/star/drawing/PolyPolygonShape3D.hpp> 35 #include <com/sun/star/drawing/Position3D.hpp> 36 #include <com/sun/star/drawing/XShapes.hpp> 37 #include <basegfx/matrix/b3dhommatrix.hxx> 38 39 /* 40 //for WeakImplHelper1 41 #include <cppuhelper/implbase1.hxx> 42 */ 43 //............................................................................. 44 namespace chart 45 { 46 //............................................................................. 47 48 class ShapeFactory; 49 50 //----------------------------------------------------------------------------- 51 /** 52 */ 53 54 class PlottingPositionHelper 55 { 56 public: 57 PlottingPositionHelper(); 58 PlottingPositionHelper( const PlottingPositionHelper& rSource ); 59 virtual ~PlottingPositionHelper(); 60 61 virtual PlottingPositionHelper* clone() const; 62 virtual PlottingPositionHelper* createSecondaryPosHelper( const ExplicitScaleData& rSecondaryScale ); 63 64 virtual void setTransformationSceneToScreen( const ::com::sun::star::drawing::HomogenMatrix& rMatrix); 65 66 virtual void setScales( const ::std::vector< ExplicitScaleData >& rScales, bool bSwapXAndYAxis ); 67 const ::std::vector< ExplicitScaleData >& getScales() const; 68 69 //better performance for big data 70 inline void setCoordinateSystemResolution( const ::com::sun::star::uno::Sequence< sal_Int32 >& rCoordinateSystemResolution ); 71 inline bool isSameForGivenResolution( double fX, double fY, double fZ 72 , double fX2, double fY2, double fZ2 ); 73 74 inline bool isStrongLowerRequested( sal_Int32 nDimensionIndex ) const; 75 inline bool isLogicVisible( double fX, double fY, double fZ ) const; 76 inline void doLogicScaling( double* pX, double* pY, double* pZ, bool bClip=false ) const; 77 inline void doUnshiftedLogicScaling( double* pX, double* pY, double* pZ, bool bClip=false ) const; 78 inline void clipLogicValues( double* pX, double* pY, double* pZ ) const; 79 void clipScaledLogicValues( double* pX, double* pY, double* pZ ) const; 80 inline bool clipYRange( double& rMin, double& rMax ) const; 81 82 inline void doLogicScaling( ::com::sun::star::drawing::Position3D& rPos, bool bClip=false ) const; 83 84 virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTransformation > 85 getTransformationScaledLogicToScene() const; 86 87 virtual ::com::sun::star::drawing::Position3D 88 transformLogicToScene( double fX, double fY, double fZ, bool bClip ) const; 89 90 virtual ::com::sun::star::drawing::Position3D 91 transformScaledLogicToScene( double fX, double fY, double fZ, bool bClip ) const; 92 93 void transformScaledLogicToScene( ::com::sun::star::drawing::PolyPolygonShape3D& rPoly ) const; 94 95 static com::sun::star::awt::Point transformSceneToScreenPosition( 96 const com::sun::star::drawing::Position3D& rScenePosition3D 97 , const com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >& xSceneTarget 98 , ShapeFactory* pShapeFactory, sal_Int32 nDimensionCount ); 99 100 inline double getLogicMinX() const; 101 inline double getLogicMinY() const; 102 inline double getLogicMinZ() const; 103 inline double getLogicMaxX() const; 104 inline double getLogicMaxY() const; 105 inline double getLogicMaxZ() const; 106 107 inline bool isMathematicalOrientationX() const; 108 inline bool isMathematicalOrientationY() const; 109 inline bool isMathematicalOrientationZ() const; 110 111 ::basegfx::B2DRectangle getScaledLogicClipDoubleRect() const; 112 ::com::sun::star::drawing::Direction3D getScaledLogicWidth() const; 113 114 inline bool isSwapXAndY() const; 115 116 bool isPercentY() const; 117 118 double getBaseValueY() const; 119 120 inline bool maySkipPointsInRegressionCalculation() const; 121 122 void setTimeResolution( long nTimeResolution, const Date& rNullDate ); 123 virtual void setScaledCategoryWidth( double fScaledCategoryWidth ); 124 void AllowShiftXAxisPos( bool bAllowShift ); 125 void AllowShiftZAxisPos( bool bAllowShift ); 126 127 protected: //member 128 ::std::vector< ExplicitScaleData > m_aScales; 129 ::basegfx::B3DHomMatrix m_aMatrixScreenToScene; 130 131 //this is calculated based on m_aScales and m_aMatrixScreenToScene 132 mutable ::com::sun::star::uno::Reference< 133 ::com::sun::star::chart2::XTransformation > m_xTransformationLogicToScene; 134 135 bool m_bSwapXAndY;//e.g. true for bar chart and false for column chart 136 137 sal_Int32 m_nXResolution; 138 sal_Int32 m_nYResolution; 139 sal_Int32 m_nZResolution; 140 141 bool m_bMaySkipPointsInRegressionCalculation; 142 143 bool m_bDateAxis; 144 long m_nTimeResolution; 145 Date m_aNullDate; 146 147 double m_fScaledCategoryWidth; 148 bool m_bAllowShiftXAxisPos; 149 bool m_bAllowShiftZAxisPos; 150 }; 151 152 //describes wich axis of the drawinglayer scene or sreen axis are the normal axis 153 enum NormalAxis 154 { 155 NormalAxis_X 156 , NormalAxis_Y 157 , NormalAxis_Z 158 }; 159 160 class PolarPlottingPositionHelper : public PlottingPositionHelper 161 /* 162 , public ::cppu::WeakImplHelper1< 163 ::com::sun::star::chart2::XTransformation > 164 */ 165 { 166 public: 167 PolarPlottingPositionHelper( NormalAxis eNormalAxis=NormalAxis_Z ); 168 PolarPlottingPositionHelper( const PolarPlottingPositionHelper& rSource ); 169 virtual ~PolarPlottingPositionHelper(); 170 171 virtual PlottingPositionHelper* clone() const; 172 173 virtual void setTransformationSceneToScreen( const ::com::sun::star::drawing::HomogenMatrix& rMatrix); 174 virtual void setScales( const std::vector< ExplicitScaleData >& rScales, bool bSwapXAndYAxis ); 175 176 ::basegfx::B3DHomMatrix getUnitCartesianToScene() const; 177 178 virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTransformation > 179 getTransformationScaledLogicToScene() const; 180 181 //the resulting values should be used for input to the transformation 182 //received with 'getTransformationScaledLogicToScene' 183 double transformToRadius( double fLogicValueOnRadiusAxis, bool bDoScaling=true ) const; 184 double transformToAngleDegree( double fLogicValueOnAngleAxis, bool bDoScaling=true ) const; 185 double getWidthAngleDegree( double& fStartLogicValueOnAngleAxis, double& fEndLogicValueOnAngleAxis ) const; 186 // 187 188 virtual ::com::sun::star::drawing::Position3D 189 transformLogicToScene( double fX, double fY, double fZ, bool bClip ) const; 190 virtual ::com::sun::star::drawing::Position3D 191 transformScaledLogicToScene( double fX, double fY, double fZ, bool bClip ) const; 192 ::com::sun::star::drawing::Position3D 193 transformAngleRadiusToScene( double fLogicValueOnAngleAxis, double fLogicValueOnRadiusAxis, double fLogicZ, bool bDoScaling=true ) const; 194 ::com::sun::star::drawing::Position3D 195 transformUnitCircleToScene( double fUnitAngleDegree, double fUnitRadius, double fLogicZ, bool bDoScaling=true ) const; 196 197 using PlottingPositionHelper::transformScaledLogicToScene; 198 199 #ifdef NOTYET 200 double getInnerLogicRadius() const; 201 #endif 202 double getOuterLogicRadius() const; 203 204 inline bool isMathematicalOrientationAngle() const; 205 inline bool isMathematicalOrientationRadius() const; 206 207 /* 208 // ____ XTransformation ____ 209 /// @see ::com::sun::star::chart2::XTransformation 210 virtual ::com::sun::star::uno::Sequence< double > SAL_CALL transform( 211 const ::com::sun::star::uno::Sequence< double >& rSourceValues ) 212 throw (::com::sun::star::lang::IllegalArgumentException, 213 ::com::sun::star::uno::RuntimeException); 214 /// @see ::com::sun::star::chart2::XTransformation 215 virtual sal_Int32 SAL_CALL getSourceDimension() 216 throw (::com::sun::star::uno::RuntimeException); 217 /// @see ::com::sun::star::chart2::XTransformation 218 virtual sal_Int32 SAL_CALL getTargetDimension() 219 throw (::com::sun::star::uno::RuntimeException); 220 */ 221 public: 222 //Offset for radius axis in absolute logic scaled values (1.0 == 1 category) 223 double m_fRadiusOffset; 224 //Offset for angle axis in real degree 225 double m_fAngleDegreeOffset; 226 227 private: 228 ::basegfx::B3DHomMatrix m_aUnitCartesianToScene; 229 NormalAxis m_eNormalAxis; 230 231 ::basegfx::B3DHomMatrix impl_calculateMatrixUnitCartesianToScene( const ::basegfx::B3DHomMatrix& rMatrixScreenToScene ) const; 232 }; 233 234 bool PolarPlottingPositionHelper::isMathematicalOrientationAngle() const 235 { 236 const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[1] : m_aScales[2]; 237 if( ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL==rScale.Orientation ) 238 return true; 239 return false; 240 } 241 bool PolarPlottingPositionHelper::isMathematicalOrientationRadius() const 242 { 243 const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[0] : m_aScales[1]; 244 if( ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL==rScale.Orientation ) 245 return true; 246 return false; 247 } 248 249 //better performance for big data 250 void PlottingPositionHelper::setCoordinateSystemResolution( const ::com::sun::star::uno::Sequence< sal_Int32 >& rCoordinateSystemResolution ) 251 { 252 m_nXResolution = 1000; 253 m_nYResolution = 1000; 254 m_nZResolution = 1000; 255 if( rCoordinateSystemResolution.getLength() > 0 ) 256 m_nXResolution = rCoordinateSystemResolution[0]; 257 if( rCoordinateSystemResolution.getLength() > 1 ) 258 m_nYResolution = rCoordinateSystemResolution[1]; 259 if( rCoordinateSystemResolution.getLength() > 2 ) 260 m_nZResolution = rCoordinateSystemResolution[2]; 261 } 262 263 bool PlottingPositionHelper::isSameForGivenResolution( double fX, double fY, double fZ 264 , double fX2, double fY2, double fZ2 /*these values are all expected tp be scaled already*/ ) 265 { 266 if( !::rtl::math::isFinite(fX) || !::rtl::math::isFinite(fY) || !::rtl::math::isFinite(fZ) 267 || !::rtl::math::isFinite(fX2) || !::rtl::math::isFinite(fY2) || !::rtl::math::isFinite(fZ2) ) 268 return false; 269 270 double fScaledMinX = getLogicMinX(); 271 double fScaledMinY = getLogicMinY(); 272 double fScaledMinZ = getLogicMinZ(); 273 double fScaledMaxX = getLogicMaxX(); 274 double fScaledMaxY = getLogicMaxY(); 275 double fScaledMaxZ = getLogicMaxZ(); 276 277 doLogicScaling( &fScaledMinX, &fScaledMinY, &fScaledMinZ ); 278 doLogicScaling( &fScaledMaxX, &fScaledMaxY, &fScaledMaxZ); 279 280 bool bSameX = ( static_cast<sal_Int32>(m_nXResolution*(fX - fScaledMinX)/(fScaledMaxX-fScaledMinX)) 281 == static_cast<sal_Int32>(m_nXResolution*(fX2 - fScaledMinX)/(fScaledMaxX-fScaledMinX)) ); 282 283 bool bSameY = ( static_cast<sal_Int32>(m_nYResolution*(fY - fScaledMinY)/(fScaledMaxY-fScaledMinY)) 284 == static_cast<sal_Int32>(m_nYResolution*(fY2 - fScaledMinY)/(fScaledMaxY-fScaledMinY)) ); 285 286 bool bSameZ = ( static_cast<sal_Int32>(m_nZResolution*(fZ - fScaledMinZ)/(fScaledMaxZ-fScaledMinZ)) 287 == static_cast<sal_Int32>(m_nZResolution*(fZ2 - fScaledMinZ)/(fScaledMaxZ-fScaledMinZ)) ); 288 289 return (bSameX && bSameY && bSameZ); 290 } 291 292 bool PlottingPositionHelper::isStrongLowerRequested( sal_Int32 nDimensionIndex ) const 293 { 294 if( m_aScales.empty() ) 295 return false; 296 if( 0==nDimensionIndex ) 297 return m_bAllowShiftXAxisPos && m_aScales[nDimensionIndex].ShiftedCategoryPosition; 298 else if( 2==nDimensionIndex ) 299 return m_bAllowShiftZAxisPos && m_aScales[nDimensionIndex].ShiftedCategoryPosition; 300 return false; 301 } 302 303 bool PlottingPositionHelper::isLogicVisible( 304 double fX, double fY, double fZ ) const 305 { 306 return fX >= m_aScales[0].Minimum && ( isStrongLowerRequested(0) ? fX < m_aScales[0].Maximum : fX <= m_aScales[0].Maximum ) 307 && fY >= m_aScales[1].Minimum && fY <= m_aScales[1].Maximum 308 && fZ >= m_aScales[2].Minimum && ( isStrongLowerRequested(2) ? fZ < m_aScales[2].Maximum : fZ <= m_aScales[2].Maximum ); 309 } 310 311 void PlottingPositionHelper::doLogicScaling( double* pX, double* pY, double* pZ, bool bClip ) const 312 { 313 if(bClip) 314 this->clipLogicValues( pX,pY,pZ ); 315 316 if(pX) 317 { 318 if( m_aScales[0].Scaling.is()) 319 *pX = m_aScales[0].Scaling->doScaling(*pX); 320 if( m_bAllowShiftXAxisPos && m_aScales[0].ShiftedCategoryPosition ) 321 (*pX) += m_fScaledCategoryWidth/2.0; 322 } 323 if(pY && m_aScales[1].Scaling.is()) 324 *pY = m_aScales[1].Scaling->doScaling(*pY); 325 if(pZ) 326 { 327 if( m_aScales[2].Scaling.is()) 328 *pZ = m_aScales[2].Scaling->doScaling(*pZ); 329 if( m_bAllowShiftZAxisPos && m_aScales[2].ShiftedCategoryPosition) 330 (*pZ) += 0.5; 331 } 332 } 333 334 void PlottingPositionHelper::doUnshiftedLogicScaling( double* pX, double* pY, double* pZ, bool bClip ) const 335 { 336 if(bClip) 337 this->clipLogicValues( pX,pY,pZ ); 338 339 if(pX && m_aScales[0].Scaling.is()) 340 *pX = m_aScales[0].Scaling->doScaling(*pX); 341 if(pY && m_aScales[1].Scaling.is()) 342 *pY = m_aScales[1].Scaling->doScaling(*pY); 343 if(pZ && m_aScales[2].Scaling.is()) 344 *pZ = m_aScales[2].Scaling->doScaling(*pZ); 345 } 346 347 void PlottingPositionHelper::doLogicScaling( ::com::sun::star::drawing::Position3D& rPos, bool bClip ) const 348 { 349 doLogicScaling( &rPos.PositionX, &rPos.PositionY, &rPos.PositionZ, bClip ); 350 } 351 352 void PlottingPositionHelper::clipLogicValues( double* pX, double* pY, double* pZ ) const 353 { 354 if(pX) 355 { 356 if( *pX < m_aScales[0].Minimum ) 357 *pX = m_aScales[0].Minimum; 358 else if( *pX > m_aScales[0].Maximum ) 359 *pX = m_aScales[0].Maximum; 360 } 361 if(pY) 362 { 363 if( *pY < m_aScales[1].Minimum ) 364 *pY = m_aScales[1].Minimum; 365 else if( *pY > m_aScales[1].Maximum ) 366 *pY = m_aScales[1].Maximum; 367 } 368 if(pZ) 369 { 370 if( *pZ < m_aScales[2].Minimum ) 371 *pZ = m_aScales[2].Minimum; 372 else if( *pZ > m_aScales[2].Maximum ) 373 *pZ = m_aScales[2].Maximum; 374 } 375 } 376 377 inline bool PlottingPositionHelper::clipYRange( double& rMin, double& rMax ) const 378 { 379 //returns true if something remains 380 if( rMin > rMax ) 381 { 382 double fHelp = rMin; 383 rMin = rMax; 384 rMax = fHelp; 385 } 386 if( rMin > getLogicMaxY() ) 387 return false; 388 if( rMax < getLogicMinY() ) 389 return false; 390 if( rMin < getLogicMinY() ) 391 rMin = getLogicMinY(); 392 if( rMax > getLogicMaxY() ) 393 rMax = getLogicMaxY(); 394 return true; 395 } 396 397 inline double PlottingPositionHelper::getLogicMinX() const 398 { 399 return m_aScales[0].Minimum; 400 } 401 inline double PlottingPositionHelper::getLogicMinY() const 402 { 403 return m_aScales[1].Minimum; 404 } 405 inline double PlottingPositionHelper::getLogicMinZ() const 406 { 407 return m_aScales[2].Minimum; 408 } 409 410 inline double PlottingPositionHelper::getLogicMaxX() const 411 { 412 return m_aScales[0].Maximum; 413 } 414 inline double PlottingPositionHelper::getLogicMaxY() const 415 { 416 return m_aScales[1].Maximum; 417 } 418 inline double PlottingPositionHelper::getLogicMaxZ() const 419 { 420 return m_aScales[2].Maximum; 421 } 422 inline bool PlottingPositionHelper::isMathematicalOrientationX() const 423 { 424 return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[0].Orientation; 425 } 426 inline bool PlottingPositionHelper::isMathematicalOrientationY() const 427 { 428 return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[1].Orientation; 429 } 430 inline bool PlottingPositionHelper::isMathematicalOrientationZ() const 431 { 432 return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[2].Orientation; 433 } 434 inline bool PlottingPositionHelper::isSwapXAndY() const 435 { 436 return m_bSwapXAndY; 437 } 438 inline bool PlottingPositionHelper::maySkipPointsInRegressionCalculation() const 439 { 440 return m_bMaySkipPointsInRegressionCalculation; 441 } 442 443 //............................................................................. 444 } //namespace chart 445 //............................................................................. 446 #endif 447