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 .
20 #include "AxisHelper.hxx"
21 #include "DiagramHelper.hxx"
22 #include "ChartTypeHelper.hxx"
24 #include "AxisIndexDefines.hxx"
25 #include "LinePropertiesHelper.hxx"
26 #include "ContainerHelper.hxx"
27 #include "servicenames_coosystems.hxx"
28 #include "DataSeriesHelper.hxx"
29 #include "Scaling.hxx"
30 #include "ChartModelHelper.hxx"
31 #include "DataSourceHelper.hxx"
32 #include <unonames.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 #include <rtl/ustrbuf.hxx>
44 #include <rtl/math.hxx>
46 #include <com/sun/star/util/XCloneable.hpp>
47 #include <com/sun/star/lang/XServiceName.hpp>
53 using namespace ::com::sun::star
;
54 using namespace ::com::sun::star::chart2
;
55 using ::com::sun::star::uno::Reference
;
56 using ::com::sun::star::uno::Sequence
;
58 Reference
< chart2::XScaling
> AxisHelper::createLinearScaling()
60 return new LinearScaling( 1.0, 0.0 );
63 Reference
< chart2::XScaling
> AxisHelper::createLogarithmicScaling( double fBase
)
65 return new LogarithmicScaling( fBase
);
68 ScaleData
AxisHelper::createDefaultScale()
71 aScaleData
.AxisType
= chart2::AxisType::REALNUMBER
;
72 aScaleData
.AutoDateAxis
= true;
73 aScaleData
.ShiftedCategoryPosition
= false;//this is adapted in the view code currently
74 Sequence
< SubIncrement
> aSubIncrements(1);
75 aSubIncrements
[0] = SubIncrement();
76 aScaleData
.IncrementData
.SubIncrements
= aSubIncrements
;
80 void AxisHelper::removeExplicitScaling( ScaleData
& rScaleData
)
83 rScaleData
.Minimum
= rScaleData
.Maximum
= rScaleData
.Origin
= aEmpty
;
84 rScaleData
.Scaling
= 0;
85 ScaleData
aDefaultScale( createDefaultScale() );
86 rScaleData
.IncrementData
= aDefaultScale
.IncrementData
;
87 rScaleData
.TimeIncrement
= aDefaultScale
.TimeIncrement
;
90 bool AxisHelper::isLogarithmic( const Reference
< XScaling
>& xScaling
)
92 Reference
< lang::XServiceName
> xServiceName( xScaling
, uno::UNO_QUERY
);
93 return xServiceName
.is()
94 && xServiceName
->getServiceName() == "com.sun.star.chart2.LogarithmicScaling";
97 chart2::ScaleData
AxisHelper::getDateCheckedScale( const Reference
< chart2::XAxis
>& xAxis
, ChartModel
& rModel
)
99 ScaleData aScale
= xAxis
->getScaleData();
100 Reference
< chart2::XCoordinateSystem
> xCooSys( ChartModelHelper::getFirstCoordinateSystem( rModel
) );
101 if( aScale
.AutoDateAxis
&& aScale
.AxisType
== AxisType::CATEGORY
)
103 sal_Int32 nDimensionIndex
=0; sal_Int32 nAxisIndex
=0;
104 AxisHelper::getIndicesForAxis(xAxis
, xCooSys
, nDimensionIndex
, nAxisIndex
);
105 bool bChartTypeAllowsDateAxis
= ChartTypeHelper::isSupportingDateAxis( AxisHelper::getChartTypeByIndex( xCooSys
, 0 ), 2, nDimensionIndex
);
106 if( bChartTypeAllowsDateAxis
)
107 aScale
.AxisType
= AxisType::DATE
;
109 if( aScale
.AxisType
== AxisType::DATE
)
111 ExplicitCategoriesProvider
aExplicitCategoriesProvider( xCooSys
, rModel
);
112 if( !aExplicitCategoriesProvider
.isDateAxis() )
113 aScale
.AxisType
= AxisType::CATEGORY
;
118 void AxisHelper::checkDateAxis( chart2::ScaleData
& rScale
, ExplicitCategoriesProvider
* pExplicitCategoriesProvider
, bool bChartTypeAllowsDateAxis
)
120 if( rScale
.AutoDateAxis
&& rScale
.AxisType
== AxisType::CATEGORY
&& bChartTypeAllowsDateAxis
)
122 rScale
.AxisType
= AxisType::DATE
;
123 removeExplicitScaling( rScale
);
125 if( rScale
.AxisType
== AxisType::DATE
&& (!pExplicitCategoriesProvider
|| !pExplicitCategoriesProvider
->isDateAxis()) )
127 rScale
.AxisType
= AxisType::CATEGORY
;
128 removeExplicitScaling( rScale
);
132 sal_Int32
AxisHelper::getExplicitNumberFormatKeyForAxis(
133 const Reference
< chart2::XAxis
>& xAxis
134 , const Reference
< chart2::XCoordinateSystem
> & xCorrespondingCoordinateSystem
135 , const Reference
<chart2::XChartDocument
>& xChartDoc
136 , bool bSearchForParallelAxisIfNothingIsFound
)
138 sal_Int32
nNumberFormatKey(0);
139 sal_Int32 nAxisIndex
= 0;
140 sal_Int32 nDimensionIndex
= 1;
141 AxisHelper::getIndicesForAxis( xAxis
, xCorrespondingCoordinateSystem
, nDimensionIndex
, nAxisIndex
);
142 Reference
<util::XNumberFormatsSupplier
> const xNumberFormatsSupplier(xChartDoc
, uno::UNO_QUERY
);
144 Reference
< beans::XPropertySet
> xProp( xAxis
, uno::UNO_QUERY
);
148 bool bLinkToSource
= true;
149 xProp
->getPropertyValue(CHART_UNONAME_LINK_TO_SRC_NUMFMT
) >>= bLinkToSource
;
150 xProp
->getPropertyValue(CHART_UNONAME_NUMFMT
) >>= nNumberFormatKey
;
152 sal_Int32 nOldNumberFormat
= nNumberFormatKey
;
156 bool bFormatSet
= false;
157 //check whether we have a percent scale -> use percent format
158 ChartModel
* pModel
= NULL
;
159 if( xNumberFormatsSupplier
.is() )
161 pModel
= dynamic_cast<ChartModel
*>( xChartDoc
.get() );
166 ScaleData aData
= AxisHelper::getDateCheckedScale( xAxis
, *pModel
);
167 if( aData
.AxisType
==AxisType::PERCENT
)
169 sal_Int32 nPercentFormat
= DiagramHelper::getPercentNumberFormat( xNumberFormatsSupplier
);
170 if( nPercentFormat
!= -1 )
172 nNumberFormatKey
= nPercentFormat
;
176 else if( aData
.AxisType
==AxisType::DATE
)
178 if( aData
.Categories
.is() )
180 Reference
< data::XDataSequence
> xSeq( aData
.Categories
->getValues());
181 if( xSeq
.is() && !( xChartDoc
.is() && xChartDoc
->hasInternalDataProvider()) )
182 nNumberFormatKey
= xSeq
->getNumberFormatKeyByIndex( -1 );
184 nNumberFormatKey
= DiagramHelper::getDateNumberFormat( xNumberFormatsSupplier
);
188 else if( xChartDoc
.is() && xChartDoc
->hasInternalDataProvider() && nDimensionIndex
== 0 ) //maybe date axis
190 Reference
< chart2::XDiagram
> xDiagram( xChartDoc
->getFirstDiagram() );
191 if( DiagramHelper::isSupportingDateAxis( xDiagram
) )
193 nNumberFormatKey
= DiagramHelper::getDateNumberFormat( xNumberFormatsSupplier
);
197 Reference
< data::XDataSource
> xSource( DataSourceHelper::getUsedData( xChartDoc
) );
200 ::std::vector
< Reference
< chart2::data::XLabeledDataSequence
> > aXValues(
201 DataSeriesHelper::getAllDataSequencesByRole( xSource
->getDataSequences(), "values-x", true ) );
202 if( aXValues
.empty() )
204 Reference
< data::XLabeledDataSequence
> xCategories( DiagramHelper::getCategoriesFromDiagram( xDiagram
) );
205 if( xCategories
.is() )
207 Reference
< data::XDataSequence
> xSeq( xCategories
->getValues());
210 bool bHasValidDoubles
= false;
212 Sequence
< uno::Any
> aCats( xSeq
->getData() );
213 sal_Int32 nCount
= aCats
.getLength();
214 for( sal_Int32 i
= 0; i
< nCount
; ++i
)
216 if( (aCats
[i
]>>=fTest
) && !::rtl::math::isNan(fTest
) )
218 bHasValidDoubles
=true;
222 if( bHasValidDoubles
)
223 nNumberFormatKey
= DiagramHelper::getDateNumberFormat( xNumberFormatsSupplier
);
235 typedef ::std::map
< sal_Int32
, sal_Int32
> tNumberformatFrequency
;
236 tNumberformatFrequency aKeyMap
;
237 bool bNumberFormatKeyFoundViaAttachedData
= false;
241 Reference
< XChartTypeContainer
> xCTCnt( xCorrespondingCoordinateSystem
, uno::UNO_QUERY_THROW
);
244 OUString aRoleToMatch
;
245 if( nDimensionIndex
== 0 )
246 aRoleToMatch
= "values-x";
247 Sequence
< Reference
< XChartType
> > aChartTypes( xCTCnt
->getChartTypes());
248 for( sal_Int32 nCTIdx
=0; nCTIdx
<aChartTypes
.getLength(); ++nCTIdx
)
250 if( nDimensionIndex
!= 0 )
251 aRoleToMatch
= ChartTypeHelper::getRoleOfSequenceForYAxisNumberFormatDetection( aChartTypes
[nCTIdx
] );
252 Reference
< XDataSeriesContainer
> xDSCnt( aChartTypes
[nCTIdx
], uno::UNO_QUERY_THROW
);
253 Sequence
< Reference
< XDataSeries
> > aDataSeriesSeq( xDSCnt
->getDataSeries());
254 for( sal_Int32 nSeriesIdx
=0; nSeriesIdx
<aDataSeriesSeq
.getLength(); ++nSeriesIdx
)
256 Reference
< chart2::XDataSeries
> xDataSeries(aDataSeriesSeq
[nSeriesIdx
]);
257 Reference
< data::XDataSource
> xSource( xDataSeries
, uno::UNO_QUERY_THROW
);
259 if( nDimensionIndex
== 1 )
261 //only take those series into accoutn that are attached to this axis
262 sal_Int32 nAttachedAxisIndex
= DataSeriesHelper::getAttachedAxisIndex(xDataSeries
);
263 if( nAttachedAxisIndex
!= nAxisIndex
)
267 Reference
< data::XLabeledDataSequence
> xLabeledSeq(
268 DataSeriesHelper::getDataSequenceByRole( xSource
, aRoleToMatch
) );
270 if( !xLabeledSeq
.is() && nDimensionIndex
==0 )
272 ScaleData aData
= xAxis
->getScaleData();
273 xLabeledSeq
= aData
.Categories
;
276 if( xLabeledSeq
.is() )
278 Reference
< data::XDataSequence
> xSeq( xLabeledSeq
->getValues());
281 sal_Int32 nKey
= xSeq
->getNumberFormatKeyByIndex( -1 );
282 // initialize the value
283 if( aKeyMap
.find( nKey
) == aKeyMap
.end())
285 // increase frequency
286 aKeyMap
[ nKey
] = (aKeyMap
[ nKey
] + 1);
293 catch( const uno::Exception
& ex
)
295 ASSERT_EXCEPTION( ex
);
298 if( ! aKeyMap
.empty())
300 sal_Int32 nMaxFreq
= 0;
301 // find most frequent key
302 for( tNumberformatFrequency::const_iterator aIt
= aKeyMap
.begin();
303 aIt
!= aKeyMap
.end(); ++aIt
)
307 "NumberFormatKey " << (*aIt
).first
<< " appears "
308 << (*aIt
).second
<< " times");
309 // all values must at least be 1
310 if( (*aIt
).second
> nMaxFreq
)
312 nNumberFormatKey
= (*aIt
).first
;
313 bNumberFormatKeyFoundViaAttachedData
= true;
314 nMaxFreq
= (*aIt
).second
;
319 if( bSearchForParallelAxisIfNothingIsFound
)
321 //no format is set to this axis and no data is set to this axis
322 //--> try to obtain the format from the parallel y-axis
323 if( !bNumberFormatKeyFoundViaAttachedData
&& nDimensionIndex
== 1 )
325 sal_Int32 nParallelAxisIndex
= (nAxisIndex
==1) ?0 :1;
326 Reference
< XAxis
> xParallelAxis( AxisHelper::getAxis( 1, nParallelAxisIndex
, xCorrespondingCoordinateSystem
) );
327 nNumberFormatKey
= AxisHelper::getExplicitNumberFormatKeyForAxis(xParallelAxis
, xCorrespondingCoordinateSystem
, xChartDoc
, false);
332 if (nOldNumberFormat
!= nNumberFormatKey
)
333 xProp
->setPropertyValue(CHART_UNONAME_NUMFMT
, uno::makeAny(nNumberFormatKey
));
336 return nNumberFormatKey
;
339 Reference
< XAxis
> AxisHelper::createAxis(
340 sal_Int32 nDimensionIndex
341 , sal_Int32 nAxisIndex
// 0==main or 1==secondary axis
342 , const Reference
< XCoordinateSystem
>& xCooSys
343 , const Reference
< uno::XComponentContext
> & xContext
344 , ReferenceSizeProvider
* pRefSizeProvider
)
346 if( !xContext
.is() || !xCooSys
.is() )
348 if( nDimensionIndex
>= xCooSys
->getDimension() )
351 Reference
< XAxis
> xAxis( xContext
->getServiceManager()->createInstanceWithContext(
352 "com.sun.star.chart2.Axis", xContext
), uno::UNO_QUERY
);
354 OSL_ASSERT( xAxis
.is());
357 xCooSys
->setAxisByDimension( nDimensionIndex
, xAxis
, nAxisIndex
);
359 if( nAxisIndex
>0 )//when inserting secondary axes copy some things from the main axis
361 ::com::sun::star::chart::ChartAxisPosition
eNewAxisPos( ::com::sun::star::chart::ChartAxisPosition_END
);
363 Reference
< XAxis
> xMainAxis( xCooSys
->getAxisByDimension( nDimensionIndex
, 0 ) );
366 ScaleData aScale
= xAxis
->getScaleData();
367 ScaleData aMainScale
= xMainAxis
->getScaleData();
369 aScale
.AxisType
= aMainScale
.AxisType
;
370 aScale
.AutoDateAxis
= aMainScale
.AutoDateAxis
;
371 aScale
.Categories
= aMainScale
.Categories
;
372 aScale
.Orientation
= aMainScale
.Orientation
;
374 xAxis
->setScaleData( aScale
);
376 //ensure that the second axis is not placed on the main axis
377 Reference
< beans::XPropertySet
> xMainProp( xMainAxis
, uno::UNO_QUERY
);
380 ::com::sun::star::chart::ChartAxisPosition
eMainAxisPos( ::com::sun::star::chart::ChartAxisPosition_ZERO
);
381 xMainProp
->getPropertyValue("CrossoverPosition") >>= eMainAxisPos
;
382 if( ::com::sun::star::chart::ChartAxisPosition_END
== eMainAxisPos
)
383 eNewAxisPos
= ::com::sun::star::chart::ChartAxisPosition_START
;
387 Reference
< beans::XPropertySet
> xProp( xAxis
, uno::UNO_QUERY
);
389 xProp
->setPropertyValue("CrossoverPosition", uno::makeAny(eNewAxisPos
) );
392 Reference
< beans::XPropertySet
> xProp( xAxis
, uno::UNO_QUERY
);
395 // set correct initial AutoScale
396 if( pRefSizeProvider
)
397 pRefSizeProvider
->setValuesAtPropertySet( xProp
);
399 catch( const uno::Exception
& e
)
401 ASSERT_EXCEPTION( e
);
407 Reference
< XAxis
> AxisHelper::createAxis( sal_Int32 nDimensionIndex
, bool bMainAxis
408 , const Reference
< chart2::XDiagram
>& xDiagram
409 , const Reference
< uno::XComponentContext
>& xContext
410 , ReferenceSizeProvider
* pRefSizeProvider
)
412 OSL_ENSURE( xContext
.is(), "need a context to create an axis" );
416 sal_Int32 nAxisIndex
= bMainAxis
? MAIN_AXIS_INDEX
: SECONDARY_AXIS_INDEX
;
417 sal_Int32 nCooSysIndex
= 0;
418 Reference
< XCoordinateSystem
> xCooSys
= AxisHelper::getCoordinateSystemByIndex( xDiagram
, nCooSysIndex
);
421 return AxisHelper::createAxis(
422 nDimensionIndex
, nAxisIndex
, xCooSys
, xContext
, pRefSizeProvider
);
425 void AxisHelper::showAxis( sal_Int32 nDimensionIndex
, bool bMainAxis
426 , const Reference
< chart2::XDiagram
>& xDiagram
427 , const Reference
< uno::XComponentContext
>& xContext
428 , ReferenceSizeProvider
* pRefSizeProvider
)
433 bool bNewAxisCreated
= false;
434 Reference
< XAxis
> xAxis( AxisHelper::getAxis( nDimensionIndex
, bMainAxis
, xDiagram
) );
435 if( !xAxis
.is() && xContext
.is() )
438 bNewAxisCreated
= true;
439 xAxis
.set( AxisHelper::createAxis( nDimensionIndex
, bMainAxis
, xDiagram
, xContext
, pRefSizeProvider
) );
442 OSL_ASSERT( xAxis
.is());
443 if( !bNewAxisCreated
) //default is true already if created
444 AxisHelper::makeAxisVisible( xAxis
);
447 void AxisHelper::showGrid( sal_Int32 nDimensionIndex
, sal_Int32 nCooSysIndex
, bool bMainGrid
448 , const Reference
< XDiagram
>& xDiagram
449 , const Reference
< uno::XComponentContext
>& /*xContext*/ )
454 Reference
< XCoordinateSystem
> xCooSys
= AxisHelper::getCoordinateSystemByIndex( xDiagram
, nCooSysIndex
);
458 Reference
< XAxis
> xAxis( AxisHelper::getAxis( nDimensionIndex
, MAIN_AXIS_INDEX
, xCooSys
) );
461 //hhhh todo create axis without axis visibility
467 AxisHelper::makeGridVisible( xAxis
->getGridProperties() );
470 Sequence
< Reference
< beans::XPropertySet
> > aSubGrids( xAxis
->getSubGridProperties() );
471 for( sal_Int32 nN
=0; nN
<aSubGrids
.getLength(); nN
++)
472 AxisHelper::makeGridVisible( aSubGrids
[nN
] );
476 void AxisHelper::makeAxisVisible( const Reference
< XAxis
>& xAxis
)
478 Reference
< beans::XPropertySet
> xProps( xAxis
, uno::UNO_QUERY
);
481 xProps
->setPropertyValue( "Show", uno::makeAny( sal_True
) );
482 LinePropertiesHelper::SetLineVisible( xProps
);
483 xProps
->setPropertyValue( "DisplayLabels", uno::makeAny( sal_True
) );
487 void AxisHelper::makeGridVisible( const Reference
< beans::XPropertySet
>& xGridProperties
)
489 if( xGridProperties
.is() )
491 xGridProperties
->setPropertyValue( "Show", uno::makeAny( sal_True
) );
492 LinePropertiesHelper::SetLineVisible( xGridProperties
);
496 void AxisHelper::hideAxis( sal_Int32 nDimensionIndex
, bool bMainAxis
497 , const Reference
< XDiagram
>& xDiagram
)
499 AxisHelper::makeAxisInvisible( AxisHelper::getAxis( nDimensionIndex
, bMainAxis
, xDiagram
) );
502 void AxisHelper::makeAxisInvisible( const Reference
< XAxis
>& xAxis
)
504 Reference
< beans::XPropertySet
> xProps( xAxis
, uno::UNO_QUERY
);
507 xProps
->setPropertyValue( "Show", uno::makeAny( sal_False
) );
511 void AxisHelper::hideAxisIfNoDataIsAttached( const Reference
< XAxis
>& xAxis
, const Reference
< XDiagram
>& xDiagram
)
513 //axis is hidden if no data is attached anymore but data is available
514 bool bOtherSeriesAttachedToThisAxis
= false;
515 ::std::vector
< Reference
< chart2::XDataSeries
> > aSeriesVector( DiagramHelper::getDataSeriesFromDiagram( xDiagram
) );
516 ::std::vector
< Reference
< chart2::XDataSeries
> >::const_iterator aIt
= aSeriesVector
.begin();
517 for( ; aIt
!= aSeriesVector
.end(); ++aIt
)
519 uno::Reference
< chart2::XAxis
> xCurrentAxis( DiagramHelper::getAttachedAxis( *aIt
, xDiagram
), uno::UNO_QUERY
);
520 if( xCurrentAxis
==xAxis
)
522 bOtherSeriesAttachedToThisAxis
= true;
526 if(!bOtherSeriesAttachedToThisAxis
&& !aSeriesVector
.empty() )
527 AxisHelper::makeAxisInvisible( xAxis
);
530 void AxisHelper::hideGrid( sal_Int32 nDimensionIndex
, sal_Int32 nCooSysIndex
, bool bMainGrid
531 , const Reference
< XDiagram
>& xDiagram
)
536 Reference
< XCoordinateSystem
> xCooSys
= AxisHelper::getCoordinateSystemByIndex( xDiagram
, nCooSysIndex
);
540 Reference
< XAxis
> xAxis( AxisHelper::getAxis( nDimensionIndex
, MAIN_AXIS_INDEX
, xCooSys
) );
545 AxisHelper::makeGridInvisible( xAxis
->getGridProperties() );
548 Sequence
< Reference
< beans::XPropertySet
> > aSubGrids( xAxis
->getSubGridProperties() );
549 for( sal_Int32 nN
=0; nN
<aSubGrids
.getLength(); nN
++)
550 AxisHelper::makeGridInvisible( aSubGrids
[nN
] );
554 void AxisHelper::makeGridInvisible( const Reference
< beans::XPropertySet
>& xGridProperties
)
556 if( xGridProperties
.is() )
558 xGridProperties
->setPropertyValue( "Show", uno::makeAny( sal_False
) );
562 bool AxisHelper::isGridShown( sal_Int32 nDimensionIndex
, sal_Int32 nCooSysIndex
, bool bMainGrid
563 , const Reference
< ::com::sun::star::chart2::XDiagram
>& xDiagram
)
567 Reference
< XCoordinateSystem
> xCooSys
= AxisHelper::getCoordinateSystemByIndex( xDiagram
, nCooSysIndex
);
571 Reference
< XAxis
> xAxis( AxisHelper::getAxis( nDimensionIndex
, MAIN_AXIS_INDEX
, xCooSys
) );
576 bRet
= AxisHelper::isGridVisible( xAxis
->getGridProperties() );
579 Sequence
< Reference
< beans::XPropertySet
> > aSubGrids( xAxis
->getSubGridProperties() );
580 if( aSubGrids
.getLength() )
581 bRet
= AxisHelper::isGridVisible( aSubGrids
[0] );
587 Reference
< XCoordinateSystem
> AxisHelper::getCoordinateSystemByIndex(
588 const Reference
< XDiagram
>& xDiagram
, sal_Int32 nIndex
)
590 Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
591 if(!xCooSysContainer
.is())
593 Sequence
< Reference
< XCoordinateSystem
> > aCooSysList
= xCooSysContainer
->getCoordinateSystems();
594 if(0<=nIndex
&& nIndex
<aCooSysList
.getLength())
595 return aCooSysList
[nIndex
];
599 Reference
< XAxis
> AxisHelper::getAxis( sal_Int32 nDimensionIndex
, bool bMainAxis
600 , const Reference
< XDiagram
>& xDiagram
)
602 Reference
< XAxis
> xRet
;
605 Reference
< XCoordinateSystem
> xCooSys
= AxisHelper::getCoordinateSystemByIndex( xDiagram
, 0 );
606 xRet
.set( AxisHelper::getAxis( nDimensionIndex
, bMainAxis
? 0 : 1, xCooSys
) );
608 catch( const uno::Exception
& )
614 Reference
< XAxis
> AxisHelper::getAxis( sal_Int32 nDimensionIndex
, sal_Int32 nAxisIndex
615 , const Reference
< XCoordinateSystem
>& xCooSys
)
617 Reference
< XAxis
> xRet
;
621 if(nDimensionIndex
>= xCooSys
->getDimension())
624 if(nAxisIndex
> xCooSys
->getMaximumAxisIndexByDimension(nDimensionIndex
))
627 assert(nAxisIndex
>= 0);
628 assert(nDimensionIndex
>= 0);
629 xRet
.set( xCooSys
->getAxisByDimension( nDimensionIndex
, nAxisIndex
) );
633 Reference
< XAxis
> AxisHelper::getCrossingMainAxis( const Reference
< XAxis
>& xAxis
634 , const Reference
< XCoordinateSystem
>& xCooSys
)
636 sal_Int32 nDimensionIndex
= 0;
637 sal_Int32 nAxisIndex
= 0;
638 AxisHelper::getIndicesForAxis( xAxis
, xCooSys
, nDimensionIndex
, nAxisIndex
);
639 if( 2==nDimensionIndex
)
642 bool bSwapXY
= false;
643 Reference
< beans::XPropertySet
> xCooSysProp( xCooSys
, uno::UNO_QUERY
);
644 if( xCooSysProp
.is() && (xCooSysProp
->getPropertyValue( "SwapXAndYAxis" ) >>= bSwapXY
) && bSwapXY
)
647 else if( 1==nDimensionIndex
)
651 return AxisHelper::getAxis( nDimensionIndex
, 0, xCooSys
);
654 Reference
< XAxis
> AxisHelper::getParallelAxis( const Reference
< XAxis
>& xAxis
655 , const Reference
< XDiagram
>& xDiagram
)
659 sal_Int32 nCooSysIndex
=-1;
660 sal_Int32 nDimensionIndex
=-1;
661 sal_Int32 nAxisIndex
=-1;
662 if( getIndicesForAxis( xAxis
, xDiagram
, nCooSysIndex
, nDimensionIndex
, nAxisIndex
) )
664 sal_Int32 nParallelAxisIndex
= (nAxisIndex
==1) ?0 :1;
665 return getAxis( nDimensionIndex
, nParallelAxisIndex
, getCoordinateSystemByIndex( xDiagram
, nCooSysIndex
) );
668 catch( const uno::RuntimeException
& )
674 bool AxisHelper::isAxisShown( sal_Int32 nDimensionIndex
, bool bMainAxis
675 , const Reference
< XDiagram
>& xDiagram
)
677 return AxisHelper::isAxisVisible( AxisHelper::getAxis( nDimensionIndex
, bMainAxis
, xDiagram
) );
680 bool AxisHelper::isAxisVisible( const Reference
< XAxis
>& xAxis
)
684 Reference
< beans::XPropertySet
> xProps( xAxis
, uno::UNO_QUERY
);
687 xProps
->getPropertyValue( "Show" ) >>= bRet
;
688 bRet
= bRet
&& ( LinePropertiesHelper::IsLineVisible( xProps
)
689 || areAxisLabelsVisible( xProps
) );
695 bool AxisHelper::areAxisLabelsVisible( const Reference
< beans::XPropertySet
>& xAxisProperties
)
698 if( xAxisProperties
.is() )
700 xAxisProperties
->getPropertyValue( "DisplayLabels" ) >>= bRet
;
705 bool AxisHelper::isGridVisible( const Reference
< beans::XPropertySet
>& xGridProperies
)
709 if( xGridProperies
.is() )
711 xGridProperies
->getPropertyValue( "Show" ) >>= bRet
;
712 bRet
= bRet
&& LinePropertiesHelper::IsLineVisible( xGridProperies
);
718 Reference
< beans::XPropertySet
> AxisHelper::getGridProperties(
719 const Reference
< XCoordinateSystem
>& xCooSys
720 , sal_Int32 nDimensionIndex
, sal_Int32 nAxisIndex
, sal_Int32 nSubGridIndex
)
722 Reference
< beans::XPropertySet
> xRet
;
724 Reference
< XAxis
> xAxis( AxisHelper::getAxis( nDimensionIndex
, nAxisIndex
, xCooSys
) );
727 if( nSubGridIndex
<0 )
728 xRet
.set( xAxis
->getGridProperties() );
731 Sequence
< Reference
< beans::XPropertySet
> > aSubGrids( xAxis
->getSubGridProperties() );
732 if( nSubGridIndex
>= 0 && nSubGridIndex
< aSubGrids
.getLength() )
733 xRet
.set( aSubGrids
[nSubGridIndex
] );
740 sal_Int32
AxisHelper::getDimensionIndexOfAxis(
741 const Reference
< XAxis
>& xAxis
742 , const Reference
< XDiagram
>& xDiagram
)
744 sal_Int32 nDimensionIndex
= -1;
745 sal_Int32 nCooSysIndex
= -1;
746 sal_Int32 nAxisIndex
= -1;
747 AxisHelper::getIndicesForAxis( xAxis
, xDiagram
, nCooSysIndex
, nDimensionIndex
, nAxisIndex
);
748 return nDimensionIndex
;
751 bool AxisHelper::getIndicesForAxis(
752 const Reference
< XAxis
>& xAxis
753 , const Reference
< XCoordinateSystem
>& xCooSys
754 , sal_Int32
& rOutDimensionIndex
, sal_Int32
& rOutAxisIndex
)
756 //returns true if indices are found
758 rOutDimensionIndex
= -1;
761 if( xCooSys
.is() && xAxis
.is() )
763 Reference
< XAxis
> xCurrentAxis
;
764 sal_Int32
nDimensionCount( xCooSys
->getDimension() );
765 for( sal_Int32 nDimensionIndex
= 0; nDimensionIndex
< nDimensionCount
; nDimensionIndex
++ )
767 sal_Int32 nMaxAxisIndex
= xCooSys
->getMaximumAxisIndexByDimension(nDimensionIndex
);
768 for( sal_Int32 nAxisIndex
= 0; nAxisIndex
<= nMaxAxisIndex
; nAxisIndex
++ )
770 xCurrentAxis
= xCooSys
->getAxisByDimension(nDimensionIndex
,nAxisIndex
);
771 if( xCurrentAxis
== xAxis
)
773 rOutDimensionIndex
= nDimensionIndex
;
774 rOutAxisIndex
= nAxisIndex
;
783 bool AxisHelper::getIndicesForAxis( const Reference
< XAxis
>& xAxis
, const Reference
< XDiagram
>& xDiagram
784 , sal_Int32
& rOutCooSysIndex
, sal_Int32
& rOutDimensionIndex
, sal_Int32
& rOutAxisIndex
)
786 //returns true if indices are found
788 rOutCooSysIndex
= -1;
789 rOutDimensionIndex
= -1;
792 Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
793 if(xCooSysContainer
.is())
795 Sequence
< Reference
< XCoordinateSystem
> > aCooSysList
= xCooSysContainer
->getCoordinateSystems();
796 for( sal_Int32 nC
=0; nC
<aCooSysList
.getLength(); ++nC
)
798 if( AxisHelper::getIndicesForAxis( xAxis
, aCooSysList
[nC
], rOutDimensionIndex
, rOutAxisIndex
) )
800 rOutCooSysIndex
= nC
;
809 std::vector
< Reference
< XAxis
> > AxisHelper::getAllAxesOfCoordinateSystem(
810 const Reference
< XCoordinateSystem
>& xCooSys
811 , bool bOnlyVisible
/* = false */ )
813 std::vector
< Reference
< XAxis
> > aAxisVector
;
817 sal_Int32 nMaxDimensionIndex
= xCooSys
->getDimension() -1;
818 if( nMaxDimensionIndex
>=0 )
820 sal_Int32 nDimensionIndex
= 0;
821 for(; nDimensionIndex
<=nMaxDimensionIndex
; ++nDimensionIndex
)
823 const sal_Int32 nMaximumAxisIndex
= xCooSys
->getMaximumAxisIndexByDimension(nDimensionIndex
);
824 for(sal_Int32 nAxisIndex
=0; nAxisIndex
<=nMaximumAxisIndex
; ++nAxisIndex
)
828 Reference
< XAxis
> xAxis( xCooSys
->getAxisByDimension( nDimensionIndex
, nAxisIndex
) );
831 bool bAddAxis
= true;
834 Reference
< beans::XPropertySet
> xAxisProp( xAxis
, uno::UNO_QUERY
);
835 if( !xAxisProp
.is() ||
836 !(xAxisProp
->getPropertyValue( "Show") >>= bAddAxis
) )
840 aAxisVector
.push_back( xAxis
);
843 catch( const uno::Exception
& ex
)
845 ASSERT_EXCEPTION( ex
);
855 Sequence
< Reference
< XAxis
> > AxisHelper::getAllAxesOfDiagram(
856 const Reference
< XDiagram
>& xDiagram
857 , bool bOnlyVisible
)
859 std::vector
< Reference
< XAxis
> > aAxisVector
;
861 Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
862 if(xCooSysContainer
.is())
864 Sequence
< Reference
< XCoordinateSystem
> > aCooSysList
= xCooSysContainer
->getCoordinateSystems();
866 for( nC
=0; nC
<aCooSysList
.getLength(); ++nC
)
868 std::vector
< Reference
< XAxis
> > aAxesPerCooSys( AxisHelper::getAllAxesOfCoordinateSystem( aCooSysList
[nC
], bOnlyVisible
) );
869 aAxisVector
.insert( aAxisVector
.end(), aAxesPerCooSys
.begin(), aAxesPerCooSys
.end() );
873 return ContainerHelper::ContainerToSequence( aAxisVector
);
876 Sequence
< Reference
< beans::XPropertySet
> > AxisHelper::getAllGrids( const Reference
< XDiagram
>& xDiagram
)
878 Sequence
< Reference
< XAxis
> > aAllAxes( AxisHelper::getAllAxesOfDiagram( xDiagram
) );
879 std::vector
< Reference
< beans::XPropertySet
> > aGridVector
;
882 for( nA
=0; nA
<aAllAxes
.getLength(); ++nA
)
884 Reference
< XAxis
> xAxis( aAllAxes
[nA
] );
887 Reference
< beans::XPropertySet
> xGridProperties( xAxis
->getGridProperties() );
888 if( xGridProperties
.is() )
889 aGridVector
.push_back( xGridProperties
);
891 Sequence
< Reference
< beans::XPropertySet
> > aSubGrids( xAxis
->getSubGridProperties() );;
892 sal_Int32 nSubGrid
= 0;
893 for( nSubGrid
= 0; nSubGrid
< aSubGrids
.getLength(); ++nSubGrid
)
895 Reference
< beans::XPropertySet
> xSubGrid( aSubGrids
[nSubGrid
] );
897 aGridVector
.push_back( xSubGrid
);
901 return ContainerHelper::ContainerToSequence( aGridVector
);
904 void AxisHelper::getAxisOrGridPossibilities( Sequence
< sal_Bool
>& rPossibilityList
905 , const Reference
< XDiagram
>& xDiagram
, bool bAxis
)
907 rPossibilityList
.realloc(6);
909 sal_Int32 nDimensionCount
= DiagramHelper::getDimension( xDiagram
);
913 Reference
< XChartType
> xChartType
= DiagramHelper::getChartTypeByIndex( xDiagram
, 0 );
914 for(nIndex
=0;nIndex
<3;nIndex
++)
915 rPossibilityList
[nIndex
]=ChartTypeHelper::isSupportingMainAxis(xChartType
,nDimensionCount
,nIndex
);
916 for(nIndex
=3;nIndex
<6;nIndex
++)
918 rPossibilityList
[nIndex
]=ChartTypeHelper::isSupportingSecondaryAxis(xChartType
,nDimensionCount
,nIndex
-3);
920 rPossibilityList
[nIndex
] = rPossibilityList
[nIndex
-3];
923 bool AxisHelper::isSecondaryYAxisNeeded( const Reference
< XCoordinateSystem
>& xCooSys
)
925 Reference
< chart2::XChartTypeContainer
> xCTCnt( xCooSys
, uno::UNO_QUERY
);
928 Sequence
< Reference
< chart2::XChartType
> > aChartTypes( xCTCnt
->getChartTypes() );
929 for( sal_Int32 i
=0; i
<aChartTypes
.getLength(); ++i
)
931 Reference
< XDataSeriesContainer
> xSeriesContainer( aChartTypes
[i
] , uno::UNO_QUERY
);
932 if( !xSeriesContainer
.is() )
935 Sequence
< Reference
< XDataSeries
> > aSeriesList( xSeriesContainer
->getDataSeries() );
936 for( sal_Int32 nS
= aSeriesList
.getLength(); nS
-- ; )
938 Reference
< beans::XPropertySet
> xProp( aSeriesList
[nS
], uno::UNO_QUERY
);
941 sal_Int32 nAttachedAxisIndex
= 0;
942 if( ( xProp
->getPropertyValue( "AttachedAxisIndex" ) >>= nAttachedAxisIndex
) && nAttachedAxisIndex
>0 )
951 bool AxisHelper::shouldAxisBeDisplayed( const Reference
< XAxis
>& xAxis
952 , const Reference
< XCoordinateSystem
>& xCooSys
)
956 if( xAxis
.is() && xCooSys
.is() )
958 sal_Int32 nDimensionIndex
=-1;
959 sal_Int32 nAxisIndex
=-1;
960 if( AxisHelper::getIndicesForAxis( xAxis
, xCooSys
, nDimensionIndex
, nAxisIndex
) )
962 sal_Int32 nDimensionCount
= xCooSys
->getDimension();
963 Reference
< XChartType
> xChartType( AxisHelper::getChartTypeByIndex( xCooSys
, 0 ) );
965 bool bMainAxis
= (nAxisIndex
==MAIN_AXIS_INDEX
);
967 bRet
= ChartTypeHelper::isSupportingMainAxis(xChartType
,nDimensionCount
,nDimensionIndex
);
969 bRet
= ChartTypeHelper::isSupportingSecondaryAxis(xChartType
,nDimensionCount
,nDimensionIndex
);
976 void AxisHelper::getAxisOrGridExcistence( Sequence
< sal_Bool
>& rExistenceList
977 , const Reference
< XDiagram
>& xDiagram
, bool bAxis
)
979 rExistenceList
.realloc(6);
984 Reference
< XAxis
> xAxis
;
986 rExistenceList
[nN
] = AxisHelper::isAxisShown( nN
, true, xDiagram
);
988 rExistenceList
[nN
] = AxisHelper::isAxisShown( nN
%3, false, xDiagram
);
995 rExistenceList
[nN
] = AxisHelper::isGridShown( nN
, 0, true, xDiagram
);
997 rExistenceList
[nN
] = AxisHelper::isGridShown( nN
%3, 0, false, xDiagram
);
1001 bool AxisHelper::changeVisibilityOfAxes( const Reference
< XDiagram
>& xDiagram
1002 , const Sequence
< sal_Bool
>& rOldExistenceList
1003 , const Sequence
< sal_Bool
>& rNewExistenceList
1004 , const Reference
< uno::XComponentContext
>& xContext
1005 , ReferenceSizeProvider
* pRefSizeProvider
)
1007 bool bChanged
= false;
1008 for(sal_Int32 nN
=0;nN
<6;nN
++)
1010 if(rOldExistenceList
[nN
]!=rNewExistenceList
[nN
])
1013 if(rNewExistenceList
[nN
])
1015 AxisHelper::showAxis( nN
%3, nN
<3, xDiagram
, xContext
, pRefSizeProvider
);
1018 AxisHelper::hideAxis( nN
%3, nN
<3, xDiagram
);
1024 bool AxisHelper::changeVisibilityOfGrids( const Reference
< XDiagram
>& xDiagram
1025 , const Sequence
< sal_Bool
>& rOldExistenceList
1026 , const Sequence
< sal_Bool
>& rNewExistenceList
1027 , const Reference
< uno::XComponentContext
>& xContext
)
1029 bool bChanged
= false;
1030 for(sal_Int32 nN
=0;nN
<6;nN
++)
1032 if(rOldExistenceList
[nN
]!=rNewExistenceList
[nN
])
1035 if(rNewExistenceList
[nN
])
1036 AxisHelper::showGrid( nN
%3, 0, nN
<3, xDiagram
, xContext
);
1038 AxisHelper::hideGrid( nN
%3, 0, nN
<3, xDiagram
);
1044 Reference
< XCoordinateSystem
> AxisHelper::getCoordinateSystemOfAxis(
1045 const Reference
< XAxis
>& xAxis
1046 , const Reference
< XDiagram
>& xDiagram
)
1048 Reference
< XCoordinateSystem
> xRet
;
1050 Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
1051 if( xCooSysContainer
.is() )
1053 Reference
< XCoordinateSystem
> xCooSys
;
1054 Sequence
< Reference
< XCoordinateSystem
> > aCooSysList( xCooSysContainer
->getCoordinateSystems() );
1055 for( sal_Int32 nCooSysIndex
= 0; nCooSysIndex
< aCooSysList
.getLength(); ++nCooSysIndex
)
1057 xCooSys
= aCooSysList
[nCooSysIndex
];
1058 std::vector
< Reference
< XAxis
> > aAllAxis( AxisHelper::getAllAxesOfCoordinateSystem( xCooSys
) );
1060 ::std::vector
< Reference
< XAxis
> >::iterator aFound
=
1061 ::std::find( aAllAxis
.begin(), aAllAxis
.end(), xAxis
);
1062 if( aFound
!= aAllAxis
.end())
1064 xRet
.set( xCooSys
);
1072 Reference
< XChartType
> AxisHelper::getChartTypeByIndex( const Reference
< XCoordinateSystem
>& xCooSys
, sal_Int32 nIndex
)
1074 Reference
< XChartType
> xChartType
;
1076 Reference
< XChartTypeContainer
> xChartTypeContainer( xCooSys
, uno::UNO_QUERY
);
1077 if( xChartTypeContainer
.is() )
1079 Sequence
< Reference
< XChartType
> > aChartTypeList( xChartTypeContainer
->getChartTypes() );
1080 if( nIndex
>= 0 && nIndex
< aChartTypeList
.getLength() )
1081 xChartType
.set( aChartTypeList
[nIndex
] );
1087 void AxisHelper::setRTLAxisLayout( const Reference
< XCoordinateSystem
>& xCooSys
)
1091 bool bCartesian
= xCooSys
->getViewServiceName() == CHART2_COOSYSTEM_CARTESIAN_VIEW_SERVICE_NAME
;
1094 bool bVertical
= false;
1095 Reference
< beans::XPropertySet
> xCooSysProp( xCooSys
, uno::UNO_QUERY
);
1096 if( xCooSysProp
.is() )
1097 xCooSysProp
->getPropertyValue( "SwapXAndYAxis" ) >>= bVertical
;
1099 sal_Int32 nHorizontalAxisDimension
= bVertical
? 1 : 0;
1100 sal_Int32 nVerticalAxisDimension
= bVertical
? 0 : 1;
1104 //reverse direction for horizontal main axis
1105 Reference
< chart2::XAxis
> xHorizontalMainAxis( AxisHelper::getAxis( nHorizontalAxisDimension
, MAIN_AXIS_INDEX
, xCooSys
) );
1106 if( xHorizontalMainAxis
.is() )
1108 chart2::ScaleData aScale
= xHorizontalMainAxis
->getScaleData();
1109 aScale
.Orientation
= chart2::AxisOrientation_REVERSE
;
1110 xHorizontalMainAxis
->setScaleData(aScale
);
1113 //mathematical direction for vertical main axis
1114 Reference
< chart2::XAxis
> xVerticalMainAxis( AxisHelper::getAxis( nVerticalAxisDimension
, MAIN_AXIS_INDEX
, xCooSys
) );
1115 if( xVerticalMainAxis
.is() )
1117 chart2::ScaleData aScale
= xVerticalMainAxis
->getScaleData();
1118 aScale
.Orientation
= chart2::AxisOrientation_MATHEMATICAL
;
1119 xVerticalMainAxis
->setScaleData(aScale
);
1122 catch( const uno::Exception
& ex
)
1124 ASSERT_EXCEPTION( ex
);
1129 //reverse direction for horizontal secondary axis
1130 Reference
< chart2::XAxis
> xHorizontalSecondaryAxis( AxisHelper::getAxis( nHorizontalAxisDimension
, SECONDARY_AXIS_INDEX
, xCooSys
) );
1131 if( xHorizontalSecondaryAxis
.is() )
1133 chart2::ScaleData aScale
= xHorizontalSecondaryAxis
->getScaleData();
1134 aScale
.Orientation
= chart2::AxisOrientation_REVERSE
;
1135 xHorizontalSecondaryAxis
->setScaleData(aScale
);
1138 //mathematical direction for vertical secondary axis
1139 Reference
< chart2::XAxis
> xVerticalSecondaryAxis( AxisHelper::getAxis( nVerticalAxisDimension
, SECONDARY_AXIS_INDEX
, xCooSys
) );
1140 if( xVerticalSecondaryAxis
.is() )
1142 chart2::ScaleData aScale
= xVerticalSecondaryAxis
->getScaleData();
1143 aScale
.Orientation
= chart2::AxisOrientation_MATHEMATICAL
;
1144 xVerticalSecondaryAxis
->setScaleData(aScale
);
1147 catch( const uno::Exception
& ex
)
1149 ASSERT_EXCEPTION( ex
);
1155 Reference
< XChartType
> AxisHelper::getFirstChartTypeWithSeriesAttachedToAxisIndex( const Reference
< chart2::XDiagram
>& xDiagram
, const sal_Int32 nAttachedAxisIndex
)
1157 Reference
< XChartType
> xChartType
;
1158 ::std::vector
< Reference
< XDataSeries
> > aSeriesVector( DiagramHelper::getDataSeriesFromDiagram( xDiagram
) );
1159 ::std::vector
< Reference
< XDataSeries
> >::const_iterator aIter
= aSeriesVector
.begin();
1160 for( ; aIter
!= aSeriesVector
.end(); ++aIter
)
1162 sal_Int32 nCurrentIndex
= DataSeriesHelper::getAttachedAxisIndex( *aIter
);
1163 if( nAttachedAxisIndex
== nCurrentIndex
)
1165 xChartType
= DiagramHelper::getChartTypeOfSeries( xDiagram
, *aIter
);
1173 bool AxisHelper::isAxisPositioningEnabled()
1175 const SvtSaveOptions::ODFDefaultVersion
nCurrentVersion( SvtSaveOptions().GetODFDefaultVersion() );
1176 return nCurrentVersion
>= SvtSaveOptions::ODFVER_012
;
1181 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */