1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_chart2.hxx"
30 #include "DataSeriesHelper.hxx"
31 #include "DiagramHelper.hxx"
32 #include "DataSource.hxx"
34 #include "ContainerHelper.hxx"
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/chart2/DataPointLabel.hpp>
37 #include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
38 #include <com/sun/star/chart2/StackingDirection.hpp>
39 #include <com/sun/star/chart2/data/LabelOrigin.hpp>
40 #include <com/sun/star/chart2/AxisType.hpp>
41 #include <com/sun/star/chart2/SymbolStyle.hpp>
42 #include <com/sun/star/chart2/Symbol.hpp>
43 #include <com/sun/star/drawing/LineStyle.hpp>
46 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
47 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
48 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
49 #include <rtl/ustrbuf.hxx>
57 using namespace ::com::sun::star
;
58 using namespace ::com::sun::star::chart2
;
60 using ::com::sun::star::uno::Reference
;
61 using ::com::sun::star::uno::Sequence
;
62 using ::rtl::OUString
;
63 using ::rtl::OUStringBuffer
;
65 // ----------------------------------------
69 class lcl_MatchesRole
: public ::std::unary_function
< Reference
< chart2::data::XLabeledDataSequence
>, bool >
72 explicit lcl_MatchesRole( const OUString
& aRole
, bool bMatchPrefix
) :
74 m_bMatchPrefix( bMatchPrefix
)
77 bool operator () ( const Reference
< chart2::data::XLabeledDataSequence
> & xSeq
) const
81 Reference
< beans::XPropertySet
> xProp( xSeq
->getValues(), uno::UNO_QUERY
);
85 return ( xProp
.is() &&
86 (xProp
->getPropertyValue(
87 OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" )) ) >>= aRole
) &&
88 aRole
.match( m_aRole
));
90 return ( xProp
.is() &&
91 (xProp
->getPropertyValue(
92 OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" )) ) >>= aRole
) &&
93 m_aRole
.equals( aRole
));
101 Reference
< chart2::data::XLabeledDataSequence
> lcl_findLSequenceWithOnlyLabel(
102 const Reference
< chart2::data::XDataSource
> & xDataSource
)
104 Reference
< chart2::data::XLabeledDataSequence
> xResult
;
105 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSequences( xDataSource
->getDataSequences());
107 for( sal_Int32 i
=0; i
<aSequences
.getLength(); ++i
)
109 OSL_ENSURE( aSequences
[i
].is(), "empty LabeledDataSequence" );
110 // no values are set but a label exists
111 if( aSequences
[i
].is() &&
112 ( ! aSequences
[i
]->getValues().is() &&
113 aSequences
[i
]->getLabel().is()))
115 xResult
.set( aSequences
[i
] );
123 void lcl_getCooSysAndChartTypeOfSeries(
124 const Reference
< chart2::XDataSeries
> & xSeries
,
125 const Reference
< chart2::XDiagram
> & xDiagram
,
126 Reference
< chart2::XCoordinateSystem
> & xOutCooSys
,
127 Reference
< chart2::XChartType
> & xOutChartType
)
129 Reference
< chart2::XCoordinateSystemContainer
> xCooSysCnt( xDiagram
, uno::UNO_QUERY
);
132 Sequence
< Reference
< chart2::XCoordinateSystem
> > aCooSysSeq( xCooSysCnt
->getCoordinateSystems());
133 for( sal_Int32 nCooSysIdx
=0; nCooSysIdx
<aCooSysSeq
.getLength(); ++nCooSysIdx
)
135 Reference
< chart2::XChartTypeContainer
> xCTCnt( aCooSysSeq
[nCooSysIdx
], uno::UNO_QUERY_THROW
);
136 Sequence
< Reference
< chart2::XChartType
> > aChartTypes( xCTCnt
->getChartTypes());
137 for( sal_Int32 nCTIdx
=0; nCTIdx
<aChartTypes
.getLength(); ++nCTIdx
)
139 Reference
< chart2::XDataSeriesContainer
> xSeriesCnt( aChartTypes
[nCTIdx
], uno::UNO_QUERY
);
142 Sequence
< Reference
< chart2::XDataSeries
> > aSeries( xSeriesCnt
->getDataSeries());
143 for( sal_Int32 nSeriesIdx
=0; nSeriesIdx
<aSeries
.getLength(); ++nSeriesIdx
)
145 if( aSeries
[nSeriesIdx
] == xSeries
)
147 xOutCooSys
.set( aCooSysSeq
[nCooSysIdx
] );
148 xOutChartType
.set( aChartTypes
[nCTIdx
] );
157 void lcl_insertOrDeleteDataLabelsToSeriesAndAllPoints( const Reference
< chart2::XDataSeries
>& xSeries
, bool bInsert
)
161 Reference
< beans::XPropertySet
> xSeriesProperties( xSeries
, uno::UNO_QUERY
);
162 if( xSeriesProperties
.is() )
164 DataPointLabel aLabelAtSeries
;
165 xSeriesProperties
->getPropertyValue( C2U( "Label" ) ) >>= aLabelAtSeries
;
166 aLabelAtSeries
.ShowNumber
= bInsert
;
169 aLabelAtSeries
.ShowNumberInPercent
= false;
170 aLabelAtSeries
.ShowCategoryName
= false;
172 xSeriesProperties
->setPropertyValue( C2U( "Label" ), uno::makeAny( aLabelAtSeries
) );
173 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
174 if( xSeriesProperties
->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList
)
176 for(sal_Int32 nN
=aAttributedDataPointIndexList
.getLength();nN
--;)
178 Reference
< beans::XPropertySet
> xPointProp( xSeries
->getDataPointByIndex(aAttributedDataPointIndexList
[nN
]) );
179 if( xPointProp
.is() )
181 DataPointLabel aLabel
;
182 xPointProp
->getPropertyValue( C2U( "Label" ) ) >>= aLabel
;
183 aLabel
.ShowNumber
= bInsert
;
186 aLabel
.ShowNumberInPercent
= false;
187 aLabel
.ShowCategoryName
= false;
189 xPointProp
->setPropertyValue( C2U( "Label" ), uno::makeAny( aLabel
) );
195 catch( uno::Exception
&e
)
197 ASSERT_EXCEPTION( e
);
201 } // anonymous namespace
202 // ----------------------------------------
207 namespace DataSeriesHelper
210 OUString
GetRole( const uno::Reference
< chart2::data::XLabeledDataSequence
>& xLabeledDataSequence
)
213 if( xLabeledDataSequence
.is() )
215 Reference
< beans::XPropertySet
> xProp( xLabeledDataSequence
->getValues(), uno::UNO_QUERY
);
217 xProp
->getPropertyValue( C2U("Role") ) >>= aRet
;
222 Reference
< chart2::data::XLabeledDataSequence
>
223 getDataSequenceByRole(
224 const Reference
< chart2::data::XDataSource
> & xSource
, OUString aRole
,
225 bool bMatchPrefix
/* = false */ )
227 Reference
< chart2::data::XLabeledDataSequence
> aNoResult
;
230 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aLabeledSeq( xSource
->getDataSequences());
232 const Reference
< chart2::data::XLabeledDataSequence
> * pBegin
= aLabeledSeq
.getConstArray();
233 const Reference
< chart2::data::XLabeledDataSequence
> * pEnd
= pBegin
+ aLabeledSeq
.getLength();
234 const Reference
< chart2::data::XLabeledDataSequence
> * pMatch
=
235 ::std::find_if( pBegin
, pEnd
, lcl_MatchesRole( aRole
, bMatchPrefix
));
243 ::std::vector
< Reference
< chart2::data::XLabeledDataSequence
> >
244 getAllDataSequencesByRole( const Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > & aDataSequences
,
245 OUString aRole
, bool bMatchPrefix
/* = false */ )
247 ::std::vector
< Reference
< chart2::data::XLabeledDataSequence
> > aResultVec
;
248 ::std::remove_copy_if( aDataSequences
.getConstArray(), aDataSequences
.getConstArray() + aDataSequences
.getLength(),
249 ::std::back_inserter( aResultVec
),
250 ::std::not1( lcl_MatchesRole( aRole
, bMatchPrefix
)));
254 Reference
< chart2::data::XDataSource
>
255 getDataSource( const Sequence
< Reference
< chart2::XDataSeries
> > & aSeries
)
257 ::std::vector
< Reference
< chart2::data::XLabeledDataSequence
> > aSeqVec
;
259 for( sal_Int32 i
= 0; i
< aSeries
.getLength(); ++i
)
261 Reference
< chart2::data::XDataSource
> xSource( aSeries
[ i
], uno::UNO_QUERY
);
264 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aSeq( xSource
->getDataSequences());
265 ::std::copy( aSeq
.getConstArray(), aSeq
.getConstArray() + aSeq
.getLength(),
266 ::std::back_inserter( aSeqVec
));
270 return Reference
< chart2::data::XDataSource
>(
271 new DataSource( ContainerHelper::ContainerToSequence( aSeqVec
)));
276 OUString
lcl_getDataSequenceLabel( const Reference
< chart2::data::XDataSequence
> & xSequence
)
280 Reference
< chart2::data::XTextualDataSequence
> xTextSeq( xSequence
, uno::UNO_QUERY
);
283 Sequence
< OUString
> aSeq( xTextSeq
->getTextualData());
285 const sal_Int32 nMax
= aSeq
.getLength() - 1;
289 for( sal_Int32 i
= 0; i
<= nMax
; ++i
)
291 aBuf
.append( aSeq
[i
] );
293 aBuf
.append( sal_Unicode( ' ' ));
295 aResult
= aBuf
.makeStringAndClear();
297 else if( xSequence
.is())
299 Sequence
< uno::Any
> aSeq( xSequence
->getData());
301 const sal_Int32 nMax
= aSeq
.getLength() - 1;
306 for( sal_Int32 i
= 0; i
<= nMax
; ++i
)
308 if( aSeq
[i
] >>= aVal
)
312 aBuf
.append( sal_Unicode( ' ' ));
314 else if( aSeq
[ i
] >>= fNum
)
318 aBuf
.append( sal_Unicode( ' ' ));
321 aResult
= aBuf
.makeStringAndClear();
328 OUString
getLabelForLabeledDataSequence(
329 const Reference
< chart2::data::XLabeledDataSequence
> & xLabeledSeq
)
332 if( xLabeledSeq
.is())
334 Reference
< chart2::data::XDataSequence
> xSeq( xLabeledSeq
->getLabel());
336 aResult
= lcl_getDataSequenceLabel( xSeq
);
337 if( !xSeq
.is() || !aResult
.getLength() )
339 // no label set or label content is empty -> use auto-generated one
340 Reference
< chart2::data::XDataSequence
> xValueSeq( xLabeledSeq
->getValues() );
343 Sequence
< OUString
> aLabels( xValueSeq
->generateLabel(
344 chart2::data::LabelOrigin_SHORT_SIDE
) );
345 // no labels returned is interpreted as: auto-generation not
346 // supported by sequence
347 if( aLabels
.getLength() )
351 //todo?: maybe use the index of the series as name
352 //but as the index may change it would be better to have such a name persistent
353 //what is not possible at the moment
354 //--> maybe use the identifier as part of the name ...
355 aResult
= lcl_getDataSequenceLabel( xValueSeq
);
363 OUString
getDataSeriesLabel(
364 const Reference
< chart2::XDataSeries
> & xSeries
,
365 const OUString
& rLabelSequenceRole
)
369 Reference
< chart2::data::XDataSource
> xSource( xSeries
, uno::UNO_QUERY
);
372 Reference
< chart2::data::XLabeledDataSequence
> xLabeledSeq(
373 ::chart::DataSeriesHelper::getDataSequenceByRole( xSource
, rLabelSequenceRole
));
374 if( xLabeledSeq
.is())
375 aResult
= getLabelForLabeledDataSequence( xLabeledSeq
);
378 // special case: labeled data series with only a label and no values may
380 xLabeledSeq
.set( lcl_findLSequenceWithOnlyLabel( xSource
));
381 if( xLabeledSeq
.is())
383 Reference
< chart2::data::XDataSequence
> xSeq( xLabeledSeq
->getLabel());
385 aResult
= lcl_getDataSequenceLabel( xSeq
);
394 void setStackModeAtSeries(
395 const Sequence
< Reference
< chart2::XDataSeries
> > & aSeries
,
396 const Reference
< chart2::XCoordinateSystem
> & xCorrespondingCoordinateSystem
,
397 StackMode eStackMode
)
399 if( eStackMode
== StackMode_AMBIGUOUS
)
402 const OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( "StackingDirection" ));
403 const uno::Any aPropValue
= uno::makeAny(
404 ( (eStackMode
== StackMode_Y_STACKED
) ||
405 (eStackMode
== StackMode_Y_STACKED_PERCENT
) )
406 ? chart2::StackingDirection_Y_STACKING
407 : (eStackMode
== StackMode_Z_STACKED
)
408 ? chart2::StackingDirection_Z_STACKING
409 : chart2::StackingDirection_NO_STACKING
);
411 std::set
< sal_Int32
> aAxisIndexSet
;
412 for( sal_Int32 i
=0; i
<aSeries
.getLength(); ++i
)
416 Reference
< beans::XPropertySet
> xProp( aSeries
[i
], uno::UNO_QUERY
);
419 xProp
->setPropertyValue( aPropName
, aPropValue
);
421 sal_Int32 nAxisIndex
;
422 xProp
->getPropertyValue( C2U("AttachedAxisIndex") ) >>= nAxisIndex
;
423 aAxisIndexSet
.insert(nAxisIndex
);
426 catch( uno::Exception
& ex
)
428 ASSERT_EXCEPTION( ex
);
432 if( xCorrespondingCoordinateSystem
.is() &&
433 1 < xCorrespondingCoordinateSystem
->getDimension() )
435 sal_Int32 nAxisIndexCount
= aAxisIndexSet
.size();
436 if( !nAxisIndexCount
)
438 aAxisIndexSet
.insert(0);
439 nAxisIndexCount
= aAxisIndexSet
.size();
442 for( ::std::set
< sal_Int32
>::const_iterator aIt
= aAxisIndexSet
.begin();
443 aIt
!= aAxisIndexSet
.end(); ++aIt
)
445 sal_Int32 nAxisIndex
= *aIt
;
446 Reference
< chart2::XAxis
> xAxis(
447 xCorrespondingCoordinateSystem
->getAxisByDimension( 1, nAxisIndex
));
450 sal_Bool bPercent
= (eStackMode
== StackMode_Y_STACKED_PERCENT
);
451 chart2::ScaleData aScaleData
= xAxis
->getScaleData();
453 if( bPercent
!= (aScaleData
.AxisType
==chart2::AxisType::PERCENT
) )
456 aScaleData
.AxisType
= chart2::AxisType::PERCENT
;
458 aScaleData
.AxisType
= chart2::AxisType::REALNUMBER
;
459 xAxis
->setScaleData( aScaleData
);
466 sal_Int32
getAttachedAxisIndex( const Reference
< chart2::XDataSeries
> & xSeries
)
471 Reference
< beans::XPropertySet
> xProp( xSeries
, uno::UNO_QUERY
);
474 xProp
->getPropertyValue( C2U("AttachedAxisIndex") ) >>= nRet
;
477 catch( uno::Exception
& ex
)
479 ASSERT_EXCEPTION( ex
);
484 sal_Int32
getNumberFormatKeyFromAxis(
485 const Reference
< chart2::XDataSeries
> & xSeries
,
486 const Reference
< chart2::XCoordinateSystem
> & xCorrespondingCoordinateSystem
,
487 sal_Int32 nDimensionIndex
,
488 sal_Int32 nAxisIndex
/* = -1 */ )
490 sal_Int32 nResult
= 0;
491 if( nAxisIndex
== -1 )
492 nAxisIndex
= getAttachedAxisIndex( xSeries
);
495 Reference
< beans::XPropertySet
> xAxisProp(
496 xCorrespondingCoordinateSystem
->getAxisByDimension( nDimensionIndex
, nAxisIndex
), uno::UNO_QUERY
);
498 xAxisProp
->getPropertyValue( C2U("NumberFormat")) >>= nResult
;
500 catch( const uno::Exception
& ex
)
502 ASSERT_EXCEPTION( ex
);
508 Reference
< chart2::XCoordinateSystem
> getCoordinateSystemOfSeries(
509 const Reference
< chart2::XDataSeries
> & xSeries
,
510 const Reference
< chart2::XDiagram
> & xDiagram
)
512 Reference
< chart2::XCoordinateSystem
> xResult
;
513 Reference
< chart2::XChartType
> xDummy
;
514 lcl_getCooSysAndChartTypeOfSeries( xSeries
, xDiagram
, xResult
, xDummy
);
519 Reference
< chart2::XChartType
> getChartTypeOfSeries(
520 const Reference
< chart2::XDataSeries
> & xSeries
,
521 const Reference
< chart2::XDiagram
> & xDiagram
)
523 Reference
< chart2::XChartType
> xResult
;
524 Reference
< chart2::XCoordinateSystem
> xDummy
;
525 lcl_getCooSysAndChartTypeOfSeries( xSeries
, xDiagram
, xDummy
, xResult
);
531 const Reference
< chart2::XDataSeries
> & xSeries
,
532 const Reference
< chart2::XChartType
> & xChartType
)
536 Reference
< chart2::XDataSeriesContainer
> xSeriesCnt( xChartType
, uno::UNO_QUERY_THROW
);
537 ::std::vector
< Reference
< chart2::XDataSeries
> > aSeries(
538 ContainerHelper::SequenceToVector( xSeriesCnt
->getDataSeries()));
539 ::std::vector
< Reference
< chart2::XDataSeries
> >::iterator aIt
=
540 ::std::find( aSeries
.begin(), aSeries
.end(), xSeries
);
541 if( aIt
!= aSeries
.end())
543 aSeries
.erase( aIt
);
544 xSeriesCnt
->setDataSeries( ContainerHelper::ContainerToSequence( aSeries
));
547 catch( uno::Exception
& ex
)
549 ASSERT_EXCEPTION( ex
);
553 void switchSymbolsOnOrOff( const Reference
< beans::XPropertySet
> & xSeriesProperties
,
554 bool bSymbolsOn
, sal_Int32 nSeriesIndex
)
556 if( !xSeriesProperties
.is() )
559 chart2::Symbol aSymbProp
;
560 if( (xSeriesProperties
->getPropertyValue( C2U( "Symbol" )) >>= aSymbProp
) )
563 aSymbProp
.Style
= chart2::SymbolStyle_NONE
;
564 else if( aSymbProp
.Style
== chart2::SymbolStyle_NONE
)
566 aSymbProp
.Style
= chart2::SymbolStyle_STANDARD
;
567 aSymbProp
.StandardSymbol
= nSeriesIndex
;
569 xSeriesProperties
->setPropertyValue( C2U( "Symbol" ), uno::makeAny( aSymbProp
));
571 //todo: check attributed data points
574 void switchLinesOnOrOff( const Reference
< beans::XPropertySet
> & xSeriesProperties
, bool bLinesOn
)
576 if( !xSeriesProperties
.is() )
581 // keep line-styles that are not NONE
582 drawing::LineStyle eLineStyle
;
583 if( (xSeriesProperties
->getPropertyValue( C2U( "LineStyle" )) >>= eLineStyle
) &&
584 eLineStyle
== drawing::LineStyle_NONE
)
586 xSeriesProperties
->setPropertyValue( C2U( "LineStyle" ), uno::makeAny( drawing::LineStyle_SOLID
) );
590 xSeriesProperties
->setPropertyValue( C2U( "LineStyle" ), uno::makeAny( drawing::LineStyle_NONE
) );
593 void makeLinesThickOrThin( const Reference
< beans::XPropertySet
> & xSeriesProperties
, bool bThick
)
595 if( !xSeriesProperties
.is() )
598 sal_Int32 nNewValue
= bThick
? 80 : 0;
599 sal_Int32 nOldValue
= 0;
600 if( (xSeriesProperties
->getPropertyValue( C2U( "LineWidth" )) >>= nOldValue
) &&
601 nOldValue
!= nNewValue
)
603 if( !(bThick
&& nOldValue
>0))
604 xSeriesProperties
->setPropertyValue( C2U( "LineWidth" ), uno::makeAny( nNewValue
) );
608 void setPropertyAlsoToAllAttributedDataPoints( const Reference
< chart2::XDataSeries
>& xSeries
,
609 const OUString
& rPropertyName
, const uno::Any
& rPropertyValue
)
611 Reference
< beans::XPropertySet
> xSeriesProperties( xSeries
, uno::UNO_QUERY
);
612 if( !xSeriesProperties
.is() )
615 xSeriesProperties
->setPropertyValue( rPropertyName
, rPropertyValue
);
616 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
617 if( xSeriesProperties
->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList
)
619 for(sal_Int32 nN
=aAttributedDataPointIndexList
.getLength();nN
--;)
621 Reference
< beans::XPropertySet
> xPointProp( xSeries
->getDataPointByIndex(aAttributedDataPointIndexList
[nN
]) );
624 xPointProp
->setPropertyValue( rPropertyName
, rPropertyValue
);
629 bool hasAttributedDataPointDifferentValue( const Reference
< chart2::XDataSeries
>& xSeries
,
630 const OUString
& rPropertyName
, const uno::Any
& rPropertyValue
)
632 Reference
< beans::XPropertySet
> xSeriesProperties( xSeries
, uno::UNO_QUERY
);
633 if( !xSeriesProperties
.is() )
636 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
637 if( xSeriesProperties
->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList
)
639 for(sal_Int32 nN
=aAttributedDataPointIndexList
.getLength();nN
--;)
641 Reference
< beans::XPropertySet
> xPointProp( xSeries
->getDataPointByIndex(aAttributedDataPointIndexList
[nN
]) );
644 uno::Any
aPointValue( xPointProp
->getPropertyValue( rPropertyName
) );
645 if( !( rPropertyValue
==aPointValue
) )
652 bool areAllSeriesAttachedToSameAxis( const uno::Reference
< chart2::XChartType
>& xChartType
, sal_Int32
& rOutAxisIndex
)
656 uno::Reference
< chart2::XDataSeriesContainer
> xDataSeriesContainer( xChartType
, uno::UNO_QUERY_THROW
);
657 uno::Sequence
< uno::Reference
< chart2::XDataSeries
> > aSeriesSeq( xDataSeriesContainer
->getDataSeries());
659 const sal_Int32
nSeriesCount( aSeriesSeq
.getLength());
660 // AxisIndex can only be 0 or 1
661 sal_Int32 nSeriesAtFirstAxis
= 0;
662 sal_Int32 nSeriesAtSecondAxis
= 0;
664 for( sal_Int32 nI
= 0; nI
< nSeriesCount
; ++nI
)
666 uno::Reference
< chart2::XDataSeries
> xSeries( aSeriesSeq
[nI
], uno::UNO_QUERY
);
667 sal_Int32 nAxisIndex
= DataSeriesHelper::getAttachedAxisIndex( xSeries
);
668 if( nAxisIndex
== 0 )
669 ++nSeriesAtFirstAxis
;
670 else if( nAxisIndex
== 1 )
671 ++nSeriesAtSecondAxis
;
673 OSL_ENSURE( nSeriesAtFirstAxis
+ nSeriesAtSecondAxis
== nSeriesCount
, "Invalid axis index found" );
675 if( nSeriesAtFirstAxis
== nSeriesCount
)
677 else if( nSeriesAtSecondAxis
== nSeriesCount
)
680 return ( nSeriesAtFirstAxis
== nSeriesCount
||
681 nSeriesAtSecondAxis
== nSeriesCount
);
683 catch( const uno::Exception
& ex
)
685 ASSERT_EXCEPTION( ex
);
693 bool lcl_SequenceHasUnhiddenData( const uno::Reference
< chart2::data::XDataSequence
>& xDataSequence
)
695 if( !xDataSequence
.is() )
697 uno::Reference
< beans::XPropertySet
> xProp( xDataSequence
, uno::UNO_QUERY
);
700 uno::Sequence
< sal_Int32
> aHiddenValues
;
703 xProp
->getPropertyValue( C2U( "HiddenValues" ) ) >>= aHiddenValues
;
704 if( !aHiddenValues
.getLength() )
707 catch( uno::Exception
& e
)
709 (void)e
; // avoid warning
713 if( xDataSequence
->getData().getLength() )
720 bool hasUnhiddenData( const uno::Reference
< chart2::XDataSeries
>& xSeries
)
722 uno::Reference
< chart2::data::XDataSource
> xDataSource
=
723 uno::Reference
< chart2::data::XDataSource
>( xSeries
, uno::UNO_QUERY
);
725 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aDataSequences
= xDataSource
->getDataSequences();
727 for(sal_Int32 nN
= aDataSequences
.getLength();nN
--;)
729 if( !aDataSequences
[nN
].is() )
731 if( lcl_SequenceHasUnhiddenData( aDataSequences
[nN
]->getValues() ) )
733 if( lcl_SequenceHasUnhiddenData( aDataSequences
[nN
]->getLabel() ) )
741 inline bool operator() ( const sal_Int32
& first
, const sal_Int32
& second
)
743 return ( first
< second
);
747 sal_Int32
translateIndexFromHiddenToFullSequence( sal_Int32 nIndex
, const Reference
< chart2::data::XDataSequence
>& xDataSequence
, bool bTranslate
)
754 uno::Reference
<beans::XPropertySet
> xProp( xDataSequence
, uno::UNO_QUERY
);
757 Sequence
<sal_Int32
> aHiddenIndicesSeq
;
758 xProp
->getPropertyValue( C2U("HiddenValues") ) >>= aHiddenIndicesSeq
;
759 if( aHiddenIndicesSeq
.getLength() )
761 ::std::vector
< sal_Int32
> aHiddenIndices( ContainerHelper::SequenceToVector( aHiddenIndicesSeq
) );
762 ::std::sort( aHiddenIndices
.begin(), aHiddenIndices
.end(), lcl_LessIndex() );
764 sal_Int32 nHiddenCount
= static_cast<sal_Int32
>(aHiddenIndices
.size());
765 for( sal_Int32 nN
= 0; nN
< nHiddenCount
; ++nN
)
767 if( aHiddenIndices
[nN
] <= nIndex
)
775 catch (const beans::UnknownPropertyException
&)
781 bool hasDataLabelsAtSeries( const Reference
< chart2::XDataSeries
>& xSeries
)
786 Reference
< beans::XPropertySet
> xProp( xSeries
, uno::UNO_QUERY
);
789 DataPointLabel aLabel
;
790 if( (xProp
->getPropertyValue( C2U( "Label" ) ) >>= aLabel
) )
791 bRet
= aLabel
.ShowNumber
|| aLabel
.ShowNumberInPercent
|| aLabel
.ShowCategoryName
;
794 catch( uno::Exception
&e
)
796 ASSERT_EXCEPTION( e
);
801 bool hasDataLabelsAtPoints( const Reference
< chart2::XDataSeries
>& xSeries
)
806 Reference
< beans::XPropertySet
> xSeriesProperties( xSeries
, uno::UNO_QUERY
);
807 if( xSeriesProperties
.is() )
809 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
810 if( xSeriesProperties
->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList
)
812 for(sal_Int32 nN
=aAttributedDataPointIndexList
.getLength();nN
--;)
814 Reference
< beans::XPropertySet
> xPointProp( xSeries
->getDataPointByIndex(aAttributedDataPointIndexList
[nN
]) );
815 if( xPointProp
.is() )
817 DataPointLabel aLabel
;
818 if( (xPointProp
->getPropertyValue( C2U( "Label" ) ) >>= aLabel
) )
819 bRet
= aLabel
.ShowNumber
|| aLabel
.ShowNumberInPercent
|| aLabel
.ShowCategoryName
;
827 catch( uno::Exception
&e
)
829 ASSERT_EXCEPTION( e
);
834 bool hasDataLabelAtPoint( const Reference
< chart2::XDataSeries
>& xSeries
, sal_Int32 nPointIndex
)
839 Reference
< beans::XPropertySet
> xProp
;
840 Reference
< beans::XPropertySet
> xSeriesProperties( xSeries
, uno::UNO_QUERY
);
841 if( xSeriesProperties
.is() )
843 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
844 if( xSeriesProperties
->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList
)
846 ::std::vector
< sal_Int32
> aIndices( ContainerHelper::SequenceToVector( aAttributedDataPointIndexList
) );
847 ::std::vector
< sal_Int32
>::iterator aIt
= ::std::find( aIndices
.begin(), aIndices
.end(), nPointIndex
);
848 if( aIt
!= aIndices
.end())
849 xProp
= xSeries
->getDataPointByIndex(nPointIndex
);
851 xProp
= xSeriesProperties
;
855 DataPointLabel aLabel
;
856 if( (xProp
->getPropertyValue( C2U( "Label" ) ) >>= aLabel
) )
857 bRet
= aLabel
.ShowNumber
|| aLabel
.ShowNumberInPercent
|| aLabel
.ShowCategoryName
;
861 catch( uno::Exception
&e
)
863 ASSERT_EXCEPTION( e
);
868 void insertDataLabelsToSeriesAndAllPoints( const Reference
< chart2::XDataSeries
>& xSeries
)
870 lcl_insertOrDeleteDataLabelsToSeriesAndAllPoints( xSeries
, true /*bInsert*/ );
873 void deleteDataLabelsFromSeriesAndAllPoints( const Reference
< chart2::XDataSeries
>& xSeries
)
875 lcl_insertOrDeleteDataLabelsToSeriesAndAllPoints( xSeries
, false /*bInsert*/ );
879 void insertDataLabelToPoint( const Reference
< beans::XPropertySet
>& xPointProp
)
883 if( xPointProp
.is() )
885 DataPointLabel aLabel
;
886 xPointProp
->getPropertyValue( C2U( "Label" ) ) >>= aLabel
;
887 aLabel
.ShowNumber
= true;
888 xPointProp
->setPropertyValue( C2U( "Label" ), uno::makeAny( aLabel
) );
891 catch( uno::Exception
&e
)
893 ASSERT_EXCEPTION( e
);
897 void deleteDataLabelsFromPoint( const Reference
< beans::XPropertySet
>& xPointProp
)
901 if( xPointProp
.is() )
903 DataPointLabel aLabel
;
904 xPointProp
->getPropertyValue( C2U( "Label" ) ) >>= aLabel
;
905 aLabel
.ShowNumber
= false;
906 aLabel
.ShowNumberInPercent
= false;
907 aLabel
.ShowCategoryName
= false;
908 xPointProp
->setPropertyValue( C2U( "Label" ), uno::makeAny( aLabel
) );
911 catch( uno::Exception
&e
)
913 ASSERT_EXCEPTION( e
);
917 } // namespace DataSeriesHelper