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
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_chart2.hxx"
26 #include "PlottingPositionHelper.hxx"
27 #include "CommonConverters.hxx"
28 #include "ViewDefines.hxx"
29 #include "Linear3DTransformation.hxx"
30 #include "VPolarTransformation.hxx"
31 #include "ShapeFactory.hxx"
32 #include "PropertyMapper.hxx"
33 #include "DateHelper.hxx"
34
35 #include <com/sun/star/chart/TimeUnit.hpp>
36 #include <com/sun/star/chart2/AxisType.hpp>
37 #include <com/sun/star/drawing/DoubleSequence.hpp>
38 #include <com/sun/star/drawing/Position3D.hpp>
39
40 #include <rtl/math.hxx>
41
42 //.............................................................................
43 namespace chart
44 {
45 //.............................................................................
46 using namespace ::com::sun::star;
47 using namespace ::com::sun::star::chart2;
48
PlottingPositionHelper()49 PlottingPositionHelper::PlottingPositionHelper()
50 : m_aScales()
51 , m_aMatrixScreenToScene()
52 , m_xTransformationLogicToScene(NULL)
53 , m_bSwapXAndY( false )
54 , m_nXResolution( 1000 )
55 , m_nYResolution( 1000 )
56 , m_nZResolution( 1000 )
57 , m_bMaySkipPointsInRegressionCalculation( true )
58 , m_bDateAxis(false)
59 , m_nTimeResolution( ::com::sun::star::chart::TimeUnit::DAY )
60 , m_aNullDate(30,12,1899)
61 , m_fScaledCategoryWidth(1.0)
62 , m_bAllowShiftXAxisPos(false)
63 , m_bAllowShiftZAxisPos(false)
64 {
65 }
PlottingPositionHelper(const PlottingPositionHelper & rSource)66 PlottingPositionHelper::PlottingPositionHelper( const PlottingPositionHelper& rSource )
67 : m_aScales( rSource.m_aScales )
68 , m_aMatrixScreenToScene( rSource.m_aMatrixScreenToScene )
69 , m_xTransformationLogicToScene( NULL ) //should be recalculated
70 , m_bSwapXAndY( rSource.m_bSwapXAndY )
71 , m_nXResolution( rSource.m_nXResolution )
72 , m_nYResolution( rSource.m_nYResolution )
73 , m_nZResolution( rSource.m_nZResolution )
74 , m_bMaySkipPointsInRegressionCalculation( rSource.m_bMaySkipPointsInRegressionCalculation )
75 , m_bDateAxis( rSource.m_bDateAxis )
76 , m_nTimeResolution( rSource.m_nTimeResolution )
77 , m_aNullDate( rSource.m_aNullDate )
78 , m_fScaledCategoryWidth( rSource.m_fScaledCategoryWidth )
79 , m_bAllowShiftXAxisPos( rSource.m_bAllowShiftXAxisPos )
80 , m_bAllowShiftZAxisPos( rSource.m_bAllowShiftZAxisPos )
81 {
82 }
83
~PlottingPositionHelper()84 PlottingPositionHelper::~PlottingPositionHelper()
85 {
86
87 }
88
clone() const89 PlottingPositionHelper* PlottingPositionHelper::clone() const
90 {
91 PlottingPositionHelper* pRet = new PlottingPositionHelper(*this);
92 return pRet;
93 }
94
createSecondaryPosHelper(const ExplicitScaleData & rSecondaryScale)95 PlottingPositionHelper* PlottingPositionHelper::createSecondaryPosHelper( const ExplicitScaleData& rSecondaryScale )
96 {
97 PlottingPositionHelper* pRet = this->clone();
98 pRet->m_aScales[1]=rSecondaryScale;
99 return pRet;
100 }
101
setTransformationSceneToScreen(const drawing::HomogenMatrix & rMatrix)102 void PlottingPositionHelper::setTransformationSceneToScreen( const drawing::HomogenMatrix& rMatrix)
103 {
104 m_aMatrixScreenToScene = HomogenMatrixToB3DHomMatrix(rMatrix);
105 m_xTransformationLogicToScene = NULL;
106 }
107
setScales(const std::vector<ExplicitScaleData> & rScales,bool bSwapXAndYAxis)108 void PlottingPositionHelper::setScales( const std::vector< ExplicitScaleData >& rScales, bool bSwapXAndYAxis )
109 {
110 m_aScales = rScales;
111 m_bSwapXAndY = bSwapXAndYAxis;
112 m_xTransformationLogicToScene = NULL;
113 }
getScales() const114 const std::vector< ExplicitScaleData >& PlottingPositionHelper::getScales() const
115 {
116 return m_aScales;
117 }
118
getTransformationScaledLogicToScene() const119 uno::Reference< XTransformation > PlottingPositionHelper::getTransformationScaledLogicToScene() const
120 {
121 //this is a standard transformation for a cartesian coordinate system
122
123 //transformation from 2) to 4) //@todo 2) and 4) need a ink to a document
124
125 //we need to apply this transformation to each geometric object because of a bug/problem
126 //of the old drawing layer (the UNO_NAME_3D_EXTRUDE_DEPTH is an integer value instead of an double )
127 if(!m_xTransformationLogicToScene.is())
128 {
129 ::basegfx::B3DHomMatrix aMatrix;
130 double MinX = getLogicMinX();
131 double MinY = getLogicMinY();
132 double MinZ = getLogicMinZ();
133 double MaxX = getLogicMaxX();
134 double MaxY = getLogicMaxY();
135 double MaxZ = getLogicMaxZ();
136
137 AxisOrientation nXAxisOrientation = m_aScales[0].Orientation;
138 AxisOrientation nYAxisOrientation = m_aScales[1].Orientation;
139 AxisOrientation nZAxisOrientation = m_aScales[2].Orientation;
140
141 //apply scaling
142 doUnshiftedLogicScaling( &MinX, &MinY, &MinZ );
143 doUnshiftedLogicScaling( &MaxX, &MaxY, &MaxZ);
144
145 if(m_bSwapXAndY)
146 {
147 std::swap(MinX,MinY);
148 std::swap(MaxX,MaxY);
149 std::swap(nXAxisOrientation,nYAxisOrientation);
150 }
151
152 double fWidthX = MaxX - MinX;
153 double fWidthY = MaxY - MinY;
154 double fWidthZ = MaxZ - MinZ;
155
156 double fScaleDirectionX = AxisOrientation_MATHEMATICAL==nXAxisOrientation ? 1.0 : -1.0;
157 double fScaleDirectionY = AxisOrientation_MATHEMATICAL==nYAxisOrientation ? 1.0 : -1.0;
158 double fScaleDirectionZ = AxisOrientation_MATHEMATICAL==nZAxisOrientation ? -1.0 : 1.0;
159
160 double fScaleX = fScaleDirectionX*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthX;
161 double fScaleY = fScaleDirectionY*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthY;
162 double fScaleZ = fScaleDirectionZ*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthZ;
163
164 aMatrix.scale(fScaleX, fScaleY, fScaleZ);
165
166 if( AxisOrientation_MATHEMATICAL==nXAxisOrientation )
167 aMatrix.translate(-MinX*fScaleX, 0.0, 0.0);
168 else
169 aMatrix.translate(-MaxX*fScaleX, 0.0, 0.0);
170 if( AxisOrientation_MATHEMATICAL==nYAxisOrientation )
171 aMatrix.translate(0.0, -MinY*fScaleY, 0.0);
172 else
173 aMatrix.translate(0.0, -MaxY*fScaleY, 0.0);
174 if( AxisOrientation_MATHEMATICAL==nZAxisOrientation )
175 aMatrix.translate(0.0, 0.0, -MaxZ*fScaleZ);//z direction in draw is reverse mathematical direction
176 else
177 aMatrix.translate(0.0, 0.0, -MinZ*fScaleZ);
178
179 aMatrix = m_aMatrixScreenToScene*aMatrix;
180
181 m_xTransformationLogicToScene = new Linear3DTransformation(B3DHomMatrixToHomogenMatrix( aMatrix ),m_bSwapXAndY);
182 }
183 return m_xTransformationLogicToScene;
184 }
185
transformLogicToScene(double fX,double fY,double fZ,bool bClip) const186 drawing::Position3D PlottingPositionHelper::transformLogicToScene(
187 double fX, double fY, double fZ, bool bClip ) const
188 {
189 this->doLogicScaling( &fX,&fY,&fZ );
190 if(bClip)
191 this->clipScaledLogicValues( &fX,&fY,&fZ );
192
193 return this->transformScaledLogicToScene( fX, fY, fZ, false );
194 }
195
transformScaledLogicToScene(double fX,double fY,double fZ,bool bClip) const196 drawing::Position3D PlottingPositionHelper::transformScaledLogicToScene(
197 double fX, double fY, double fZ, bool bClip ) const
198 {
199 if( bClip )
200 this->clipScaledLogicValues( &fX,&fY,&fZ );
201
202 drawing::Position3D aPos( fX, fY, fZ);
203
204 uno::Reference< XTransformation > xTransformation =
205 this->getTransformationScaledLogicToScene();
206 uno::Sequence< double > aSeq =
207 xTransformation->transform( Position3DToSequence(aPos) );
208 return SequenceToPosition3D(aSeq);
209 }
210
transformSceneToScreenPosition(const drawing::Position3D & rScenePosition3D,const uno::Reference<drawing::XShapes> & xSceneTarget,ShapeFactory * pShapeFactory,sal_Int32 nDimensionCount)211 awt::Point PlottingPositionHelper::transformSceneToScreenPosition( const drawing::Position3D& rScenePosition3D
212 , const uno::Reference< drawing::XShapes >& xSceneTarget
213 , ShapeFactory* pShapeFactory
214 , sal_Int32 nDimensionCount )
215 {
216 //@todo would like to have a cheaper method to do this transformation
217 awt::Point aScreenPoint( static_cast<sal_Int32>(rScenePosition3D.PositionX), static_cast<sal_Int32>(rScenePosition3D.PositionY) );
218
219 //transformation from scene to screen (only neccessary for 3D):
220 if(3==nDimensionCount)
221 {
222 //create 3D anchor shape
223 tPropertyNameMap aDummyPropertyNameMap;
224 uno::Reference< drawing::XShape > xShape3DAnchor = pShapeFactory->createCube( xSceneTarget
225 , rScenePosition3D,drawing::Direction3D(1,1,1)
226 , 0, 0, aDummyPropertyNameMap);
227 //get 2D position from xShape3DAnchor
228 aScreenPoint = xShape3DAnchor->getPosition();
229 xSceneTarget->remove(xShape3DAnchor);
230 }
231 return aScreenPoint;
232 }
233
transformScaledLogicToScene(drawing::PolyPolygonShape3D & rPolygon) const234 void PlottingPositionHelper::transformScaledLogicToScene( drawing::PolyPolygonShape3D& rPolygon ) const
235 {
236 drawing::Position3D aScenePosition;
237 for( sal_Int32 nS = rPolygon.SequenceX.getLength(); nS--;)
238 {
239 drawing::DoubleSequence& xValues = rPolygon.SequenceX[nS];
240 drawing::DoubleSequence& yValues = rPolygon.SequenceY[nS];
241 drawing::DoubleSequence& zValues = rPolygon.SequenceZ[nS];
242 for( sal_Int32 nP = xValues.getLength(); nP--; )
243 {
244 double& fX = xValues[nP];
245 double& fY = yValues[nP];
246 double& fZ = zValues[nP];
247 aScenePosition = this->transformScaledLogicToScene( fX,fY,fZ,true );
248 fX = aScenePosition.PositionX;
249 fY = aScenePosition.PositionY;
250 fZ = aScenePosition.PositionZ;
251 }
252 }
253 }
254
255
clipScaledLogicValues(double * pX,double * pY,double * pZ) const256 void PlottingPositionHelper::clipScaledLogicValues( double* pX, double* pY, double* pZ ) const
257 {
258 //get logic clip values:
259 double MinX = getLogicMinX();
260 double MinY = getLogicMinY();
261 double MinZ = getLogicMinZ();
262 double MaxX = getLogicMaxX();
263 double MaxY = getLogicMaxY();
264 double MaxZ = getLogicMaxZ();
265
266 //apply scaling
267 doUnshiftedLogicScaling( &MinX, &MinY, &MinZ );
268 doUnshiftedLogicScaling( &MaxX, &MaxY, &MaxZ);
269
270 if(pX)
271 {
272 if( *pX < MinX )
273 *pX = MinX;
274 else if( *pX > MaxX )
275 *pX = MaxX;
276 }
277 if(pY)
278 {
279 if( *pY < MinY )
280 *pY = MinY;
281 else if( *pY > MaxY )
282 *pY = MaxY;
283 }
284 if(pZ)
285 {
286 if( *pZ < MinZ )
287 *pZ = MinZ;
288 else if( *pZ > MaxZ )
289 *pZ = MaxZ;
290 }
291 }
292
getScaledLogicClipDoubleRect() const293 basegfx::B2DRectangle PlottingPositionHelper::getScaledLogicClipDoubleRect() const
294 {
295 //get logic clip values:
296 double MinX = getLogicMinX();
297 double MinY = getLogicMinY();
298 double MinZ = getLogicMinZ();
299 double MaxX = getLogicMaxX();
300 double MaxY = getLogicMaxY();
301 double MaxZ = getLogicMaxZ();
302
303 //apply scaling
304 doUnshiftedLogicScaling( &MinX, &MinY, &MinZ );
305 doUnshiftedLogicScaling( &MaxX, &MaxY, &MaxZ);
306
307 basegfx::B2DRectangle aRet( MinX, MaxY, MaxX, MinY );
308 return aRet;
309 }
310
getScaledLogicWidth() const311 drawing::Direction3D PlottingPositionHelper::getScaledLogicWidth() const
312 {
313 drawing::Direction3D aRet;
314
315 double MinX = getLogicMinX();
316 double MinY = getLogicMinY();
317 double MinZ = getLogicMinZ();
318 double MaxX = getLogicMaxX();
319 double MaxY = getLogicMaxY();
320 double MaxZ = getLogicMaxZ();
321
322 doLogicScaling( &MinX, &MinY, &MinZ );
323 doLogicScaling( &MaxX, &MaxY, &MaxZ);
324
325 aRet.DirectionX = MaxX - MinX;
326 aRet.DirectionY = MaxY - MinY;
327 aRet.DirectionZ = MaxZ - MinZ;
328 return aRet;
329 }
330
331 //-----------------------------------------------------------------------------
332 //-----------------------------------------------------------------------------
333 //-----------------------------------------------------------------------------
334
PolarPlottingPositionHelper(NormalAxis eNormalAxis)335 PolarPlottingPositionHelper::PolarPlottingPositionHelper( NormalAxis eNormalAxis )
336 : m_fRadiusOffset(0.0)
337 , m_fAngleDegreeOffset(90.0)
338 , m_aUnitCartesianToScene()
339 , m_eNormalAxis(eNormalAxis)
340 {
341 m_bMaySkipPointsInRegressionCalculation = false;
342 }
343
PolarPlottingPositionHelper(const PolarPlottingPositionHelper & rSource)344 PolarPlottingPositionHelper::PolarPlottingPositionHelper( const PolarPlottingPositionHelper& rSource )
345 : PlottingPositionHelper(rSource)
346 , m_fRadiusOffset( rSource.m_fRadiusOffset )
347 , m_fAngleDegreeOffset( rSource.m_fAngleDegreeOffset )
348 , m_aUnitCartesianToScene( rSource.m_aUnitCartesianToScene )
349 , m_eNormalAxis( rSource.m_eNormalAxis )
350 {
351 }
352
~PolarPlottingPositionHelper()353 PolarPlottingPositionHelper::~PolarPlottingPositionHelper()
354 {
355 }
356
clone() const357 PlottingPositionHelper* PolarPlottingPositionHelper::clone() const
358 {
359 PolarPlottingPositionHelper* pRet = new PolarPlottingPositionHelper(*this);
360 return pRet;
361 }
362
setTransformationSceneToScreen(const drawing::HomogenMatrix & rMatrix)363 void PolarPlottingPositionHelper::setTransformationSceneToScreen( const drawing::HomogenMatrix& rMatrix)
364 {
365 PlottingPositionHelper::setTransformationSceneToScreen( rMatrix);
366 m_aUnitCartesianToScene =impl_calculateMatrixUnitCartesianToScene( m_aMatrixScreenToScene );
367 }
setScales(const std::vector<ExplicitScaleData> & rScales,bool bSwapXAndYAxis)368 void PolarPlottingPositionHelper::setScales( const std::vector< ExplicitScaleData >& rScales, bool bSwapXAndYAxis )
369 {
370 PlottingPositionHelper::setScales( rScales, bSwapXAndYAxis );
371 m_aUnitCartesianToScene =impl_calculateMatrixUnitCartesianToScene( m_aMatrixScreenToScene );
372 }
373
impl_calculateMatrixUnitCartesianToScene(const::basegfx::B3DHomMatrix & rMatrixScreenToScene) const374 ::basegfx::B3DHomMatrix PolarPlottingPositionHelper::impl_calculateMatrixUnitCartesianToScene( const ::basegfx::B3DHomMatrix& rMatrixScreenToScene ) const
375 {
376 ::basegfx::B3DHomMatrix aRet;
377
378 if( m_aScales.empty() )
379 return aRet;
380
381 double fTranslate =1.0;
382 double fScale =FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0;
383
384 double fTranslateLogicZ =fTranslate;
385 double fScaleLogicZ =fScale;
386 {
387 double fScaleDirectionZ = AxisOrientation_MATHEMATICAL==m_aScales[2].Orientation ? 1.0 : -1.0;
388 double MinZ = getLogicMinZ();
389 double MaxZ = getLogicMaxZ();
390 doLogicScaling( 0, 0, &MinZ );
391 doLogicScaling( 0, 0, &MaxZ );
392 double fWidthZ = MaxZ - MinZ;
393
394 if( AxisOrientation_MATHEMATICAL==m_aScales[2].Orientation )
395 fTranslateLogicZ=MinZ;
396 else
397 fTranslateLogicZ=MaxZ;
398 fScaleLogicZ = fScaleDirectionZ*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthZ;
399 }
400
401 double fTranslateX = fTranslate;
402 double fTranslateY = fTranslate;
403 double fTranslateZ = fTranslate;
404
405 double fScaleX = fScale;
406 double fScaleY = fScale;
407 double fScaleZ = fScale;
408
409 switch(m_eNormalAxis)
410 {
411 case NormalAxis_X:
412 {
413 fTranslateX = fTranslateLogicZ;
414 fScaleX = fScaleLogicZ;
415 }
416 break;
417 case NormalAxis_Y:
418 {
419 fTranslateY = fTranslateLogicZ;
420 fScaleY = fScaleLogicZ;
421 }
422 break;
423 default: //NormalAxis_Z:
424 {
425 fTranslateZ = fTranslateLogicZ;
426 fScaleZ = fScaleLogicZ;
427 }
428 break;
429 }
430
431 aRet.translate(fTranslateX, fTranslateY, fTranslateZ);//x first
432 aRet.scale(fScaleX, fScaleY, fScaleZ);//x first
433
434 aRet = rMatrixScreenToScene * aRet;
435 return aRet;
436 }
437
getUnitCartesianToScene() const438 ::basegfx::B3DHomMatrix PolarPlottingPositionHelper::getUnitCartesianToScene() const
439 {
440 return m_aUnitCartesianToScene;
441 }
442
getTransformationScaledLogicToScene() const443 uno::Reference< XTransformation > PolarPlottingPositionHelper::getTransformationScaledLogicToScene() const
444 {
445 if( !m_xTransformationLogicToScene.is() )
446 m_xTransformationLogicToScene = new VPolarTransformation(*this);
447 return m_xTransformationLogicToScene;
448 }
449
getWidthAngleDegree(double & fStartLogicValueOnAngleAxis,double & fEndLogicValueOnAngleAxis) const450 double PolarPlottingPositionHelper::getWidthAngleDegree( double& fStartLogicValueOnAngleAxis, double& fEndLogicValueOnAngleAxis ) const
451 {
452 const ExplicitScaleData& rAngleScale = m_bSwapXAndY ? m_aScales[1] : m_aScales[0];
453 if( AxisOrientation_MATHEMATICAL != rAngleScale.Orientation )
454 {
455 double fHelp = fEndLogicValueOnAngleAxis;
456 fEndLogicValueOnAngleAxis = fStartLogicValueOnAngleAxis;
457 fStartLogicValueOnAngleAxis = fHelp;
458 }
459
460 double fStartAngleDegree = this->transformToAngleDegree( fStartLogicValueOnAngleAxis );
461 double fEndAngleDegree = this->transformToAngleDegree( fEndLogicValueOnAngleAxis );
462 double fWidthAngleDegree = fEndAngleDegree - fStartAngleDegree;
463
464 if( ::rtl::math::approxEqual( fStartAngleDegree, fEndAngleDegree )
465 && !::rtl::math::approxEqual( fStartLogicValueOnAngleAxis, fEndLogicValueOnAngleAxis ) )
466 fWidthAngleDegree = 360.0;
467
468 while(fWidthAngleDegree<0.0)
469 fWidthAngleDegree+=360.0;
470 while(fWidthAngleDegree>360.0)
471 fWidthAngleDegree-=360.0;
472
473 return fWidthAngleDegree;
474 }
475
transformToAngleDegree(double fLogicValueOnAngleAxis,bool bDoScaling) const476 double PolarPlottingPositionHelper::transformToAngleDegree( double fLogicValueOnAngleAxis, bool bDoScaling ) const
477 {
478 double fRet=0.0;
479
480 double fAxisAngleScaleDirection = 1.0;
481 {
482 const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[1] : m_aScales[0];
483 if(AxisOrientation_MATHEMATICAL != rScale.Orientation)
484 fAxisAngleScaleDirection *= -1.0;
485 }
486
487 double MinAngleValue = 0.0;
488 double MaxAngleValue = 0.0;
489 {
490 double MinX = getLogicMinX();
491 double MinY = getLogicMinY();
492 double MaxX = getLogicMaxX();
493 double MaxY = getLogicMaxY();
494 double MinZ = getLogicMinZ();
495 double MaxZ = getLogicMaxZ();
496
497 doLogicScaling( &MinX, &MinY, &MinZ );
498 doLogicScaling( &MaxX, &MaxY, &MaxZ);
499
500 MinAngleValue = m_bSwapXAndY ? MinY : MinX;
501 MaxAngleValue = m_bSwapXAndY ? MaxY : MaxX;
502 }
503
504 double fScaledLogicAngleValue = 0.0;
505 if(bDoScaling)
506 {
507 double fX = m_bSwapXAndY ? getLogicMaxX() : fLogicValueOnAngleAxis;
508 double fY = m_bSwapXAndY ? fLogicValueOnAngleAxis : getLogicMaxY();
509 double fZ = getLogicMaxZ();
510 clipLogicValues( &fX, &fY, &fZ );
511 doLogicScaling( &fX, &fY, &fZ );
512 fScaledLogicAngleValue = m_bSwapXAndY ? fY : fX;
513 }
514 else
515 fScaledLogicAngleValue = fLogicValueOnAngleAxis;
516
517 fRet = m_fAngleDegreeOffset
518 + fAxisAngleScaleDirection*(fScaledLogicAngleValue-MinAngleValue)*360.0
519 /fabs(MaxAngleValue-MinAngleValue);
520 while(fRet>360.0)
521 fRet-=360.0;
522 while(fRet<0)
523 fRet+=360.0;
524 return fRet;
525 }
526
transformToRadius(double fLogicValueOnRadiusAxis,bool bDoScaling) const527 double PolarPlottingPositionHelper::transformToRadius( double fLogicValueOnRadiusAxis, bool bDoScaling ) const
528 {
529 double fNormalRadius = 0.0;
530 {
531 double fScaledLogicRadiusValue = 0.0;
532 double fX = m_bSwapXAndY ? fLogicValueOnRadiusAxis: getLogicMaxX();
533 double fY = m_bSwapXAndY ? getLogicMaxY() : fLogicValueOnRadiusAxis;
534 if(bDoScaling)
535 doLogicScaling( &fX, &fY, 0 );
536
537 fScaledLogicRadiusValue = m_bSwapXAndY ? fX : fY;
538
539 bool bMinIsInnerRadius = true;
540 const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[0] : m_aScales[1];
541 if(AxisOrientation_MATHEMATICAL != rScale.Orientation)
542 bMinIsInnerRadius = false;
543
544 double fInnerScaledLogicRadius=0.0;
545 double fOuterScaledLogicRadius=0.0;
546 {
547 double MinX = getLogicMinX();
548 double MinY = getLogicMinY();
549 doLogicScaling( &MinX, &MinY, 0 );
550 double MaxX = getLogicMaxX();
551 double MaxY = getLogicMaxY();
552 doLogicScaling( &MaxX, &MaxY, 0 );
553
554 double fMin = m_bSwapXAndY ? MinX : MinY;
555 double fMax = m_bSwapXAndY ? MaxX : MaxY;
556
557 fInnerScaledLogicRadius = bMinIsInnerRadius ? fMin : fMax;
558 fOuterScaledLogicRadius = bMinIsInnerRadius ? fMax : fMin;
559 }
560
561 if( bMinIsInnerRadius )
562 fInnerScaledLogicRadius -= fabs(m_fRadiusOffset);
563 else
564 fInnerScaledLogicRadius += fabs(m_fRadiusOffset);
565 fNormalRadius = (fScaledLogicRadiusValue-fInnerScaledLogicRadius)/(fOuterScaledLogicRadius-fInnerScaledLogicRadius);
566 }
567 return fNormalRadius;
568 }
569
transformLogicToScene(double fX,double fY,double fZ,bool bClip) const570 drawing::Position3D PolarPlottingPositionHelper::transformLogicToScene( double fX, double fY, double fZ, bool bClip ) const
571 {
572 if(bClip)
573 this->clipLogicValues( &fX,&fY,&fZ );
574 double fLogicValueOnAngleAxis = m_bSwapXAndY ? fY : fX;
575 double fLogicValueOnRadiusAxis = m_bSwapXAndY ? fX : fY;
576 return this->transformAngleRadiusToScene( fLogicValueOnAngleAxis, fLogicValueOnRadiusAxis, fZ, true );
577 }
578
transformScaledLogicToScene(double fX,double fY,double fZ,bool bClip) const579 drawing::Position3D PolarPlottingPositionHelper::transformScaledLogicToScene( double fX, double fY, double fZ, bool bClip ) const
580 {
581 if(bClip)
582 this->clipScaledLogicValues( &fX,&fY,&fZ );
583 double fLogicValueOnAngleAxis = m_bSwapXAndY ? fY : fX;
584 double fLogicValueOnRadiusAxis = m_bSwapXAndY ? fX : fY;
585 return this->transformAngleRadiusToScene( fLogicValueOnAngleAxis, fLogicValueOnRadiusAxis, fZ, false );
586 }
transformUnitCircleToScene(double fUnitAngleDegree,double fUnitRadius,double fLogicZ,bool) const587 drawing::Position3D PolarPlottingPositionHelper::transformUnitCircleToScene( double fUnitAngleDegree, double fUnitRadius
588 , double fLogicZ, bool /* bDoScaling */ ) const
589 {
590 double fAnglePi = fUnitAngleDegree*F_PI/180.0;
591
592 double fX=fUnitRadius*rtl::math::cos(fAnglePi);
593 double fY=fUnitRadius*rtl::math::sin(fAnglePi);
594 double fZ=fLogicZ;
595
596 switch(m_eNormalAxis)
597 {
598 case NormalAxis_X:
599 std::swap(fX,fZ);
600 break;
601 case NormalAxis_Y:
602 std::swap(fY,fZ);
603 fZ*=-1;
604 break;
605 default: //NormalAxis_Z
606 break;
607 }
608
609 //!! applying matrix to vector does ignore translation, so it is important to use a B3DPoint here instead of B3DVector
610 ::basegfx::B3DPoint aPoint(fX,fY,fZ);
611 ::basegfx::B3DPoint aRet = m_aUnitCartesianToScene * aPoint;
612 return B3DPointToPosition3D(aRet);
613 }
614
transformAngleRadiusToScene(double fLogicValueOnAngleAxis,double fLogicValueOnRadiusAxis,double fLogicZ,bool bDoScaling) const615 drawing::Position3D PolarPlottingPositionHelper::transformAngleRadiusToScene( double fLogicValueOnAngleAxis, double fLogicValueOnRadiusAxis, double fLogicZ, bool bDoScaling ) const
616 {
617 double fUnitAngleDegree = this->transformToAngleDegree(fLogicValueOnAngleAxis,bDoScaling);
618 double fUnitRadius = this->transformToRadius(fLogicValueOnRadiusAxis,bDoScaling);
619
620 return transformUnitCircleToScene( fUnitAngleDegree, fUnitRadius, fLogicZ, bDoScaling );
621 }
622
623 #ifdef NOTYET
getInnerLogicRadius() const624 double PolarPlottingPositionHelper::getInnerLogicRadius() const
625 {
626 const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[0] : m_aScales[1];
627 if( AxisOrientation_MATHEMATICAL==rScale.Orientation )
628 return rScale.Minimum;
629 else
630 return rScale.Maximum;
631 }
632 #endif
633
getOuterLogicRadius() const634 double PolarPlottingPositionHelper::getOuterLogicRadius() const
635 {
636 const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[0] : m_aScales[1];
637 if( AxisOrientation_MATHEMATICAL==rScale.Orientation )
638 return rScale.Maximum;
639 else
640 return rScale.Minimum;
641 }
642
isPercentY() const643 bool PlottingPositionHelper::isPercentY() const
644 {
645 return m_aScales[1].AxisType==AxisType::PERCENT;
646 }
647
getBaseValueY() const648 double PlottingPositionHelper::getBaseValueY() const
649 {
650 return m_aScales[1].Origin;
651 }
652
setTimeResolution(long nTimeResolution,const Date & rNullDate)653 void PlottingPositionHelper::setTimeResolution( long nTimeResolution, const Date& rNullDate )
654 {
655 m_nTimeResolution = nTimeResolution;
656 m_aNullDate = rNullDate;
657
658 //adapt category width
659 double fCategoryWidth = 1.0;
660 if( !m_aScales.empty() )
661 {
662 if( m_aScales[0].AxisType == ::com::sun::star::chart2::AxisType::DATE )
663 {
664 m_bDateAxis = true;
665 if( nTimeResolution == ::com::sun::star::chart::TimeUnit::YEAR )
666 {
667 const double fMonthCount = 12.0;//todo: this depends on the DateScaling and must be adjusted in case we use more generic calendars in future
668 fCategoryWidth = fMonthCount;
669 }
670 }
671 }
672 setScaledCategoryWidth(fCategoryWidth);
673 }
674
setScaledCategoryWidth(double fScaledCategoryWidth)675 void PlottingPositionHelper::setScaledCategoryWidth( double fScaledCategoryWidth )
676 {
677 m_fScaledCategoryWidth = fScaledCategoryWidth;
678 }
AllowShiftXAxisPos(bool bAllowShift)679 void PlottingPositionHelper::AllowShiftXAxisPos( bool bAllowShift )
680 {
681 m_bAllowShiftXAxisPos = bAllowShift;
682 }
AllowShiftZAxisPos(bool bAllowShift)683 void PlottingPositionHelper::AllowShiftZAxisPos( bool bAllowShift )
684 {
685 m_bAllowShiftZAxisPos = bAllowShift;
686 }
687
688 /*
689 // ____ XTransformation ____
690 uno::Sequence< double > SAL_CALL PolarPlottingPositionHelper::transform(
691 const uno::Sequence< double >& rSourceValues )
692 throw (uno::RuntimeException, lang::IllegalArgumentException)
693 {
694 uno::Sequence< double > aSourceValues(3);
695 return aSourceValues;
696 }
697
698 sal_Int32 SAL_CALL PolarPlottingPositionHelper::getSourceDimension() throw (uno::RuntimeException)
699 {
700 return 3;
701 }
702
703 sal_Int32 SAL_CALL PolarPlottingPositionHelper::getTargetDimension() throw (uno::RuntimeException)
704 {
705 return 3;
706 }
707 */
708
709 //.............................................................................
710 } //namespace chart
711 //.............................................................................
712