fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / chart2 / source / view / axes / VCoordinateSystem.cxx
blob9d7ebf2994b9cab13a7315ebd76d8cf503aa0ad9
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 .
20 #include "VCoordinateSystem.hxx"
21 #include "VCartesianCoordinateSystem.hxx"
22 #include "VPolarCoordinateSystem.hxx"
23 #include "ScaleAutomatism.hxx"
24 #include "VSeriesPlotter.hxx"
25 #include "AbstractShapeFactory.hxx"
26 #include "servicenames_coosystems.hxx"
27 #include "macros.hxx"
28 #include "AxisIndexDefines.hxx"
29 #include "ObjectIdentifier.hxx"
30 #include "ExplicitCategoriesProvider.hxx"
31 #include "AxisHelper.hxx"
32 #include "ContainerHelper.hxx"
33 #include "VAxisBase.hxx"
34 #include "ViewDefines.hxx"
35 #include "DataSeriesHelper.hxx"
36 #include "defines.hxx"
37 #include "chartview/ExplicitValueProvider.hxx"
38 #include <com/sun/star/chart2/AxisType.hpp>
39 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
40 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
42 #include <rtl/math.hxx>
44 namespace chart
46 using namespace ::com::sun::star;
47 using namespace ::com::sun::star::chart2;
48 using ::com::sun::star::uno::Reference;
49 using ::com::sun::star::uno::Sequence;
51 VCoordinateSystem* VCoordinateSystem::createCoordinateSystem(
52 const Reference< XCoordinateSystem >& xCooSysModel )
54 if( !xCooSysModel.is() )
55 return 0;
57 OUString aViewServiceName = xCooSysModel->getViewServiceName();
59 //@todo: in future the coordinatesystems should be instantiated via service factory
60 VCoordinateSystem* pRet=NULL;
61 if( aViewServiceName == CHART2_COOSYSTEM_CARTESIAN_VIEW_SERVICE_NAME )
62 pRet = new VCartesianCoordinateSystem(xCooSysModel);
63 else if( aViewServiceName == CHART2_COOSYSTEM_POLAR_VIEW_SERVICE_NAME )
64 pRet = new VPolarCoordinateSystem(xCooSysModel);
65 if(!pRet)
66 pRet = new VCoordinateSystem(xCooSysModel);
67 return pRet;
70 VCoordinateSystem::VCoordinateSystem( const Reference< XCoordinateSystem >& xCooSys )
71 : m_xCooSysModel(xCooSys)
72 , m_xLogicTargetForGrids(0)
73 , m_xLogicTargetForAxes(0)
74 , m_xFinalTarget(0)
75 , m_xShapeFactory(0)
76 , m_aMatrixSceneToScreen()
77 , m_eLeftWallPos(CuboidPlanePosition_Left)
78 , m_eBackWallPos(CuboidPlanePosition_Back)
79 , m_eBottomPos(CuboidPlanePosition_Bottom)
80 , m_aMergedMinMaxSupplier()
81 , m_aExplicitScales(3)
82 , m_aExplicitIncrements(3)
83 , m_apExplicitCategoriesProvider(NULL)
85 if( !m_xCooSysModel.is() || m_xCooSysModel->getDimension()<3 )
87 m_aExplicitScales[2].Minimum = 1.0;
88 m_aExplicitScales[2].Maximum = 2.0;
89 m_aExplicitScales[2].Orientation = AxisOrientation_MATHEMATICAL;
92 VCoordinateSystem::~VCoordinateSystem()
96 void VCoordinateSystem::initPlottingTargets( const Reference< drawing::XShapes >& xLogicTarget
97 , const Reference< drawing::XShapes >& xFinalTarget
98 , const Reference< lang::XMultiServiceFactory >& xShapeFactory
99 , Reference< drawing::XShapes >& xLogicTargetForSeriesBehindAxis )
100 throw (uno::RuntimeException)
102 OSL_PRECOND(xLogicTarget.is()&&xFinalTarget.is()&&xShapeFactory.is(),"no proper initialization parameters");
103 //is only allowed to be called once
105 sal_Int32 nDimensionCount = m_xCooSysModel->getDimension();
106 //create group shape for grids first thus axes are always painted above grids
107 AbstractShapeFactory* pShapeFactory = AbstractShapeFactory::getOrCreateShapeFactory(xShapeFactory);
108 if(nDimensionCount==2)
110 //create and add to target
111 m_xLogicTargetForGrids = pShapeFactory->createGroup2D( xLogicTarget );
112 xLogicTargetForSeriesBehindAxis = pShapeFactory->createGroup2D( xLogicTarget );
113 m_xLogicTargetForAxes = pShapeFactory->createGroup2D( xLogicTarget );
115 else
117 //create and added to target
118 m_xLogicTargetForGrids = pShapeFactory->createGroup3D( xLogicTarget );
119 xLogicTargetForSeriesBehindAxis = pShapeFactory->createGroup3D( xLogicTarget );
120 m_xLogicTargetForAxes = pShapeFactory->createGroup3D( xLogicTarget );
122 m_xFinalTarget = xFinalTarget;
123 m_xShapeFactory = xShapeFactory;
126 void VCoordinateSystem::setParticle( const OUString& rCooSysParticle )
128 m_aCooSysParticle = rCooSysParticle;
131 void VCoordinateSystem::setTransformationSceneToScreen(
132 const drawing::HomogenMatrix& rMatrix )
134 m_aMatrixSceneToScreen = rMatrix;
136 //correct transformation for axis
137 tVAxisMap::iterator aIt( m_aAxisMap.begin() );
138 tVAxisMap::const_iterator aEnd( m_aAxisMap.end() );
139 for( ; aIt != aEnd; ++aIt )
141 VAxisBase* pVAxis = aIt->second.get();
142 if( pVAxis )
144 if(2==pVAxis->getDimensionCount())
145 pVAxis->setTransformationSceneToScreen( m_aMatrixSceneToScreen );
150 //better performance for big data
151 uno::Sequence< sal_Int32 > VCoordinateSystem::getCoordinateSystemResolution(
152 const awt::Size& rPageSize, const awt::Size& rPageResolution )
154 uno::Sequence< sal_Int32 > aResolution(2);
156 sal_Int32 nDimensionCount = m_xCooSysModel->getDimension();
157 if(nDimensionCount>2)
158 aResolution.realloc(nDimensionCount);
159 sal_Int32 nN = 0;
160 for( nN = 0 ;nN<aResolution.getLength(); nN++ )
161 aResolution[nN]=1000;
163 ::basegfx::B3DTuple aScale( BaseGFXHelper::GetScaleFromMatrix(
164 BaseGFXHelper::HomogenMatrixToB3DHomMatrix(
165 m_aMatrixSceneToScreen ) ) );
167 double fCoosysWidth = static_cast< double >( fabs(aScale.getX()*FIXED_SIZE_FOR_3D_CHART_VOLUME));
168 double fCoosysHeight = static_cast< double >( fabs(aScale.getY()*FIXED_SIZE_FOR_3D_CHART_VOLUME));
170 double fPageWidth = rPageSize.Width;
171 double fPageHeight = rPageSize.Height;
173 //factor 2 to avoid rounding problems
174 sal_Int32 nXResolution = static_cast<sal_Int32>(2.0*static_cast<double>(rPageResolution.Width)*fCoosysWidth/fPageWidth);
175 sal_Int32 nYResolution = static_cast<sal_Int32>(2.0*static_cast<double>(rPageResolution.Height)*fCoosysHeight/fPageHeight);
177 if( nXResolution < 10 )
178 nXResolution = 10;
179 if( nYResolution < 10 )
180 nYResolution = 10;
182 if( this->getPropertySwapXAndYAxis() )
183 std::swap(nXResolution,nYResolution);
185 //2D
186 if( 2 == aResolution.getLength() )
188 aResolution[0]=nXResolution;
189 aResolution[1]=nYResolution;
191 else
193 //this maybe can be optimized further ...
194 sal_Int32 nMaxResolution = std::max( nXResolution, nYResolution );
195 nMaxResolution*=2;
196 for( nN = 0 ;nN<aResolution.getLength(); nN++ )
197 aResolution[nN]=nMaxResolution;
200 return aResolution;
203 Reference< XAxis > VCoordinateSystem::getAxisByDimension( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex ) const
205 if( m_xCooSysModel.is() )
206 return m_xCooSysModel->getAxisByDimension( nDimensionIndex, nAxisIndex );
207 return 0;
210 Sequence< Reference< beans::XPropertySet > > VCoordinateSystem::getGridListFromAxis( const Reference< XAxis >& xAxis )
212 std::vector< Reference< beans::XPropertySet > > aRet;
214 if( xAxis.is() )
216 aRet.push_back( xAxis->getGridProperties() );
217 std::vector< Reference< beans::XPropertySet > > aSubGrids( ContainerHelper::SequenceToVector( xAxis->getSubGridProperties() ) );
218 aRet.insert( aRet.end(), aSubGrids.begin(), aSubGrids.end() );
221 return ContainerHelper::ContainerToSequence( aRet );
224 void VCoordinateSystem::impl_adjustDimension( sal_Int32& rDimensionIndex )
226 if( rDimensionIndex<0 )
227 rDimensionIndex=0;
228 if( rDimensionIndex>2 )
229 rDimensionIndex=2;
232 void VCoordinateSystem::impl_adjustDimensionAndIndex( sal_Int32& rDimensionIndex, sal_Int32& rAxisIndex ) const
234 impl_adjustDimension( rDimensionIndex );
236 if( rAxisIndex < 0 || rAxisIndex > this->getMaximumAxisIndexByDimension(rDimensionIndex) )
237 rAxisIndex = 0;
240 void VCoordinateSystem::setExplicitCategoriesProvider( ExplicitCategoriesProvider* pExplicitCategoriesProvider /*takes ownership*/ )
242 m_apExplicitCategoriesProvider.reset(pExplicitCategoriesProvider);
245 ExplicitCategoriesProvider* VCoordinateSystem::getExplicitCategoriesProvider()
247 return m_apExplicitCategoriesProvider.get();
250 std::vector< ExplicitScaleData > VCoordinateSystem::getExplicitScales( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex ) const
252 std::vector< ExplicitScaleData > aRet(m_aExplicitScales);
254 impl_adjustDimensionAndIndex( nDimensionIndex, nAxisIndex );
255 aRet[nDimensionIndex]=this->getExplicitScale( nDimensionIndex, nAxisIndex );
257 return aRet;
260 std::vector< ExplicitIncrementData > VCoordinateSystem::getExplicitIncrements( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex ) const
262 std::vector< ExplicitIncrementData > aRet(m_aExplicitIncrements);
264 impl_adjustDimensionAndIndex( nDimensionIndex, nAxisIndex );
265 aRet[nDimensionIndex]=this->getExplicitIncrement( nDimensionIndex, nAxisIndex );
267 return aRet;
270 ExplicitScaleData VCoordinateSystem::getExplicitScale( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex ) const
272 ExplicitScaleData aRet;
274 impl_adjustDimensionAndIndex( nDimensionIndex, nAxisIndex );
276 if( nAxisIndex == 0)
278 aRet = m_aExplicitScales[nDimensionIndex];
280 else
282 tFullAxisIndex aFullAxisIndex( nDimensionIndex, nAxisIndex );
283 tFullExplicitScaleMap::const_iterator aIt = m_aSecondaryExplicitScales.find( aFullAxisIndex );
284 if( aIt != m_aSecondaryExplicitScales.end() )
285 aRet = aIt->second;
286 else
287 aRet = m_aExplicitScales[nDimensionIndex];
290 return aRet;
293 ExplicitIncrementData VCoordinateSystem::getExplicitIncrement( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex ) const
295 ExplicitIncrementData aRet;
297 impl_adjustDimensionAndIndex( nDimensionIndex, nAxisIndex );
299 if( nAxisIndex == 0)
301 aRet = m_aExplicitIncrements[nDimensionIndex];
303 else
305 tFullAxisIndex aFullAxisIndex( nDimensionIndex, nAxisIndex );
306 tFullExplicitIncrementMap::const_iterator aIt = m_aSecondaryExplicitIncrements.find( aFullAxisIndex );
307 if( aIt != m_aSecondaryExplicitIncrements.end() )
308 aRet = aIt->second;
309 else
310 aRet = m_aExplicitIncrements[nDimensionIndex];
313 return aRet;
316 OUString VCoordinateSystem::createCIDForAxis( const Reference< chart2::XAxis >& /* xAxis */, sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex )
318 OUString aAxisParticle( ObjectIdentifier::createParticleForAxis( nDimensionIndex, nAxisIndex ) );
319 return ObjectIdentifier::createClassifiedIdentifierForParticles( m_aCooSysParticle, aAxisParticle );
321 OUString VCoordinateSystem::createCIDForGrid( const Reference< chart2::XAxis >& /* xAxis */, sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex )
323 OUString aGridParticle( ObjectIdentifier::createParticleForGrid( nDimensionIndex, nAxisIndex ) );
324 return ObjectIdentifier::createClassifiedIdentifierForParticles( m_aCooSysParticle, aGridParticle );
327 sal_Int32 VCoordinateSystem::getMaximumAxisIndexByDimension( sal_Int32 nDimensionIndex ) const
329 sal_Int32 nRet = 0;
330 tFullExplicitScaleMap::const_iterator aIt = m_aSecondaryExplicitScales.begin();
331 tFullExplicitScaleMap::const_iterator aEnd = m_aSecondaryExplicitScales.end();
332 for(; aIt!=aEnd; ++aIt)
334 if(aIt->first.first==nDimensionIndex)
336 sal_Int32 nLocalIdx = aIt->first.second;
337 if( nRet < nLocalIdx )
338 nRet = nLocalIdx;
341 return nRet;
344 void VCoordinateSystem::createVAxisList(
345 const uno::Reference<chart2::XChartDocument> & /* xChartDoc */
346 , const awt::Size& /* rFontReferenceSize */
347 , const awt::Rectangle& /* rMaximumSpaceForLabels */
352 void VCoordinateSystem::initVAxisInList()
355 void VCoordinateSystem::updateScalesAndIncrementsOnAxes()
359 void VCoordinateSystem::prepareAutomaticAxisScaling( ScaleAutomatism& rScaleAutomatism, sal_Int32 nDimIndex, sal_Int32 nAxisIndex )
361 if( rScaleAutomatism.getScale().AxisType==AxisType::DATE && nDimIndex==0 )
363 // This is a date X dimension. Determine proper time resolution.
364 sal_Int32 nTimeResolution = ::com::sun::star::chart::TimeUnit::MONTH;
365 if( !(rScaleAutomatism.getScale().TimeIncrement.TimeResolution >>= nTimeResolution) )
367 nTimeResolution = m_aMergedMinMaxSupplier.calculateTimeResolutionOnXAxis();
368 rScaleAutomatism.setAutomaticTimeResolution( nTimeResolution );
370 m_aMergedMinMaxSupplier.setTimeResolutionOnXAxis( nTimeResolution, rScaleAutomatism.getNullDate() );
373 double fMin = 0.0;
374 double fMax = 0.0;
375 ::rtl::math::setInf(&fMin, false);
376 ::rtl::math::setInf(&fMax, true);
377 if( 0 == nDimIndex )
379 // x dimension
380 fMin = m_aMergedMinMaxSupplier.getMinimumX();
381 fMax = m_aMergedMinMaxSupplier.getMaximumX();
383 else if( 1 == nDimIndex )
385 // y dimension
386 ExplicitScaleData aScale = getExplicitScale( 0, 0 );
387 fMin = m_aMergedMinMaxSupplier.getMinimumYInRange(aScale.Minimum,aScale.Maximum, nAxisIndex);
388 fMax = m_aMergedMinMaxSupplier.getMaximumYInRange(aScale.Minimum,aScale.Maximum, nAxisIndex);
390 else if( 2 == nDimIndex )
392 // z dimension
393 fMin = m_aMergedMinMaxSupplier.getMinimumZ();
394 fMax = m_aMergedMinMaxSupplier.getMaximumZ();
397 //merge our values with those already contained in rScaleAutomatism
398 rScaleAutomatism.expandValueRange( fMin, fMax );
400 rScaleAutomatism.setAutoScalingOptions(
401 m_aMergedMinMaxSupplier.isExpandBorderToIncrementRhythm( nDimIndex ),
402 m_aMergedMinMaxSupplier.isExpandIfValuesCloseToBorder( nDimIndex ),
403 m_aMergedMinMaxSupplier.isExpandWideValuesToZero( nDimIndex ),
404 m_aMergedMinMaxSupplier.isExpandNarrowValuesTowardZero( nDimIndex ) );
406 VAxisBase* pVAxis = getVAxis(nDimIndex, nAxisIndex);
407 if( pVAxis )
408 rScaleAutomatism.setMaximumAutoMainIncrementCount( pVAxis->estimateMaximumAutoMainIncrementCount() );
411 VAxisBase* VCoordinateSystem::getVAxis( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex )
413 VAxisBase* pRet = 0;
415 tFullAxisIndex aFullAxisIndex( nDimensionIndex, nAxisIndex );
417 tVAxisMap::const_iterator aIt = m_aAxisMap.find( aFullAxisIndex );
418 if( aIt != m_aAxisMap.end() )
419 pRet = aIt->second.get();
421 return pRet;
424 void VCoordinateSystem::setExplicitScaleAndIncrement(
425 sal_Int32 nDimensionIndex
426 , sal_Int32 nAxisIndex
427 , const ExplicitScaleData& rExplicitScale
428 , const ExplicitIncrementData& rExplicitIncrement )
430 impl_adjustDimension( nDimensionIndex );
432 if( nAxisIndex==0 )
434 m_aExplicitScales[nDimensionIndex]=rExplicitScale;
435 m_aExplicitIncrements[nDimensionIndex]=rExplicitIncrement;
437 else
439 tFullAxisIndex aFullAxisIndex( nDimensionIndex, nAxisIndex );
440 m_aSecondaryExplicitScales[aFullAxisIndex] = rExplicitScale;
441 m_aSecondaryExplicitIncrements[aFullAxisIndex] = rExplicitIncrement;
445 void VCoordinateSystem::set3DWallPositions( CuboidPlanePosition eLeftWallPos, CuboidPlanePosition eBackWallPos, CuboidPlanePosition eBottomPos )
447 m_eLeftWallPos = eLeftWallPos;
448 m_eBackWallPos = eBackWallPos;
449 m_eBottomPos = eBottomPos;
452 void VCoordinateSystem::createMaximumAxesLabels()
454 tVAxisMap::iterator aIt( m_aAxisMap.begin() );
455 tVAxisMap::const_iterator aEnd( m_aAxisMap.end() );
456 for( ; aIt != aEnd; ++aIt )
458 VAxisBase* pVAxis = aIt->second.get();
459 if( pVAxis )
461 if(2==pVAxis->getDimensionCount())
462 pVAxis->setTransformationSceneToScreen( m_aMatrixSceneToScreen );
463 pVAxis->createMaximumLabels();
467 void VCoordinateSystem::createAxesLabels()
469 tVAxisMap::iterator aIt( m_aAxisMap.begin() );
470 tVAxisMap::const_iterator aEnd( m_aAxisMap.end() );
471 for( ; aIt != aEnd; ++aIt )
473 VAxisBase* pVAxis = aIt->second.get();
474 if( pVAxis )
476 if(2==pVAxis->getDimensionCount())
477 pVAxis->setTransformationSceneToScreen( m_aMatrixSceneToScreen );
478 pVAxis->createLabels();
483 void VCoordinateSystem::updatePositions()
485 tVAxisMap::iterator aIt( m_aAxisMap.begin() );
486 tVAxisMap::const_iterator aEnd( m_aAxisMap.end() );
487 for( ; aIt != aEnd; ++aIt )
489 VAxisBase* pVAxis = aIt->second.get();
490 if( pVAxis )
492 if(2==pVAxis->getDimensionCount())
493 pVAxis->setTransformationSceneToScreen( m_aMatrixSceneToScreen );
494 pVAxis->updatePositions();
499 void VCoordinateSystem::createAxesShapes()
501 tVAxisMap::iterator aIt( m_aAxisMap.begin() );
502 tVAxisMap::const_iterator aEnd( m_aAxisMap.end() );
503 for( ; aIt != aEnd; ++aIt )
505 VAxisBase* pVAxis = aIt->second.get();
506 if( pVAxis )
508 if(2==pVAxis->getDimensionCount())
509 pVAxis->setTransformationSceneToScreen( m_aMatrixSceneToScreen );
511 tFullAxisIndex aFullAxisIndex = aIt->first;
512 if( aFullAxisIndex.second == 0 )
514 if( aFullAxisIndex.first == 0 )
516 if( AxisType::CATEGORY!=m_aExplicitScales[1].AxisType )
517 pVAxis->setExtraLinePositionAtOtherAxis(
518 m_aExplicitScales[1].Origin );
520 else if( aFullAxisIndex.first == 1 )
522 if( AxisType::CATEGORY!=m_aExplicitScales[0].AxisType )
523 pVAxis->setExtraLinePositionAtOtherAxis(
524 m_aExplicitScales[0].Origin );
528 pVAxis->createShapes();
532 void VCoordinateSystem::createGridShapes()
535 void VCoordinateSystem::addMinimumAndMaximumSupplier( MinimumAndMaximumSupplier* pMinimumAndMaximumSupplier )
537 m_aMergedMinMaxSupplier.addMinimumAndMaximumSupplier(pMinimumAndMaximumSupplier);
540 bool VCoordinateSystem::hasMinimumAndMaximumSupplier( MinimumAndMaximumSupplier* pMinimumAndMaximumSupplier )
542 return m_aMergedMinMaxSupplier.hasMinimumAndMaximumSupplier(pMinimumAndMaximumSupplier);
545 void VCoordinateSystem::clearMinimumAndMaximumSupplierList()
547 m_aMergedMinMaxSupplier.clearMinimumAndMaximumSupplierList();
550 bool VCoordinateSystem::getPropertySwapXAndYAxis() const
552 Reference<beans::XPropertySet> xProp(m_xCooSysModel, uno::UNO_QUERY );
553 bool bSwapXAndY = false;
554 if( xProp.is()) try
556 xProp->getPropertyValue( "SwapXAndYAxis" ) >>= bSwapXAndY;
558 catch( const uno::Exception& e )
560 ASSERT_EXCEPTION( e );
562 return bSwapXAndY;
565 bool VCoordinateSystem::needSeriesNamesForAxis() const
567 return ( m_xCooSysModel.is() && m_xCooSysModel->getDimension() == 3 );
569 void VCoordinateSystem::setSeriesNamesForAxis( const Sequence< OUString >& rSeriesNames )
571 m_aSeriesNamesForZAxis = rSeriesNames;
574 sal_Int32 VCoordinateSystem::getNumberFormatKeyForAxis(
575 const Reference< chart2::XAxis >& xAxis
576 , const Reference<chart2::XChartDocument>& xChartDoc)
578 return ExplicitValueProvider::getExplicitNumberFormatKeyForAxis(
579 xAxis, m_xCooSysModel, xChartDoc);
582 } //namespace chart
584 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */