/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_chart2.hxx" #include "DataSeriesHelper.hxx" #include "DiagramHelper.hxx" #include "DataSource.hxx" #include "macros.hxx" #include "ContainerHelper.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace ::com::sun::star; using namespace ::com::sun::star::chart2; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Sequence; using ::rtl::OUString; using ::rtl::OUStringBuffer; // ---------------------------------------- namespace { class lcl_MatchesRole : public ::std::unary_function< Reference< chart2::data::XLabeledDataSequence >, bool > { public: explicit lcl_MatchesRole( const OUString & aRole, bool bMatchPrefix ) : m_aRole( aRole ), m_bMatchPrefix( bMatchPrefix ) {} bool operator () ( const Reference< chart2::data::XLabeledDataSequence > & xSeq ) const { if(!xSeq.is()) return false; Reference< beans::XPropertySet > xProp( xSeq->getValues(), uno::UNO_QUERY ); OUString aRole; if( m_bMatchPrefix ) return ( xProp.is() && (xProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" )) ) >>= aRole ) && aRole.match( m_aRole )); return ( xProp.is() && (xProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" )) ) >>= aRole ) && m_aRole.equals( aRole )); } private: OUString m_aRole; bool m_bMatchPrefix; }; Reference< chart2::data::XLabeledDataSequence > lcl_findLSequenceWithOnlyLabel( const Reference< chart2::data::XDataSource > & xDataSource ) { Reference< chart2::data::XLabeledDataSequence > xResult; Sequence< Reference< chart2::data::XLabeledDataSequence > > aSequences( xDataSource->getDataSequences()); for( sal_Int32 i=0; igetValues().is() && aSequences[i]->getLabel().is())) { xResult.set( aSequences[i] ); break; } } return xResult; } void lcl_getCooSysAndChartTypeOfSeries( const Reference< chart2::XDataSeries > & xSeries, const Reference< chart2::XDiagram > & xDiagram, Reference< chart2::XCoordinateSystem > & xOutCooSys, Reference< chart2::XChartType > & xOutChartType ) { Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY ); if( xCooSysCnt.is()) { Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems()); for( sal_Int32 nCooSysIdx=0; nCooSysIdx xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW ); Sequence< Reference< chart2::XChartType > > aChartTypes( xCTCnt->getChartTypes()); for( sal_Int32 nCTIdx=0; nCTIdx xSeriesCnt( aChartTypes[nCTIdx], uno::UNO_QUERY ); if( xSeriesCnt.is()) { Sequence< Reference< chart2::XDataSeries > > aSeries( xSeriesCnt->getDataSeries()); for( sal_Int32 nSeriesIdx=0; nSeriesIdx& xSeries, bool bInsert ) { try { Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY ); if( xSeriesProperties.is() ) { DataPointLabel aLabelAtSeries; xSeriesProperties->getPropertyValue( C2U( "Label" ) ) >>= aLabelAtSeries; aLabelAtSeries.ShowNumber = bInsert; if( !bInsert ) { aLabelAtSeries.ShowNumberInPercent = false; aLabelAtSeries.ShowCategoryName = false; } xSeriesProperties->setPropertyValue( C2U( "Label" ), uno::makeAny( aLabelAtSeries ) ); uno::Sequence< sal_Int32 > aAttributedDataPointIndexList; if( xSeriesProperties->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList ) { for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;) { Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]) ); if( xPointProp.is() ) { DataPointLabel aLabel; xPointProp->getPropertyValue( C2U( "Label" ) ) >>= aLabel; aLabel.ShowNumber = bInsert; if( !bInsert ) { aLabel.ShowNumberInPercent = false; aLabel.ShowCategoryName = false; } xPointProp->setPropertyValue( C2U( "Label" ), uno::makeAny( aLabel ) ); } } } } } catch( uno::Exception &e) { ASSERT_EXCEPTION( e ); } } } // anonymous namespace // ---------------------------------------- namespace chart { namespace DataSeriesHelper { OUString GetRole( const uno::Reference< chart2::data::XLabeledDataSequence >& xLabeledDataSequence ) { OUString aRet; if( xLabeledDataSequence.is() ) { Reference< beans::XPropertySet > xProp( xLabeledDataSequence->getValues(), uno::UNO_QUERY ); if( xProp.is() ) xProp->getPropertyValue( C2U("Role") ) >>= aRet; } return aRet; } Reference< chart2::data::XLabeledDataSequence > getDataSequenceByRole( const Reference< chart2::data::XDataSource > & xSource, OUString aRole, bool bMatchPrefix /* = false */ ) { Reference< chart2::data::XLabeledDataSequence > aNoResult; if( ! xSource.is()) return aNoResult; Sequence< Reference< chart2::data::XLabeledDataSequence > > aLabeledSeq( xSource->getDataSequences()); const Reference< chart2::data::XLabeledDataSequence > * pBegin = aLabeledSeq.getConstArray(); const Reference< chart2::data::XLabeledDataSequence > * pEnd = pBegin + aLabeledSeq.getLength(); const Reference< chart2::data::XLabeledDataSequence > * pMatch = ::std::find_if( pBegin, pEnd, lcl_MatchesRole( aRole, bMatchPrefix )); if( pMatch != pEnd ) return *pMatch; return aNoResult; } ::std::vector< Reference< chart2::data::XLabeledDataSequence > > getAllDataSequencesByRole( const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aDataSequences, OUString aRole, bool bMatchPrefix /* = false */ ) { ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aResultVec; ::std::remove_copy_if( aDataSequences.getConstArray(), aDataSequences.getConstArray() + aDataSequences.getLength(), ::std::back_inserter( aResultVec ), ::std::not1( lcl_MatchesRole( aRole, bMatchPrefix ))); return aResultVec; } Reference< chart2::data::XDataSource > getDataSource( const Sequence< Reference< chart2::XDataSeries > > & aSeries ) { ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aSeqVec; for( sal_Int32 i = 0; i < aSeries.getLength(); ++i ) { Reference< chart2::data::XDataSource > xSource( aSeries[ i ], uno::UNO_QUERY ); if( xSource.is()) { Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeq( xSource->getDataSequences()); ::std::copy( aSeq.getConstArray(), aSeq.getConstArray() + aSeq.getLength(), ::std::back_inserter( aSeqVec )); } } return Reference< chart2::data::XDataSource >( new DataSource( ContainerHelper::ContainerToSequence( aSeqVec ))); } namespace { OUString lcl_getDataSequenceLabel( const Reference< chart2::data::XDataSequence > & xSequence ) { OUString aResult; Reference< chart2::data::XTextualDataSequence > xTextSeq( xSequence, uno::UNO_QUERY ); if( xTextSeq.is()) { Sequence< OUString > aSeq( xTextSeq->getTextualData()); const sal_Int32 nMax = aSeq.getLength() - 1; OUString aVal; OUStringBuffer aBuf; for( sal_Int32 i = 0; i <= nMax; ++i ) { aBuf.append( aSeq[i] ); if( i < nMax ) aBuf.append( sal_Unicode( ' ' )); } aResult = aBuf.makeStringAndClear(); } else if( xSequence.is()) { Sequence< uno::Any > aSeq( xSequence->getData()); const sal_Int32 nMax = aSeq.getLength() - 1; OUString aVal; OUStringBuffer aBuf; double fNum = 0; for( sal_Int32 i = 0; i <= nMax; ++i ) { if( aSeq[i] >>= aVal ) { aBuf.append( aVal ); if( i < nMax ) aBuf.append( sal_Unicode( ' ' )); } else if( aSeq[ i ] >>= fNum ) { aBuf.append( fNum ); if( i < nMax ) aBuf.append( sal_Unicode( ' ' )); } } aResult = aBuf.makeStringAndClear(); } return aResult; } } OUString getLabelForLabeledDataSequence( const Reference< chart2::data::XLabeledDataSequence > & xLabeledSeq ) { OUString aResult; if( xLabeledSeq.is()) { Reference< chart2::data::XDataSequence > xSeq( xLabeledSeq->getLabel()); if( xSeq.is() ) aResult = lcl_getDataSequenceLabel( xSeq ); if( !xSeq.is() || aResult.isEmpty() ) { // no label set or label content is empty -> use auto-generated one Reference< chart2::data::XDataSequence > xValueSeq( xLabeledSeq->getValues() ); if( xValueSeq.is() ) { Sequence< OUString > aLabels( xValueSeq->generateLabel( chart2::data::LabelOrigin_SHORT_SIDE ) ); // no labels returned is interpreted as: auto-generation not // supported by sequence if( aLabels.getLength() ) aResult=aLabels[0]; else { //todo?: maybe use the index of the series as name //but as the index may change it would be better to have such a name persistent //what is not possible at the moment //--> maybe use the identifier as part of the name ... aResult = lcl_getDataSequenceLabel( xValueSeq ); } } } } return aResult; } OUString getDataSeriesLabel( const Reference< chart2::XDataSeries > & xSeries, const OUString & rLabelSequenceRole ) { OUString aResult; Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY ); if( xSource.is()) { Reference< chart2::data::XLabeledDataSequence > xLabeledSeq( ::chart::DataSeriesHelper::getDataSequenceByRole( xSource, rLabelSequenceRole )); if( xLabeledSeq.is()) aResult = getLabelForLabeledDataSequence( xLabeledSeq ); else { // special case: labeled data series with only a label and no values may // serve as label xLabeledSeq.set( lcl_findLSequenceWithOnlyLabel( xSource )); if( xLabeledSeq.is()) { Reference< chart2::data::XDataSequence > xSeq( xLabeledSeq->getLabel()); if( xSeq.is()) aResult = lcl_getDataSequenceLabel( xSeq ); } } } return aResult; } void setStackModeAtSeries( const Sequence< Reference< chart2::XDataSeries > > & aSeries, const Reference< chart2::XCoordinateSystem > & xCorrespondingCoordinateSystem, StackMode eStackMode ) { if( eStackMode == StackMode_AMBIGUOUS ) return; const OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( "StackingDirection" )); const uno::Any aPropValue = uno::makeAny( ( (eStackMode == StackMode_Y_STACKED) || (eStackMode == StackMode_Y_STACKED_PERCENT) ) ? chart2::StackingDirection_Y_STACKING : (eStackMode == StackMode_Z_STACKED ) ? chart2::StackingDirection_Z_STACKING : chart2::StackingDirection_NO_STACKING ); std::set< sal_Int32 > aAxisIndexSet; for( sal_Int32 i=0; i xProp( aSeries[i], uno::UNO_QUERY ); if( xProp.is() ) { xProp->setPropertyValue( aPropName, aPropValue ); sal_Int32 nAxisIndex; xProp->getPropertyValue( C2U("AttachedAxisIndex") ) >>= nAxisIndex; aAxisIndexSet.insert(nAxisIndex); } } catch( uno::Exception & ex ) { ASSERT_EXCEPTION( ex ); } } if( xCorrespondingCoordinateSystem.is() && 1 < xCorrespondingCoordinateSystem->getDimension() ) { sal_Int32 nAxisIndexCount = aAxisIndexSet.size(); if( !nAxisIndexCount ) { aAxisIndexSet.insert(0); nAxisIndexCount = aAxisIndexSet.size(); } for( ::std::set< sal_Int32 >::const_iterator aIt = aAxisIndexSet.begin(); aIt != aAxisIndexSet.end(); ++aIt ) { sal_Int32 nAxisIndex = *aIt; Reference< chart2::XAxis > xAxis( xCorrespondingCoordinateSystem->getAxisByDimension( 1, nAxisIndex )); if( xAxis.is()) { sal_Bool bPercent = (eStackMode == StackMode_Y_STACKED_PERCENT); chart2::ScaleData aScaleData = xAxis->getScaleData(); if( bPercent != (aScaleData.AxisType==chart2::AxisType::PERCENT) ) { if( bPercent ) aScaleData.AxisType = chart2::AxisType::PERCENT; else aScaleData.AxisType = chart2::AxisType::REALNUMBER; xAxis->setScaleData( aScaleData ); } } } } } sal_Int32 getAttachedAxisIndex( const Reference< chart2::XDataSeries > & xSeries ) { sal_Int32 nRet = 0; try { Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY ); if( xProp.is() ) { xProp->getPropertyValue( C2U("AttachedAxisIndex") ) >>= nRet; } } catch( uno::Exception & ex ) { ASSERT_EXCEPTION( ex ); } return nRet; } sal_Int32 getNumberFormatKeyFromAxis( const Reference< chart2::XDataSeries > & xSeries, const Reference< chart2::XCoordinateSystem > & xCorrespondingCoordinateSystem, sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex /* = -1 */ ) { sal_Int32 nResult = 0; if( nAxisIndex == -1 ) nAxisIndex = getAttachedAxisIndex( xSeries ); try { Reference< beans::XPropertySet > xAxisProp( xCorrespondingCoordinateSystem->getAxisByDimension( nDimensionIndex, nAxisIndex ), uno::UNO_QUERY ); if( xAxisProp.is()) xAxisProp->getPropertyValue( C2U("NumberFormat")) >>= nResult; } catch( const uno::Exception & ex ) { ASSERT_EXCEPTION( ex ); } return nResult; } Reference< chart2::XCoordinateSystem > getCoordinateSystemOfSeries( const Reference< chart2::XDataSeries > & xSeries, const Reference< chart2::XDiagram > & xDiagram ) { Reference< chart2::XCoordinateSystem > xResult; Reference< chart2::XChartType > xDummy; lcl_getCooSysAndChartTypeOfSeries( xSeries, xDiagram, xResult, xDummy ); return xResult; } Reference< chart2::XChartType > getChartTypeOfSeries( const Reference< chart2::XDataSeries > & xSeries, const Reference< chart2::XDiagram > & xDiagram ) { Reference< chart2::XChartType > xResult; Reference< chart2::XCoordinateSystem > xDummy; lcl_getCooSysAndChartTypeOfSeries( xSeries, xDiagram, xDummy, xResult ); return xResult; } void deleteSeries( const Reference< chart2::XDataSeries > & xSeries, const Reference< chart2::XChartType > & xChartType ) { try { Reference< chart2::XDataSeriesContainer > xSeriesCnt( xChartType, uno::UNO_QUERY_THROW ); ::std::vector< Reference< chart2::XDataSeries > > aSeries( ContainerHelper::SequenceToVector( xSeriesCnt->getDataSeries())); ::std::vector< Reference< chart2::XDataSeries > >::iterator aIt = ::std::find( aSeries.begin(), aSeries.end(), xSeries ); if( aIt != aSeries.end()) { aSeries.erase( aIt ); xSeriesCnt->setDataSeries( ContainerHelper::ContainerToSequence( aSeries )); } } catch( uno::Exception & ex ) { ASSERT_EXCEPTION( ex ); } } void switchSymbolsOnOrOff( const Reference< beans::XPropertySet > & xSeriesProperties, bool bSymbolsOn, sal_Int32 nSeriesIndex ) { if( !xSeriesProperties.is() ) return; chart2::Symbol aSymbProp; if( (xSeriesProperties->getPropertyValue( C2U( "Symbol" )) >>= aSymbProp ) ) { if( !bSymbolsOn ) aSymbProp.Style = chart2::SymbolStyle_NONE; else if( aSymbProp.Style == chart2::SymbolStyle_NONE ) { aSymbProp.Style = chart2::SymbolStyle_STANDARD; aSymbProp.StandardSymbol = nSeriesIndex; } xSeriesProperties->setPropertyValue( C2U( "Symbol" ), uno::makeAny( aSymbProp )); } //todo: check attributed data points } void switchLinesOnOrOff( const Reference< beans::XPropertySet > & xSeriesProperties, bool bLinesOn ) { if( !xSeriesProperties.is() ) return; if( bLinesOn ) { // keep line-styles that are not NONE drawing::LineStyle eLineStyle; if( (xSeriesProperties->getPropertyValue( C2U( "LineStyle" )) >>= eLineStyle ) && eLineStyle == drawing::LineStyle_NONE ) { xSeriesProperties->setPropertyValue( C2U( "LineStyle" ), uno::makeAny( drawing::LineStyle_SOLID ) ); } } else xSeriesProperties->setPropertyValue( C2U( "LineStyle" ), uno::makeAny( drawing::LineStyle_NONE ) ); } void makeLinesThickOrThin( const Reference< beans::XPropertySet > & xSeriesProperties, bool bThick ) { if( !xSeriesProperties.is() ) return; sal_Int32 nNewValue = bThick ? 80 : 0; sal_Int32 nOldValue = 0; if( (xSeriesProperties->getPropertyValue( C2U( "LineWidth" )) >>= nOldValue ) && nOldValue != nNewValue ) { if( !(bThick && nOldValue>0)) xSeriesProperties->setPropertyValue( C2U( "LineWidth" ), uno::makeAny( nNewValue ) ); } } void setPropertyAlsoToAllAttributedDataPoints( const Reference< chart2::XDataSeries >& xSeries, const OUString& rPropertyName, const uno::Any& rPropertyValue ) { Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY ); if( !xSeriesProperties.is() ) return; xSeriesProperties->setPropertyValue( rPropertyName, rPropertyValue ); uno::Sequence< sal_Int32 > aAttributedDataPointIndexList; if( xSeriesProperties->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList ) { for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;) { Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]) ); if(!xPointProp.is()) continue; xPointProp->setPropertyValue( rPropertyName, rPropertyValue ); } } } bool hasAttributedDataPointDifferentValue( const Reference< chart2::XDataSeries >& xSeries, const OUString& rPropertyName, const uno::Any& rPropertyValue ) { Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY ); if( !xSeriesProperties.is() ) return false; uno::Sequence< sal_Int32 > aAttributedDataPointIndexList; if( xSeriesProperties->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList ) { for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;) { Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]) ); if(!xPointProp.is()) continue; uno::Any aPointValue( xPointProp->getPropertyValue( rPropertyName ) ); if( !( rPropertyValue==aPointValue ) ) return true; } } return false; } bool areAllSeriesAttachedToSameAxis( const uno::Reference< chart2::XChartType >& xChartType, sal_Int32 & rOutAxisIndex ) { try { uno::Reference< chart2::XDataSeriesContainer > xDataSeriesContainer( xChartType, uno::UNO_QUERY_THROW ); uno::Sequence< uno::Reference< chart2::XDataSeries > > aSeriesSeq( xDataSeriesContainer->getDataSeries()); const sal_Int32 nSeriesCount( aSeriesSeq.getLength()); // AxisIndex can only be 0 or 1 sal_Int32 nSeriesAtFirstAxis = 0; sal_Int32 nSeriesAtSecondAxis = 0; for( sal_Int32 nI = 0; nI < nSeriesCount; ++nI ) { uno::Reference< chart2::XDataSeries > xSeries( aSeriesSeq[nI], uno::UNO_QUERY ); sal_Int32 nAxisIndex = DataSeriesHelper::getAttachedAxisIndex( xSeries ); if( nAxisIndex == 0 ) ++nSeriesAtFirstAxis; else if( nAxisIndex == 1 ) ++nSeriesAtSecondAxis; } OSL_ENSURE( nSeriesAtFirstAxis + nSeriesAtSecondAxis == nSeriesCount, "Invalid axis index found" ); if( nSeriesAtFirstAxis == nSeriesCount ) rOutAxisIndex = 0; else if( nSeriesAtSecondAxis == nSeriesCount ) rOutAxisIndex = 1; return ( nSeriesAtFirstAxis == nSeriesCount || nSeriesAtSecondAxis == nSeriesCount ); } catch( const uno::Exception & ex ) { ASSERT_EXCEPTION( ex ); return false; } } namespace { bool lcl_SequenceHasUnhiddenData( const uno::Reference< chart2::data::XDataSequence >& xDataSequence ) { if( !xDataSequence.is() ) return false; uno::Reference< beans::XPropertySet > xProp( xDataSequence, uno::UNO_QUERY ); if( xProp.is() ) { uno::Sequence< sal_Int32 > aHiddenValues; try { xProp->getPropertyValue( C2U( "HiddenValues" ) ) >>= aHiddenValues; if( !aHiddenValues.getLength() ) return true; } catch( uno::Exception& e ) { (void)e; // avoid warning return true; } } if( xDataSequence->getData().getLength() ) return true; return false; } } bool hasUnhiddenData( const uno::Reference< chart2::XDataSeries >& xSeries ) { uno::Reference< chart2::data::XDataSource > xDataSource = uno::Reference< chart2::data::XDataSource >( xSeries, uno::UNO_QUERY ); uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aDataSequences = xDataSource->getDataSequences(); for(sal_Int32 nN = aDataSequences.getLength();nN--;) { if( !aDataSequences[nN].is() ) continue; if( lcl_SequenceHasUnhiddenData( aDataSequences[nN]->getValues() ) ) return true; if( lcl_SequenceHasUnhiddenData( aDataSequences[nN]->getLabel() ) ) return true; } return false; } struct lcl_LessIndex { inline bool operator() ( const sal_Int32& first, const sal_Int32& second ) { return ( first < second ); } }; sal_Int32 translateIndexFromHiddenToFullSequence( sal_Int32 nIndex, const Reference< chart2::data::XDataSequence >& xDataSequence, bool bTranslate ) { if( !bTranslate ) return nIndex; try { uno::Reference xProp( xDataSequence, uno::UNO_QUERY ); if( xProp.is()) { Sequence aHiddenIndicesSeq; xProp->getPropertyValue( C2U("HiddenValues") ) >>= aHiddenIndicesSeq; if( aHiddenIndicesSeq.getLength() ) { ::std::vector< sal_Int32 > aHiddenIndices( ContainerHelper::SequenceToVector( aHiddenIndicesSeq ) ); ::std::sort( aHiddenIndices.begin(), aHiddenIndices.end(), lcl_LessIndex() ); sal_Int32 nHiddenCount = static_cast(aHiddenIndices.size()); for( sal_Int32 nN = 0; nN < nHiddenCount; ++nN) { if( aHiddenIndices[nN] <= nIndex ) nIndex += 1; else break; } } } } catch (const beans::UnknownPropertyException&) { } return nIndex; } bool hasDataLabelsAtSeries( const Reference< chart2::XDataSeries >& xSeries ) { bool bRet = false; try { Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY ); if( xProp.is() ) { DataPointLabel aLabel; if( (xProp->getPropertyValue( C2U( "Label" ) ) >>= aLabel) ) bRet = aLabel.ShowNumber || aLabel.ShowNumberInPercent || aLabel.ShowCategoryName; } } catch( uno::Exception &e) { ASSERT_EXCEPTION( e ); } return bRet; } bool hasDataLabelsAtPoints( const Reference< chart2::XDataSeries >& xSeries ) { bool bRet = false; try { Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY ); if( xSeriesProperties.is() ) { uno::Sequence< sal_Int32 > aAttributedDataPointIndexList; if( xSeriesProperties->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList ) { for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;) { Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]) ); if( xPointProp.is() ) { DataPointLabel aLabel; if( (xPointProp->getPropertyValue( C2U( "Label" ) ) >>= aLabel) ) bRet = aLabel.ShowNumber || aLabel.ShowNumberInPercent || aLabel.ShowCategoryName; if( bRet ) break; } } } } } catch( uno::Exception &e) { ASSERT_EXCEPTION( e ); } return bRet; } bool hasDataLabelAtPoint( const Reference< chart2::XDataSeries >& xSeries, sal_Int32 nPointIndex ) { bool bRet = false; try { Reference< beans::XPropertySet > xProp; Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY ); if( xSeriesProperties.is() ) { uno::Sequence< sal_Int32 > aAttributedDataPointIndexList; if( xSeriesProperties->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList ) { ::std::vector< sal_Int32 > aIndices( ContainerHelper::SequenceToVector( aAttributedDataPointIndexList ) ); ::std::vector< sal_Int32 >::iterator aIt = ::std::find( aIndices.begin(), aIndices.end(), nPointIndex ); if( aIt != aIndices.end()) xProp = xSeries->getDataPointByIndex(nPointIndex); else xProp = xSeriesProperties; } if( xProp.is() ) { DataPointLabel aLabel; if( (xProp->getPropertyValue( C2U( "Label" ) ) >>= aLabel) ) bRet = aLabel.ShowNumber || aLabel.ShowNumberInPercent || aLabel.ShowCategoryName; } } } catch( uno::Exception &e) { ASSERT_EXCEPTION( e ); } return bRet; } void insertDataLabelsToSeriesAndAllPoints( const Reference< chart2::XDataSeries >& xSeries ) { lcl_insertOrDeleteDataLabelsToSeriesAndAllPoints( xSeries, true /*bInsert*/ ); } void deleteDataLabelsFromSeriesAndAllPoints( const Reference< chart2::XDataSeries >& xSeries ) { lcl_insertOrDeleteDataLabelsToSeriesAndAllPoints( xSeries, false /*bInsert*/ ); } void insertDataLabelToPoint( const Reference< beans::XPropertySet >& xPointProp ) { try { if( xPointProp.is() ) { DataPointLabel aLabel; xPointProp->getPropertyValue( C2U( "Label" ) ) >>= aLabel; aLabel.ShowNumber = true; xPointProp->setPropertyValue( C2U( "Label" ), uno::makeAny( aLabel ) ); } } catch( uno::Exception &e) { ASSERT_EXCEPTION( e ); } } void deleteDataLabelsFromPoint( const Reference< beans::XPropertySet >& xPointProp ) { try { if( xPointProp.is() ) { DataPointLabel aLabel; xPointProp->getPropertyValue( C2U( "Label" ) ) >>= aLabel; aLabel.ShowNumber = false; aLabel.ShowNumberInPercent = false; aLabel.ShowCategoryName = false; xPointProp->setPropertyValue( C2U( "Label" ), uno::makeAny( aLabel ) ); } } catch( uno::Exception &e) { ASSERT_EXCEPTION( e ); } } } // namespace DataSeriesHelper } // namespace chart