1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
21 #include "AxisHelper.hxx"
22 #include "DiagramHelper.hxx"
23 #include "ChartTypeHelper.hxx"
25 #include "AxisIndexDefines.hxx"
26 #include "LinePropertiesHelper.hxx"
27 #include "ContainerHelper.hxx"
28 #include "servicenames_coosystems.hxx"
29 #include "DataSeriesHelper.hxx"
30 #include "Scaling.hxx"
31 #include "ChartModelHelper.hxx"
32 #include "DataSourceHelper.hxx"
34 #include <unotools/saveopt.hxx>
36 #include <com/sun/star/chart/ChartAxisPosition.hpp>
38 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
39 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
40 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
41 #include <com/sun/star/chart2/data/XDataSource.hpp>
43 // header for class OUStringBuffer
44 #include <rtl/ustrbuf.hxx>
45 #include <rtl/math.hxx>
47 #include <com/sun/star/util/XCloneable.hpp>
48 #include <com/sun/star/lang/XServiceName.hpp>
52 //.............................................................................
55 //.............................................................................
56 using namespace ::com::sun::star
;
57 using namespace ::com::sun::star::chart2
;
58 using ::com::sun::star::uno::Reference
;
59 using ::com::sun::star::uno::Sequence
;
61 Reference
< chart2::XScaling
> AxisHelper::createLinearScaling()
63 return new LinearScaling( 1.0, 0.0 );
66 Reference
< chart2::XScaling
> AxisHelper::createLogarithmicScaling( double fBase
)
68 return new LogarithmicScaling( fBase
);
71 ScaleData
AxisHelper::createDefaultScale()
74 aScaleData
.AxisType
= chart2::AxisType::REALNUMBER
;
75 aScaleData
.AutoDateAxis
= true;
76 aScaleData
.ShiftedCategoryPosition
= false;//this is adapted in the view code currently
77 Sequence
< SubIncrement
> aSubIncrements(1);
78 aSubIncrements
[0] = SubIncrement();
79 aScaleData
.IncrementData
.SubIncrements
= aSubIncrements
;
83 void AxisHelper::removeExplicitScaling( ScaleData
& rScaleData
)
86 rScaleData
.Minimum
= rScaleData
.Maximum
= rScaleData
.Origin
= aEmpty
;
87 rScaleData
.Scaling
= 0;
88 ScaleData
aDefaultScale( createDefaultScale() );
89 rScaleData
.IncrementData
= aDefaultScale
.IncrementData
;
90 rScaleData
.TimeIncrement
= aDefaultScale
.TimeIncrement
;
93 bool AxisHelper::isLogarithmic( const Reference
< XScaling
>& xScaling
)
96 Reference
< lang::XServiceName
> xServiceName( xScaling
, uno::UNO_QUERY
);
97 bReturn
=( xServiceName
.is() && (xServiceName
->getServiceName()).equals(
98 "com.sun.star.chart2.LogarithmicScaling"));
102 chart2::ScaleData
AxisHelper::getDateCheckedScale( const Reference
< chart2::XAxis
>& xAxis
, const Reference
< frame::XModel
>& xChartModel
)
104 OSL_ENSURE(xChartModel
.is(),"missing chart model");
105 ScaleData aScale
= xAxis
->getScaleData();
106 Reference
< chart2::XCoordinateSystem
> xCooSys( ChartModelHelper::getFirstCoordinateSystem( xChartModel
) );
107 if( aScale
.AutoDateAxis
&& aScale
.AxisType
== AxisType::CATEGORY
)
109 sal_Int32 nDimensionIndex
=0; sal_Int32 nAxisIndex
=0;
110 AxisHelper::getIndicesForAxis(xAxis
, xCooSys
, nDimensionIndex
, nAxisIndex
);
111 bool bChartTypeAllowsDateAxis
= ChartTypeHelper::isSupportingDateAxis( AxisHelper::getChartTypeByIndex( xCooSys
, 0 ), 2, nDimensionIndex
);
112 if( bChartTypeAllowsDateAxis
)
113 aScale
.AxisType
= AxisType::DATE
;
115 if( aScale
.AxisType
== AxisType::DATE
)
117 ExplicitCategoriesProvider
aExplicitCategoriesProvider( xCooSys
,xChartModel
);
118 if( !aExplicitCategoriesProvider
.isDateAxis() )
119 aScale
.AxisType
= AxisType::CATEGORY
;
124 void AxisHelper::checkDateAxis( chart2::ScaleData
& rScale
, ExplicitCategoriesProvider
* pExplicitCategoriesProvider
, bool bChartTypeAllowsDateAxis
)
126 if( rScale
.AutoDateAxis
&& rScale
.AxisType
== AxisType::CATEGORY
&& bChartTypeAllowsDateAxis
)
128 rScale
.AxisType
= AxisType::DATE
;
129 removeExplicitScaling( rScale
);
131 if( rScale
.AxisType
== AxisType::DATE
&& (!pExplicitCategoriesProvider
|| !pExplicitCategoriesProvider
->isDateAxis()) )
133 rScale
.AxisType
= AxisType::CATEGORY
;
134 removeExplicitScaling( rScale
);
138 sal_Int32
AxisHelper::getExplicitNumberFormatKeyForAxis(
139 const Reference
< chart2::XAxis
>& xAxis
140 , const Reference
< chart2::XCoordinateSystem
> & xCorrespondingCoordinateSystem
141 , const Reference
< util::XNumberFormatsSupplier
>& xNumberFormatsSupplier
142 , bool bSearchForParallelAxisIfNothingIsFound
)
144 sal_Int32
nNumberFormatKey(0);
145 bool bNumberFormatKeyFoundViaAttachedData
= false;
146 sal_Int32 nAxisIndex
= 0;
147 sal_Int32 nDimensionIndex
= 1;
148 AxisHelper::getIndicesForAxis( xAxis
, xCorrespondingCoordinateSystem
, nDimensionIndex
, nAxisIndex
);
149 Reference
< chart2::XChartDocument
> xChartDoc( xNumberFormatsSupplier
, uno::UNO_QUERY
);
151 Reference
< beans::XPropertySet
> xProp( xAxis
, uno::UNO_QUERY
);
152 if( xProp
.is() && !( xProp
->getPropertyValue( "NumberFormat" ) >>= nNumberFormatKey
) )
154 bool bFormatSet
= false;
155 //check whether we have a percent scale -> use percent format
156 if( xNumberFormatsSupplier
.is() )
158 ScaleData aData
= AxisHelper::getDateCheckedScale( xAxis
, Reference
< frame::XModel
>( xNumberFormatsSupplier
, uno::UNO_QUERY
) );
159 if( aData
.AxisType
==AxisType::PERCENT
)
161 sal_Int32 nPercentFormat
= DiagramHelper::getPercentNumberFormat( xNumberFormatsSupplier
);
162 if( nPercentFormat
!= -1 )
164 nNumberFormatKey
= nPercentFormat
;
168 else if( aData
.AxisType
==AxisType::DATE
)
170 if( aData
.Categories
.is() )
172 Reference
< data::XDataSequence
> xSeq( aData
.Categories
->getValues());
173 if( xSeq
.is() && !( xChartDoc
.is() && xChartDoc
->hasInternalDataProvider()) )
174 nNumberFormatKey
= xSeq
->getNumberFormatKeyByIndex( -1 );
176 nNumberFormatKey
= DiagramHelper::getDateNumberFormat( xNumberFormatsSupplier
);
180 else if( xChartDoc
.is() && xChartDoc
->hasInternalDataProvider() && nDimensionIndex
== 0 ) //maybe date axis
182 Reference
< chart2::XDiagram
> xDiagram( xChartDoc
->getFirstDiagram() );
183 if( DiagramHelper::isSupportingDateAxis( xDiagram
) )
185 nNumberFormatKey
= DiagramHelper::getDateNumberFormat( xNumberFormatsSupplier
);
189 Reference
< data::XDataSource
> xSource( DataSourceHelper::getUsedData( xChartDoc
) );
192 ::std::vector
< Reference
< chart2::data::XLabeledDataSequence
> > aXValues(
193 DataSeriesHelper::getAllDataSequencesByRole( xSource
->getDataSequences(), "values-x", true ) );
194 if( aXValues
.empty() )
196 Reference
< data::XLabeledDataSequence
> xCategories( DiagramHelper::getCategoriesFromDiagram( xDiagram
) );
197 if( xCategories
.is() )
199 Reference
< data::XDataSequence
> xSeq( xCategories
->getValues());
202 bool bHasValidDoubles
= false;
204 Sequence
< uno::Any
> aCats( xSeq
->getData() );
205 sal_Int32 nCount
= aCats
.getLength();
206 for( sal_Int32 i
= 0; i
< nCount
; ++i
)
208 if( (aCats
[i
]>>=fTest
) && !::rtl::math::isNan(fTest
) )
210 bHasValidDoubles
=true;
214 if( bHasValidDoubles
)
215 nNumberFormatKey
= DiagramHelper::getDateNumberFormat( xNumberFormatsSupplier
);
227 typedef ::std::map
< sal_Int32
, sal_Int32
> tNumberformatFrequency
;
228 tNumberformatFrequency aKeyMap
;
232 Reference
< XChartTypeContainer
> xCTCnt( xCorrespondingCoordinateSystem
, uno::UNO_QUERY_THROW
);
235 OUString aRoleToMatch
;
236 if( nDimensionIndex
== 0 )
237 aRoleToMatch
= "values-x";
238 Sequence
< Reference
< XChartType
> > aChartTypes( xCTCnt
->getChartTypes());
239 for( sal_Int32 nCTIdx
=0; nCTIdx
<aChartTypes
.getLength(); ++nCTIdx
)
241 if( nDimensionIndex
!= 0 )
242 aRoleToMatch
= ChartTypeHelper::getRoleOfSequenceForYAxisNumberFormatDetection( aChartTypes
[nCTIdx
] );
243 Reference
< XDataSeriesContainer
> xDSCnt( aChartTypes
[nCTIdx
], uno::UNO_QUERY_THROW
);
244 Sequence
< Reference
< XDataSeries
> > aDataSeriesSeq( xDSCnt
->getDataSeries());
245 for( sal_Int32 nSeriesIdx
=0; nSeriesIdx
<aDataSeriesSeq
.getLength(); ++nSeriesIdx
)
247 Reference
< chart2::XDataSeries
> xDataSeries(aDataSeriesSeq
[nSeriesIdx
]);
248 Reference
< data::XDataSource
> xSource( xDataSeries
, uno::UNO_QUERY_THROW
);
250 if( nDimensionIndex
== 1 )
252 //only take those series into accoutn that are attached to this axis
253 sal_Int32 nAttachedAxisIndex
= DataSeriesHelper::getAttachedAxisIndex(xDataSeries
);
254 if( nAttachedAxisIndex
!= nAxisIndex
)
258 Reference
< data::XLabeledDataSequence
> xLabeledSeq(
259 DataSeriesHelper::getDataSequenceByRole( xSource
, aRoleToMatch
) );
261 if( !xLabeledSeq
.is() && nDimensionIndex
==0 )
263 ScaleData aData
= xAxis
->getScaleData();
264 xLabeledSeq
= aData
.Categories
;
267 if( xLabeledSeq
.is() )
269 Reference
< data::XDataSequence
> xSeq( xLabeledSeq
->getValues());
272 sal_Int32 nKey
= xSeq
->getNumberFormatKeyByIndex( -1 );
273 // initialize the value
274 if( aKeyMap
.find( nKey
) == aKeyMap
.end())
276 // increase frequency
277 aKeyMap
[ nKey
] = (aKeyMap
[ nKey
] + 1);
284 catch( const uno::Exception
& ex
)
286 ASSERT_EXCEPTION( ex
);
289 if( ! aKeyMap
.empty())
291 sal_Int32 nMaxFreq
= 0;
292 // find most frequent key
293 for( tNumberformatFrequency::const_iterator aIt
= aKeyMap
.begin();
294 aIt
!= aKeyMap
.end(); ++aIt
)
296 OSL_TRACE( "NumberFormatKey %d appears %d times", (*aIt
).first
, (*aIt
).second
);
297 // all values must at least be 1
298 if( (*aIt
).second
> nMaxFreq
)
300 nNumberFormatKey
= (*aIt
).first
;
301 bNumberFormatKeyFoundViaAttachedData
= true;
302 nMaxFreq
= (*aIt
).second
;
307 if( bSearchForParallelAxisIfNothingIsFound
)
309 //no format is set to this axis and no data is set to this axis
310 //--> try to obtain the format from the parallel y-axis
311 if( !bNumberFormatKeyFoundViaAttachedData
&& nDimensionIndex
== 1 )
313 sal_Int32 nParallelAxisIndex
= (nAxisIndex
==1) ?0 :1;
314 Reference
< XAxis
> xParallelAxis( AxisHelper::getAxis( 1, nParallelAxisIndex
, xCorrespondingCoordinateSystem
) );
315 nNumberFormatKey
= AxisHelper::getExplicitNumberFormatKeyForAxis( xParallelAxis
, xCorrespondingCoordinateSystem
, xNumberFormatsSupplier
, false );
320 return nNumberFormatKey
;
323 Reference
< XAxis
> AxisHelper::createAxis(
324 sal_Int32 nDimensionIndex
325 , sal_Int32 nAxisIndex
// 0==main or 1==secondary axis
326 , const Reference
< XCoordinateSystem
>& xCooSys
327 , const Reference
< uno::XComponentContext
> & xContext
328 , ReferenceSizeProvider
* pRefSizeProvider
)
330 if( !xContext
.is() || !xCooSys
.is() )
332 if( nDimensionIndex
>= xCooSys
->getDimension() )
335 Reference
< XAxis
> xAxis( xContext
->getServiceManager()->createInstanceWithContext(
336 "com.sun.star.chart2.Axis", xContext
), uno::UNO_QUERY
);
338 OSL_ASSERT( xAxis
.is());
341 xCooSys
->setAxisByDimension( nDimensionIndex
, xAxis
, nAxisIndex
);
343 if( nAxisIndex
>0 )//when inserting secondary axes copy some things from the main axis
345 ::com::sun::star::chart::ChartAxisPosition
eNewAxisPos( ::com::sun::star::chart::ChartAxisPosition_END
);
347 Reference
< XAxis
> xMainAxis( xCooSys
->getAxisByDimension( nDimensionIndex
, 0 ) );
350 ScaleData aScale
= xAxis
->getScaleData();
351 ScaleData aMainScale
= xMainAxis
->getScaleData();
353 aScale
.AxisType
= aMainScale
.AxisType
;
354 aScale
.AutoDateAxis
= aMainScale
.AutoDateAxis
;
355 aScale
.Categories
= aMainScale
.Categories
;
356 aScale
.Orientation
= aMainScale
.Orientation
;
358 xAxis
->setScaleData( aScale
);
360 //ensure that the second axis is not placed on the main axis
361 Reference
< beans::XPropertySet
> xMainProp( xMainAxis
, uno::UNO_QUERY
);
364 ::com::sun::star::chart::ChartAxisPosition
eMainAxisPos( ::com::sun::star::chart::ChartAxisPosition_ZERO
);
365 xMainProp
->getPropertyValue("CrossoverPosition") >>= eMainAxisPos
;
366 if( ::com::sun::star::chart::ChartAxisPosition_END
== eMainAxisPos
)
367 eNewAxisPos
= ::com::sun::star::chart::ChartAxisPosition_START
;
371 Reference
< beans::XPropertySet
> xProp( xAxis
, uno::UNO_QUERY
);
373 xProp
->setPropertyValue("CrossoverPosition", uno::makeAny(eNewAxisPos
) );
376 Reference
< beans::XPropertySet
> xProp( xAxis
, uno::UNO_QUERY
);
379 // set correct initial AutoScale
380 if( pRefSizeProvider
)
381 pRefSizeProvider
->setValuesAtPropertySet( xProp
);
383 catch( const uno::Exception
& e
)
385 ASSERT_EXCEPTION( e
);
391 Reference
< XAxis
> AxisHelper::createAxis( sal_Int32 nDimensionIndex
, bool bMainAxis
392 , const Reference
< chart2::XDiagram
>& xDiagram
393 , const Reference
< uno::XComponentContext
>& xContext
394 , ReferenceSizeProvider
* pRefSizeProvider
)
396 OSL_ENSURE( xContext
.is(), "need a context to create an axis" );
400 sal_Int32 nAxisIndex
= bMainAxis
? MAIN_AXIS_INDEX
: SECONDARY_AXIS_INDEX
;
401 sal_Int32 nCooSysIndex
= 0;
402 Reference
< XCoordinateSystem
> xCooSys
= AxisHelper::getCoordinateSystemByIndex( xDiagram
, nCooSysIndex
);
405 return AxisHelper::createAxis(
406 nDimensionIndex
, nAxisIndex
, xCooSys
, xContext
, pRefSizeProvider
);
409 void AxisHelper::showAxis( sal_Int32 nDimensionIndex
, bool bMainAxis
410 , const Reference
< chart2::XDiagram
>& xDiagram
411 , const Reference
< uno::XComponentContext
>& xContext
412 , ReferenceSizeProvider
* pRefSizeProvider
)
417 bool bNewAxisCreated
= false;
418 Reference
< XAxis
> xAxis( AxisHelper::getAxis( nDimensionIndex
, bMainAxis
, xDiagram
) );
419 if( !xAxis
.is() && xContext
.is() )
422 bNewAxisCreated
= true;
423 xAxis
.set( AxisHelper::createAxis( nDimensionIndex
, bMainAxis
, xDiagram
, xContext
, pRefSizeProvider
) );
426 OSL_ASSERT( xAxis
.is());
427 if( !bNewAxisCreated
) //default is true already if created
428 AxisHelper::makeAxisVisible( xAxis
);
431 void AxisHelper::showGrid( sal_Int32 nDimensionIndex
, sal_Int32 nCooSysIndex
, bool bMainGrid
432 , const Reference
< XDiagram
>& xDiagram
433 , const Reference
< uno::XComponentContext
>& /*xContext*/ )
438 Reference
< XCoordinateSystem
> xCooSys
= AxisHelper::getCoordinateSystemByIndex( xDiagram
, nCooSysIndex
);
442 Reference
< XAxis
> xAxis( AxisHelper::getAxis( nDimensionIndex
, MAIN_AXIS_INDEX
, xCooSys
) );
445 //hhhh todo create axis without axis visibility
451 AxisHelper::makeGridVisible( xAxis
->getGridProperties() );
454 Sequence
< Reference
< beans::XPropertySet
> > aSubGrids( xAxis
->getSubGridProperties() );
455 for( sal_Int32 nN
=0; nN
<aSubGrids
.getLength(); nN
++)
456 AxisHelper::makeGridVisible( aSubGrids
[nN
] );
460 void AxisHelper::makeAxisVisible( const Reference
< XAxis
>& xAxis
)
462 Reference
< beans::XPropertySet
> xProps( xAxis
, uno::UNO_QUERY
);
465 xProps
->setPropertyValue( "Show", uno::makeAny( sal_True
) );
466 LinePropertiesHelper::SetLineVisible( xProps
);
467 xProps
->setPropertyValue( "DisplayLabels", uno::makeAny( sal_True
) );
471 void AxisHelper::makeGridVisible( const Reference
< beans::XPropertySet
>& xGridProperties
)
473 if( xGridProperties
.is() )
475 xGridProperties
->setPropertyValue( "Show", uno::makeAny( sal_True
) );
476 LinePropertiesHelper::SetLineVisible( xGridProperties
);
480 void AxisHelper::hideAxis( sal_Int32 nDimensionIndex
, bool bMainAxis
481 , const Reference
< XDiagram
>& xDiagram
)
483 AxisHelper::makeAxisInvisible( AxisHelper::getAxis( nDimensionIndex
, bMainAxis
, xDiagram
) );
486 void AxisHelper::makeAxisInvisible( const Reference
< XAxis
>& xAxis
)
488 Reference
< beans::XPropertySet
> xProps( xAxis
, uno::UNO_QUERY
);
491 xProps
->setPropertyValue( "Show", uno::makeAny( sal_False
) );
495 void AxisHelper::hideAxisIfNoDataIsAttached( const Reference
< XAxis
>& xAxis
, const Reference
< XDiagram
>& xDiagram
)
497 //axis is hidden if no data is attached anymore but data is available
498 bool bOtherSeriesAttachedToThisAxis
= false;
499 ::std::vector
< Reference
< chart2::XDataSeries
> > aSeriesVector( DiagramHelper::getDataSeriesFromDiagram( xDiagram
) );
500 ::std::vector
< Reference
< chart2::XDataSeries
> >::const_iterator aIt
= aSeriesVector
.begin();
501 for( ; aIt
!= aSeriesVector
.end(); ++aIt
)
503 uno::Reference
< chart2::XAxis
> xCurrentAxis( DiagramHelper::getAttachedAxis( *aIt
, xDiagram
), uno::UNO_QUERY
);
504 if( xCurrentAxis
==xAxis
)
506 bOtherSeriesAttachedToThisAxis
= true;
510 if(!bOtherSeriesAttachedToThisAxis
&& !aSeriesVector
.empty() )
511 AxisHelper::makeAxisInvisible( xAxis
);
514 void AxisHelper::hideGrid( sal_Int32 nDimensionIndex
, sal_Int32 nCooSysIndex
, bool bMainGrid
515 , const Reference
< XDiagram
>& xDiagram
)
520 Reference
< XCoordinateSystem
> xCooSys
= AxisHelper::getCoordinateSystemByIndex( xDiagram
, nCooSysIndex
);
524 Reference
< XAxis
> xAxis( AxisHelper::getAxis( nDimensionIndex
, MAIN_AXIS_INDEX
, xCooSys
) );
529 AxisHelper::makeGridInvisible( xAxis
->getGridProperties() );
532 Sequence
< Reference
< beans::XPropertySet
> > aSubGrids( xAxis
->getSubGridProperties() );
533 for( sal_Int32 nN
=0; nN
<aSubGrids
.getLength(); nN
++)
534 AxisHelper::makeGridInvisible( aSubGrids
[nN
] );
538 void AxisHelper::makeGridInvisible( const Reference
< beans::XPropertySet
>& xGridProperties
)
540 if( xGridProperties
.is() )
542 xGridProperties
->setPropertyValue( "Show", uno::makeAny( sal_False
) );
546 sal_Bool
AxisHelper::isGridShown( sal_Int32 nDimensionIndex
, sal_Int32 nCooSysIndex
, bool bMainGrid
547 , const Reference
< ::com::sun::star::chart2::XDiagram
>& xDiagram
)
549 sal_Bool bRet
= false;
551 Reference
< XCoordinateSystem
> xCooSys
= AxisHelper::getCoordinateSystemByIndex( xDiagram
, nCooSysIndex
);
555 Reference
< XAxis
> xAxis( AxisHelper::getAxis( nDimensionIndex
, MAIN_AXIS_INDEX
, xCooSys
) );
560 bRet
= AxisHelper::isGridVisible( xAxis
->getGridProperties() );
563 Sequence
< Reference
< beans::XPropertySet
> > aSubGrids( xAxis
->getSubGridProperties() );
564 if( aSubGrids
.getLength() )
565 bRet
= AxisHelper::isGridVisible( aSubGrids
[0] );
571 Reference
< XCoordinateSystem
> AxisHelper::getCoordinateSystemByIndex(
572 const Reference
< XDiagram
>& xDiagram
, sal_Int32 nIndex
)
574 Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
575 if(!xCooSysContainer
.is())
577 Sequence
< Reference
< XCoordinateSystem
> > aCooSysList
= xCooSysContainer
->getCoordinateSystems();
578 if(0<=nIndex
&& nIndex
<aCooSysList
.getLength())
579 return aCooSysList
[nIndex
];
583 Reference
< XAxis
> AxisHelper::getAxis( sal_Int32 nDimensionIndex
, bool bMainAxis
584 , const Reference
< XDiagram
>& xDiagram
)
586 Reference
< XAxis
> xRet
;
589 Reference
< XCoordinateSystem
> xCooSys
= AxisHelper::getCoordinateSystemByIndex( xDiagram
, 0 );
590 xRet
.set( AxisHelper::getAxis( nDimensionIndex
, bMainAxis
? 0 : 1, xCooSys
) );
592 catch( const uno::Exception
& )
598 Reference
< XAxis
> AxisHelper::getAxis( sal_Int32 nDimensionIndex
, sal_Int32 nAxisIndex
599 , const Reference
< XCoordinateSystem
>& xCooSys
)
601 Reference
< XAxis
> xRet
;
605 xRet
.set( xCooSys
->getAxisByDimension( nDimensionIndex
, nAxisIndex
) );
607 catch( const uno::Exception
& )
613 Reference
< XAxis
> AxisHelper::getCrossingMainAxis( const Reference
< XAxis
>& xAxis
614 , const Reference
< XCoordinateSystem
>& xCooSys
)
616 sal_Int32 nDimensionIndex
= 0;
617 sal_Int32 nAxisIndex
= 0;
618 AxisHelper::getIndicesForAxis( xAxis
, xCooSys
, nDimensionIndex
, nAxisIndex
);
619 if( 2==nDimensionIndex
)
622 bool bSwapXY
= false;
623 Reference
< beans::XPropertySet
> xCooSysProp( xCooSys
, uno::UNO_QUERY
);
624 if( xCooSysProp
.is() && (xCooSysProp
->getPropertyValue( "SwapXAndYAxis" ) >>= bSwapXY
) && bSwapXY
)
627 else if( 1==nDimensionIndex
)
631 return AxisHelper::getAxis( nDimensionIndex
, 0, xCooSys
);
634 Reference
< XAxis
> AxisHelper::getParallelAxis( const Reference
< XAxis
>& xAxis
635 , const Reference
< XDiagram
>& xDiagram
)
639 sal_Int32 nCooSysIndex
=-1;
640 sal_Int32 nDimensionIndex
=-1;
641 sal_Int32 nAxisIndex
=-1;
642 if( getIndicesForAxis( xAxis
, xDiagram
, nCooSysIndex
, nDimensionIndex
, nAxisIndex
) )
644 sal_Int32 nParallelAxisIndex
= (nAxisIndex
==1) ?0 :1;
645 return getAxis( nDimensionIndex
, nParallelAxisIndex
, getCoordinateSystemByIndex( xDiagram
, nCooSysIndex
) );
648 catch( const uno::RuntimeException
& )
654 sal_Bool
AxisHelper::isAxisShown( sal_Int32 nDimensionIndex
, bool bMainAxis
655 , const Reference
< XDiagram
>& xDiagram
)
657 return AxisHelper::isAxisVisible( AxisHelper::getAxis( nDimensionIndex
, bMainAxis
, xDiagram
) );
660 sal_Bool
AxisHelper::isAxisVisible( const Reference
< XAxis
>& xAxis
)
662 sal_Bool bRet
= false;
664 Reference
< beans::XPropertySet
> xProps( xAxis
, uno::UNO_QUERY
);
667 xProps
->getPropertyValue( "Show" ) >>= bRet
;
668 bRet
= bRet
&& ( LinePropertiesHelper::IsLineVisible( xProps
)
669 || areAxisLabelsVisible( xProps
) );
675 sal_Bool
AxisHelper::areAxisLabelsVisible( const Reference
< beans::XPropertySet
>& xAxisProperties
)
677 sal_Bool bRet
= false;
678 if( xAxisProperties
.is() )
680 xAxisProperties
->getPropertyValue( "DisplayLabels" ) >>= bRet
;
685 sal_Bool
AxisHelper::isGridVisible( const Reference
< beans::XPropertySet
>& xGridProperies
)
687 sal_Bool bRet
= false;
689 if( xGridProperies
.is() )
691 xGridProperies
->getPropertyValue( "Show" ) >>= bRet
;
692 bRet
= bRet
&& LinePropertiesHelper::IsLineVisible( xGridProperies
);
698 Reference
< beans::XPropertySet
> AxisHelper::getGridProperties(
699 const Reference
< XCoordinateSystem
>& xCooSys
700 , sal_Int32 nDimensionIndex
, sal_Int32 nAxisIndex
, sal_Int32 nSubGridIndex
)
702 Reference
< beans::XPropertySet
> xRet
;
704 Reference
< XAxis
> xAxis( AxisHelper::getAxis( nDimensionIndex
, nAxisIndex
, xCooSys
) );
707 if( nSubGridIndex
<0 )
708 xRet
.set( xAxis
->getGridProperties() );
711 Sequence
< Reference
< beans::XPropertySet
> > aSubGrids( xAxis
->getSubGridProperties() );
712 if( nSubGridIndex
>= 0 && nSubGridIndex
< aSubGrids
.getLength() )
713 xRet
.set( aSubGrids
[nSubGridIndex
] );
720 sal_Int32
AxisHelper::getDimensionIndexOfAxis(
721 const Reference
< XAxis
>& xAxis
722 , const Reference
< XDiagram
>& xDiagram
)
724 sal_Int32 nDimensionIndex
= -1;
725 sal_Int32 nCooSysIndex
= -1;
726 sal_Int32 nAxisIndex
= -1;
727 AxisHelper::getIndicesForAxis( xAxis
, xDiagram
, nCooSysIndex
, nDimensionIndex
, nAxisIndex
);
728 return nDimensionIndex
;
731 bool AxisHelper::getIndicesForAxis(
732 const Reference
< XAxis
>& xAxis
733 , const Reference
< XCoordinateSystem
>& xCooSys
734 , sal_Int32
& rOutDimensionIndex
, sal_Int32
& rOutAxisIndex
)
736 //returns true if indices are found
738 rOutDimensionIndex
= -1;
741 if( xCooSys
.is() && xAxis
.is() )
743 Reference
< XAxis
> xCurrentAxis
;
744 sal_Int32
nDimensionCount( xCooSys
->getDimension() );
745 for( sal_Int32 nDimensionIndex
= 0; nDimensionIndex
< nDimensionCount
; nDimensionIndex
++ )
747 sal_Int32 nMaxAxisIndex
= xCooSys
->getMaximumAxisIndexByDimension(nDimensionIndex
);
748 for( sal_Int32 nAxisIndex
= 0; nAxisIndex
<= nMaxAxisIndex
; nAxisIndex
++ )
750 xCurrentAxis
= xCooSys
->getAxisByDimension(nDimensionIndex
,nAxisIndex
);
751 if( xCurrentAxis
== xAxis
)
753 rOutDimensionIndex
= nDimensionIndex
;
754 rOutAxisIndex
= nAxisIndex
;
763 bool AxisHelper::getIndicesForAxis( const Reference
< XAxis
>& xAxis
, const Reference
< XDiagram
>& xDiagram
764 , sal_Int32
& rOutCooSysIndex
, sal_Int32
& rOutDimensionIndex
, sal_Int32
& rOutAxisIndex
)
766 //returns true if indices are found
768 rOutCooSysIndex
= -1;
769 rOutDimensionIndex
= -1;
772 Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
773 if(xCooSysContainer
.is())
775 Sequence
< Reference
< XCoordinateSystem
> > aCooSysList
= xCooSysContainer
->getCoordinateSystems();
776 for( sal_Int32 nC
=0; nC
<aCooSysList
.getLength(); ++nC
)
778 if( AxisHelper::getIndicesForAxis( xAxis
, aCooSysList
[nC
], rOutDimensionIndex
, rOutAxisIndex
) )
780 rOutCooSysIndex
= nC
;
789 std::vector
< Reference
< XAxis
> > AxisHelper::getAllAxesOfCoordinateSystem(
790 const Reference
< XCoordinateSystem
>& xCooSys
791 , bool bOnlyVisible
/* = false */ )
793 std::vector
< Reference
< XAxis
> > aAxisVector
;
797 sal_Int32 nMaxDimensionIndex
= xCooSys
->getDimension() -1;
798 if( nMaxDimensionIndex
>=0 )
800 sal_Int32 nDimensionIndex
= 0;
801 for(; nDimensionIndex
<=nMaxDimensionIndex
; ++nDimensionIndex
)
803 const sal_Int32 nMaximumAxisIndex
= xCooSys
->getMaximumAxisIndexByDimension(nDimensionIndex
);
804 for(sal_Int32 nAxisIndex
=0; nAxisIndex
<=nMaximumAxisIndex
; ++nAxisIndex
)
808 Reference
< XAxis
> xAxis( xCooSys
->getAxisByDimension( nDimensionIndex
, nAxisIndex
) );
809 bool bAddAxis
= true;
814 Reference
< beans::XPropertySet
> xAxisProp( xAxis
, uno::UNO_QUERY
);
815 if( !xAxisProp
.is() ||
816 !(xAxisProp
->getPropertyValue( "Show") >>= bAddAxis
) )
820 aAxisVector
.push_back( xAxis
);
823 catch( const uno::Exception
& ex
)
825 ASSERT_EXCEPTION( ex
);
835 Sequence
< Reference
< XAxis
> > AxisHelper::getAllAxesOfDiagram(
836 const Reference
< XDiagram
>& xDiagram
837 , bool bOnlyVisible
)
839 std::vector
< Reference
< XAxis
> > aAxisVector
;
841 Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
842 if(xCooSysContainer
.is())
844 Sequence
< Reference
< XCoordinateSystem
> > aCooSysList
= xCooSysContainer
->getCoordinateSystems();
846 for( nC
=0; nC
<aCooSysList
.getLength(); ++nC
)
848 std::vector
< Reference
< XAxis
> > aAxesPerCooSys( AxisHelper::getAllAxesOfCoordinateSystem( aCooSysList
[nC
], bOnlyVisible
) );
849 aAxisVector
.insert( aAxisVector
.end(), aAxesPerCooSys
.begin(), aAxesPerCooSys
.end() );
853 return ContainerHelper::ContainerToSequence( aAxisVector
);
856 Sequence
< Reference
< beans::XPropertySet
> > AxisHelper::getAllGrids( const Reference
< XDiagram
>& xDiagram
)
858 Sequence
< Reference
< XAxis
> > aAllAxes( AxisHelper::getAllAxesOfDiagram( xDiagram
) );
859 std::vector
< Reference
< beans::XPropertySet
> > aGridVector
;
862 for( nA
=0; nA
<aAllAxes
.getLength(); ++nA
)
864 Reference
< XAxis
> xAxis( aAllAxes
[nA
] );
867 Reference
< beans::XPropertySet
> xGridProperties( xAxis
->getGridProperties() );
868 if( xGridProperties
.is() )
869 aGridVector
.push_back( xGridProperties
);
871 Sequence
< Reference
< beans::XPropertySet
> > aSubGrids( xAxis
->getSubGridProperties() );;
872 sal_Int32 nSubGrid
= 0;
873 for( nSubGrid
= 0; nSubGrid
< aSubGrids
.getLength(); ++nSubGrid
)
875 Reference
< beans::XPropertySet
> xSubGrid( aSubGrids
[nSubGrid
] );
877 aGridVector
.push_back( xSubGrid
);
881 return ContainerHelper::ContainerToSequence( aGridVector
);
884 void AxisHelper::getAxisOrGridPossibilities( Sequence
< sal_Bool
>& rPossibilityList
885 , const Reference
< XDiagram
>& xDiagram
, sal_Bool bAxis
)
887 rPossibilityList
.realloc(6);
889 sal_Int32 nDimensionCount
= DiagramHelper::getDimension( xDiagram
);
893 Reference
< XChartType
> xChartType
= DiagramHelper::getChartTypeByIndex( xDiagram
, 0 );
894 for(nIndex
=0;nIndex
<3;nIndex
++)
895 rPossibilityList
[nIndex
]=ChartTypeHelper::isSupportingMainAxis(xChartType
,nDimensionCount
,nIndex
);
896 for(nIndex
=3;nIndex
<6;nIndex
++)
898 rPossibilityList
[nIndex
]=ChartTypeHelper::isSupportingSecondaryAxis(xChartType
,nDimensionCount
,nIndex
-3);
900 rPossibilityList
[nIndex
] = rPossibilityList
[nIndex
-3];
903 bool AxisHelper::isSecondaryYAxisNeeded( const Reference
< XCoordinateSystem
>& xCooSys
)
905 Reference
< chart2::XChartTypeContainer
> xCTCnt( xCooSys
, uno::UNO_QUERY
);
908 Sequence
< Reference
< chart2::XChartType
> > aChartTypes( xCTCnt
->getChartTypes() );
909 for( sal_Int32 i
=0; i
<aChartTypes
.getLength(); ++i
)
911 Reference
< XDataSeriesContainer
> xSeriesContainer( aChartTypes
[i
] , uno::UNO_QUERY
);
912 if( !xSeriesContainer
.is() )
915 Sequence
< Reference
< XDataSeries
> > aSeriesList( xSeriesContainer
->getDataSeries() );
916 for( sal_Int32 nS
= aSeriesList
.getLength(); nS
-- ; )
918 Reference
< beans::XPropertySet
> xProp( aSeriesList
[nS
], uno::UNO_QUERY
);
921 sal_Int32 nAttachedAxisIndex
= 0;
922 if( ( xProp
->getPropertyValue( "AttachedAxisIndex" ) >>= nAttachedAxisIndex
) && nAttachedAxisIndex
>0 )
931 bool AxisHelper::shouldAxisBeDisplayed( const Reference
< XAxis
>& xAxis
932 , const Reference
< XCoordinateSystem
>& xCooSys
)
936 if( xAxis
.is() && xCooSys
.is() )
938 sal_Int32 nDimensionIndex
=-1;
939 sal_Int32 nAxisIndex
=-1;
940 if( AxisHelper::getIndicesForAxis( xAxis
, xCooSys
, nDimensionIndex
, nAxisIndex
) )
942 sal_Int32 nDimensionCount
= xCooSys
->getDimension();
943 Reference
< XChartType
> xChartType( AxisHelper::getChartTypeByIndex( xCooSys
, 0 ) );
945 bool bMainAxis
= (nAxisIndex
==MAIN_AXIS_INDEX
);
947 bRet
= ChartTypeHelper::isSupportingMainAxis(xChartType
,nDimensionCount
,nDimensionIndex
);
949 bRet
= ChartTypeHelper::isSupportingSecondaryAxis(xChartType
,nDimensionCount
,nDimensionIndex
);
956 void AxisHelper::getAxisOrGridExcistence( Sequence
< sal_Bool
>& rExistenceList
957 , const Reference
< XDiagram
>& xDiagram
, sal_Bool bAxis
)
959 rExistenceList
.realloc(6);
964 Reference
< XAxis
> xAxis
;
966 rExistenceList
[nN
] = AxisHelper::isAxisShown( nN
, true, xDiagram
);
968 rExistenceList
[nN
] = AxisHelper::isAxisShown( nN
%3, false, xDiagram
);
975 rExistenceList
[nN
] = AxisHelper::isGridShown( nN
, 0, true, xDiagram
);
977 rExistenceList
[nN
] = AxisHelper::isGridShown( nN
%3, 0, false, xDiagram
);
981 bool AxisHelper::changeVisibilityOfAxes( const Reference
< XDiagram
>& xDiagram
982 , const Sequence
< sal_Bool
>& rOldExistenceList
983 , const Sequence
< sal_Bool
>& rNewExistenceList
984 , const Reference
< uno::XComponentContext
>& xContext
985 , ReferenceSizeProvider
* pRefSizeProvider
)
987 bool bChanged
= false;
988 for(sal_Int32 nN
=0;nN
<6;nN
++)
990 if(rOldExistenceList
[nN
]!=rNewExistenceList
[nN
])
993 if(rNewExistenceList
[nN
])
995 AxisHelper::showAxis( nN
%3, nN
<3, xDiagram
, xContext
, pRefSizeProvider
);
998 AxisHelper::hideAxis( nN
%3, nN
<3, xDiagram
);
1004 bool AxisHelper::changeVisibilityOfGrids( const Reference
< XDiagram
>& xDiagram
1005 , const Sequence
< sal_Bool
>& rOldExistenceList
1006 , const Sequence
< sal_Bool
>& rNewExistenceList
1007 , const Reference
< uno::XComponentContext
>& xContext
)
1009 bool bChanged
= false;
1010 for(sal_Int32 nN
=0;nN
<6;nN
++)
1012 if(rOldExistenceList
[nN
]!=rNewExistenceList
[nN
])
1015 if(rNewExistenceList
[nN
])
1016 AxisHelper::showGrid( nN
%3, 0, nN
<3, xDiagram
, xContext
);
1018 AxisHelper::hideGrid( nN
%3, 0, nN
<3, xDiagram
);
1024 Reference
< XCoordinateSystem
> AxisHelper::getCoordinateSystemOfAxis(
1025 const Reference
< XAxis
>& xAxis
1026 , const Reference
< XDiagram
>& xDiagram
)
1028 Reference
< XCoordinateSystem
> xRet
;
1030 Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
1031 if( xCooSysContainer
.is() )
1033 Reference
< XCoordinateSystem
> xCooSys
;
1034 Sequence
< Reference
< XCoordinateSystem
> > aCooSysList( xCooSysContainer
->getCoordinateSystems() );
1035 for( sal_Int32 nCooSysIndex
= 0; nCooSysIndex
< aCooSysList
.getLength(); ++nCooSysIndex
)
1037 xCooSys
= aCooSysList
[nCooSysIndex
];
1038 std::vector
< Reference
< XAxis
> > aAllAxis( AxisHelper::getAllAxesOfCoordinateSystem( xCooSys
) );
1040 ::std::vector
< Reference
< XAxis
> >::iterator aFound
=
1041 ::std::find( aAllAxis
.begin(), aAllAxis
.end(), xAxis
);
1042 if( aFound
!= aAllAxis
.end())
1044 xRet
.set( xCooSys
);
1052 Reference
< XChartType
> AxisHelper::getChartTypeByIndex( const Reference
< XCoordinateSystem
>& xCooSys
, sal_Int32 nIndex
)
1054 Reference
< XChartType
> xChartType
;
1056 Reference
< XChartTypeContainer
> xChartTypeContainer( xCooSys
, uno::UNO_QUERY
);
1057 if( xChartTypeContainer
.is() )
1059 Sequence
< Reference
< XChartType
> > aChartTypeList( xChartTypeContainer
->getChartTypes() );
1060 if( nIndex
>= 0 && nIndex
< aChartTypeList
.getLength() )
1061 xChartType
.set( aChartTypeList
[nIndex
] );
1067 void AxisHelper::setRTLAxisLayout( const Reference
< XCoordinateSystem
>& xCooSys
)
1071 bool bCartesian
= xCooSys
->getViewServiceName().equals( CHART2_COOSYSTEM_CARTESIAN_VIEW_SERVICE_NAME
);
1074 bool bVertical
= false;
1075 Reference
< beans::XPropertySet
> xCooSysProp( xCooSys
, uno::UNO_QUERY
);
1076 if( xCooSysProp
.is() )
1077 xCooSysProp
->getPropertyValue( "SwapXAndYAxis" ) >>= bVertical
;
1079 sal_Int32 nHorizontalAxisDimension
= bVertical
? 1 : 0;
1080 sal_Int32 nVerticalAxisDimension
= bVertical
? 0 : 1;
1084 //reverse direction for horizontal main axis
1085 Reference
< chart2::XAxis
> xHorizontalMainAxis( AxisHelper::getAxis( nHorizontalAxisDimension
, MAIN_AXIS_INDEX
, xCooSys
) );
1086 if( xHorizontalMainAxis
.is() )
1088 chart2::ScaleData aScale
= xHorizontalMainAxis
->getScaleData();
1089 aScale
.Orientation
= chart2::AxisOrientation_REVERSE
;
1090 xHorizontalMainAxis
->setScaleData(aScale
);
1093 //mathematical direction for vertical main axis
1094 Reference
< chart2::XAxis
> xVerticalMainAxis( AxisHelper::getAxis( nVerticalAxisDimension
, MAIN_AXIS_INDEX
, xCooSys
) );
1095 if( xVerticalMainAxis
.is() )
1097 chart2::ScaleData aScale
= xVerticalMainAxis
->getScaleData();
1098 aScale
.Orientation
= chart2::AxisOrientation_MATHEMATICAL
;
1099 xVerticalMainAxis
->setScaleData(aScale
);
1102 catch( const uno::Exception
& ex
)
1104 ASSERT_EXCEPTION( ex
);
1109 //reverse direction for horizontal secondary axis
1110 Reference
< chart2::XAxis
> xHorizontalSecondaryAxis( AxisHelper::getAxis( nHorizontalAxisDimension
, SECONDARY_AXIS_INDEX
, xCooSys
) );
1111 if( xHorizontalSecondaryAxis
.is() )
1113 chart2::ScaleData aScale
= xHorizontalSecondaryAxis
->getScaleData();
1114 aScale
.Orientation
= chart2::AxisOrientation_REVERSE
;
1115 xHorizontalSecondaryAxis
->setScaleData(aScale
);
1118 //mathematical direction for vertical secondary axis
1119 Reference
< chart2::XAxis
> xVerticalSecondaryAxis( AxisHelper::getAxis( nVerticalAxisDimension
, SECONDARY_AXIS_INDEX
, xCooSys
) );
1120 if( xVerticalSecondaryAxis
.is() )
1122 chart2::ScaleData aScale
= xVerticalSecondaryAxis
->getScaleData();
1123 aScale
.Orientation
= chart2::AxisOrientation_MATHEMATICAL
;
1124 xVerticalSecondaryAxis
->setScaleData(aScale
);
1127 catch( const uno::Exception
& ex
)
1129 ASSERT_EXCEPTION( ex
);
1135 Reference
< XChartType
> AxisHelper::getFirstChartTypeWithSeriesAttachedToAxisIndex( const Reference
< chart2::XDiagram
>& xDiagram
, const sal_Int32 nAttachedAxisIndex
)
1137 Reference
< XChartType
> xChartType
;
1138 ::std::vector
< Reference
< XDataSeries
> > aSeriesVector( DiagramHelper::getDataSeriesFromDiagram( xDiagram
) );
1139 ::std::vector
< Reference
< XDataSeries
> >::const_iterator aIter
= aSeriesVector
.begin();
1140 for( ; aIter
!= aSeriesVector
.end(); ++aIter
)
1142 sal_Int32 nCurrentIndex
= DataSeriesHelper::getAttachedAxisIndex( *aIter
);
1143 if( nAttachedAxisIndex
== nCurrentIndex
)
1145 xChartType
= DiagramHelper::getChartTypeOfSeries( xDiagram
, *aIter
);
1153 bool AxisHelper::isAxisPositioningEnabled()
1155 const SvtSaveOptions::ODFDefaultVersion
nCurrentVersion( SvtSaveOptions().GetODFDefaultVersion() );
1156 return nCurrentVersion
>= SvtSaveOptions::ODFVER_012
;
1159 //.............................................................................
1161 //.............................................................................
1163 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */