Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / chart2 / source / tools / DataSeriesHelper.cxx
blobc00e5ad3457aa56e087816bbd6419245707cc826
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <DataSource.hxx>
22 #include <unonames.hxx>
24 #include <com/sun/star/beans/XPropertySet.hpp>
25 #include <com/sun/star/chart2/DataPointLabel.hpp>
26 #include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
27 #include <com/sun/star/chart2/StackingDirection.hpp>
28 #include <com/sun/star/chart2/data/LabelOrigin.hpp>
29 #include <com/sun/star/chart2/AxisType.hpp>
30 #include <com/sun/star/chart2/SymbolStyle.hpp>
31 #include <com/sun/star/chart2/Symbol.hpp>
32 #include <com/sun/star/drawing/LineStyle.hpp>
34 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
35 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
36 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
37 #include <comphelper/sequence.hxx>
38 #include <rtl/ustrbuf.hxx>
39 #include <tools/diagnose_ex.h>
40 #include <sal/log.hxx>
42 #include <algorithm>
43 #include <iterator>
44 #include <vector>
45 #include <set>
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 namespace
56 class lcl_MatchesRole
58 public:
59 explicit lcl_MatchesRole( const OUString & aRole, bool bMatchPrefix ) :
60 m_aRole( aRole ),
61 m_bMatchPrefix( bMatchPrefix )
64 bool operator () ( const Reference< chart2::data::XLabeledDataSequence > & xSeq ) const
66 if(!xSeq.is())
67 return false;
68 Reference< beans::XPropertySet > xProp( xSeq->getValues(), uno::UNO_QUERY );
69 OUString aRole;
71 if( m_bMatchPrefix )
72 return ( xProp.is() &&
73 (xProp->getPropertyValue( "Role" ) >>= aRole ) &&
74 aRole.match( m_aRole ));
76 return ( xProp.is() &&
77 (xProp->getPropertyValue( "Role" ) >>= aRole ) &&
78 m_aRole == aRole );
81 private:
82 OUString m_aRole;
83 bool m_bMatchPrefix;
86 Reference< chart2::data::XLabeledDataSequence > lcl_findLSequenceWithOnlyLabel(
87 const Reference< chart2::data::XDataSource > & xDataSource )
89 Reference< chart2::data::XLabeledDataSequence > xResult;
90 Sequence< Reference< chart2::data::XLabeledDataSequence > > aSequences( xDataSource->getDataSequences());
92 for( sal_Int32 i=0; i<aSequences.getLength(); ++i )
94 OSL_ENSURE( aSequences[i].is(), "empty LabeledDataSequence" );
95 // no values are set but a label exists
96 if( aSequences[i].is() &&
97 ( ! aSequences[i]->getValues().is() &&
98 aSequences[i]->getLabel().is()))
100 xResult.set( aSequences[i] );
101 break;
105 return xResult;
108 void lcl_getCooSysAndChartTypeOfSeries(
109 const Reference< chart2::XDataSeries > & xSeries,
110 const Reference< chart2::XDiagram > & xDiagram,
111 Reference< chart2::XCoordinateSystem > & xOutCooSys,
112 Reference< chart2::XChartType > & xOutChartType )
114 Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY );
115 if( xCooSysCnt.is())
117 Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems());
118 for( sal_Int32 nCooSysIdx=0; nCooSysIdx<aCooSysSeq.getLength(); ++nCooSysIdx )
120 Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW );
121 Sequence< Reference< chart2::XChartType > > aChartTypes( xCTCnt->getChartTypes());
122 for( sal_Int32 nCTIdx=0; nCTIdx<aChartTypes.getLength(); ++nCTIdx )
124 Reference< chart2::XDataSeriesContainer > xSeriesCnt( aChartTypes[nCTIdx], uno::UNO_QUERY );
125 if( xSeriesCnt.is())
127 Sequence< Reference< chart2::XDataSeries > > aSeries( xSeriesCnt->getDataSeries());
128 for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeries.getLength(); ++nSeriesIdx )
130 if( aSeries[nSeriesIdx] == xSeries )
132 xOutCooSys.set( aCooSysSeq[nCooSysIdx] );
133 xOutChartType.set( aChartTypes[nCTIdx] );
142 void lcl_insertOrDeleteDataLabelsToSeriesAndAllPoints( const Reference< chart2::XDataSeries >& xSeries, bool bInsert )
146 Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY );
147 if( xSeriesProperties.is() )
149 DataPointLabel aLabelAtSeries;
150 xSeriesProperties->getPropertyValue(CHART_UNONAME_LABEL) >>= aLabelAtSeries;
151 aLabelAtSeries.ShowNumber = bInsert;
152 if( !bInsert )
154 aLabelAtSeries.ShowNumberInPercent = false;
155 aLabelAtSeries.ShowCategoryName = false;
157 xSeriesProperties->setPropertyValue(CHART_UNONAME_LABEL, uno::Any(aLabelAtSeries));
158 uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
159 if( xSeriesProperties->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList )
161 for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
163 Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]) );
164 if( xPointProp.is() )
166 DataPointLabel aLabel;
167 xPointProp->getPropertyValue(CHART_UNONAME_LABEL) >>= aLabel;
168 aLabel.ShowNumber = bInsert;
169 if( !bInsert )
171 aLabel.ShowNumberInPercent = false;
172 aLabel.ShowCategoryName = false;
174 xPointProp->setPropertyValue(CHART_UNONAME_LABEL, uno::Any(aLabel));
180 catch(const uno::Exception &)
182 TOOLS_WARN_EXCEPTION("chart2", "" );
186 } // anonymous namespace
188 namespace chart
191 namespace DataSeriesHelper
194 OUString getRole( const uno::Reference< chart2::data::XLabeledDataSequence >& xLabeledDataSequence )
196 OUString aRet;
197 if( xLabeledDataSequence.is() )
199 Reference< beans::XPropertySet > xProp( xLabeledDataSequence->getValues(), uno::UNO_QUERY );
200 if( xProp.is() )
201 xProp->getPropertyValue( "Role" ) >>= aRet;
203 return aRet;
206 Reference< chart2::data::XLabeledDataSequence >
207 getDataSequenceByRole(
208 const Reference< chart2::data::XDataSource > & xSource,
209 const OUString& aRole,
210 bool bMatchPrefix /* = false */ )
212 Reference< chart2::data::XLabeledDataSequence > aNoResult;
213 if( ! xSource.is())
214 return aNoResult;
215 Sequence< Reference< chart2::data::XLabeledDataSequence > > aLabeledSeq( xSource->getDataSequences());
217 const Reference< chart2::data::XLabeledDataSequence > * pBegin = aLabeledSeq.getConstArray();
218 const Reference< chart2::data::XLabeledDataSequence > * pEnd = pBegin + aLabeledSeq.getLength();
219 const Reference< chart2::data::XLabeledDataSequence > * pMatch =
220 std::find_if( pBegin, pEnd, lcl_MatchesRole( aRole, bMatchPrefix ));
222 if( pMatch != pEnd )
223 return *pMatch;
225 return aNoResult;
228 std::vector< Reference< chart2::data::XLabeledDataSequence > >
229 getAllDataSequencesByRole( const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aDataSequences,
230 const OUString& aRole )
232 std::vector< Reference< chart2::data::XLabeledDataSequence > > aResultVec;
233 std::copy_if( aDataSequences.begin(), aDataSequences.end(),
234 std::back_inserter( aResultVec ),
235 lcl_MatchesRole(aRole, /*bMatchPrefix*/true) );
236 return aResultVec;
239 std::vector<Reference<css::chart2::data::XLabeledDataSequence> >
240 getAllDataSequences( const uno::Sequence<uno::Reference<chart2::XDataSeries> >& aSeries )
242 std::vector< Reference< chart2::data::XLabeledDataSequence > > aSeqVec;
244 for( sal_Int32 i = 0; i < aSeries.getLength(); ++i )
246 Reference< chart2::data::XDataSource > xSource( aSeries[ i ], uno::UNO_QUERY );
247 if( xSource.is())
249 Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeq( xSource->getDataSequences());
250 std::copy( aSeq.begin(), aSeq.end(),
251 std::back_inserter( aSeqVec ));
255 return aSeqVec;
258 Reference< chart2::data::XDataSource >
259 getDataSource( const Sequence< Reference< chart2::XDataSeries > > & aSeries )
261 return Reference< chart2::data::XDataSource >(
262 new DataSource(comphelper::containerToSequence(getAllDataSequences(aSeries))));
265 namespace
267 OUString lcl_getDataSequenceLabel( const Reference< chart2::data::XDataSequence > & xSequence )
269 OUString aResult;
271 Reference< chart2::data::XTextualDataSequence > xTextSeq( xSequence, uno::UNO_QUERY );
272 if( xTextSeq.is())
274 Sequence< OUString > aSeq( xTextSeq->getTextualData());
276 const sal_Int32 nMax = aSeq.getLength() - 1;
277 OUStringBuffer aBuf;
279 for( sal_Int32 i = 0; i <= nMax; ++i )
281 aBuf.append( aSeq[i] );
282 if( i < nMax )
283 aBuf.append( ' ');
285 aResult = aBuf.makeStringAndClear();
287 else if( xSequence.is())
289 Sequence< uno::Any > aSeq( xSequence->getData());
291 const sal_Int32 nMax = aSeq.getLength() - 1;
292 OUString aVal;
293 OUStringBuffer aBuf;
294 double fNum = 0;
296 for( sal_Int32 i = 0; i <= nMax; ++i )
298 if( aSeq[i] >>= aVal )
300 aBuf.append( aVal );
301 if( i < nMax )
302 aBuf.append( ' ');
304 else if( aSeq[ i ] >>= fNum )
306 aBuf.append( fNum );
307 if( i < nMax )
308 aBuf.append( ' ');
311 aResult = aBuf.makeStringAndClear();
314 return aResult;
318 OUString getLabelForLabeledDataSequence(
319 const Reference< chart2::data::XLabeledDataSequence > & xLabeledSeq )
321 OUString aResult;
322 if( xLabeledSeq.is())
324 Reference< chart2::data::XDataSequence > xSeq( xLabeledSeq->getLabel());
325 if( xSeq.is() )
326 aResult = lcl_getDataSequenceLabel( xSeq );
327 if( !xSeq.is() || aResult.isEmpty() )
329 // no label set or label content is empty -> use auto-generated one
330 Reference< chart2::data::XDataSequence > xValueSeq( xLabeledSeq->getValues() );
331 if( xValueSeq.is() )
333 Sequence< OUString > aLabels( xValueSeq->generateLabel(
334 chart2::data::LabelOrigin_SHORT_SIDE ) );
335 // no labels returned is interpreted as: auto-generation not
336 // supported by sequence
337 if( aLabels.hasElements() )
338 aResult=aLabels[0];
339 else
341 //todo?: maybe use the index of the series as name
342 //but as the index may change it would be better to have such a name persistent
343 //what is not possible at the moment
344 //--> maybe use the identifier as part of the name ...
345 aResult = lcl_getDataSequenceLabel( xValueSeq );
350 return aResult;
353 OUString getDataSeriesLabel(
354 const Reference< chart2::XDataSeries > & xSeries,
355 const OUString & rLabelSequenceRole )
357 OUString aResult;
359 Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
360 if( xSource.is())
362 Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
363 ::chart::DataSeriesHelper::getDataSequenceByRole( xSource, rLabelSequenceRole ));
364 if( xLabeledSeq.is())
365 aResult = getLabelForLabeledDataSequence( xLabeledSeq );
366 else
368 // special case: labeled data series with only a label and no values may
369 // serve as label
370 xLabeledSeq.set( lcl_findLSequenceWithOnlyLabel( xSource ));
371 if( xLabeledSeq.is())
373 Reference< chart2::data::XDataSequence > xSeq( xLabeledSeq->getLabel());
374 if( xSeq.is())
375 aResult = lcl_getDataSequenceLabel( xSeq );
381 return aResult;
384 void setStackModeAtSeries(
385 const Sequence< Reference< chart2::XDataSeries > > & aSeries,
386 const Reference< chart2::XCoordinateSystem > & xCorrespondingCoordinateSystem,
387 StackMode eStackMode )
389 const uno::Any aPropValue(
390 ( (eStackMode == StackMode::YStacked) ||
391 (eStackMode == StackMode::YStackedPercent) )
392 ? chart2::StackingDirection_Y_STACKING
393 : (eStackMode == StackMode::ZStacked )
394 ? chart2::StackingDirection_Z_STACKING
395 : chart2::StackingDirection_NO_STACKING );
397 std::set< sal_Int32 > aAxisIndexSet;
398 for( sal_Int32 i=0; i<aSeries.getLength(); ++i )
402 Reference< beans::XPropertySet > xProp( aSeries[i], uno::UNO_QUERY );
403 if( xProp.is() )
405 xProp->setPropertyValue( "StackingDirection", aPropValue );
407 sal_Int32 nAxisIndex;
408 xProp->getPropertyValue( "AttachedAxisIndex" ) >>= nAxisIndex;
409 aAxisIndexSet.insert(nAxisIndex);
412 catch( const uno::Exception & )
414 DBG_UNHANDLED_EXCEPTION("chart2");
418 if( xCorrespondingCoordinateSystem.is() &&
419 1 < xCorrespondingCoordinateSystem->getDimension() )
421 if( aAxisIndexSet.empty() )
423 aAxisIndexSet.insert(0);
426 for (auto const& axisIndex : aAxisIndexSet)
428 Reference< chart2::XAxis > xAxis(
429 xCorrespondingCoordinateSystem->getAxisByDimension(1, axisIndex));
430 if( xAxis.is())
432 bool bPercent = (eStackMode == StackMode::YStackedPercent);
433 chart2::ScaleData aScaleData = xAxis->getScaleData();
435 if( bPercent != (aScaleData.AxisType==chart2::AxisType::PERCENT) )
437 if( bPercent )
438 aScaleData.AxisType = chart2::AxisType::PERCENT;
439 else
440 aScaleData.AxisType = chart2::AxisType::REALNUMBER;
441 xAxis->setScaleData( aScaleData );
448 sal_Int32 getAttachedAxisIndex( const Reference< chart2::XDataSeries > & xSeries )
450 sal_Int32 nRet = 0;
453 Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY );
454 if( xProp.is() )
456 xProp->getPropertyValue( "AttachedAxisIndex" ) >>= nRet;
459 catch( const uno::Exception & )
461 DBG_UNHANDLED_EXCEPTION("chart2");
463 return nRet;
466 sal_Int32 getNumberFormatKeyFromAxis(
467 const Reference< chart2::XDataSeries > & xSeries,
468 const Reference< chart2::XCoordinateSystem > & xCorrespondingCoordinateSystem,
469 sal_Int32 nDimensionIndex,
470 sal_Int32 nAxisIndex /* = -1 */ )
472 sal_Int32 nResult = 0;
473 if( nAxisIndex == -1 )
474 nAxisIndex = getAttachedAxisIndex( xSeries );
477 Reference< beans::XPropertySet > xAxisProp(
478 xCorrespondingCoordinateSystem->getAxisByDimension( nDimensionIndex, nAxisIndex ), uno::UNO_QUERY );
479 if( xAxisProp.is())
480 xAxisProp->getPropertyValue(CHART_UNONAME_NUMFMT) >>= nResult;
482 catch( const uno::Exception & )
484 DBG_UNHANDLED_EXCEPTION("chart2");
487 return nResult;
490 Reference< chart2::XCoordinateSystem > getCoordinateSystemOfSeries(
491 const Reference< chart2::XDataSeries > & xSeries,
492 const Reference< chart2::XDiagram > & xDiagram )
494 Reference< chart2::XCoordinateSystem > xResult;
495 Reference< chart2::XChartType > xDummy;
496 lcl_getCooSysAndChartTypeOfSeries( xSeries, xDiagram, xResult, xDummy );
498 return xResult;
501 Reference< chart2::XChartType > getChartTypeOfSeries(
502 const Reference< chart2::XDataSeries > & xSeries,
503 const Reference< chart2::XDiagram > & xDiagram )
505 Reference< chart2::XChartType > xResult;
506 Reference< chart2::XCoordinateSystem > xDummy;
507 lcl_getCooSysAndChartTypeOfSeries( xSeries, xDiagram, xDummy, xResult );
509 return xResult;
512 void deleteSeries(
513 const Reference< chart2::XDataSeries > & xSeries,
514 const Reference< chart2::XChartType > & xChartType )
518 Reference< chart2::XDataSeriesContainer > xSeriesCnt( xChartType, uno::UNO_QUERY_THROW );
519 auto aSeries(
520 comphelper::sequenceToContainer<std::vector< Reference< chart2::XDataSeries > > >( xSeriesCnt->getDataSeries()));
521 std::vector< Reference< chart2::XDataSeries > >::iterator aIt =
522 std::find( aSeries.begin(), aSeries.end(), xSeries );
523 if( aIt != aSeries.end())
525 aSeries.erase( aIt );
526 xSeriesCnt->setDataSeries( comphelper::containerToSequence( aSeries ));
529 catch( const uno::Exception & )
531 DBG_UNHANDLED_EXCEPTION("chart2");
535 void switchSymbolsOnOrOff( const Reference< beans::XPropertySet > & xSeriesProperties,
536 bool bSymbolsOn, sal_Int32 nSeriesIndex )
538 if( !xSeriesProperties.is() )
539 return;
541 chart2::Symbol aSymbProp;
542 if( xSeriesProperties->getPropertyValue( "Symbol") >>= aSymbProp )
544 if( !bSymbolsOn )
545 aSymbProp.Style = chart2::SymbolStyle_NONE;
546 else if( aSymbProp.Style == chart2::SymbolStyle_NONE )
548 aSymbProp.Style = chart2::SymbolStyle_STANDARD;
549 aSymbProp.StandardSymbol = nSeriesIndex;
551 xSeriesProperties->setPropertyValue( "Symbol", uno::Any( aSymbProp ));
553 //todo: check attributed data points
556 void switchLinesOnOrOff( const Reference< beans::XPropertySet > & xSeriesProperties, bool bLinesOn )
558 if( !xSeriesProperties.is() )
559 return;
561 if( bLinesOn )
563 // keep line-styles that are not NONE
564 drawing::LineStyle eLineStyle;
565 if( (xSeriesProperties->getPropertyValue( "LineStyle") >>= eLineStyle ) &&
566 eLineStyle == drawing::LineStyle_NONE )
568 xSeriesProperties->setPropertyValue( "LineStyle", uno::Any( drawing::LineStyle_SOLID ) );
571 else
572 xSeriesProperties->setPropertyValue( "LineStyle", uno::Any( drawing::LineStyle_NONE ) );
575 void makeLinesThickOrThin( const Reference< beans::XPropertySet > & xSeriesProperties, bool bThick )
577 if( !xSeriesProperties.is() )
578 return;
580 sal_Int32 nNewValue = bThick ? 80 : 0;
581 sal_Int32 nOldValue = 0;
582 if( (xSeriesProperties->getPropertyValue( "LineWidth") >>= nOldValue ) &&
583 nOldValue != nNewValue )
585 if( !(bThick && nOldValue>0))
586 xSeriesProperties->setPropertyValue( "LineWidth", uno::Any( nNewValue ) );
590 void setPropertyAlsoToAllAttributedDataPoints( const Reference< chart2::XDataSeries >& xSeries,
591 const OUString& rPropertyName, const uno::Any& rPropertyValue )
593 Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY );
594 if( !xSeriesProperties.is() )
595 return;
597 xSeriesProperties->setPropertyValue( rPropertyName, rPropertyValue );
598 uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
599 if( xSeriesProperties->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList )
601 for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
603 Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]) );
604 if(!xPointProp.is())
605 continue;
606 xPointProp->setPropertyValue( rPropertyName, rPropertyValue );
611 bool hasAttributedDataPointDifferentValue( 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() )
616 return false;
618 uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
619 if( xSeriesProperties->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList )
621 for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
623 Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]) );
624 if(!xPointProp.is())
625 continue;
626 uno::Any aPointValue( xPointProp->getPropertyValue( rPropertyName ) );
627 if( rPropertyValue != aPointValue )
628 return true;
631 return false;
634 namespace
637 bool lcl_SequenceHasUnhiddenData( const uno::Reference< chart2::data::XDataSequence >& xDataSequence )
639 if( !xDataSequence.is() )
640 return false;
641 uno::Reference< beans::XPropertySet > xProp( xDataSequence, uno::UNO_QUERY );
642 if( xProp.is() )
644 uno::Sequence< sal_Int32 > aHiddenValues;
647 xProp->getPropertyValue( "HiddenValues" ) >>= aHiddenValues;
648 if( !aHiddenValues.hasElements() )
649 return true;
651 catch( const uno::Exception& )
653 return true;
656 return xDataSequence->getData().hasElements();
661 bool hasUnhiddenData( const uno::Reference< chart2::XDataSeries >& xSeries )
663 uno::Reference< chart2::data::XDataSource > xDataSource( xSeries, uno::UNO_QUERY );
665 uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aDataSequences = xDataSource->getDataSequences();
667 for(sal_Int32 nN = aDataSequences.getLength();nN--;)
669 if( !aDataSequences[nN].is() )
670 continue;
671 if( lcl_SequenceHasUnhiddenData( aDataSequences[nN]->getValues() ) )
672 return true;
673 if( lcl_SequenceHasUnhiddenData( aDataSequences[nN]->getLabel() ) )
674 return true;
676 return false;
679 sal_Int32 translateIndexFromHiddenToFullSequence( sal_Int32 nIndex, const Reference< chart2::data::XDataSequence >& xDataSequence, bool bTranslate )
681 if( !bTranslate )
682 return nIndex;
686 uno::Reference<beans::XPropertySet> xProp( xDataSequence, uno::UNO_QUERY );
687 if( xProp.is())
689 Sequence<sal_Int32> aHiddenIndicesSeq;
690 xProp->getPropertyValue( "HiddenValues" ) >>= aHiddenIndicesSeq;
691 if( aHiddenIndicesSeq.hasElements() )
693 auto aHiddenIndices( comphelper::sequenceToContainer<std::vector< sal_Int32 >>( aHiddenIndicesSeq ) );
694 std::sort( aHiddenIndices.begin(), aHiddenIndices.end() );
696 sal_Int32 nHiddenCount = static_cast<sal_Int32>(aHiddenIndices.size());
697 for( sal_Int32 nN = 0; nN < nHiddenCount; ++nN)
699 if( aHiddenIndices[nN] <= nIndex )
700 nIndex += 1;
701 else
702 break;
707 catch (const beans::UnknownPropertyException&)
710 return nIndex;
713 bool hasDataLabelsAtSeries( const Reference< chart2::XDataSeries >& xSeries )
715 bool bRet = false;
718 Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY );
719 if( xProp.is() )
721 DataPointLabel aLabel;
722 if( xProp->getPropertyValue(CHART_UNONAME_LABEL) >>= aLabel )
723 bRet = aLabel.ShowNumber || aLabel.ShowNumberInPercent || aLabel.ShowCategoryName;
726 catch(const uno::Exception &)
728 TOOLS_WARN_EXCEPTION("chart2", "" );
730 return bRet;
733 bool hasDataLabelsAtPoints( const Reference< chart2::XDataSeries >& xSeries )
735 bool bRet = false;
738 Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY );
739 if( xSeriesProperties.is() )
741 uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
742 if( xSeriesProperties->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList )
744 for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
746 Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]) );
747 if( xPointProp.is() )
749 DataPointLabel aLabel;
750 if( xPointProp->getPropertyValue(CHART_UNONAME_LABEL) >>= aLabel )
751 bRet = aLabel.ShowNumber || aLabel.ShowNumberInPercent || aLabel.ShowCategoryName;
752 if( bRet )
753 break;
759 catch(const uno::Exception &)
761 TOOLS_WARN_EXCEPTION("chart2", "" );
763 return bRet;
766 bool hasDataLabelAtPoint( const Reference< chart2::XDataSeries >& xSeries, sal_Int32 nPointIndex )
768 bool bRet = false;
771 Reference< beans::XPropertySet > xProp;
772 Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY );
773 if( xSeriesProperties.is() )
775 uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
776 if( xSeriesProperties->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList )
778 auto aIndices( comphelper::sequenceToContainer<std::vector< sal_Int32 >>( aAttributedDataPointIndexList ) );
779 std::vector< sal_Int32 >::iterator aIt = std::find( aIndices.begin(), aIndices.end(), nPointIndex );
780 if( aIt != aIndices.end())
781 xProp = xSeries->getDataPointByIndex(nPointIndex);
782 else
783 xProp = xSeriesProperties;
785 if( xProp.is() )
787 DataPointLabel aLabel;
788 if( xProp->getPropertyValue(CHART_UNONAME_LABEL) >>= aLabel )
789 bRet = aLabel.ShowNumber || aLabel.ShowNumberInPercent || aLabel.ShowCategoryName;
793 catch(const uno::Exception &)
795 TOOLS_WARN_EXCEPTION("chart2", "" );
797 return bRet;
800 void insertDataLabelsToSeriesAndAllPoints( const Reference< chart2::XDataSeries >& xSeries )
802 lcl_insertOrDeleteDataLabelsToSeriesAndAllPoints( xSeries, true /*bInsert*/ );
805 void deleteDataLabelsFromSeriesAndAllPoints( const Reference< chart2::XDataSeries >& xSeries )
807 lcl_insertOrDeleteDataLabelsToSeriesAndAllPoints( xSeries, false /*bInsert*/ );
810 void insertDataLabelToPoint( const Reference< beans::XPropertySet >& xPointProp )
814 if( xPointProp.is() )
816 DataPointLabel aLabel;
817 xPointProp->getPropertyValue(CHART_UNONAME_LABEL) >>= aLabel;
818 aLabel.ShowNumber = true;
819 xPointProp->setPropertyValue(CHART_UNONAME_LABEL, uno::Any(aLabel));
822 catch(const uno::Exception &)
824 TOOLS_WARN_EXCEPTION("chart2", "" );
828 void deleteDataLabelsFromPoint( const Reference< beans::XPropertySet >& xPointProp )
832 if( xPointProp.is() )
834 DataPointLabel aLabel;
835 xPointProp->getPropertyValue(CHART_UNONAME_LABEL) >>= aLabel;
836 aLabel.ShowNumber = false;
837 aLabel.ShowNumberInPercent = false;
838 aLabel.ShowCategoryName = false;
839 xPointProp->setPropertyValue(CHART_UNONAME_LABEL, uno::Any(aLabel));
842 catch(const uno::Exception &)
844 TOOLS_WARN_EXCEPTION("chart2", "" );
848 } // namespace DataSeriesHelper
849 } // namespace chart
851 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */