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 "DataSeriesHelper.hxx"
21 #include "DiagramHelper.hxx"
22 #include "DataSource.hxx"
24 #include "ContainerHelper.hxx"
25 #include <com/sun/star/beans/XPropertySet.hpp>
26 #include <com/sun/star/chart2/DataPointLabel.hpp>
27 #include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
28 #include <com/sun/star/chart2/StackingDirection.hpp>
29 #include <com/sun/star/chart2/data/LabelOrigin.hpp>
30 #include <com/sun/star/chart2/AxisType.hpp>
31 #include <com/sun/star/chart2/SymbolStyle.hpp>
32 #include <com/sun/star/chart2/Symbol.hpp>
33 #include <com/sun/star/drawing/LineStyle.hpp>
36 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
37 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
38 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
39 #include <rtl/ustrbuf.hxx>
47 using namespace ::com::sun::star
;
48 using namespace ::com::sun::star::chart2
;
50 using ::com::sun::star::uno::Reference
;
51 using ::com::sun::star::uno::Sequence
;
53 // ----------------------------------------
57 class lcl_MatchesRole
: public ::std::unary_function
< Reference
< chart2::data::XLabeledDataSequence
>, bool >
60 explicit lcl_MatchesRole( const OUString
& aRole
, bool bMatchPrefix
) :
62 m_bMatchPrefix( bMatchPrefix
)
65 bool operator () ( const Reference
< chart2::data::XLabeledDataSequence
> & xSeq
) const
69 Reference
< beans::XPropertySet
> xProp( xSeq
->getValues(), uno::UNO_QUERY
);
73 return ( xProp
.is() &&
74 (xProp
->getPropertyValue( "Role" ) >>= aRole
) &&
75 aRole
.match( m_aRole
));
77 return ( xProp
.is() &&
78 (xProp
->getPropertyValue( "Role" ) >>= aRole
) &&
79 m_aRole
.equals( aRole
));
87 Reference
< chart2::data::XLabeledDataSequence
> lcl_findLSequenceWithOnlyLabel(
88 const Reference
< chart2::data::XDataSource
> & xDataSource
)
90 Reference
< chart2::data::XLabeledDataSequence
> xResult
;
91 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSequences( xDataSource
->getDataSequences());
93 for( sal_Int32 i
=0; i
<aSequences
.getLength(); ++i
)
95 OSL_ENSURE( aSequences
[i
].is(), "empty LabeledDataSequence" );
96 // no values are set but a label exists
97 if( aSequences
[i
].is() &&
98 ( ! aSequences
[i
]->getValues().is() &&
99 aSequences
[i
]->getLabel().is()))
101 xResult
.set( aSequences
[i
] );
109 void lcl_getCooSysAndChartTypeOfSeries(
110 const Reference
< chart2::XDataSeries
> & xSeries
,
111 const Reference
< chart2::XDiagram
> & xDiagram
,
112 Reference
< chart2::XCoordinateSystem
> & xOutCooSys
,
113 Reference
< chart2::XChartType
> & xOutChartType
)
115 Reference
< chart2::XCoordinateSystemContainer
> xCooSysCnt( xDiagram
, uno::UNO_QUERY
);
118 Sequence
< Reference
< chart2::XCoordinateSystem
> > aCooSysSeq( xCooSysCnt
->getCoordinateSystems());
119 for( sal_Int32 nCooSysIdx
=0; nCooSysIdx
<aCooSysSeq
.getLength(); ++nCooSysIdx
)
121 Reference
< chart2::XChartTypeContainer
> xCTCnt( aCooSysSeq
[nCooSysIdx
], uno::UNO_QUERY_THROW
);
122 Sequence
< Reference
< chart2::XChartType
> > aChartTypes( xCTCnt
->getChartTypes());
123 for( sal_Int32 nCTIdx
=0; nCTIdx
<aChartTypes
.getLength(); ++nCTIdx
)
125 Reference
< chart2::XDataSeriesContainer
> xSeriesCnt( aChartTypes
[nCTIdx
], uno::UNO_QUERY
);
128 Sequence
< Reference
< chart2::XDataSeries
> > aSeries( xSeriesCnt
->getDataSeries());
129 for( sal_Int32 nSeriesIdx
=0; nSeriesIdx
<aSeries
.getLength(); ++nSeriesIdx
)
131 if( aSeries
[nSeriesIdx
] == xSeries
)
133 xOutCooSys
.set( aCooSysSeq
[nCooSysIdx
] );
134 xOutChartType
.set( aChartTypes
[nCTIdx
] );
143 void lcl_insertOrDeleteDataLabelsToSeriesAndAllPoints( const Reference
< chart2::XDataSeries
>& xSeries
, bool bInsert
)
147 Reference
< beans::XPropertySet
> xSeriesProperties( xSeries
, uno::UNO_QUERY
);
148 if( xSeriesProperties
.is() )
150 DataPointLabel aLabelAtSeries
;
151 xSeriesProperties
->getPropertyValue( "Label" ) >>= aLabelAtSeries
;
152 aLabelAtSeries
.ShowNumber
= bInsert
;
155 aLabelAtSeries
.ShowNumberInPercent
= false;
156 aLabelAtSeries
.ShowCategoryName
= false;
158 xSeriesProperties
->setPropertyValue( "Label", uno::makeAny( aLabelAtSeries
) );
159 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
160 if( xSeriesProperties
->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList
)
162 for(sal_Int32 nN
=aAttributedDataPointIndexList
.getLength();nN
--;)
164 Reference
< beans::XPropertySet
> xPointProp( xSeries
->getDataPointByIndex(aAttributedDataPointIndexList
[nN
]) );
165 if( xPointProp
.is() )
167 DataPointLabel aLabel
;
168 xPointProp
->getPropertyValue( "Label" ) >>= aLabel
;
169 aLabel
.ShowNumber
= bInsert
;
172 aLabel
.ShowNumberInPercent
= false;
173 aLabel
.ShowCategoryName
= false;
175 xPointProp
->setPropertyValue( "Label", uno::makeAny( aLabel
) );
181 catch(const uno::Exception
&e
)
183 ASSERT_EXCEPTION( e
);
187 } // anonymous namespace
188 // ----------------------------------------
193 namespace DataSeriesHelper
196 OUString
GetRole( const uno::Reference
< chart2::data::XLabeledDataSequence
>& xLabeledDataSequence
)
199 if( xLabeledDataSequence
.is() )
201 Reference
< beans::XPropertySet
> xProp( xLabeledDataSequence
->getValues(), uno::UNO_QUERY
);
203 xProp
->getPropertyValue( "Role" ) >>= aRet
;
208 Reference
< chart2::data::XLabeledDataSequence
>
209 getDataSequenceByRole(
210 const Reference
< chart2::data::XDataSource
> & xSource
, OUString aRole
,
211 bool bMatchPrefix
/* = false */ )
213 Reference
< chart2::data::XLabeledDataSequence
> aNoResult
;
216 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aLabeledSeq( xSource
->getDataSequences());
218 const Reference
< chart2::data::XLabeledDataSequence
> * pBegin
= aLabeledSeq
.getConstArray();
219 const Reference
< chart2::data::XLabeledDataSequence
> * pEnd
= pBegin
+ aLabeledSeq
.getLength();
220 const Reference
< chart2::data::XLabeledDataSequence
> * pMatch
=
221 ::std::find_if( pBegin
, pEnd
, lcl_MatchesRole( aRole
, bMatchPrefix
));
229 ::std::vector
< Reference
< chart2::data::XLabeledDataSequence
> >
230 getAllDataSequencesByRole( const Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > & aDataSequences
,
231 OUString aRole
, bool bMatchPrefix
/* = false */ )
233 ::std::vector
< Reference
< chart2::data::XLabeledDataSequence
> > aResultVec
;
234 ::std::remove_copy_if( aDataSequences
.getConstArray(), aDataSequences
.getConstArray() + aDataSequences
.getLength(),
235 ::std::back_inserter( aResultVec
),
236 ::std::not1( lcl_MatchesRole( aRole
, bMatchPrefix
)));
240 Reference
< chart2::data::XDataSource
>
241 getDataSource( const Sequence
< Reference
< chart2::XDataSeries
> > & aSeries
)
243 ::std::vector
< Reference
< chart2::data::XLabeledDataSequence
> > aSeqVec
;
245 for( sal_Int32 i
= 0; i
< aSeries
.getLength(); ++i
)
247 Reference
< chart2::data::XDataSource
> xSource( aSeries
[ i
], uno::UNO_QUERY
);
250 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSeq( xSource
->getDataSequences());
251 ::std::copy( aSeq
.getConstArray(), aSeq
.getConstArray() + aSeq
.getLength(),
252 ::std::back_inserter( aSeqVec
));
256 return Reference
< chart2::data::XDataSource
>(
257 new DataSource( ContainerHelper::ContainerToSequence( aSeqVec
)));
262 OUString
lcl_getDataSequenceLabel( const Reference
< chart2::data::XDataSequence
> & xSequence
)
266 Reference
< chart2::data::XTextualDataSequence
> xTextSeq( xSequence
, uno::UNO_QUERY
);
269 Sequence
< OUString
> aSeq( xTextSeq
->getTextualData());
271 const sal_Int32 nMax
= aSeq
.getLength() - 1;
274 for( sal_Int32 i
= 0; i
<= nMax
; ++i
)
276 aBuf
.append( aSeq
[i
] );
278 aBuf
.append( sal_Unicode( ' ' ));
280 aResult
= aBuf
.makeStringAndClear();
282 else if( xSequence
.is())
284 Sequence
< uno::Any
> aSeq( xSequence
->getData());
286 const sal_Int32 nMax
= aSeq
.getLength() - 1;
291 for( sal_Int32 i
= 0; i
<= nMax
; ++i
)
293 if( aSeq
[i
] >>= aVal
)
297 aBuf
.append( sal_Unicode( ' ' ));
299 else if( aSeq
[ i
] >>= fNum
)
303 aBuf
.append( sal_Unicode( ' ' ));
306 aResult
= aBuf
.makeStringAndClear();
313 OUString
getLabelForLabeledDataSequence(
314 const Reference
< chart2::data::XLabeledDataSequence
> & xLabeledSeq
)
317 if( xLabeledSeq
.is())
319 Reference
< chart2::data::XDataSequence
> xSeq( xLabeledSeq
->getLabel());
321 aResult
= lcl_getDataSequenceLabel( xSeq
);
322 if( !xSeq
.is() || aResult
.isEmpty() )
324 // no label set or label content is empty -> use auto-generated one
325 Reference
< chart2::data::XDataSequence
> xValueSeq( xLabeledSeq
->getValues() );
328 Sequence
< OUString
> aLabels( xValueSeq
->generateLabel(
329 chart2::data::LabelOrigin_SHORT_SIDE
) );
330 // no labels returned is interpreted as: auto-generation not
331 // supported by sequence
332 if( aLabels
.getLength() )
336 //todo?: maybe use the index of the series as name
337 //but as the index may change it would be better to have such a name persistent
338 //what is not possible at the moment
339 //--> maybe use the identifier as part of the name ...
340 aResult
= lcl_getDataSequenceLabel( xValueSeq
);
348 OUString
getDataSeriesLabel(
349 const Reference
< chart2::XDataSeries
> & xSeries
,
350 const OUString
& rLabelSequenceRole
)
354 Reference
< chart2::data::XDataSource
> xSource( xSeries
, uno::UNO_QUERY
);
357 Reference
< chart2::data::XLabeledDataSequence
> xLabeledSeq(
358 ::chart::DataSeriesHelper::getDataSequenceByRole( xSource
, rLabelSequenceRole
));
359 if( xLabeledSeq
.is())
360 aResult
= getLabelForLabeledDataSequence( xLabeledSeq
);
363 // special case: labeled data series with only a label and no values may
365 xLabeledSeq
.set( lcl_findLSequenceWithOnlyLabel( xSource
));
366 if( xLabeledSeq
.is())
368 Reference
< chart2::data::XDataSequence
> xSeq( xLabeledSeq
->getLabel());
370 aResult
= lcl_getDataSequenceLabel( xSeq
);
379 void setStackModeAtSeries(
380 const Sequence
< Reference
< chart2::XDataSeries
> > & aSeries
,
381 const Reference
< chart2::XCoordinateSystem
> & xCorrespondingCoordinateSystem
,
382 StackMode eStackMode
)
384 if( eStackMode
== StackMode_AMBIGUOUS
)
387 const OUString
aPropName( "StackingDirection" );
388 const uno::Any aPropValue
= uno::makeAny(
389 ( (eStackMode
== StackMode_Y_STACKED
) ||
390 (eStackMode
== StackMode_Y_STACKED_PERCENT
) )
391 ? chart2::StackingDirection_Y_STACKING
392 : (eStackMode
== StackMode_Z_STACKED
)
393 ? chart2::StackingDirection_Z_STACKING
394 : chart2::StackingDirection_NO_STACKING
);
396 std::set
< sal_Int32
> aAxisIndexSet
;
397 for( sal_Int32 i
=0; i
<aSeries
.getLength(); ++i
)
401 Reference
< beans::XPropertySet
> xProp( aSeries
[i
], uno::UNO_QUERY
);
404 xProp
->setPropertyValue( aPropName
, aPropValue
);
406 sal_Int32 nAxisIndex
;
407 xProp
->getPropertyValue( "AttachedAxisIndex" ) >>= nAxisIndex
;
408 aAxisIndexSet
.insert(nAxisIndex
);
411 catch( const uno::Exception
& ex
)
413 ASSERT_EXCEPTION( ex
);
417 if( xCorrespondingCoordinateSystem
.is() &&
418 1 < xCorrespondingCoordinateSystem
->getDimension() )
420 sal_Int32 nAxisIndexCount
= aAxisIndexSet
.size();
421 if( !nAxisIndexCount
)
423 aAxisIndexSet
.insert(0);
424 nAxisIndexCount
= aAxisIndexSet
.size();
427 for( ::std::set
< sal_Int32
>::const_iterator aIt
= aAxisIndexSet
.begin();
428 aIt
!= aAxisIndexSet
.end(); ++aIt
)
430 sal_Int32 nAxisIndex
= *aIt
;
431 Reference
< chart2::XAxis
> xAxis(
432 xCorrespondingCoordinateSystem
->getAxisByDimension( 1, nAxisIndex
));
435 sal_Bool bPercent
= (eStackMode
== StackMode_Y_STACKED_PERCENT
);
436 chart2::ScaleData aScaleData
= xAxis
->getScaleData();
438 if( bPercent
!= (aScaleData
.AxisType
==chart2::AxisType::PERCENT
) )
441 aScaleData
.AxisType
= chart2::AxisType::PERCENT
;
443 aScaleData
.AxisType
= chart2::AxisType::REALNUMBER
;
444 xAxis
->setScaleData( aScaleData
);
451 sal_Int32
getAttachedAxisIndex( const Reference
< chart2::XDataSeries
> & xSeries
)
456 Reference
< beans::XPropertySet
> xProp( xSeries
, uno::UNO_QUERY
);
459 xProp
->getPropertyValue( "AttachedAxisIndex" ) >>= nRet
;
462 catch( const uno::Exception
& ex
)
464 ASSERT_EXCEPTION( ex
);
469 sal_Int32
getNumberFormatKeyFromAxis(
470 const Reference
< chart2::XDataSeries
> & xSeries
,
471 const Reference
< chart2::XCoordinateSystem
> & xCorrespondingCoordinateSystem
,
472 sal_Int32 nDimensionIndex
,
473 sal_Int32 nAxisIndex
/* = -1 */ )
475 sal_Int32 nResult
= 0;
476 if( nAxisIndex
== -1 )
477 nAxisIndex
= getAttachedAxisIndex( xSeries
);
480 Reference
< beans::XPropertySet
> xAxisProp(
481 xCorrespondingCoordinateSystem
->getAxisByDimension( nDimensionIndex
, nAxisIndex
), uno::UNO_QUERY
);
483 xAxisProp
->getPropertyValue( "NumberFormat") >>= nResult
;
485 catch( const uno::Exception
& ex
)
487 ASSERT_EXCEPTION( ex
);
493 Reference
< chart2::XCoordinateSystem
> getCoordinateSystemOfSeries(
494 const Reference
< chart2::XDataSeries
> & xSeries
,
495 const Reference
< chart2::XDiagram
> & xDiagram
)
497 Reference
< chart2::XCoordinateSystem
> xResult
;
498 Reference
< chart2::XChartType
> xDummy
;
499 lcl_getCooSysAndChartTypeOfSeries( xSeries
, xDiagram
, xResult
, xDummy
);
504 Reference
< chart2::XChartType
> getChartTypeOfSeries(
505 const Reference
< chart2::XDataSeries
> & xSeries
,
506 const Reference
< chart2::XDiagram
> & xDiagram
)
508 Reference
< chart2::XChartType
> xResult
;
509 Reference
< chart2::XCoordinateSystem
> xDummy
;
510 lcl_getCooSysAndChartTypeOfSeries( xSeries
, xDiagram
, xDummy
, xResult
);
516 const Reference
< chart2::XDataSeries
> & xSeries
,
517 const Reference
< chart2::XChartType
> & xChartType
)
521 Reference
< chart2::XDataSeriesContainer
> xSeriesCnt( xChartType
, uno::UNO_QUERY_THROW
);
522 ::std::vector
< Reference
< chart2::XDataSeries
> > aSeries(
523 ContainerHelper::SequenceToVector( xSeriesCnt
->getDataSeries()));
524 ::std::vector
< Reference
< chart2::XDataSeries
> >::iterator aIt
=
525 ::std::find( aSeries
.begin(), aSeries
.end(), xSeries
);
526 if( aIt
!= aSeries
.end())
528 aSeries
.erase( aIt
);
529 xSeriesCnt
->setDataSeries( ContainerHelper::ContainerToSequence( aSeries
));
532 catch( const uno::Exception
& ex
)
534 ASSERT_EXCEPTION( ex
);
538 void switchSymbolsOnOrOff( const Reference
< beans::XPropertySet
> & xSeriesProperties
,
539 bool bSymbolsOn
, sal_Int32 nSeriesIndex
)
541 if( !xSeriesProperties
.is() )
544 chart2::Symbol aSymbProp
;
545 if( (xSeriesProperties
->getPropertyValue( "Symbol") >>= aSymbProp
) )
548 aSymbProp
.Style
= chart2::SymbolStyle_NONE
;
549 else if( aSymbProp
.Style
== chart2::SymbolStyle_NONE
)
551 aSymbProp
.Style
= chart2::SymbolStyle_STANDARD
;
552 aSymbProp
.StandardSymbol
= nSeriesIndex
;
554 xSeriesProperties
->setPropertyValue( "Symbol", uno::makeAny( aSymbProp
));
556 //todo: check attributed data points
559 void switchLinesOnOrOff( const Reference
< beans::XPropertySet
> & xSeriesProperties
, bool bLinesOn
)
561 if( !xSeriesProperties
.is() )
566 // keep line-styles that are not NONE
567 drawing::LineStyle eLineStyle
;
568 if( (xSeriesProperties
->getPropertyValue( "LineStyle") >>= eLineStyle
) &&
569 eLineStyle
== drawing::LineStyle_NONE
)
571 xSeriesProperties
->setPropertyValue( "LineStyle", uno::makeAny( drawing::LineStyle_SOLID
) );
575 xSeriesProperties
->setPropertyValue( "LineStyle", uno::makeAny( drawing::LineStyle_NONE
) );
578 void makeLinesThickOrThin( const Reference
< beans::XPropertySet
> & xSeriesProperties
, bool bThick
)
580 if( !xSeriesProperties
.is() )
583 sal_Int32 nNewValue
= bThick
? 80 : 0;
584 sal_Int32 nOldValue
= 0;
585 if( (xSeriesProperties
->getPropertyValue( "LineWidth") >>= nOldValue
) &&
586 nOldValue
!= nNewValue
)
588 if( !(bThick
&& nOldValue
>0))
589 xSeriesProperties
->setPropertyValue( "LineWidth", uno::makeAny( nNewValue
) );
593 void setPropertyAlsoToAllAttributedDataPoints( const Reference
< chart2::XDataSeries
>& xSeries
,
594 const OUString
& rPropertyName
, const uno::Any
& rPropertyValue
)
596 Reference
< beans::XPropertySet
> xSeriesProperties( xSeries
, uno::UNO_QUERY
);
597 if( !xSeriesProperties
.is() )
600 xSeriesProperties
->setPropertyValue( rPropertyName
, rPropertyValue
);
601 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
602 if( xSeriesProperties
->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList
)
604 for(sal_Int32 nN
=aAttributedDataPointIndexList
.getLength();nN
--;)
606 Reference
< beans::XPropertySet
> xPointProp( xSeries
->getDataPointByIndex(aAttributedDataPointIndexList
[nN
]) );
609 xPointProp
->setPropertyValue( rPropertyName
, rPropertyValue
);
614 bool hasAttributedDataPointDifferentValue( const Reference
< chart2::XDataSeries
>& xSeries
,
615 const OUString
& rPropertyName
, const uno::Any
& rPropertyValue
)
617 Reference
< beans::XPropertySet
> xSeriesProperties( xSeries
, uno::UNO_QUERY
);
618 if( !xSeriesProperties
.is() )
621 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
622 if( xSeriesProperties
->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList
)
624 for(sal_Int32 nN
=aAttributedDataPointIndexList
.getLength();nN
--;)
626 Reference
< beans::XPropertySet
> xPointProp( xSeries
->getDataPointByIndex(aAttributedDataPointIndexList
[nN
]) );
629 uno::Any
aPointValue( xPointProp
->getPropertyValue( rPropertyName
) );
630 if( !( rPropertyValue
==aPointValue
) )
637 bool areAllSeriesAttachedToSameAxis( const uno::Reference
< chart2::XChartType
>& xChartType
, sal_Int32
& rOutAxisIndex
)
641 uno::Reference
< chart2::XDataSeriesContainer
> xDataSeriesContainer( xChartType
, uno::UNO_QUERY_THROW
);
642 uno::Sequence
< uno::Reference
< chart2::XDataSeries
> > aSeriesSeq( xDataSeriesContainer
->getDataSeries());
644 const sal_Int32
nSeriesCount( aSeriesSeq
.getLength());
645 // AxisIndex can only be 0 or 1
646 sal_Int32 nSeriesAtFirstAxis
= 0;
647 sal_Int32 nSeriesAtSecondAxis
= 0;
649 for( sal_Int32 nI
= 0; nI
< nSeriesCount
; ++nI
)
651 uno::Reference
< chart2::XDataSeries
> xSeries( aSeriesSeq
[nI
], uno::UNO_QUERY
);
652 sal_Int32 nAxisIndex
= DataSeriesHelper::getAttachedAxisIndex( xSeries
);
653 if( nAxisIndex
== 0 )
654 ++nSeriesAtFirstAxis
;
655 else if( nAxisIndex
== 1 )
656 ++nSeriesAtSecondAxis
;
658 OSL_ENSURE( nSeriesAtFirstAxis
+ nSeriesAtSecondAxis
== nSeriesCount
, "Invalid axis index found" );
660 if( nSeriesAtFirstAxis
== nSeriesCount
)
662 else if( nSeriesAtSecondAxis
== nSeriesCount
)
665 return ( nSeriesAtFirstAxis
== nSeriesCount
||
666 nSeriesAtSecondAxis
== nSeriesCount
);
668 catch( const uno::Exception
& ex
)
670 ASSERT_EXCEPTION( ex
);
678 bool lcl_SequenceHasUnhiddenData( const uno::Reference
< chart2::data::XDataSequence
>& xDataSequence
)
680 if( !xDataSequence
.is() )
682 uno::Reference
< beans::XPropertySet
> xProp( xDataSequence
, uno::UNO_QUERY
);
685 uno::Sequence
< sal_Int32
> aHiddenValues
;
688 xProp
->getPropertyValue( "HiddenValues" ) >>= aHiddenValues
;
689 if( !aHiddenValues
.getLength() )
692 catch( const uno::Exception
& )
697 if( xDataSequence
->getData().getLength() )
704 bool hasUnhiddenData( const uno::Reference
< chart2::XDataSeries
>& xSeries
)
706 uno::Reference
< chart2::data::XDataSource
> xDataSource
=
707 uno::Reference
< chart2::data::XDataSource
>( xSeries
, uno::UNO_QUERY
);
709 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aDataSequences
= xDataSource
->getDataSequences();
711 for(sal_Int32 nN
= aDataSequences
.getLength();nN
--;)
713 if( !aDataSequences
[nN
].is() )
715 if( lcl_SequenceHasUnhiddenData( aDataSequences
[nN
]->getValues() ) )
717 if( lcl_SequenceHasUnhiddenData( aDataSequences
[nN
]->getLabel() ) )
725 inline bool operator() ( const sal_Int32
& first
, const sal_Int32
& second
) const
727 return ( first
< second
);
731 sal_Int32
translateIndexFromHiddenToFullSequence( sal_Int32 nIndex
, const Reference
< chart2::data::XDataSequence
>& xDataSequence
, bool bTranslate
)
738 uno::Reference
<beans::XPropertySet
> xProp( xDataSequence
, uno::UNO_QUERY
);
741 Sequence
<sal_Int32
> aHiddenIndicesSeq
;
742 xProp
->getPropertyValue( "HiddenValues" ) >>= aHiddenIndicesSeq
;
743 if( aHiddenIndicesSeq
.getLength() )
745 ::std::vector
< sal_Int32
> aHiddenIndices( ContainerHelper::SequenceToVector( aHiddenIndicesSeq
) );
746 ::std::sort( aHiddenIndices
.begin(), aHiddenIndices
.end(), lcl_LessIndex() );
748 sal_Int32 nHiddenCount
= static_cast<sal_Int32
>(aHiddenIndices
.size());
749 for( sal_Int32 nN
= 0; nN
< nHiddenCount
; ++nN
)
751 if( aHiddenIndices
[nN
] <= nIndex
)
759 catch (const beans::UnknownPropertyException
&)
765 bool hasDataLabelsAtSeries( const Reference
< chart2::XDataSeries
>& xSeries
)
770 Reference
< beans::XPropertySet
> xProp( xSeries
, uno::UNO_QUERY
);
773 DataPointLabel aLabel
;
774 if( (xProp
->getPropertyValue( "Label" ) >>= aLabel
) )
775 bRet
= aLabel
.ShowNumber
|| aLabel
.ShowNumberInPercent
|| aLabel
.ShowCategoryName
;
778 catch(const uno::Exception
&e
)
780 ASSERT_EXCEPTION( e
);
785 bool hasDataLabelsAtPoints( const Reference
< chart2::XDataSeries
>& xSeries
)
790 Reference
< beans::XPropertySet
> xSeriesProperties( xSeries
, uno::UNO_QUERY
);
791 if( xSeriesProperties
.is() )
793 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
794 if( xSeriesProperties
->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList
)
796 for(sal_Int32 nN
=aAttributedDataPointIndexList
.getLength();nN
--;)
798 Reference
< beans::XPropertySet
> xPointProp( xSeries
->getDataPointByIndex(aAttributedDataPointIndexList
[nN
]) );
799 if( xPointProp
.is() )
801 DataPointLabel aLabel
;
802 if( (xPointProp
->getPropertyValue( "Label" ) >>= aLabel
) )
803 bRet
= aLabel
.ShowNumber
|| aLabel
.ShowNumberInPercent
|| aLabel
.ShowCategoryName
;
811 catch(const uno::Exception
&e
)
813 ASSERT_EXCEPTION( e
);
818 bool hasDataLabelAtPoint( const Reference
< chart2::XDataSeries
>& xSeries
, sal_Int32 nPointIndex
)
823 Reference
< beans::XPropertySet
> xProp
;
824 Reference
< beans::XPropertySet
> xSeriesProperties( xSeries
, uno::UNO_QUERY
);
825 if( xSeriesProperties
.is() )
827 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
828 if( xSeriesProperties
->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList
)
830 ::std::vector
< sal_Int32
> aIndices( ContainerHelper::SequenceToVector( aAttributedDataPointIndexList
) );
831 ::std::vector
< sal_Int32
>::iterator aIt
= ::std::find( aIndices
.begin(), aIndices
.end(), nPointIndex
);
832 if( aIt
!= aIndices
.end())
833 xProp
= xSeries
->getDataPointByIndex(nPointIndex
);
835 xProp
= xSeriesProperties
;
839 DataPointLabel aLabel
;
840 if( (xProp
->getPropertyValue( "Label" ) >>= aLabel
) )
841 bRet
= aLabel
.ShowNumber
|| aLabel
.ShowNumberInPercent
|| aLabel
.ShowCategoryName
;
845 catch(const uno::Exception
&e
)
847 ASSERT_EXCEPTION( e
);
852 void insertDataLabelsToSeriesAndAllPoints( const Reference
< chart2::XDataSeries
>& xSeries
)
854 lcl_insertOrDeleteDataLabelsToSeriesAndAllPoints( xSeries
, true /*bInsert*/ );
857 void deleteDataLabelsFromSeriesAndAllPoints( const Reference
< chart2::XDataSeries
>& xSeries
)
859 lcl_insertOrDeleteDataLabelsToSeriesAndAllPoints( xSeries
, false /*bInsert*/ );
863 void insertDataLabelToPoint( const Reference
< beans::XPropertySet
>& xPointProp
)
867 if( xPointProp
.is() )
869 DataPointLabel aLabel
;
870 xPointProp
->getPropertyValue( "Label" ) >>= aLabel
;
871 aLabel
.ShowNumber
= true;
872 xPointProp
->setPropertyValue( "Label", uno::makeAny( aLabel
) );
875 catch(const uno::Exception
&e
)
877 ASSERT_EXCEPTION( e
);
881 void deleteDataLabelsFromPoint( const Reference
< beans::XPropertySet
>& xPointProp
)
885 if( xPointProp
.is() )
887 DataPointLabel aLabel
;
888 xPointProp
->getPropertyValue( "Label" ) >>= aLabel
;
889 aLabel
.ShowNumber
= false;
890 aLabel
.ShowNumberInPercent
= false;
891 aLabel
.ShowCategoryName
= false;
892 xPointProp
->setPropertyValue( "Label", uno::makeAny( aLabel
) );
895 catch(const uno::Exception
&e
)
897 ASSERT_EXCEPTION( e
);
901 } // namespace DataSeriesHelper
904 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */