1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_chart2.hxx"
30 #include "VCoordinateSystem.hxx"
31 #include "VCartesianCoordinateSystem.hxx"
32 #include "VPolarCoordinateSystem.hxx"
33 #include "ScaleAutomatism.hxx"
34 #include "VSeriesPlotter.hxx"
35 #include "ShapeFactory.hxx"
36 #include "servicenames_coosystems.hxx"
37 #include "macros.hxx"
38 #include "AxisIndexDefines.hxx"
39 #include "ObjectIdentifier.hxx"
40 #include "ExplicitCategoriesProvider.hxx"
41 #include "AxisHelper.hxx"
42 #include "ContainerHelper.hxx"
43 #include "VAxisBase.hxx"
44 #include "ViewDefines.hxx"
45 #include "DataSeriesHelper.hxx"
46 #include "chartview/ExplicitValueProvider.hxx"
47 #include <com/sun/star/chart2/AxisType.hpp>
48 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
49 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
50 
51 // header for define DBG_ASSERT
52 #include <tools/debug.hxx>
53 #include <rtl/math.hxx>
54 
55 //.............................................................................
56 namespace chart
57 {
58 //.............................................................................
59 using namespace ::com::sun::star;
60 using namespace ::com::sun::star::chart2;
61 using ::com::sun::star::uno::Reference;
62 using ::com::sun::star::uno::Sequence;
63 
64 VCoordinateSystem* VCoordinateSystem::createCoordinateSystem(
65             const Reference< XCoordinateSystem >& xCooSysModel )
66 {
67     if( !xCooSysModel.is() )
68         return 0;
69 
70     rtl::OUString aViewServiceName = xCooSysModel->getViewServiceName();
71 
72     //@todo: in future the coordinatesystems should be instanciated via service factory
73     VCoordinateSystem* pRet=NULL;
74     if( aViewServiceName.equals( CHART2_COOSYSTEM_CARTESIAN_VIEW_SERVICE_NAME ) )
75         pRet = new VCartesianCoordinateSystem(xCooSysModel);
76     else if( aViewServiceName.equals( CHART2_COOSYSTEM_POLAR_VIEW_SERVICE_NAME ) )
77         pRet = new VPolarCoordinateSystem(xCooSysModel);
78     if(!pRet)
79         pRet = new VCoordinateSystem(xCooSysModel);
80     return pRet;
81 }
82 
83 VCoordinateSystem::VCoordinateSystem( const Reference< XCoordinateSystem >& xCooSys )
84     : m_xCooSysModel(xCooSys)
85     , m_xLogicTargetForGrids(0)
86     , m_xLogicTargetForAxes(0)
87     , m_xFinalTarget(0)
88     , m_xShapeFactory(0)
89     , m_aMatrixSceneToScreen()
90     , m_eLeftWallPos(CuboidPlanePosition_Left)
91     , m_eBackWallPos(CuboidPlanePosition_Back)
92     , m_eBottomPos(CuboidPlanePosition_Bottom)
93     , m_aMergedMinimumAndMaximumSupplier()
94     , m_aExplicitScales(3)
95     , m_aExplicitIncrements(3)
96     , m_apExplicitCategoriesProvider(NULL)
97 {
98     if( !m_xCooSysModel.is() || m_xCooSysModel->getDimension()<3 )
99     {
100         m_aExplicitScales[2].Minimum = 1.0;
101         m_aExplicitScales[2].Maximum = 2.0;
102         m_aExplicitScales[2].Orientation = AxisOrientation_MATHEMATICAL;
103     }
104 }
105 VCoordinateSystem::~VCoordinateSystem()
106 {
107 }
108 
109 void VCoordinateSystem::initPlottingTargets(  const Reference< drawing::XShapes >& xLogicTarget
110 	   , const Reference< drawing::XShapes >& xFinalTarget
111 	   , const Reference< lang::XMultiServiceFactory >& xShapeFactory
112        , Reference< drawing::XShapes >& xLogicTargetForSeriesBehindAxis )
113 	        throw (uno::RuntimeException)
114 {
115     DBG_ASSERT(xLogicTarget.is()&&xFinalTarget.is()&&xShapeFactory.is(),"no proper initialization parameters");
116 	//is only allowed to be called once
117 
118     sal_Int32 nDimensionCount = m_xCooSysModel->getDimension();
119     //create group shape for grids first thus axes are always painted above grids
120     ShapeFactory aShapeFactory(xShapeFactory);
121     if(nDimensionCount==2)
122     {
123         //create and add to target
124         m_xLogicTargetForGrids = aShapeFactory.createGroup2D( xLogicTarget );
125         xLogicTargetForSeriesBehindAxis = aShapeFactory.createGroup2D( xLogicTarget );
126         m_xLogicTargetForAxes = aShapeFactory.createGroup2D( xLogicTarget );
127     }
128     else
129     {
130         //create and added to target
131         m_xLogicTargetForGrids = aShapeFactory.createGroup3D( xLogicTarget );
132         xLogicTargetForSeriesBehindAxis = aShapeFactory.createGroup3D( xLogicTarget );
133         m_xLogicTargetForAxes = aShapeFactory.createGroup3D( xLogicTarget );
134     }
135 	m_xFinalTarget  = xFinalTarget;
136 	m_xShapeFactory = xShapeFactory;
137 }
138 
139 void VCoordinateSystem::setParticle( const rtl::OUString& rCooSysParticle )
140 {
141     m_aCooSysParticle = rCooSysParticle;
142 }
143 
144 void VCoordinateSystem::setTransformationSceneToScreen(
145     const drawing::HomogenMatrix& rMatrix )
146 {
147     m_aMatrixSceneToScreen = rMatrix;
148 
149     //correct transformation for axis
150     tVAxisMap::iterator aIt( m_aAxisMap.begin() );
151     tVAxisMap::const_iterator aEnd( m_aAxisMap.end() );
152     for( ; aIt != aEnd; ++aIt )
153     {
154         VAxisBase* pVAxis = aIt->second.get();
155         if( pVAxis )
156         {
157             if(2==pVAxis->getDimensionCount())
158                 pVAxis->setTransformationSceneToScreen( m_aMatrixSceneToScreen );
159         }
160     }
161 }
162 
163 drawing::HomogenMatrix VCoordinateSystem::getTransformationSceneToScreen()
164 {
165     return m_aMatrixSceneToScreen;
166 }
167 
168 //better performance for big data
169 uno::Sequence< sal_Int32 > VCoordinateSystem::getCoordinateSystemResolution(
170             const awt::Size& rPageSize, const awt::Size& rPageResolution )
171 {
172     uno::Sequence< sal_Int32 > aResolution(2);
173 
174     sal_Int32 nDimensionCount = m_xCooSysModel->getDimension();
175     if(nDimensionCount>2)
176         aResolution.realloc(nDimensionCount);
177     sal_Int32 nN = 0;
178     for( nN = 0 ;nN<aResolution.getLength(); nN++ )
179         aResolution[nN]=1000;
180 
181     ::basegfx::B3DTuple aScale( BaseGFXHelper::GetScaleFromMatrix(
182         BaseGFXHelper::HomogenMatrixToB3DHomMatrix(
183             m_aMatrixSceneToScreen ) ) );
184 
185     double fCoosysWidth = static_cast< double >( fabs(aScale.getX()*FIXED_SIZE_FOR_3D_CHART_VOLUME));
186     double fCoosysHeight = static_cast< double >( fabs(aScale.getY()*FIXED_SIZE_FOR_3D_CHART_VOLUME));
187 
188     double fPageWidth = rPageSize.Width;
189     double fPageHeight = rPageSize.Height;
190 
191     //factor 2 to avoid rounding problems
192     sal_Int32 nXResolution = static_cast<sal_Int32>(2.0*static_cast<double>(rPageResolution.Width)*fCoosysWidth/fPageWidth);
193     sal_Int32 nYResolution = static_cast<sal_Int32>(2.0*static_cast<double>(rPageResolution.Height)*fCoosysHeight/fPageHeight);
194 
195     if( nXResolution < 10 )
196         nXResolution = 10;
197     if( nYResolution < 10 )
198         nYResolution = 10;
199 
200     if( this->getPropertySwapXAndYAxis() )
201         std::swap(nXResolution,nYResolution);
202 
203     //2D
204     if( 2 == aResolution.getLength() )
205     {
206         aResolution[0]=nXResolution;
207         aResolution[1]=nYResolution;
208     }
209     else
210     {
211         //this maybe can be optimized further ...
212         sal_Int32 nMaxResolution = std::max( nXResolution, nYResolution );
213         nMaxResolution*=2;
214         for( nN = 0 ;nN<aResolution.getLength(); nN++ )
215             aResolution[nN]=nMaxResolution;
216     }
217 
218     return aResolution;
219 }
220 
221 Reference< XCoordinateSystem > VCoordinateSystem::getModel() const
222 {
223     return m_xCooSysModel;
224 }
225 
226 Reference< XAxis > VCoordinateSystem::getAxisByDimension( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex ) const
227 {
228     if( m_xCooSysModel.is() )
229         return m_xCooSysModel->getAxisByDimension( nDimensionIndex, nAxisIndex );
230     return 0;
231 }
232 
233 Sequence< Reference< beans::XPropertySet > > VCoordinateSystem::getGridListFromAxis( const Reference< XAxis >& xAxis )
234 {
235     std::vector< Reference< beans::XPropertySet > > aRet;
236 
237     if( xAxis.is() )
238     {
239         aRet.push_back( xAxis->getGridProperties() );
240         std::vector< Reference< beans::XPropertySet > > aSubGrids( ContainerHelper::SequenceToVector( xAxis->getSubGridProperties() ) );
241         aRet.insert( aRet.end(), aSubGrids.begin(), aSubGrids.end() );
242     }
243 
244     return ContainerHelper::ContainerToSequence( aRet );
245 }
246 
247 void VCoordinateSystem::impl_adjustDimension( sal_Int32& rDimensionIndex ) const
248 {
249     if( rDimensionIndex<0 )
250         rDimensionIndex=0;
251     if( rDimensionIndex>2 )
252         rDimensionIndex=2;
253 }
254 
255 void VCoordinateSystem::impl_adjustDimensionAndIndex( sal_Int32& rDimensionIndex, sal_Int32& rAxisIndex ) const
256 {
257     impl_adjustDimension( rDimensionIndex );
258 
259     if( rAxisIndex < 0 || rAxisIndex > this->getMaximumAxisIndexByDimension(rDimensionIndex) )
260         rAxisIndex = 0;
261 }
262 
263 void VCoordinateSystem::setExplicitCategoriesProvider( ExplicitCategoriesProvider* pExplicitCategoriesProvider /*takes ownership*/ )
264 {
265     m_apExplicitCategoriesProvider = ::std::auto_ptr< ExplicitCategoriesProvider >(pExplicitCategoriesProvider);
266 }
267 
268 ExplicitCategoriesProvider* VCoordinateSystem::getExplicitCategoriesProvider()
269 {
270     return m_apExplicitCategoriesProvider.get();
271 }
272 
273 std::vector< ExplicitScaleData > VCoordinateSystem::getExplicitScales( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex ) const
274 {
275     std::vector< ExplicitScaleData > aRet(m_aExplicitScales);
276 
277     impl_adjustDimensionAndIndex( nDimensionIndex, nAxisIndex );
278     aRet[nDimensionIndex]=this->getExplicitScale( nDimensionIndex, nAxisIndex );
279 
280     return aRet;
281 }
282 
283 std::vector< ExplicitIncrementData > VCoordinateSystem::getExplicitIncrements( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex ) const
284 {
285     std::vector< ExplicitIncrementData > aRet(m_aExplicitIncrements);
286 
287     impl_adjustDimensionAndIndex( nDimensionIndex, nAxisIndex );
288     aRet[nDimensionIndex]=this->getExplicitIncrement( nDimensionIndex, nAxisIndex );
289 
290     return aRet;
291 }
292 
293 ExplicitScaleData VCoordinateSystem::getExplicitScale( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex ) const
294 {
295     ExplicitScaleData aRet;
296 
297     impl_adjustDimensionAndIndex( nDimensionIndex, nAxisIndex );
298 
299     if( nAxisIndex == 0)
300     {
301         aRet = m_aExplicitScales[nDimensionIndex];
302     }
303     else
304     {
305         tFullAxisIndex aFullAxisIndex( nDimensionIndex, nAxisIndex );
306         tFullExplicitScaleMap::const_iterator aIt = m_aSecondaryExplicitScales.find( aFullAxisIndex );
307         if( aIt != m_aSecondaryExplicitScales.end() )
308             aRet = aIt->second;
309         else
310             aRet = m_aExplicitScales[nDimensionIndex];
311     }
312 
313     return aRet;
314 }
315 
316 ExplicitIncrementData VCoordinateSystem::getExplicitIncrement( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex ) const
317 {
318     ExplicitIncrementData aRet;
319 
320     impl_adjustDimensionAndIndex( nDimensionIndex, nAxisIndex );
321 
322     if( nAxisIndex == 0)
323     {
324         aRet = m_aExplicitIncrements[nDimensionIndex];
325     }
326     else
327     {
328         tFullAxisIndex aFullAxisIndex( nDimensionIndex, nAxisIndex );
329         tFullExplicitIncrementMap::const_iterator aIt = m_aSecondaryExplicitIncrements.find( aFullAxisIndex );
330         if( aIt != m_aSecondaryExplicitIncrements.end() )
331             aRet = aIt->second;
332         else
333             aRet = m_aExplicitIncrements[nDimensionIndex];
334     }
335 
336     return aRet;
337 }
338 
339 rtl::OUString VCoordinateSystem::createCIDForAxis( const Reference< chart2::XAxis >& /* xAxis */, sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex )
340 {
341     rtl::OUString aAxisParticle( ObjectIdentifier::createParticleForAxis( nDimensionIndex, nAxisIndex ) );
342     return ObjectIdentifier::createClassifiedIdentifierForParticles( m_aCooSysParticle, aAxisParticle );
343 }
344 rtl::OUString VCoordinateSystem::createCIDForGrid( const Reference< chart2::XAxis >& /* xAxis */, sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex )
345 {
346     rtl::OUString aGridParticle( ObjectIdentifier::createParticleForGrid( nDimensionIndex, nAxisIndex ) );
347     return ObjectIdentifier::createClassifiedIdentifierForParticles( m_aCooSysParticle, aGridParticle );
348 }
349 
350 sal_Int32 VCoordinateSystem::getMaximumAxisIndexByDimension( sal_Int32 nDimensionIndex ) const
351 {
352     sal_Int32 nRet = 0;
353     tFullExplicitScaleMap::const_iterator aIt = m_aSecondaryExplicitScales.begin();
354     tFullExplicitScaleMap::const_iterator aEnd = m_aSecondaryExplicitScales.end();
355     for(; aIt!=aEnd; ++aIt)
356     {
357         if(aIt->first.first==nDimensionIndex)
358         {
359             sal_Int32 nLocalIdx = aIt->first.second;
360             if( nRet < nLocalIdx )
361                 nRet = nLocalIdx;
362         }
363     }
364     return nRet;
365 }
366 
367 void VCoordinateSystem::createVAxisList(
368               const uno::Reference< util::XNumberFormatsSupplier > & /* xNumberFormatsSupplier */
369             , const awt::Size& /* rFontReferenceSize */
370             , const awt::Rectangle& /* rMaximumSpaceForLabels */
371             )
372 {
373 }
374 
375 void VCoordinateSystem::initVAxisInList()
376 {
377 }
378 void VCoordinateSystem::updateScalesAndIncrementsOnAxes()
379 {
380 }
381 
382 void VCoordinateSystem::prepareScaleAutomatismForDimensionAndIndex( ScaleAutomatism& rScaleAutomatism, sal_Int32 nDimIndex, sal_Int32 nAxisIndex )
383 {
384     if( rScaleAutomatism.getScale().AxisType==AxisType::DATE && nDimIndex==0 )
385     {
386         sal_Int32 nTimeResolution = ::com::sun::star::chart::TimeUnit::MONTH;
387         if( !(rScaleAutomatism.getScale().TimeIncrement.TimeResolution >>= nTimeResolution) )
388         {
389             nTimeResolution = m_aMergedMinimumAndMaximumSupplier.calculateTimeResolutionOnXAxis();
390             rScaleAutomatism.setAutomaticTimeResolution( nTimeResolution );
391         }
392         m_aMergedMinimumAndMaximumSupplier.setTimeResolutionOnXAxis( nTimeResolution, rScaleAutomatism.getNullDate() );
393     }
394 
395     double fMin = 0.0;
396     double fMax = 0.0;
397     ::rtl::math::setInf(&fMin, false);
398     ::rtl::math::setInf(&fMax, true);
399     if( 0 == nDimIndex )
400     {
401         fMin = m_aMergedMinimumAndMaximumSupplier.getMinimumX();
402         fMax = m_aMergedMinimumAndMaximumSupplier.getMaximumX();
403     }
404     else if( 1 == nDimIndex )
405     {
406         ExplicitScaleData aScale = getExplicitScale( 0, 0 );
407         fMin = m_aMergedMinimumAndMaximumSupplier.getMinimumYInRange(aScale.Minimum,aScale.Maximum, nAxisIndex);
408         fMax = m_aMergedMinimumAndMaximumSupplier.getMaximumYInRange(aScale.Minimum,aScale.Maximum, nAxisIndex);
409     }
410     else if( 2 == nDimIndex )
411     {
412         fMin = m_aMergedMinimumAndMaximumSupplier.getMinimumZ();
413         fMax = m_aMergedMinimumAndMaximumSupplier.getMaximumZ();
414     }
415 
416     //merge our values with those already contained in rScaleAutomatism
417     rScaleAutomatism.expandValueRange( fMin, fMax );
418 
419     rScaleAutomatism.setAutoScalingOptions(
420         m_aMergedMinimumAndMaximumSupplier.isExpandBorderToIncrementRhythm( nDimIndex ),
421         m_aMergedMinimumAndMaximumSupplier.isExpandIfValuesCloseToBorder( nDimIndex ),
422         m_aMergedMinimumAndMaximumSupplier.isExpandWideValuesToZero( nDimIndex ),
423         m_aMergedMinimumAndMaximumSupplier.isExpandNarrowValuesTowardZero( nDimIndex ) );
424 
425     VAxisBase* pVAxis( this->getVAxis( nDimIndex, nAxisIndex ) );
426     if( pVAxis )
427         rScaleAutomatism.setMaximumAutoMainIncrementCount( pVAxis->estimateMaximumAutoMainIncrementCount() );
428 }
429 
430 VAxisBase* VCoordinateSystem::getVAxis( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex )
431 {
432     VAxisBase* pRet = 0;
433 
434     tFullAxisIndex aFullAxisIndex( nDimensionIndex, nAxisIndex );
435 
436     tVAxisMap::const_iterator aIt = m_aAxisMap.find( aFullAxisIndex );
437     if( aIt != m_aAxisMap.end() )
438         pRet = aIt->second.get();
439 
440     return pRet;
441 }
442 
443 void VCoordinateSystem::setExplicitScaleAndIncrement(
444           sal_Int32 nDimensionIndex
445         , sal_Int32 nAxisIndex
446         , const ExplicitScaleData& rExplicitScale
447         , const ExplicitIncrementData& rExplicitIncrement )
448 {
449     impl_adjustDimension( nDimensionIndex );
450 
451     if( nAxisIndex==0 )
452     {
453         m_aExplicitScales[nDimensionIndex]=rExplicitScale;
454         m_aExplicitIncrements[nDimensionIndex]=rExplicitIncrement;
455     }
456     else
457     {
458         tFullAxisIndex aFullAxisIndex( nDimensionIndex, nAxisIndex );
459         m_aSecondaryExplicitScales[aFullAxisIndex] = rExplicitScale;
460         m_aSecondaryExplicitIncrements[aFullAxisIndex] = rExplicitIncrement;
461     }
462 }
463 
464 void VCoordinateSystem::set3DWallPositions( CuboidPlanePosition eLeftWallPos, CuboidPlanePosition eBackWallPos, CuboidPlanePosition eBottomPos )
465 {
466     m_eLeftWallPos = eLeftWallPos;
467     m_eBackWallPos = eBackWallPos;
468     m_eBottomPos = eBottomPos;
469 }
470 
471 void VCoordinateSystem::createMaximumAxesLabels()
472 {
473     tVAxisMap::iterator aIt( m_aAxisMap.begin() );
474     tVAxisMap::const_iterator aEnd( m_aAxisMap.end() );
475     for( ; aIt != aEnd; ++aIt )
476     {
477         VAxisBase* pVAxis = aIt->second.get();
478         if( pVAxis )
479         {
480             if(2==pVAxis->getDimensionCount())
481                 pVAxis->setTransformationSceneToScreen( m_aMatrixSceneToScreen );
482             pVAxis->createMaximumLabels();
483         }
484     }
485 }
486 void VCoordinateSystem::createAxesLabels()
487 {
488     tVAxisMap::iterator aIt( m_aAxisMap.begin() );
489     tVAxisMap::const_iterator aEnd( m_aAxisMap.end() );
490     for( ; aIt != aEnd; ++aIt )
491     {
492         VAxisBase* pVAxis = aIt->second.get();
493         if( pVAxis )
494         {
495             if(2==pVAxis->getDimensionCount())
496                 pVAxis->setTransformationSceneToScreen( m_aMatrixSceneToScreen );
497             pVAxis->createLabels();
498         }
499     }
500 }
501 
502 void VCoordinateSystem::updatePositions()
503 {
504     tVAxisMap::iterator aIt( m_aAxisMap.begin() );
505     tVAxisMap::const_iterator aEnd( m_aAxisMap.end() );
506     for( ; aIt != aEnd; ++aIt )
507     {
508         VAxisBase* pVAxis = aIt->second.get();
509         if( pVAxis )
510         {
511             if(2==pVAxis->getDimensionCount())
512                 pVAxis->setTransformationSceneToScreen( m_aMatrixSceneToScreen );
513             pVAxis->updatePositions();
514         }
515     }
516 }
517 
518 void VCoordinateSystem::createAxesShapes()
519 {
520     tVAxisMap::iterator aIt( m_aAxisMap.begin() );
521     tVAxisMap::const_iterator aEnd( m_aAxisMap.end() );
522     for( ; aIt != aEnd; ++aIt )
523     {
524         VAxisBase* pVAxis = aIt->second.get();
525         if( pVAxis )
526         {
527             if(2==pVAxis->getDimensionCount())
528                 pVAxis->setTransformationSceneToScreen( m_aMatrixSceneToScreen );
529 
530             tFullAxisIndex aFullAxisIndex = aIt->first;
531             if( aFullAxisIndex.second == 0 )
532             {
533                 if( aFullAxisIndex.first == 0 )
534                 {
535                     if( AxisType::CATEGORY!=m_aExplicitScales[1].AxisType )
536                         pVAxis->setExrtaLinePositionAtOtherAxis(
537                             m_aExplicitScales[1].Origin );
538                 }
539                 else if( aFullAxisIndex.first == 1 )
540                 {
541                     if( AxisType::CATEGORY!=m_aExplicitScales[0].AxisType )
542                         pVAxis->setExrtaLinePositionAtOtherAxis(
543                             m_aExplicitScales[0].Origin );
544                 }
545             }
546 
547             pVAxis->createShapes();
548         }
549     }
550 }
551 void VCoordinateSystem::createGridShapes()
552 {
553 }
554 void VCoordinateSystem::addMinimumAndMaximumSupplier( MinimumAndMaximumSupplier* pMinimumAndMaximumSupplier )
555 {
556     m_aMergedMinimumAndMaximumSupplier.addMinimumAndMaximumSupplier(pMinimumAndMaximumSupplier);
557 }
558 
559 bool VCoordinateSystem::hasMinimumAndMaximumSupplier( MinimumAndMaximumSupplier* pMinimumAndMaximumSupplier )
560 {
561     return m_aMergedMinimumAndMaximumSupplier.hasMinimumAndMaximumSupplier(pMinimumAndMaximumSupplier);
562 }
563 
564 void VCoordinateSystem::clearMinimumAndMaximumSupplierList()
565 {
566     m_aMergedMinimumAndMaximumSupplier.clearMinimumAndMaximumSupplierList();
567 }
568 
569 bool VCoordinateSystem::getPropertySwapXAndYAxis() const
570 {
571     Reference<beans::XPropertySet> xProp(m_xCooSysModel, uno::UNO_QUERY );
572     sal_Bool bSwapXAndY = false;
573     if( xProp.is()) try
574     {
575         xProp->getPropertyValue( C2U( "SwapXAndYAxis" ) ) >>= bSwapXAndY;
576     }
577     catch( uno::Exception& e )
578     {
579         ASSERT_EXCEPTION( e );
580     }
581     return bSwapXAndY;
582 }
583 
584 bool VCoordinateSystem::needSeriesNamesForAxis() const
585 {
586     return ( m_xCooSysModel.is() && m_xCooSysModel->getDimension() == 3 );
587 }
588 void VCoordinateSystem::setSeriesNamesForAxis( const Sequence< rtl::OUString >& rSeriesNames )
589 {
590     m_aSeriesNamesForZAxis = rSeriesNames;
591 }
592 
593 sal_Int32 VCoordinateSystem::getNumberFormatKeyForAxis(
594         const Reference< chart2::XAxis >& xAxis
595         , const Reference< util::XNumberFormatsSupplier >& xNumberFormatsSupplier )
596 {
597     return ExplicitValueProvider::getExplicitNumberFormatKeyForAxis(
598                 xAxis, m_xCooSysModel, xNumberFormatsSupplier );
599 }
600 
601 //.............................................................................
602 } //namespace chart
603 //.............................................................................
604