1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: DataSeriesHelper.cxx,v $
10 * $Revision: 1.11.24.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_chart2.hxx"
33 #include "DataSeriesHelper.hxx"
34 #include "DiagramHelper.hxx"
35 #include "DataSource.hxx"
37 #include "ContainerHelper.hxx"
38 #include <com/sun/star/beans/XPropertySet.hpp>
39 #include <com/sun/star/chart2/DataPointLabel.hpp>
40 #include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
41 #include <com/sun/star/chart2/StackingDirection.hpp>
42 #include <com/sun/star/chart2/data/LabelOrigin.hpp>
43 #include <com/sun/star/chart2/AxisType.hpp>
44 #include <com/sun/star/chart2/SymbolStyle.hpp>
45 #include <com/sun/star/chart2/Symbol.hpp>
46 #include <com/sun/star/drawing/LineStyle.hpp>
49 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
50 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
51 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
52 #include <rtl/ustrbuf.hxx>
60 using namespace ::com::sun::star
;
61 using namespace ::com::sun::star::chart2
;
63 using ::com::sun::star::uno::Reference
;
64 using ::com::sun::star::uno::Sequence
;
65 using ::rtl::OUString
;
66 using ::rtl::OUStringBuffer
;
68 // ----------------------------------------
72 class lcl_MatchesRole
: public ::std::unary_function
< Reference
< chart2::data::XLabeledDataSequence
>, bool >
75 explicit lcl_MatchesRole( const OUString
& aRole
, bool bMatchPrefix
) :
77 m_bMatchPrefix( bMatchPrefix
)
80 bool operator () ( const Reference
< chart2::data::XLabeledDataSequence
> & xSeq
) const
84 Reference
< beans::XPropertySet
> xProp( xSeq
->getValues(), uno::UNO_QUERY
);
88 return ( xProp
.is() &&
89 (xProp
->getPropertyValue(
90 OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" )) ) >>= aRole
) &&
91 aRole
.match( m_aRole
));
93 return ( xProp
.is() &&
94 (xProp
->getPropertyValue(
95 OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" )) ) >>= aRole
) &&
96 m_aRole
.equals( aRole
));
104 Reference
< chart2::data::XLabeledDataSequence
> lcl_findLSequenceWithOnlyLabel(
105 const Reference
< chart2::data::XDataSource
> & xDataSource
)
107 Reference
< chart2::data::XLabeledDataSequence
> xResult
;
108 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSequences( xDataSource
->getDataSequences());
110 for( sal_Int32 i
=0; i
<aSequences
.getLength(); ++i
)
112 OSL_ENSURE( aSequences
[i
].is(), "empty LabeledDataSequence" );
113 // no values are set but a label exists
114 if( aSequences
[i
].is() &&
115 ( ! aSequences
[i
]->getValues().is() &&
116 aSequences
[i
]->getLabel().is()))
118 xResult
.set( aSequences
[i
] );
126 void lcl_getCooSysAndChartTypeOfSeries(
127 const Reference
< chart2::XDataSeries
> & xSeries
,
128 const Reference
< chart2::XDiagram
> & xDiagram
,
129 Reference
< chart2::XCoordinateSystem
> & xOutCooSys
,
130 Reference
< chart2::XChartType
> & xOutChartType
)
132 Reference
< chart2::XCoordinateSystemContainer
> xCooSysCnt( xDiagram
, uno::UNO_QUERY
);
135 Sequence
< Reference
< chart2::XCoordinateSystem
> > aCooSysSeq( xCooSysCnt
->getCoordinateSystems());
136 for( sal_Int32 nCooSysIdx
=0; nCooSysIdx
<aCooSysSeq
.getLength(); ++nCooSysIdx
)
138 Reference
< chart2::XChartTypeContainer
> xCTCnt( aCooSysSeq
[nCooSysIdx
], uno::UNO_QUERY_THROW
);
139 Sequence
< Reference
< chart2::XChartType
> > aChartTypes( xCTCnt
->getChartTypes());
140 for( sal_Int32 nCTIdx
=0; nCTIdx
<aChartTypes
.getLength(); ++nCTIdx
)
142 Reference
< chart2::XDataSeriesContainer
> xSeriesCnt( aChartTypes
[nCTIdx
], uno::UNO_QUERY
);
145 Sequence
< Reference
< chart2::XDataSeries
> > aSeries( xSeriesCnt
->getDataSeries());
146 for( sal_Int32 nSeriesIdx
=0; nSeriesIdx
<aSeries
.getLength(); ++nSeriesIdx
)
148 if( aSeries
[nSeriesIdx
] == xSeries
)
150 xOutCooSys
.set( aCooSysSeq
[nCooSysIdx
] );
151 xOutChartType
.set( aChartTypes
[nCTIdx
] );
160 void lcl_insertOrDeleteDataLabelsToSeriesAndAllPoints( const Reference
< chart2::XDataSeries
>& xSeries
, bool bInsert
)
164 Reference
< beans::XPropertySet
> xSeriesProperties( xSeries
, uno::UNO_QUERY
);
165 if( xSeriesProperties
.is() )
167 DataPointLabel aLabelAtSeries
;
168 xSeriesProperties
->getPropertyValue( C2U( "Label" ) ) >>= aLabelAtSeries
;
169 aLabelAtSeries
.ShowNumber
= bInsert
;
172 aLabelAtSeries
.ShowNumberInPercent
= false;
173 aLabelAtSeries
.ShowCategoryName
= false;
175 xSeriesProperties
->setPropertyValue( C2U( "Label" ), uno::makeAny( aLabelAtSeries
) );
176 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
177 if( xSeriesProperties
->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList
)
179 for(sal_Int32 nN
=aAttributedDataPointIndexList
.getLength();nN
--;)
181 Reference
< beans::XPropertySet
> xPointProp( xSeries
->getDataPointByIndex(aAttributedDataPointIndexList
[nN
]) );
182 if( xPointProp
.is() )
184 DataPointLabel aLabel
;
185 xPointProp
->getPropertyValue( C2U( "Label" ) ) >>= aLabel
;
186 aLabel
.ShowNumber
= bInsert
;
189 aLabel
.ShowNumberInPercent
= false;
190 aLabel
.ShowCategoryName
= false;
192 xPointProp
->setPropertyValue( C2U( "Label" ), uno::makeAny( aLabel
) );
198 catch( uno::Exception
&e
)
200 ASSERT_EXCEPTION( e
);
204 } // anonymous namespace
205 // ----------------------------------------
210 namespace DataSeriesHelper
213 OUString
GetRole( const uno::Reference
< chart2::data::XLabeledDataSequence
>& xLabeledDataSequence
)
216 if( xLabeledDataSequence
.is() )
218 Reference
< beans::XPropertySet
> xProp( xLabeledDataSequence
->getValues(), uno::UNO_QUERY
);
220 xProp
->getPropertyValue( C2U("Role") ) >>= aRet
;
225 Reference
< chart2::data::XLabeledDataSequence
>
226 getDataSequenceByRole(
227 const Reference
< chart2::data::XDataSource
> & xSource
, OUString aRole
,
228 bool bMatchPrefix
/* = false */ )
230 Reference
< chart2::data::XLabeledDataSequence
> aNoResult
;
233 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aLabeledSeq( xSource
->getDataSequences());
235 const Reference
< chart2::data::XLabeledDataSequence
> * pBegin
= aLabeledSeq
.getConstArray();
236 const Reference
< chart2::data::XLabeledDataSequence
> * pEnd
= pBegin
+ aLabeledSeq
.getLength();
237 const Reference
< chart2::data::XLabeledDataSequence
> * pMatch
=
238 ::std::find_if( pBegin
, pEnd
, lcl_MatchesRole( aRole
, bMatchPrefix
));
246 ::std::vector
< Reference
< chart2::data::XLabeledDataSequence
> >
247 getAllDataSequencesByRole( const Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > & aDataSequences
,
248 OUString aRole
, bool bMatchPrefix
/* = false */ )
250 ::std::vector
< Reference
< chart2::data::XLabeledDataSequence
> > aResultVec
;
251 ::std::remove_copy_if( aDataSequences
.getConstArray(), aDataSequences
.getConstArray() + aDataSequences
.getLength(),
252 ::std::back_inserter( aResultVec
),
253 ::std::not1( lcl_MatchesRole( aRole
, bMatchPrefix
)));
257 Reference
< chart2::data::XDataSource
>
258 getDataSource( const Sequence
< Reference
< chart2::XDataSeries
> > & aSeries
)
260 ::std::vector
< Reference
< chart2::data::XLabeledDataSequence
> > aSeqVec
;
262 for( sal_Int32 i
= 0; i
< aSeries
.getLength(); ++i
)
264 Reference
< chart2::data::XDataSource
> xSource( aSeries
[ i
], uno::UNO_QUERY
);
267 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSeq( xSource
->getDataSequences());
268 ::std::copy( aSeq
.getConstArray(), aSeq
.getConstArray() + aSeq
.getLength(),
269 ::std::back_inserter( aSeqVec
));
273 return Reference
< chart2::data::XDataSource
>(
274 new DataSource( ContainerHelper::ContainerToSequence( aSeqVec
)));
279 OUString
lcl_getDataSequenceLabel( const Reference
< chart2::data::XDataSequence
> & xSequence
)
283 Reference
< chart2::data::XTextualDataSequence
> xTextSeq( xSequence
, uno::UNO_QUERY
);
286 Sequence
< OUString
> aSeq( xTextSeq
->getTextualData());
288 const sal_Int32 nMax
= aSeq
.getLength() - 1;
292 for( sal_Int32 i
= 0; i
<= nMax
; ++i
)
294 aBuf
.append( aSeq
[i
] );
296 aBuf
.append( sal_Unicode( ' ' ));
298 aResult
= aBuf
.makeStringAndClear();
300 else if( xSequence
.is())
302 Sequence
< uno::Any
> aSeq( xSequence
->getData());
304 const sal_Int32 nMax
= aSeq
.getLength() - 1;
309 for( sal_Int32 i
= 0; i
<= nMax
; ++i
)
311 if( aSeq
[i
] >>= aVal
)
315 aBuf
.append( sal_Unicode( ' ' ));
317 else if( aSeq
[ i
] >>= fNum
)
321 aBuf
.append( sal_Unicode( ' ' ));
324 aResult
= aBuf
.makeStringAndClear();
331 OUString
getLabelForLabeledDataSequence(
332 const Reference
< chart2::data::XLabeledDataSequence
> & xLabeledSeq
)
335 if( xLabeledSeq
.is())
337 Reference
< chart2::data::XDataSequence
> xSeq( xLabeledSeq
->getLabel());
339 aResult
= lcl_getDataSequenceLabel( xSeq
);
340 if( !xSeq
.is() || !aResult
.getLength() )
342 // no label set or label content is empty -> use auto-generated one
343 Reference
< chart2::data::XDataSequence
> xValueSeq( xLabeledSeq
->getValues() );
346 Sequence
< OUString
> aLabels( xValueSeq
->generateLabel(
347 chart2::data::LabelOrigin_SHORT_SIDE
) );
348 // no labels returned is interpreted as: auto-generation not
349 // supported by sequence
350 if( aLabels
.getLength() )
354 //todo?: maybe use the index of the series as name
355 //but as the index may change it would be better to have such a name persistent
356 //what is not possible at the moment
357 //--> maybe use the identifier as part of the name ...
358 aResult
= lcl_getDataSequenceLabel( xValueSeq
);
366 OUString
getDataSeriesLabel(
367 const Reference
< chart2::XDataSeries
> & xSeries
,
368 const OUString
& rLabelSequenceRole
)
372 Reference
< chart2::data::XDataSource
> xSource( xSeries
, uno::UNO_QUERY
);
375 Reference
< chart2::data::XLabeledDataSequence
> xLabeledSeq(
376 ::chart::DataSeriesHelper::getDataSequenceByRole( xSource
, rLabelSequenceRole
));
377 if( xLabeledSeq
.is())
378 aResult
= getLabelForLabeledDataSequence( xLabeledSeq
);
381 // special case: labeled data series with only a label and no values may
383 xLabeledSeq
.set( lcl_findLSequenceWithOnlyLabel( xSource
));
384 if( xLabeledSeq
.is())
386 Reference
< chart2::data::XDataSequence
> xSeq( xLabeledSeq
->getLabel());
388 aResult
= lcl_getDataSequenceLabel( xSeq
);
397 void setStackModeAtSeries(
398 const Sequence
< Reference
< chart2::XDataSeries
> > & aSeries
,
399 const Reference
< chart2::XCoordinateSystem
> & xCorrespondingCoordinateSystem
,
400 StackMode eStackMode
)
402 if( eStackMode
== StackMode_AMBIGUOUS
)
405 const OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( "StackingDirection" ));
406 const uno::Any aPropValue
= uno::makeAny(
407 ( (eStackMode
== StackMode_Y_STACKED
) ||
408 (eStackMode
== StackMode_Y_STACKED_PERCENT
) )
409 ? chart2::StackingDirection_Y_STACKING
410 : (eStackMode
== StackMode_Z_STACKED
)
411 ? chart2::StackingDirection_Z_STACKING
412 : chart2::StackingDirection_NO_STACKING
);
414 std::set
< sal_Int32
> aAxisIndexSet
;
415 for( sal_Int32 i
=0; i
<aSeries
.getLength(); ++i
)
419 Reference
< beans::XPropertySet
> xProp( aSeries
[i
], uno::UNO_QUERY
);
422 xProp
->setPropertyValue( aPropName
, aPropValue
);
424 sal_Int32 nAxisIndex
;
425 xProp
->getPropertyValue( C2U("AttachedAxisIndex") ) >>= nAxisIndex
;
426 aAxisIndexSet
.insert(nAxisIndex
);
429 catch( uno::Exception
& ex
)
431 ASSERT_EXCEPTION( ex
);
435 if( xCorrespondingCoordinateSystem
.is() &&
436 1 < xCorrespondingCoordinateSystem
->getDimension() )
438 sal_Int32 nAxisIndexCount
= aAxisIndexSet
.size();
439 if( !nAxisIndexCount
)
441 aAxisIndexSet
.insert(0);
442 nAxisIndexCount
= aAxisIndexSet
.size();
445 for( ::std::set
< sal_Int32
>::const_iterator aIt
= aAxisIndexSet
.begin();
446 aIt
!= aAxisIndexSet
.end(); ++aIt
)
448 sal_Int32 nAxisIndex
= *aIt
;
449 Reference
< chart2::XAxis
> xAxis(
450 xCorrespondingCoordinateSystem
->getAxisByDimension( 1, nAxisIndex
));
453 sal_Bool bPercent
= (eStackMode
== StackMode_Y_STACKED_PERCENT
);
454 chart2::ScaleData aScaleData
= xAxis
->getScaleData();
456 if( bPercent
!= (aScaleData
.AxisType
==chart2::AxisType::PERCENT
) )
459 aScaleData
.AxisType
= chart2::AxisType::PERCENT
;
461 aScaleData
.AxisType
= chart2::AxisType::REALNUMBER
;
462 xAxis
->setScaleData( aScaleData
);
469 sal_Int32
getAttachedAxisIndex( const Reference
< chart2::XDataSeries
> & xSeries
)
474 Reference
< beans::XPropertySet
> xProp( xSeries
, uno::UNO_QUERY
);
477 xProp
->getPropertyValue( C2U("AttachedAxisIndex") ) >>= nRet
;
480 catch( uno::Exception
& ex
)
482 ASSERT_EXCEPTION( ex
);
487 sal_Int32
getNumberFormatKeyFromAxis(
488 const Reference
< chart2::XDataSeries
> & xSeries
,
489 const Reference
< chart2::XCoordinateSystem
> & xCorrespondingCoordinateSystem
,
490 sal_Int32 nDimensionIndex
,
491 sal_Int32 nAxisIndex
/* = -1 */ )
493 sal_Int32 nResult
= 0;
494 if( nAxisIndex
== -1 )
495 nAxisIndex
= getAttachedAxisIndex( xSeries
);
498 Reference
< beans::XPropertySet
> xAxisProp(
499 xCorrespondingCoordinateSystem
->getAxisByDimension( nDimensionIndex
, nAxisIndex
), uno::UNO_QUERY
);
501 xAxisProp
->getPropertyValue( C2U("NumberFormat")) >>= nResult
;
503 catch( const uno::Exception
& ex
)
505 ASSERT_EXCEPTION( ex
);
511 Reference
< chart2::XCoordinateSystem
> getCoordinateSystemOfSeries(
512 const Reference
< chart2::XDataSeries
> & xSeries
,
513 const Reference
< chart2::XDiagram
> & xDiagram
)
515 Reference
< chart2::XCoordinateSystem
> xResult
;
516 Reference
< chart2::XChartType
> xDummy
;
517 lcl_getCooSysAndChartTypeOfSeries( xSeries
, xDiagram
, xResult
, xDummy
);
522 Reference
< chart2::XChartType
> getChartTypeOfSeries(
523 const Reference
< chart2::XDataSeries
> & xSeries
,
524 const Reference
< chart2::XDiagram
> & xDiagram
)
526 Reference
< chart2::XChartType
> xResult
;
527 Reference
< chart2::XCoordinateSystem
> xDummy
;
528 lcl_getCooSysAndChartTypeOfSeries( xSeries
, xDiagram
, xDummy
, xResult
);
534 const Reference
< chart2::XDataSeries
> & xSeries
,
535 const Reference
< chart2::XChartType
> & xChartType
)
539 Reference
< chart2::XDataSeriesContainer
> xSeriesCnt( xChartType
, uno::UNO_QUERY_THROW
);
540 ::std::vector
< Reference
< chart2::XDataSeries
> > aSeries(
541 ContainerHelper::SequenceToVector( xSeriesCnt
->getDataSeries()));
542 ::std::vector
< Reference
< chart2::XDataSeries
> >::iterator aIt
=
543 ::std::find( aSeries
.begin(), aSeries
.end(), xSeries
);
544 if( aIt
!= aSeries
.end())
546 aSeries
.erase( aIt
);
547 xSeriesCnt
->setDataSeries( ContainerHelper::ContainerToSequence( aSeries
));
550 catch( uno::Exception
& ex
)
552 ASSERT_EXCEPTION( ex
);
556 void switchSymbolsOnOrOff( const Reference
< beans::XPropertySet
> & xSeriesProperties
,
557 bool bSymbolsOn
, sal_Int32 nSeriesIndex
)
559 if( !xSeriesProperties
.is() )
562 chart2::Symbol aSymbProp
;
563 if( (xSeriesProperties
->getPropertyValue( C2U( "Symbol" )) >>= aSymbProp
) )
566 aSymbProp
.Style
= chart2::SymbolStyle_NONE
;
567 else if( aSymbProp
.Style
== chart2::SymbolStyle_NONE
)
569 aSymbProp
.Style
= chart2::SymbolStyle_STANDARD
;
570 aSymbProp
.StandardSymbol
= nSeriesIndex
;
572 xSeriesProperties
->setPropertyValue( C2U( "Symbol" ), uno::makeAny( aSymbProp
));
574 //todo: check attributed data points
577 void switchLinesOnOrOff( const Reference
< beans::XPropertySet
> & xSeriesProperties
, bool bLinesOn
)
579 if( !xSeriesProperties
.is() )
584 // keep line-styles that are not NONE
585 drawing::LineStyle eLineStyle
;
586 if( (xSeriesProperties
->getPropertyValue( C2U( "LineStyle" )) >>= eLineStyle
) &&
587 eLineStyle
== drawing::LineStyle_NONE
)
589 xSeriesProperties
->setPropertyValue( C2U( "LineStyle" ), uno::makeAny( drawing::LineStyle_SOLID
) );
593 xSeriesProperties
->setPropertyValue( C2U( "LineStyle" ), uno::makeAny( drawing::LineStyle_NONE
) );
596 void makeLinesThickOrThin( const Reference
< beans::XPropertySet
> & xSeriesProperties
, bool bThick
)
598 if( !xSeriesProperties
.is() )
601 sal_Int32 nNewValue
= bThick
? 88 : 0;
602 sal_Int32 nOldValue
= 0;
603 if( (xSeriesProperties
->getPropertyValue( C2U( "LineWidth" )) >>= nOldValue
) &&
604 nOldValue
!= nNewValue
)
606 if( !(bThick
&& nOldValue
>0))
607 xSeriesProperties
->setPropertyValue( C2U( "LineWidth" ), uno::makeAny( nNewValue
) );
611 void setPropertyAlsoToAllAttributedDataPoints( const Reference
< chart2::XDataSeries
>& xSeries
,
612 const OUString
& rPropertyName
, const uno::Any
& rPropertyValue
)
614 Reference
< beans::XPropertySet
> xSeriesProperties( xSeries
, uno::UNO_QUERY
);
615 if( !xSeriesProperties
.is() )
618 xSeriesProperties
->setPropertyValue( rPropertyName
, rPropertyValue
);
619 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
620 if( xSeriesProperties
->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList
)
622 for(sal_Int32 nN
=aAttributedDataPointIndexList
.getLength();nN
--;)
624 Reference
< beans::XPropertySet
> xPointProp( xSeries
->getDataPointByIndex(aAttributedDataPointIndexList
[nN
]) );
627 xPointProp
->setPropertyValue( rPropertyName
, rPropertyValue
);
632 bool hasAttributedDataPointDifferentValue( const Reference
< chart2::XDataSeries
>& xSeries
,
633 const OUString
& rPropertyName
, const uno::Any
& rPropertyValue
)
635 Reference
< beans::XPropertySet
> xSeriesProperties( xSeries
, uno::UNO_QUERY
);
636 if( !xSeriesProperties
.is() )
639 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
640 if( xSeriesProperties
->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList
)
642 for(sal_Int32 nN
=aAttributedDataPointIndexList
.getLength();nN
--;)
644 Reference
< beans::XPropertySet
> xPointProp( xSeries
->getDataPointByIndex(aAttributedDataPointIndexList
[nN
]) );
647 uno::Any
aPointValue( xPointProp
->getPropertyValue( rPropertyName
) );
648 if( !( rPropertyValue
==aPointValue
) )
655 bool areAllSeriesAttachedToSameAxis( const uno::Reference
< chart2::XChartType
>& xChartType
, sal_Int32
& rOutAxisIndex
)
659 uno::Reference
< chart2::XDataSeriesContainer
> xDataSeriesContainer( xChartType
, uno::UNO_QUERY_THROW
);
660 uno::Sequence
< uno::Reference
< chart2::XDataSeries
> > aSeriesSeq( xDataSeriesContainer
->getDataSeries());
662 const sal_Int32
nSeriesCount( aSeriesSeq
.getLength());
663 // AxisIndex can only be 0 or 1
664 sal_Int32 nSeriesAtFirstAxis
= 0;
665 sal_Int32 nSeriesAtSecondAxis
= 0;
667 for( sal_Int32 nI
= 0; nI
< nSeriesCount
; ++nI
)
669 uno::Reference
< chart2::XDataSeries
> xSeries( aSeriesSeq
[nI
], uno::UNO_QUERY
);
670 sal_Int32 nAxisIndex
= DataSeriesHelper::getAttachedAxisIndex( xSeries
);
671 if( nAxisIndex
== 0 )
672 ++nSeriesAtFirstAxis
;
673 else if( nAxisIndex
== 1 )
674 ++nSeriesAtSecondAxis
;
676 OSL_ENSURE( nSeriesAtFirstAxis
+ nSeriesAtSecondAxis
== nSeriesCount
, "Invalid axis index found" );
678 if( nSeriesAtFirstAxis
== nSeriesCount
)
680 else if( nSeriesAtSecondAxis
== nSeriesCount
)
683 return ( nSeriesAtFirstAxis
== nSeriesCount
||
684 nSeriesAtSecondAxis
== nSeriesCount
);
686 catch( const uno::Exception
& ex
)
688 ASSERT_EXCEPTION( ex
);
696 bool lcl_SequenceHasUnhiddenData( const uno::Reference
< chart2::data::XDataSequence
>& xDataSequence
)
698 if( !xDataSequence
.is() )
700 uno::Reference
< beans::XPropertySet
> xProp( xDataSequence
, uno::UNO_QUERY
);
703 uno::Sequence
< sal_Int32
> aHiddenValues
;
706 xProp
->getPropertyValue( C2U( "HiddenValues" ) ) >>= aHiddenValues
;
707 if( !aHiddenValues
.getLength() )
710 catch( uno::Exception
& e
)
712 (void)e
; // avoid warning
716 if( xDataSequence
->getData().getLength() )
723 bool hasUnhiddenData( const uno::Reference
< chart2::XDataSeries
>& xSeries
)
725 uno::Reference
< chart2::data::XDataSource
> xDataSource
=
726 uno::Reference
< chart2::data::XDataSource
>( xSeries
, uno::UNO_QUERY
);
728 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aDataSequences
= xDataSource
->getDataSequences();
730 for(sal_Int32 nN
= aDataSequences
.getLength();nN
--;)
732 if( !aDataSequences
[nN
].is() )
734 if( lcl_SequenceHasUnhiddenData( aDataSequences
[nN
]->getValues() ) )
736 if( lcl_SequenceHasUnhiddenData( aDataSequences
[nN
]->getLabel() ) )
744 inline bool operator() ( const sal_Int32
& first
, const sal_Int32
& second
)
746 return ( first
< second
);
750 sal_Int32
translateIndexFromHiddenToFullSequence( sal_Int32 nIndex
, const Reference
< chart2::data::XDataSequence
>& xDataSequence
, bool bTranslate
)
757 uno::Reference
<beans::XPropertySet
> xProp( xDataSequence
, uno::UNO_QUERY
);
760 Sequence
<sal_Int32
> aHiddenIndicesSeq
;
761 xProp
->getPropertyValue( C2U("HiddenValues") ) >>= aHiddenIndicesSeq
;
762 if( aHiddenIndicesSeq
.getLength() )
764 ::std::vector
< sal_Int32
> aHiddenIndices( ContainerHelper::SequenceToVector( aHiddenIndicesSeq
) );
765 ::std::sort( aHiddenIndices
.begin(), aHiddenIndices
.end(), lcl_LessIndex() );
767 sal_Int32 nHiddenCount
= static_cast<sal_Int32
>(aHiddenIndices
.size());
768 for( sal_Int32 nN
= 0; nN
< nHiddenCount
; ++nN
)
770 if( aHiddenIndices
[nN
] <= nIndex
)
778 catch (const beans::UnknownPropertyException
&)
784 bool hasDataLabelsAtSeries( const Reference
< chart2::XDataSeries
>& xSeries
)
789 Reference
< beans::XPropertySet
> xProp( xSeries
, uno::UNO_QUERY
);
792 DataPointLabel aLabel
;
793 if( (xProp
->getPropertyValue( C2U( "Label" ) ) >>= aLabel
) )
794 bRet
= aLabel
.ShowNumber
|| aLabel
.ShowNumberInPercent
|| aLabel
.ShowCategoryName
;
797 catch( uno::Exception
&e
)
799 ASSERT_EXCEPTION( e
);
804 bool hasDataLabelsAtPoints( const Reference
< chart2::XDataSeries
>& xSeries
)
809 Reference
< beans::XPropertySet
> xSeriesProperties( xSeries
, uno::UNO_QUERY
);
810 if( xSeriesProperties
.is() )
812 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
813 if( xSeriesProperties
->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList
)
815 for(sal_Int32 nN
=aAttributedDataPointIndexList
.getLength();nN
--;)
817 Reference
< beans::XPropertySet
> xPointProp( xSeries
->getDataPointByIndex(aAttributedDataPointIndexList
[nN
]) );
818 if( xPointProp
.is() )
820 DataPointLabel aLabel
;
821 if( (xPointProp
->getPropertyValue( C2U( "Label" ) ) >>= aLabel
) )
822 bRet
= aLabel
.ShowNumber
|| aLabel
.ShowNumberInPercent
|| aLabel
.ShowCategoryName
;
830 catch( uno::Exception
&e
)
832 ASSERT_EXCEPTION( e
);
837 bool hasDataLabelAtPoint( const Reference
< chart2::XDataSeries
>& xSeries
, sal_Int32 nPointIndex
)
842 Reference
< beans::XPropertySet
> xProp
;
843 Reference
< beans::XPropertySet
> xSeriesProperties( xSeries
, uno::UNO_QUERY
);
844 if( xSeriesProperties
.is() )
846 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
847 if( xSeriesProperties
->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList
)
849 ::std::vector
< sal_Int32
> aIndices( ContainerHelper::SequenceToVector( aAttributedDataPointIndexList
) );
850 ::std::vector
< sal_Int32
>::iterator aIt
= ::std::find( aIndices
.begin(), aIndices
.end(), nPointIndex
);
851 if( aIt
!= aIndices
.end())
852 xProp
= xSeries
->getDataPointByIndex(nPointIndex
);
854 xProp
= xSeriesProperties
;
858 DataPointLabel aLabel
;
859 if( (xProp
->getPropertyValue( C2U( "Label" ) ) >>= aLabel
) )
860 bRet
= aLabel
.ShowNumber
|| aLabel
.ShowNumberInPercent
|| aLabel
.ShowCategoryName
;
864 catch( uno::Exception
&e
)
866 ASSERT_EXCEPTION( e
);
871 void insertDataLabelsToSeriesAndAllPoints( const Reference
< chart2::XDataSeries
>& xSeries
)
873 lcl_insertOrDeleteDataLabelsToSeriesAndAllPoints( xSeries
, true /*bInsert*/ );
876 void deleteDataLabelsFromSeriesAndAllPoints( const Reference
< chart2::XDataSeries
>& xSeries
)
878 lcl_insertOrDeleteDataLabelsToSeriesAndAllPoints( xSeries
, false /*bInsert*/ );
882 void insertDataLabelToPoint( const Reference
< beans::XPropertySet
>& xPointProp
)
886 if( xPointProp
.is() )
888 DataPointLabel aLabel
;
889 xPointProp
->getPropertyValue( C2U( "Label" ) ) >>= aLabel
;
890 aLabel
.ShowNumber
= true;
891 xPointProp
->setPropertyValue( C2U( "Label" ), uno::makeAny( aLabel
) );
894 catch( uno::Exception
&e
)
896 ASSERT_EXCEPTION( e
);
900 void deleteDataLabelsFromPoint( const Reference
< beans::XPropertySet
>& xPointProp
)
904 if( xPointProp
.is() )
906 DataPointLabel aLabel
;
907 xPointProp
->getPropertyValue( C2U( "Label" ) ) >>= aLabel
;
908 aLabel
.ShowNumber
= false;
909 aLabel
.ShowNumberInPercent
= false;
910 aLabel
.ShowCategoryName
= false;
911 xPointProp
->setPropertyValue( C2U( "Label" ), uno::makeAny( aLabel
) );
914 catch( uno::Exception
&e
)
916 ASSERT_EXCEPTION( e
);
920 } // namespace DataSeriesHelper