xref: /AOO41X/main/chart2/source/tools/DataSeriesHelper.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_chart2.hxx"
30*cdf0e10cSrcweir #include "DataSeriesHelper.hxx"
31*cdf0e10cSrcweir #include "DiagramHelper.hxx"
32*cdf0e10cSrcweir #include "DataSource.hxx"
33*cdf0e10cSrcweir #include "macros.hxx"
34*cdf0e10cSrcweir #include "ContainerHelper.hxx"
35*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
36*cdf0e10cSrcweir #include <com/sun/star/chart2/DataPointLabel.hpp>
37*cdf0e10cSrcweir #include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
38*cdf0e10cSrcweir #include <com/sun/star/chart2/StackingDirection.hpp>
39*cdf0e10cSrcweir #include <com/sun/star/chart2/data/LabelOrigin.hpp>
40*cdf0e10cSrcweir #include <com/sun/star/chart2/AxisType.hpp>
41*cdf0e10cSrcweir #include <com/sun/star/chart2/SymbolStyle.hpp>
42*cdf0e10cSrcweir #include <com/sun/star/chart2/Symbol.hpp>
43*cdf0e10cSrcweir #include <com/sun/star/drawing/LineStyle.hpp>
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
47*cdf0e10cSrcweir #include <com/sun/star/chart2/XChartTypeContainer.hpp>
48*cdf0e10cSrcweir #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
49*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir #include <functional>
52*cdf0e10cSrcweir #include <algorithm>
53*cdf0e10cSrcweir #include <iterator>
54*cdf0e10cSrcweir #include <vector>
55*cdf0e10cSrcweir #include <set>
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir using namespace ::com::sun::star;
58*cdf0e10cSrcweir using namespace ::com::sun::star::chart2;
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir using ::com::sun::star::uno::Reference;
61*cdf0e10cSrcweir using ::com::sun::star::uno::Sequence;
62*cdf0e10cSrcweir using ::rtl::OUString;
63*cdf0e10cSrcweir using ::rtl::OUStringBuffer;
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir // ----------------------------------------
66*cdf0e10cSrcweir namespace
67*cdf0e10cSrcweir {
68*cdf0e10cSrcweir 
69*cdf0e10cSrcweir class lcl_MatchesRole : public ::std::unary_function< Reference< chart2::data::XLabeledDataSequence >, bool >
70*cdf0e10cSrcweir {
71*cdf0e10cSrcweir public:
72*cdf0e10cSrcweir     explicit lcl_MatchesRole( const OUString & aRole, bool bMatchPrefix ) :
73*cdf0e10cSrcweir             m_aRole( aRole ),
74*cdf0e10cSrcweir             m_bMatchPrefix( bMatchPrefix )
75*cdf0e10cSrcweir     {}
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir     bool operator () ( const Reference< chart2::data::XLabeledDataSequence > & xSeq ) const
78*cdf0e10cSrcweir     {
79*cdf0e10cSrcweir         if(!xSeq.is())
80*cdf0e10cSrcweir             return false;
81*cdf0e10cSrcweir         Reference< beans::XPropertySet > xProp( xSeq->getValues(), uno::UNO_QUERY );
82*cdf0e10cSrcweir         OUString aRole;
83*cdf0e10cSrcweir 
84*cdf0e10cSrcweir         if( m_bMatchPrefix )
85*cdf0e10cSrcweir             return ( xProp.is() &&
86*cdf0e10cSrcweir                      (xProp->getPropertyValue(
87*cdf0e10cSrcweir                          OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" )) ) >>= aRole ) &&
88*cdf0e10cSrcweir                      aRole.match( m_aRole ));
89*cdf0e10cSrcweir 
90*cdf0e10cSrcweir         return ( xProp.is() &&
91*cdf0e10cSrcweir                  (xProp->getPropertyValue(
92*cdf0e10cSrcweir                      OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" )) ) >>= aRole ) &&
93*cdf0e10cSrcweir                  m_aRole.equals( aRole ));
94*cdf0e10cSrcweir     }
95*cdf0e10cSrcweir 
96*cdf0e10cSrcweir private:
97*cdf0e10cSrcweir     OUString m_aRole;
98*cdf0e10cSrcweir     bool     m_bMatchPrefix;
99*cdf0e10cSrcweir };
100*cdf0e10cSrcweir 
101*cdf0e10cSrcweir Reference< chart2::data::XLabeledDataSequence > lcl_findLSequenceWithOnlyLabel(
102*cdf0e10cSrcweir     const Reference< chart2::data::XDataSource > & xDataSource )
103*cdf0e10cSrcweir {
104*cdf0e10cSrcweir     Reference< chart2::data::XLabeledDataSequence > xResult;
105*cdf0e10cSrcweir     Sequence< Reference< chart2::data::XLabeledDataSequence > > aSequences( xDataSource->getDataSequences());
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir     for( sal_Int32 i=0; i<aSequences.getLength(); ++i )
108*cdf0e10cSrcweir     {
109*cdf0e10cSrcweir         OSL_ENSURE( aSequences[i].is(), "empty LabeledDataSequence" );
110*cdf0e10cSrcweir         // no values are set but a label exists
111*cdf0e10cSrcweir         if( aSequences[i].is() &&
112*cdf0e10cSrcweir             ( ! aSequences[i]->getValues().is() &&
113*cdf0e10cSrcweir               aSequences[i]->getLabel().is()))
114*cdf0e10cSrcweir         {
115*cdf0e10cSrcweir             xResult.set( aSequences[i] );
116*cdf0e10cSrcweir             break;
117*cdf0e10cSrcweir         }
118*cdf0e10cSrcweir     }
119*cdf0e10cSrcweir 
120*cdf0e10cSrcweir     return xResult;
121*cdf0e10cSrcweir }
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir void lcl_getCooSysAndChartTypeOfSeries(
124*cdf0e10cSrcweir     const Reference< chart2::XDataSeries > & xSeries,
125*cdf0e10cSrcweir     const Reference< chart2::XDiagram > & xDiagram,
126*cdf0e10cSrcweir     Reference< chart2::XCoordinateSystem > & xOutCooSys,
127*cdf0e10cSrcweir     Reference< chart2::XChartType > & xOutChartType )
128*cdf0e10cSrcweir {
129*cdf0e10cSrcweir     Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY );
130*cdf0e10cSrcweir     if( xCooSysCnt.is())
131*cdf0e10cSrcweir     {
132*cdf0e10cSrcweir         Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems());
133*cdf0e10cSrcweir         for( sal_Int32 nCooSysIdx=0; nCooSysIdx<aCooSysSeq.getLength(); ++nCooSysIdx )
134*cdf0e10cSrcweir         {
135*cdf0e10cSrcweir             Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW );
136*cdf0e10cSrcweir             Sequence< Reference< chart2::XChartType > > aChartTypes( xCTCnt->getChartTypes());
137*cdf0e10cSrcweir             for( sal_Int32 nCTIdx=0; nCTIdx<aChartTypes.getLength(); ++nCTIdx )
138*cdf0e10cSrcweir             {
139*cdf0e10cSrcweir                 Reference< chart2::XDataSeriesContainer > xSeriesCnt( aChartTypes[nCTIdx], uno::UNO_QUERY );
140*cdf0e10cSrcweir                 if( xSeriesCnt.is())
141*cdf0e10cSrcweir                 {
142*cdf0e10cSrcweir                     Sequence< Reference< chart2::XDataSeries > > aSeries( xSeriesCnt->getDataSeries());
143*cdf0e10cSrcweir                     for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeries.getLength(); ++nSeriesIdx )
144*cdf0e10cSrcweir                     {
145*cdf0e10cSrcweir                         if( aSeries[nSeriesIdx] == xSeries )
146*cdf0e10cSrcweir                         {
147*cdf0e10cSrcweir                             xOutCooSys.set( aCooSysSeq[nCooSysIdx] );
148*cdf0e10cSrcweir                             xOutChartType.set( aChartTypes[nCTIdx] );
149*cdf0e10cSrcweir                         }
150*cdf0e10cSrcweir                     }
151*cdf0e10cSrcweir                 }
152*cdf0e10cSrcweir             }
153*cdf0e10cSrcweir         }
154*cdf0e10cSrcweir     }
155*cdf0e10cSrcweir }
156*cdf0e10cSrcweir 
157*cdf0e10cSrcweir void lcl_insertOrDeleteDataLabelsToSeriesAndAllPoints( const Reference< chart2::XDataSeries >& xSeries, bool bInsert )
158*cdf0e10cSrcweir {
159*cdf0e10cSrcweir     try
160*cdf0e10cSrcweir     {
161*cdf0e10cSrcweir         Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY );
162*cdf0e10cSrcweir         if( xSeriesProperties.is() )
163*cdf0e10cSrcweir         {
164*cdf0e10cSrcweir             DataPointLabel aLabelAtSeries;
165*cdf0e10cSrcweir             xSeriesProperties->getPropertyValue( C2U( "Label" ) ) >>= aLabelAtSeries;
166*cdf0e10cSrcweir             aLabelAtSeries.ShowNumber = bInsert;
167*cdf0e10cSrcweir             if( !bInsert )
168*cdf0e10cSrcweir             {
169*cdf0e10cSrcweir                 aLabelAtSeries.ShowNumberInPercent = false;
170*cdf0e10cSrcweir                 aLabelAtSeries.ShowCategoryName = false;
171*cdf0e10cSrcweir             }
172*cdf0e10cSrcweir             xSeriesProperties->setPropertyValue( C2U( "Label" ), uno::makeAny( aLabelAtSeries ) );
173*cdf0e10cSrcweir             uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
174*cdf0e10cSrcweir             if( xSeriesProperties->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList )
175*cdf0e10cSrcweir             {
176*cdf0e10cSrcweir                 for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
177*cdf0e10cSrcweir                 {
178*cdf0e10cSrcweir                     Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]) );
179*cdf0e10cSrcweir                     if( xPointProp.is() )
180*cdf0e10cSrcweir                     {
181*cdf0e10cSrcweir                         DataPointLabel aLabel;
182*cdf0e10cSrcweir                         xPointProp->getPropertyValue( C2U( "Label" ) ) >>= aLabel;
183*cdf0e10cSrcweir                         aLabel.ShowNumber = bInsert;
184*cdf0e10cSrcweir                         if( !bInsert )
185*cdf0e10cSrcweir                         {
186*cdf0e10cSrcweir                             aLabel.ShowNumberInPercent = false;
187*cdf0e10cSrcweir                             aLabel.ShowCategoryName = false;
188*cdf0e10cSrcweir                         }
189*cdf0e10cSrcweir                         xPointProp->setPropertyValue( C2U( "Label" ), uno::makeAny( aLabel ) );
190*cdf0e10cSrcweir                     }
191*cdf0e10cSrcweir                 }
192*cdf0e10cSrcweir             }
193*cdf0e10cSrcweir         }
194*cdf0e10cSrcweir     }
195*cdf0e10cSrcweir     catch( uno::Exception &e)
196*cdf0e10cSrcweir     {
197*cdf0e10cSrcweir         ASSERT_EXCEPTION( e );
198*cdf0e10cSrcweir     }
199*cdf0e10cSrcweir }
200*cdf0e10cSrcweir 
201*cdf0e10cSrcweir } // anonymous namespace
202*cdf0e10cSrcweir // ----------------------------------------
203*cdf0e10cSrcweir 
204*cdf0e10cSrcweir namespace chart
205*cdf0e10cSrcweir {
206*cdf0e10cSrcweir 
207*cdf0e10cSrcweir namespace DataSeriesHelper
208*cdf0e10cSrcweir {
209*cdf0e10cSrcweir 
210*cdf0e10cSrcweir OUString GetRole( const uno::Reference< chart2::data::XLabeledDataSequence >& xLabeledDataSequence )
211*cdf0e10cSrcweir {
212*cdf0e10cSrcweir     OUString aRet;
213*cdf0e10cSrcweir     if( xLabeledDataSequence.is() )
214*cdf0e10cSrcweir     {
215*cdf0e10cSrcweir         Reference< beans::XPropertySet > xProp( xLabeledDataSequence->getValues(), uno::UNO_QUERY );
216*cdf0e10cSrcweir         if( xProp.is() )
217*cdf0e10cSrcweir             xProp->getPropertyValue( C2U("Role") ) >>= aRet;
218*cdf0e10cSrcweir     }
219*cdf0e10cSrcweir     return aRet;
220*cdf0e10cSrcweir }
221*cdf0e10cSrcweir 
222*cdf0e10cSrcweir Reference< chart2::data::XLabeledDataSequence >
223*cdf0e10cSrcweir     getDataSequenceByRole(
224*cdf0e10cSrcweir         const Reference< chart2::data::XDataSource > & xSource, OUString aRole,
225*cdf0e10cSrcweir         bool bMatchPrefix /* = false */ )
226*cdf0e10cSrcweir {
227*cdf0e10cSrcweir     Reference< chart2::data::XLabeledDataSequence > aNoResult;
228*cdf0e10cSrcweir     if( ! xSource.is())
229*cdf0e10cSrcweir         return aNoResult;
230*cdf0e10cSrcweir     Sequence< Reference< chart2::data::XLabeledDataSequence > > aLabeledSeq( xSource->getDataSequences());
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir     const Reference< chart2::data::XLabeledDataSequence > * pBegin = aLabeledSeq.getConstArray();
233*cdf0e10cSrcweir     const Reference< chart2::data::XLabeledDataSequence > * pEnd = pBegin + aLabeledSeq.getLength();
234*cdf0e10cSrcweir     const Reference< chart2::data::XLabeledDataSequence > * pMatch =
235*cdf0e10cSrcweir         ::std::find_if( pBegin, pEnd, lcl_MatchesRole( aRole, bMatchPrefix ));
236*cdf0e10cSrcweir 
237*cdf0e10cSrcweir     if( pMatch != pEnd )
238*cdf0e10cSrcweir         return *pMatch;
239*cdf0e10cSrcweir 
240*cdf0e10cSrcweir     return aNoResult;
241*cdf0e10cSrcweir }
242*cdf0e10cSrcweir 
243*cdf0e10cSrcweir ::std::vector< Reference< chart2::data::XLabeledDataSequence > >
244*cdf0e10cSrcweir     getAllDataSequencesByRole( const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aDataSequences,
245*cdf0e10cSrcweir                                OUString aRole, bool bMatchPrefix /* = false */ )
246*cdf0e10cSrcweir {
247*cdf0e10cSrcweir     ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aResultVec;
248*cdf0e10cSrcweir     ::std::remove_copy_if( aDataSequences.getConstArray(), aDataSequences.getConstArray() + aDataSequences.getLength(),
249*cdf0e10cSrcweir                            ::std::back_inserter( aResultVec ),
250*cdf0e10cSrcweir                            ::std::not1( lcl_MatchesRole( aRole, bMatchPrefix )));
251*cdf0e10cSrcweir     return aResultVec;
252*cdf0e10cSrcweir }
253*cdf0e10cSrcweir 
254*cdf0e10cSrcweir Reference< chart2::data::XDataSource >
255*cdf0e10cSrcweir     getDataSource( const Sequence< Reference< chart2::XDataSeries > > & aSeries )
256*cdf0e10cSrcweir {
257*cdf0e10cSrcweir     ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aSeqVec;
258*cdf0e10cSrcweir 
259*cdf0e10cSrcweir     for( sal_Int32 i = 0; i < aSeries.getLength(); ++i )
260*cdf0e10cSrcweir     {
261*cdf0e10cSrcweir         Reference< chart2::data::XDataSource > xSource( aSeries[ i ], uno::UNO_QUERY );
262*cdf0e10cSrcweir         if( xSource.is())
263*cdf0e10cSrcweir         {
264*cdf0e10cSrcweir             Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeq( xSource->getDataSequences());
265*cdf0e10cSrcweir             ::std::copy( aSeq.getConstArray(), aSeq.getConstArray() + aSeq.getLength(),
266*cdf0e10cSrcweir                          ::std::back_inserter( aSeqVec ));
267*cdf0e10cSrcweir         }
268*cdf0e10cSrcweir     }
269*cdf0e10cSrcweir 
270*cdf0e10cSrcweir     return Reference< chart2::data::XDataSource >(
271*cdf0e10cSrcweir         new DataSource( ContainerHelper::ContainerToSequence( aSeqVec )));
272*cdf0e10cSrcweir }
273*cdf0e10cSrcweir 
274*cdf0e10cSrcweir namespace
275*cdf0e10cSrcweir {
276*cdf0e10cSrcweir OUString lcl_getDataSequenceLabel( const Reference< chart2::data::XDataSequence > & xSequence )
277*cdf0e10cSrcweir {
278*cdf0e10cSrcweir     OUString aResult;
279*cdf0e10cSrcweir 
280*cdf0e10cSrcweir     Reference< chart2::data::XTextualDataSequence > xTextSeq( xSequence, uno::UNO_QUERY );
281*cdf0e10cSrcweir     if( xTextSeq.is())
282*cdf0e10cSrcweir     {
283*cdf0e10cSrcweir         Sequence< OUString > aSeq( xTextSeq->getTextualData());
284*cdf0e10cSrcweir 
285*cdf0e10cSrcweir         const sal_Int32 nMax = aSeq.getLength() - 1;
286*cdf0e10cSrcweir         OUString aVal;
287*cdf0e10cSrcweir         OUStringBuffer aBuf;
288*cdf0e10cSrcweir 
289*cdf0e10cSrcweir         for( sal_Int32 i = 0; i <= nMax; ++i )
290*cdf0e10cSrcweir         {
291*cdf0e10cSrcweir             aBuf.append( aSeq[i] );
292*cdf0e10cSrcweir             if( i < nMax )
293*cdf0e10cSrcweir                 aBuf.append( sal_Unicode( ' ' ));
294*cdf0e10cSrcweir         }
295*cdf0e10cSrcweir         aResult = aBuf.makeStringAndClear();
296*cdf0e10cSrcweir     }
297*cdf0e10cSrcweir     else if( xSequence.is())
298*cdf0e10cSrcweir     {
299*cdf0e10cSrcweir         Sequence< uno::Any > aSeq( xSequence->getData());
300*cdf0e10cSrcweir 
301*cdf0e10cSrcweir         const sal_Int32 nMax = aSeq.getLength() - 1;
302*cdf0e10cSrcweir         OUString aVal;
303*cdf0e10cSrcweir         OUStringBuffer aBuf;
304*cdf0e10cSrcweir         double fNum = 0;
305*cdf0e10cSrcweir 
306*cdf0e10cSrcweir         for( sal_Int32 i = 0; i <= nMax; ++i )
307*cdf0e10cSrcweir         {
308*cdf0e10cSrcweir             if( aSeq[i] >>= aVal )
309*cdf0e10cSrcweir             {
310*cdf0e10cSrcweir                 aBuf.append( aVal );
311*cdf0e10cSrcweir                 if( i < nMax )
312*cdf0e10cSrcweir                     aBuf.append( sal_Unicode( ' ' ));
313*cdf0e10cSrcweir             }
314*cdf0e10cSrcweir             else if( aSeq[ i ] >>= fNum )
315*cdf0e10cSrcweir             {
316*cdf0e10cSrcweir                 aBuf.append( fNum );
317*cdf0e10cSrcweir                 if( i < nMax )
318*cdf0e10cSrcweir                     aBuf.append( sal_Unicode( ' ' ));
319*cdf0e10cSrcweir             }
320*cdf0e10cSrcweir         }
321*cdf0e10cSrcweir         aResult = aBuf.makeStringAndClear();
322*cdf0e10cSrcweir     }
323*cdf0e10cSrcweir 
324*cdf0e10cSrcweir     return aResult;
325*cdf0e10cSrcweir }
326*cdf0e10cSrcweir }
327*cdf0e10cSrcweir 
328*cdf0e10cSrcweir OUString getLabelForLabeledDataSequence(
329*cdf0e10cSrcweir     const Reference< chart2::data::XLabeledDataSequence > & xLabeledSeq )
330*cdf0e10cSrcweir {
331*cdf0e10cSrcweir     OUString aResult;
332*cdf0e10cSrcweir     if( xLabeledSeq.is())
333*cdf0e10cSrcweir     {
334*cdf0e10cSrcweir         Reference< chart2::data::XDataSequence > xSeq( xLabeledSeq->getLabel());
335*cdf0e10cSrcweir         if( xSeq.is() )
336*cdf0e10cSrcweir             aResult = lcl_getDataSequenceLabel( xSeq );
337*cdf0e10cSrcweir         if( !xSeq.is() || !aResult.getLength() )
338*cdf0e10cSrcweir         {
339*cdf0e10cSrcweir             // no label set or label content is empty -> use auto-generated one
340*cdf0e10cSrcweir             Reference< chart2::data::XDataSequence > xValueSeq( xLabeledSeq->getValues() );
341*cdf0e10cSrcweir             if( xValueSeq.is() )
342*cdf0e10cSrcweir             {
343*cdf0e10cSrcweir                 Sequence< OUString > aLabels( xValueSeq->generateLabel(
344*cdf0e10cSrcweir                     chart2::data::LabelOrigin_SHORT_SIDE ) );
345*cdf0e10cSrcweir                 // no labels returned is interpreted as: auto-generation not
346*cdf0e10cSrcweir                 // supported by sequence
347*cdf0e10cSrcweir                 if( aLabels.getLength() )
348*cdf0e10cSrcweir                     aResult=aLabels[0];
349*cdf0e10cSrcweir                 else
350*cdf0e10cSrcweir                 {
351*cdf0e10cSrcweir                     //todo?: maybe use the index of the series as name
352*cdf0e10cSrcweir                     //but as the index may change it would be better to have such a name persistent
353*cdf0e10cSrcweir                     //what is not possible at the moment
354*cdf0e10cSrcweir                     //--> maybe use the identifier as part of the name ...
355*cdf0e10cSrcweir                     aResult = lcl_getDataSequenceLabel( xValueSeq );
356*cdf0e10cSrcweir                 }
357*cdf0e10cSrcweir             }
358*cdf0e10cSrcweir         }
359*cdf0e10cSrcweir     }
360*cdf0e10cSrcweir     return aResult;
361*cdf0e10cSrcweir }
362*cdf0e10cSrcweir 
363*cdf0e10cSrcweir OUString getDataSeriesLabel(
364*cdf0e10cSrcweir     const Reference< chart2::XDataSeries > & xSeries,
365*cdf0e10cSrcweir     const OUString & rLabelSequenceRole )
366*cdf0e10cSrcweir {
367*cdf0e10cSrcweir     OUString aResult;
368*cdf0e10cSrcweir 
369*cdf0e10cSrcweir     Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
370*cdf0e10cSrcweir     if( xSource.is())
371*cdf0e10cSrcweir     {
372*cdf0e10cSrcweir         Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
373*cdf0e10cSrcweir             ::chart::DataSeriesHelper::getDataSequenceByRole( xSource, rLabelSequenceRole ));
374*cdf0e10cSrcweir         if( xLabeledSeq.is())
375*cdf0e10cSrcweir             aResult = getLabelForLabeledDataSequence( xLabeledSeq );
376*cdf0e10cSrcweir         else
377*cdf0e10cSrcweir         {
378*cdf0e10cSrcweir             // special case: labeled data series with only a label and no values may
379*cdf0e10cSrcweir             // serve as label
380*cdf0e10cSrcweir             xLabeledSeq.set( lcl_findLSequenceWithOnlyLabel( xSource ));
381*cdf0e10cSrcweir             if( xLabeledSeq.is())
382*cdf0e10cSrcweir             {
383*cdf0e10cSrcweir                 Reference< chart2::data::XDataSequence > xSeq( xLabeledSeq->getLabel());
384*cdf0e10cSrcweir                 if( xSeq.is())
385*cdf0e10cSrcweir                     aResult = lcl_getDataSequenceLabel( xSeq );
386*cdf0e10cSrcweir             }
387*cdf0e10cSrcweir         }
388*cdf0e10cSrcweir 
389*cdf0e10cSrcweir     }
390*cdf0e10cSrcweir 
391*cdf0e10cSrcweir     return aResult;
392*cdf0e10cSrcweir }
393*cdf0e10cSrcweir 
394*cdf0e10cSrcweir void setStackModeAtSeries(
395*cdf0e10cSrcweir     const Sequence< Reference< chart2::XDataSeries > > & aSeries,
396*cdf0e10cSrcweir     const Reference< chart2::XCoordinateSystem > & xCorrespondingCoordinateSystem,
397*cdf0e10cSrcweir     StackMode eStackMode )
398*cdf0e10cSrcweir {
399*cdf0e10cSrcweir     if( eStackMode == StackMode_AMBIGUOUS )
400*cdf0e10cSrcweir         return;
401*cdf0e10cSrcweir 
402*cdf0e10cSrcweir     const OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( "StackingDirection" ));
403*cdf0e10cSrcweir     const uno::Any aPropValue = uno::makeAny(
404*cdf0e10cSrcweir         ( (eStackMode == StackMode_Y_STACKED) ||
405*cdf0e10cSrcweir           (eStackMode == StackMode_Y_STACKED_PERCENT) )
406*cdf0e10cSrcweir         ? chart2::StackingDirection_Y_STACKING
407*cdf0e10cSrcweir         : (eStackMode == StackMode_Z_STACKED )
408*cdf0e10cSrcweir         ? chart2::StackingDirection_Z_STACKING
409*cdf0e10cSrcweir         : chart2::StackingDirection_NO_STACKING );
410*cdf0e10cSrcweir 
411*cdf0e10cSrcweir     std::set< sal_Int32 > aAxisIndexSet;
412*cdf0e10cSrcweir     for( sal_Int32 i=0; i<aSeries.getLength(); ++i )
413*cdf0e10cSrcweir     {
414*cdf0e10cSrcweir         try
415*cdf0e10cSrcweir         {
416*cdf0e10cSrcweir             Reference< beans::XPropertySet > xProp( aSeries[i], uno::UNO_QUERY );
417*cdf0e10cSrcweir             if( xProp.is() )
418*cdf0e10cSrcweir             {
419*cdf0e10cSrcweir                 xProp->setPropertyValue( aPropName, aPropValue );
420*cdf0e10cSrcweir 
421*cdf0e10cSrcweir                 sal_Int32 nAxisIndex;
422*cdf0e10cSrcweir                 xProp->getPropertyValue( C2U("AttachedAxisIndex") ) >>= nAxisIndex;
423*cdf0e10cSrcweir                 aAxisIndexSet.insert(nAxisIndex);
424*cdf0e10cSrcweir             }
425*cdf0e10cSrcweir         }
426*cdf0e10cSrcweir         catch( uno::Exception & ex )
427*cdf0e10cSrcweir         {
428*cdf0e10cSrcweir             ASSERT_EXCEPTION( ex );
429*cdf0e10cSrcweir         }
430*cdf0e10cSrcweir     }
431*cdf0e10cSrcweir 
432*cdf0e10cSrcweir     if( xCorrespondingCoordinateSystem.is() &&
433*cdf0e10cSrcweir         1 < xCorrespondingCoordinateSystem->getDimension() )
434*cdf0e10cSrcweir     {
435*cdf0e10cSrcweir         sal_Int32 nAxisIndexCount = aAxisIndexSet.size();
436*cdf0e10cSrcweir         if( !nAxisIndexCount )
437*cdf0e10cSrcweir         {
438*cdf0e10cSrcweir             aAxisIndexSet.insert(0);
439*cdf0e10cSrcweir             nAxisIndexCount = aAxisIndexSet.size();
440*cdf0e10cSrcweir         }
441*cdf0e10cSrcweir 
442*cdf0e10cSrcweir         for( ::std::set< sal_Int32 >::const_iterator aIt = aAxisIndexSet.begin();
443*cdf0e10cSrcweir             aIt != aAxisIndexSet.end(); ++aIt )
444*cdf0e10cSrcweir         {
445*cdf0e10cSrcweir             sal_Int32 nAxisIndex = *aIt;
446*cdf0e10cSrcweir             Reference< chart2::XAxis > xAxis(
447*cdf0e10cSrcweir                 xCorrespondingCoordinateSystem->getAxisByDimension( 1, nAxisIndex ));
448*cdf0e10cSrcweir             if( xAxis.is())
449*cdf0e10cSrcweir             {
450*cdf0e10cSrcweir                 sal_Bool bPercent = (eStackMode == StackMode_Y_STACKED_PERCENT);
451*cdf0e10cSrcweir                 chart2::ScaleData aScaleData = xAxis->getScaleData();
452*cdf0e10cSrcweir 
453*cdf0e10cSrcweir                 if( bPercent != (aScaleData.AxisType==chart2::AxisType::PERCENT) )
454*cdf0e10cSrcweir                 {
455*cdf0e10cSrcweir                     if( bPercent )
456*cdf0e10cSrcweir                         aScaleData.AxisType = chart2::AxisType::PERCENT;
457*cdf0e10cSrcweir                     else
458*cdf0e10cSrcweir                         aScaleData.AxisType = chart2::AxisType::REALNUMBER;
459*cdf0e10cSrcweir                     xAxis->setScaleData( aScaleData );
460*cdf0e10cSrcweir                 }
461*cdf0e10cSrcweir             }
462*cdf0e10cSrcweir         }
463*cdf0e10cSrcweir     }
464*cdf0e10cSrcweir }
465*cdf0e10cSrcweir 
466*cdf0e10cSrcweir sal_Int32 getAttachedAxisIndex( const Reference< chart2::XDataSeries > & xSeries )
467*cdf0e10cSrcweir {
468*cdf0e10cSrcweir     sal_Int32 nRet = 0;
469*cdf0e10cSrcweir     try
470*cdf0e10cSrcweir     {
471*cdf0e10cSrcweir         Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY );
472*cdf0e10cSrcweir         if( xProp.is() )
473*cdf0e10cSrcweir         {
474*cdf0e10cSrcweir             xProp->getPropertyValue( C2U("AttachedAxisIndex") ) >>= nRet;
475*cdf0e10cSrcweir         }
476*cdf0e10cSrcweir     }
477*cdf0e10cSrcweir     catch( uno::Exception & ex )
478*cdf0e10cSrcweir     {
479*cdf0e10cSrcweir         ASSERT_EXCEPTION( ex );
480*cdf0e10cSrcweir     }
481*cdf0e10cSrcweir     return nRet;
482*cdf0e10cSrcweir }
483*cdf0e10cSrcweir 
484*cdf0e10cSrcweir sal_Int32 getNumberFormatKeyFromAxis(
485*cdf0e10cSrcweir     const Reference< chart2::XDataSeries > & xSeries,
486*cdf0e10cSrcweir     const Reference< chart2::XCoordinateSystem > & xCorrespondingCoordinateSystem,
487*cdf0e10cSrcweir     sal_Int32 nDimensionIndex,
488*cdf0e10cSrcweir     sal_Int32 nAxisIndex /* = -1 */ )
489*cdf0e10cSrcweir {
490*cdf0e10cSrcweir     sal_Int32 nResult =  0;
491*cdf0e10cSrcweir     if( nAxisIndex == -1 )
492*cdf0e10cSrcweir         nAxisIndex = getAttachedAxisIndex( xSeries );
493*cdf0e10cSrcweir     try
494*cdf0e10cSrcweir     {
495*cdf0e10cSrcweir         Reference< beans::XPropertySet > xAxisProp(
496*cdf0e10cSrcweir             xCorrespondingCoordinateSystem->getAxisByDimension( nDimensionIndex, nAxisIndex ), uno::UNO_QUERY );
497*cdf0e10cSrcweir         if( xAxisProp.is())
498*cdf0e10cSrcweir             xAxisProp->getPropertyValue( C2U("NumberFormat")) >>= nResult;
499*cdf0e10cSrcweir     }
500*cdf0e10cSrcweir     catch( const uno::Exception & ex )
501*cdf0e10cSrcweir     {
502*cdf0e10cSrcweir         ASSERT_EXCEPTION( ex );
503*cdf0e10cSrcweir     }
504*cdf0e10cSrcweir 
505*cdf0e10cSrcweir     return nResult;
506*cdf0e10cSrcweir }
507*cdf0e10cSrcweir 
508*cdf0e10cSrcweir Reference< chart2::XCoordinateSystem > getCoordinateSystemOfSeries(
509*cdf0e10cSrcweir     const Reference< chart2::XDataSeries > & xSeries,
510*cdf0e10cSrcweir     const Reference< chart2::XDiagram > & xDiagram )
511*cdf0e10cSrcweir {
512*cdf0e10cSrcweir     Reference< chart2::XCoordinateSystem > xResult;
513*cdf0e10cSrcweir     Reference< chart2::XChartType > xDummy;
514*cdf0e10cSrcweir     lcl_getCooSysAndChartTypeOfSeries( xSeries, xDiagram, xResult, xDummy );
515*cdf0e10cSrcweir 
516*cdf0e10cSrcweir     return xResult;
517*cdf0e10cSrcweir }
518*cdf0e10cSrcweir 
519*cdf0e10cSrcweir Reference< chart2::XChartType > getChartTypeOfSeries(
520*cdf0e10cSrcweir     const Reference< chart2::XDataSeries > & xSeries,
521*cdf0e10cSrcweir     const Reference< chart2::XDiagram > & xDiagram )
522*cdf0e10cSrcweir {
523*cdf0e10cSrcweir     Reference< chart2::XChartType > xResult;
524*cdf0e10cSrcweir     Reference< chart2::XCoordinateSystem > xDummy;
525*cdf0e10cSrcweir     lcl_getCooSysAndChartTypeOfSeries( xSeries, xDiagram, xDummy, xResult );
526*cdf0e10cSrcweir 
527*cdf0e10cSrcweir     return xResult;
528*cdf0e10cSrcweir }
529*cdf0e10cSrcweir 
530*cdf0e10cSrcweir void deleteSeries(
531*cdf0e10cSrcweir     const Reference< chart2::XDataSeries > & xSeries,
532*cdf0e10cSrcweir     const Reference< chart2::XChartType > & xChartType )
533*cdf0e10cSrcweir {
534*cdf0e10cSrcweir     try
535*cdf0e10cSrcweir     {
536*cdf0e10cSrcweir         Reference< chart2::XDataSeriesContainer > xSeriesCnt( xChartType, uno::UNO_QUERY_THROW );
537*cdf0e10cSrcweir         ::std::vector< Reference< chart2::XDataSeries > > aSeries(
538*cdf0e10cSrcweir             ContainerHelper::SequenceToVector( xSeriesCnt->getDataSeries()));
539*cdf0e10cSrcweir         ::std::vector< Reference< chart2::XDataSeries > >::iterator aIt =
540*cdf0e10cSrcweir               ::std::find( aSeries.begin(), aSeries.end(), xSeries );
541*cdf0e10cSrcweir         if( aIt != aSeries.end())
542*cdf0e10cSrcweir         {
543*cdf0e10cSrcweir             aSeries.erase( aIt );
544*cdf0e10cSrcweir             xSeriesCnt->setDataSeries( ContainerHelper::ContainerToSequence( aSeries ));
545*cdf0e10cSrcweir         }
546*cdf0e10cSrcweir     }
547*cdf0e10cSrcweir     catch( uno::Exception & ex )
548*cdf0e10cSrcweir     {
549*cdf0e10cSrcweir         ASSERT_EXCEPTION( ex );
550*cdf0e10cSrcweir     }
551*cdf0e10cSrcweir }
552*cdf0e10cSrcweir 
553*cdf0e10cSrcweir void switchSymbolsOnOrOff( const Reference< beans::XPropertySet > & xSeriesProperties,
554*cdf0e10cSrcweir                     bool bSymbolsOn, sal_Int32 nSeriesIndex )
555*cdf0e10cSrcweir {
556*cdf0e10cSrcweir     if( !xSeriesProperties.is() )
557*cdf0e10cSrcweir         return;
558*cdf0e10cSrcweir 
559*cdf0e10cSrcweir     chart2::Symbol aSymbProp;
560*cdf0e10cSrcweir     if( (xSeriesProperties->getPropertyValue( C2U( "Symbol" )) >>= aSymbProp ) )
561*cdf0e10cSrcweir     {
562*cdf0e10cSrcweir         if( !bSymbolsOn )
563*cdf0e10cSrcweir             aSymbProp.Style = chart2::SymbolStyle_NONE;
564*cdf0e10cSrcweir         else if( aSymbProp.Style == chart2::SymbolStyle_NONE )
565*cdf0e10cSrcweir         {
566*cdf0e10cSrcweir             aSymbProp.Style = chart2::SymbolStyle_STANDARD;
567*cdf0e10cSrcweir             aSymbProp.StandardSymbol = nSeriesIndex;
568*cdf0e10cSrcweir         }
569*cdf0e10cSrcweir         xSeriesProperties->setPropertyValue( C2U( "Symbol" ), uno::makeAny( aSymbProp ));
570*cdf0e10cSrcweir     }
571*cdf0e10cSrcweir     //todo: check attributed data points
572*cdf0e10cSrcweir }
573*cdf0e10cSrcweir 
574*cdf0e10cSrcweir void switchLinesOnOrOff( const Reference< beans::XPropertySet > & xSeriesProperties, bool bLinesOn )
575*cdf0e10cSrcweir {
576*cdf0e10cSrcweir     if( !xSeriesProperties.is() )
577*cdf0e10cSrcweir         return;
578*cdf0e10cSrcweir 
579*cdf0e10cSrcweir     if( bLinesOn )
580*cdf0e10cSrcweir     {
581*cdf0e10cSrcweir         // keep line-styles that are not NONE
582*cdf0e10cSrcweir         drawing::LineStyle eLineStyle;
583*cdf0e10cSrcweir         if( (xSeriesProperties->getPropertyValue( C2U( "LineStyle" )) >>= eLineStyle ) &&
584*cdf0e10cSrcweir             eLineStyle == drawing::LineStyle_NONE )
585*cdf0e10cSrcweir         {
586*cdf0e10cSrcweir             xSeriesProperties->setPropertyValue( C2U( "LineStyle" ), uno::makeAny( drawing::LineStyle_SOLID ) );
587*cdf0e10cSrcweir         }
588*cdf0e10cSrcweir     }
589*cdf0e10cSrcweir     else
590*cdf0e10cSrcweir         xSeriesProperties->setPropertyValue( C2U( "LineStyle" ), uno::makeAny( drawing::LineStyle_NONE ) );
591*cdf0e10cSrcweir }
592*cdf0e10cSrcweir 
593*cdf0e10cSrcweir void makeLinesThickOrThin( const Reference< beans::XPropertySet > & xSeriesProperties, bool bThick )
594*cdf0e10cSrcweir {
595*cdf0e10cSrcweir     if( !xSeriesProperties.is() )
596*cdf0e10cSrcweir         return;
597*cdf0e10cSrcweir 
598*cdf0e10cSrcweir     sal_Int32 nNewValue = bThick ? 80 : 0;
599*cdf0e10cSrcweir     sal_Int32 nOldValue = 0;
600*cdf0e10cSrcweir     if( (xSeriesProperties->getPropertyValue( C2U( "LineWidth" )) >>= nOldValue ) &&
601*cdf0e10cSrcweir         nOldValue != nNewValue )
602*cdf0e10cSrcweir     {
603*cdf0e10cSrcweir         if( !(bThick && nOldValue>0))
604*cdf0e10cSrcweir             xSeriesProperties->setPropertyValue( C2U( "LineWidth" ), uno::makeAny( nNewValue ) );
605*cdf0e10cSrcweir     }
606*cdf0e10cSrcweir }
607*cdf0e10cSrcweir 
608*cdf0e10cSrcweir void setPropertyAlsoToAllAttributedDataPoints( const Reference< chart2::XDataSeries >& xSeries,
609*cdf0e10cSrcweir                                               const OUString& rPropertyName, const uno::Any& rPropertyValue )
610*cdf0e10cSrcweir {
611*cdf0e10cSrcweir     Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY );
612*cdf0e10cSrcweir     if( !xSeriesProperties.is() )
613*cdf0e10cSrcweir         return;
614*cdf0e10cSrcweir 
615*cdf0e10cSrcweir     xSeriesProperties->setPropertyValue( rPropertyName, rPropertyValue );
616*cdf0e10cSrcweir     uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
617*cdf0e10cSrcweir     if( xSeriesProperties->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList )
618*cdf0e10cSrcweir     {
619*cdf0e10cSrcweir         for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
620*cdf0e10cSrcweir         {
621*cdf0e10cSrcweir             Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]) );
622*cdf0e10cSrcweir             if(!xPointProp.is())
623*cdf0e10cSrcweir                 continue;
624*cdf0e10cSrcweir             xPointProp->setPropertyValue( rPropertyName, rPropertyValue );
625*cdf0e10cSrcweir         }
626*cdf0e10cSrcweir     }
627*cdf0e10cSrcweir }
628*cdf0e10cSrcweir 
629*cdf0e10cSrcweir bool hasAttributedDataPointDifferentValue( const Reference< chart2::XDataSeries >& xSeries,
630*cdf0e10cSrcweir                                               const OUString& rPropertyName, const uno::Any& rPropertyValue )
631*cdf0e10cSrcweir {
632*cdf0e10cSrcweir     Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY );
633*cdf0e10cSrcweir     if( !xSeriesProperties.is() )
634*cdf0e10cSrcweir         return false;
635*cdf0e10cSrcweir 
636*cdf0e10cSrcweir     uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
637*cdf0e10cSrcweir     if( xSeriesProperties->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList )
638*cdf0e10cSrcweir     {
639*cdf0e10cSrcweir         for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
640*cdf0e10cSrcweir         {
641*cdf0e10cSrcweir             Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]) );
642*cdf0e10cSrcweir             if(!xPointProp.is())
643*cdf0e10cSrcweir                 continue;
644*cdf0e10cSrcweir             uno::Any aPointValue( xPointProp->getPropertyValue( rPropertyName ) );
645*cdf0e10cSrcweir             if( !( rPropertyValue==aPointValue ) )
646*cdf0e10cSrcweir                 return true;
647*cdf0e10cSrcweir         }
648*cdf0e10cSrcweir     }
649*cdf0e10cSrcweir     return false;
650*cdf0e10cSrcweir }
651*cdf0e10cSrcweir 
652*cdf0e10cSrcweir bool areAllSeriesAttachedToSameAxis( const uno::Reference< chart2::XChartType >& xChartType, sal_Int32 & rOutAxisIndex )
653*cdf0e10cSrcweir {
654*cdf0e10cSrcweir     try
655*cdf0e10cSrcweir     {
656*cdf0e10cSrcweir         uno::Reference< chart2::XDataSeriesContainer > xDataSeriesContainer( xChartType, uno::UNO_QUERY_THROW );
657*cdf0e10cSrcweir         uno::Sequence< uno::Reference< chart2::XDataSeries > > aSeriesSeq( xDataSeriesContainer->getDataSeries());
658*cdf0e10cSrcweir 
659*cdf0e10cSrcweir         const sal_Int32 nSeriesCount( aSeriesSeq.getLength());
660*cdf0e10cSrcweir         // AxisIndex can only be 0 or 1
661*cdf0e10cSrcweir         sal_Int32 nSeriesAtFirstAxis = 0;
662*cdf0e10cSrcweir         sal_Int32 nSeriesAtSecondAxis = 0;
663*cdf0e10cSrcweir 
664*cdf0e10cSrcweir         for( sal_Int32 nI = 0; nI < nSeriesCount; ++nI )
665*cdf0e10cSrcweir         {
666*cdf0e10cSrcweir             uno::Reference< chart2::XDataSeries > xSeries( aSeriesSeq[nI], uno::UNO_QUERY );
667*cdf0e10cSrcweir             sal_Int32 nAxisIndex = DataSeriesHelper::getAttachedAxisIndex( xSeries );
668*cdf0e10cSrcweir             if( nAxisIndex == 0 )
669*cdf0e10cSrcweir                 ++nSeriesAtFirstAxis;
670*cdf0e10cSrcweir             else if( nAxisIndex == 1 )
671*cdf0e10cSrcweir                 ++nSeriesAtSecondAxis;
672*cdf0e10cSrcweir         }
673*cdf0e10cSrcweir         OSL_ENSURE( nSeriesAtFirstAxis + nSeriesAtSecondAxis == nSeriesCount, "Invalid axis index found" );
674*cdf0e10cSrcweir 
675*cdf0e10cSrcweir         if( nSeriesAtFirstAxis == nSeriesCount )
676*cdf0e10cSrcweir             rOutAxisIndex = 0;
677*cdf0e10cSrcweir         else if( nSeriesAtSecondAxis == nSeriesCount )
678*cdf0e10cSrcweir             rOutAxisIndex = 1;
679*cdf0e10cSrcweir 
680*cdf0e10cSrcweir         return ( nSeriesAtFirstAxis == nSeriesCount ||
681*cdf0e10cSrcweir                  nSeriesAtSecondAxis == nSeriesCount );
682*cdf0e10cSrcweir     }
683*cdf0e10cSrcweir     catch( const uno::Exception & ex )
684*cdf0e10cSrcweir     {
685*cdf0e10cSrcweir         ASSERT_EXCEPTION( ex );
686*cdf0e10cSrcweir         return false;
687*cdf0e10cSrcweir     }
688*cdf0e10cSrcweir }
689*cdf0e10cSrcweir 
690*cdf0e10cSrcweir namespace
691*cdf0e10cSrcweir {
692*cdf0e10cSrcweir 
693*cdf0e10cSrcweir bool lcl_SequenceHasUnhiddenData( const uno::Reference< chart2::data::XDataSequence >& xDataSequence )
694*cdf0e10cSrcweir {
695*cdf0e10cSrcweir     if( !xDataSequence.is() )
696*cdf0e10cSrcweir         return false;
697*cdf0e10cSrcweir     uno::Reference< beans::XPropertySet > xProp( xDataSequence, uno::UNO_QUERY );
698*cdf0e10cSrcweir     if( xProp.is() )
699*cdf0e10cSrcweir     {
700*cdf0e10cSrcweir         uno::Sequence< sal_Int32 > aHiddenValues;
701*cdf0e10cSrcweir         try
702*cdf0e10cSrcweir         {
703*cdf0e10cSrcweir             xProp->getPropertyValue( C2U( "HiddenValues" ) ) >>= aHiddenValues;
704*cdf0e10cSrcweir             if( !aHiddenValues.getLength() )
705*cdf0e10cSrcweir                 return true;
706*cdf0e10cSrcweir         }
707*cdf0e10cSrcweir         catch( uno::Exception& e )
708*cdf0e10cSrcweir         {
709*cdf0e10cSrcweir             (void)e; // avoid warning
710*cdf0e10cSrcweir             return true;
711*cdf0e10cSrcweir         }
712*cdf0e10cSrcweir     }
713*cdf0e10cSrcweir     if( xDataSequence->getData().getLength() )
714*cdf0e10cSrcweir         return true;
715*cdf0e10cSrcweir     return false;
716*cdf0e10cSrcweir }
717*cdf0e10cSrcweir 
718*cdf0e10cSrcweir }
719*cdf0e10cSrcweir 
720*cdf0e10cSrcweir bool hasUnhiddenData( const uno::Reference< chart2::XDataSeries >& xSeries )
721*cdf0e10cSrcweir {
722*cdf0e10cSrcweir     uno::Reference< chart2::data::XDataSource > xDataSource =
723*cdf0e10cSrcweir         uno::Reference< chart2::data::XDataSource >( xSeries, uno::UNO_QUERY );
724*cdf0e10cSrcweir 
725*cdf0e10cSrcweir     uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aDataSequences = xDataSource->getDataSequences();
726*cdf0e10cSrcweir 
727*cdf0e10cSrcweir     for(sal_Int32 nN = aDataSequences.getLength();nN--;)
728*cdf0e10cSrcweir     {
729*cdf0e10cSrcweir         if( !aDataSequences[nN].is() )
730*cdf0e10cSrcweir             continue;
731*cdf0e10cSrcweir         if( lcl_SequenceHasUnhiddenData( aDataSequences[nN]->getValues() ) )
732*cdf0e10cSrcweir             return true;
733*cdf0e10cSrcweir         if( lcl_SequenceHasUnhiddenData( aDataSequences[nN]->getLabel() ) )
734*cdf0e10cSrcweir             return true;
735*cdf0e10cSrcweir     }
736*cdf0e10cSrcweir     return false;
737*cdf0e10cSrcweir }
738*cdf0e10cSrcweir 
739*cdf0e10cSrcweir struct lcl_LessIndex
740*cdf0e10cSrcweir {
741*cdf0e10cSrcweir     inline bool operator() ( const sal_Int32& first, const sal_Int32& second )
742*cdf0e10cSrcweir     {
743*cdf0e10cSrcweir         return ( first < second );
744*cdf0e10cSrcweir     }
745*cdf0e10cSrcweir };
746*cdf0e10cSrcweir 
747*cdf0e10cSrcweir sal_Int32 translateIndexFromHiddenToFullSequence( sal_Int32 nIndex, const Reference< chart2::data::XDataSequence >& xDataSequence, bool bTranslate )
748*cdf0e10cSrcweir {
749*cdf0e10cSrcweir     if( !bTranslate )
750*cdf0e10cSrcweir         return nIndex;
751*cdf0e10cSrcweir 
752*cdf0e10cSrcweir     try
753*cdf0e10cSrcweir     {
754*cdf0e10cSrcweir         uno::Reference<beans::XPropertySet> xProp( xDataSequence, uno::UNO_QUERY );
755*cdf0e10cSrcweir 	    if( xProp.is())
756*cdf0e10cSrcweir         {
757*cdf0e10cSrcweir             Sequence<sal_Int32> aHiddenIndicesSeq;
758*cdf0e10cSrcweir             xProp->getPropertyValue( C2U("HiddenValues") ) >>= aHiddenIndicesSeq;
759*cdf0e10cSrcweir             if( aHiddenIndicesSeq.getLength() )
760*cdf0e10cSrcweir             {
761*cdf0e10cSrcweir                 ::std::vector< sal_Int32 > aHiddenIndices( ContainerHelper::SequenceToVector( aHiddenIndicesSeq ) );
762*cdf0e10cSrcweir                 ::std::sort( aHiddenIndices.begin(), aHiddenIndices.end(), lcl_LessIndex() );
763*cdf0e10cSrcweir 
764*cdf0e10cSrcweir                 sal_Int32 nHiddenCount = static_cast<sal_Int32>(aHiddenIndices.size());
765*cdf0e10cSrcweir                 for( sal_Int32 nN = 0; nN < nHiddenCount; ++nN)
766*cdf0e10cSrcweir                 {
767*cdf0e10cSrcweir                     if( aHiddenIndices[nN] <= nIndex )
768*cdf0e10cSrcweir                         nIndex += 1;
769*cdf0e10cSrcweir                     else
770*cdf0e10cSrcweir                         break;
771*cdf0e10cSrcweir                 }
772*cdf0e10cSrcweir             }
773*cdf0e10cSrcweir         }
774*cdf0e10cSrcweir     }
775*cdf0e10cSrcweir     catch (const beans::UnknownPropertyException&)
776*cdf0e10cSrcweir     {
777*cdf0e10cSrcweir     }
778*cdf0e10cSrcweir     return nIndex;
779*cdf0e10cSrcweir }
780*cdf0e10cSrcweir 
781*cdf0e10cSrcweir bool hasDataLabelsAtSeries( const Reference< chart2::XDataSeries >& xSeries )
782*cdf0e10cSrcweir {
783*cdf0e10cSrcweir     bool bRet = false;
784*cdf0e10cSrcweir     try
785*cdf0e10cSrcweir     {
786*cdf0e10cSrcweir         Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY );
787*cdf0e10cSrcweir         if( xProp.is() )
788*cdf0e10cSrcweir         {
789*cdf0e10cSrcweir             DataPointLabel aLabel;
790*cdf0e10cSrcweir             if( (xProp->getPropertyValue( C2U( "Label" ) ) >>= aLabel) )
791*cdf0e10cSrcweir                 bRet = aLabel.ShowNumber || aLabel.ShowNumberInPercent || aLabel.ShowCategoryName;
792*cdf0e10cSrcweir         }
793*cdf0e10cSrcweir     }
794*cdf0e10cSrcweir     catch( uno::Exception &e)
795*cdf0e10cSrcweir     {
796*cdf0e10cSrcweir         ASSERT_EXCEPTION( e );
797*cdf0e10cSrcweir     }
798*cdf0e10cSrcweir     return bRet;
799*cdf0e10cSrcweir }
800*cdf0e10cSrcweir 
801*cdf0e10cSrcweir bool hasDataLabelsAtPoints( const Reference< chart2::XDataSeries >& xSeries )
802*cdf0e10cSrcweir {
803*cdf0e10cSrcweir     bool bRet = false;
804*cdf0e10cSrcweir     try
805*cdf0e10cSrcweir     {
806*cdf0e10cSrcweir         Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY );
807*cdf0e10cSrcweir         if( xSeriesProperties.is() )
808*cdf0e10cSrcweir         {
809*cdf0e10cSrcweir             uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
810*cdf0e10cSrcweir             if( xSeriesProperties->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList )
811*cdf0e10cSrcweir             {
812*cdf0e10cSrcweir                 for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
813*cdf0e10cSrcweir                 {
814*cdf0e10cSrcweir                     Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]) );
815*cdf0e10cSrcweir                     if( xPointProp.is() )
816*cdf0e10cSrcweir                     {
817*cdf0e10cSrcweir                         DataPointLabel aLabel;
818*cdf0e10cSrcweir                         if( (xPointProp->getPropertyValue( C2U( "Label" ) ) >>= aLabel) )
819*cdf0e10cSrcweir                             bRet = aLabel.ShowNumber || aLabel.ShowNumberInPercent || aLabel.ShowCategoryName;
820*cdf0e10cSrcweir                         if( bRet )
821*cdf0e10cSrcweir                             break;
822*cdf0e10cSrcweir                     }
823*cdf0e10cSrcweir                 }
824*cdf0e10cSrcweir             }
825*cdf0e10cSrcweir         }
826*cdf0e10cSrcweir     }
827*cdf0e10cSrcweir     catch( uno::Exception &e)
828*cdf0e10cSrcweir     {
829*cdf0e10cSrcweir         ASSERT_EXCEPTION( e );
830*cdf0e10cSrcweir     }
831*cdf0e10cSrcweir     return bRet;
832*cdf0e10cSrcweir }
833*cdf0e10cSrcweir 
834*cdf0e10cSrcweir bool hasDataLabelAtPoint( const Reference< chart2::XDataSeries >& xSeries, sal_Int32 nPointIndex )
835*cdf0e10cSrcweir {
836*cdf0e10cSrcweir     bool bRet = false;
837*cdf0e10cSrcweir     try
838*cdf0e10cSrcweir     {
839*cdf0e10cSrcweir         Reference< beans::XPropertySet > xProp;
840*cdf0e10cSrcweir         Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY );
841*cdf0e10cSrcweir         if( xSeriesProperties.is() )
842*cdf0e10cSrcweir         {
843*cdf0e10cSrcweir             uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
844*cdf0e10cSrcweir             if( xSeriesProperties->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList )
845*cdf0e10cSrcweir             {
846*cdf0e10cSrcweir                 ::std::vector< sal_Int32 > aIndices( ContainerHelper::SequenceToVector( aAttributedDataPointIndexList ) );
847*cdf0e10cSrcweir                 ::std::vector< sal_Int32 >::iterator aIt = ::std::find( aIndices.begin(), aIndices.end(), nPointIndex );
848*cdf0e10cSrcweir                 if( aIt != aIndices.end())
849*cdf0e10cSrcweir                     xProp = xSeries->getDataPointByIndex(nPointIndex);
850*cdf0e10cSrcweir                 else
851*cdf0e10cSrcweir                     xProp = xSeriesProperties;
852*cdf0e10cSrcweir             }
853*cdf0e10cSrcweir             if( xProp.is() )
854*cdf0e10cSrcweir             {
855*cdf0e10cSrcweir                 DataPointLabel aLabel;
856*cdf0e10cSrcweir                 if( (xProp->getPropertyValue( C2U( "Label" ) ) >>= aLabel) )
857*cdf0e10cSrcweir                     bRet = aLabel.ShowNumber || aLabel.ShowNumberInPercent || aLabel.ShowCategoryName;
858*cdf0e10cSrcweir             }
859*cdf0e10cSrcweir         }
860*cdf0e10cSrcweir     }
861*cdf0e10cSrcweir     catch( uno::Exception &e)
862*cdf0e10cSrcweir     {
863*cdf0e10cSrcweir         ASSERT_EXCEPTION( e );
864*cdf0e10cSrcweir     }
865*cdf0e10cSrcweir     return bRet;
866*cdf0e10cSrcweir }
867*cdf0e10cSrcweir 
868*cdf0e10cSrcweir void insertDataLabelsToSeriesAndAllPoints( const Reference< chart2::XDataSeries >& xSeries )
869*cdf0e10cSrcweir {
870*cdf0e10cSrcweir     lcl_insertOrDeleteDataLabelsToSeriesAndAllPoints( xSeries, true /*bInsert*/ );
871*cdf0e10cSrcweir }
872*cdf0e10cSrcweir 
873*cdf0e10cSrcweir void deleteDataLabelsFromSeriesAndAllPoints( const Reference< chart2::XDataSeries >& xSeries )
874*cdf0e10cSrcweir {
875*cdf0e10cSrcweir     lcl_insertOrDeleteDataLabelsToSeriesAndAllPoints( xSeries, false /*bInsert*/ );
876*cdf0e10cSrcweir }
877*cdf0e10cSrcweir 
878*cdf0e10cSrcweir 
879*cdf0e10cSrcweir void insertDataLabelToPoint( const Reference< beans::XPropertySet >& xPointProp )
880*cdf0e10cSrcweir {
881*cdf0e10cSrcweir     try
882*cdf0e10cSrcweir     {
883*cdf0e10cSrcweir         if( xPointProp.is() )
884*cdf0e10cSrcweir         {
885*cdf0e10cSrcweir             DataPointLabel aLabel;
886*cdf0e10cSrcweir             xPointProp->getPropertyValue( C2U( "Label" ) ) >>= aLabel;
887*cdf0e10cSrcweir             aLabel.ShowNumber = true;
888*cdf0e10cSrcweir             xPointProp->setPropertyValue( C2U( "Label" ), uno::makeAny( aLabel ) );
889*cdf0e10cSrcweir         }
890*cdf0e10cSrcweir     }
891*cdf0e10cSrcweir     catch( uno::Exception &e)
892*cdf0e10cSrcweir     {
893*cdf0e10cSrcweir         ASSERT_EXCEPTION( e );
894*cdf0e10cSrcweir     }
895*cdf0e10cSrcweir }
896*cdf0e10cSrcweir 
897*cdf0e10cSrcweir void deleteDataLabelsFromPoint( const Reference< beans::XPropertySet >& xPointProp )
898*cdf0e10cSrcweir {
899*cdf0e10cSrcweir     try
900*cdf0e10cSrcweir     {
901*cdf0e10cSrcweir         if( xPointProp.is() )
902*cdf0e10cSrcweir         {
903*cdf0e10cSrcweir             DataPointLabel aLabel;
904*cdf0e10cSrcweir             xPointProp->getPropertyValue( C2U( "Label" ) ) >>= aLabel;
905*cdf0e10cSrcweir             aLabel.ShowNumber = false;
906*cdf0e10cSrcweir             aLabel.ShowNumberInPercent = false;
907*cdf0e10cSrcweir             aLabel.ShowCategoryName = false;
908*cdf0e10cSrcweir             xPointProp->setPropertyValue( C2U( "Label" ), uno::makeAny( aLabel ) );
909*cdf0e10cSrcweir         }
910*cdf0e10cSrcweir     }
911*cdf0e10cSrcweir     catch( uno::Exception &e)
912*cdf0e10cSrcweir     {
913*cdf0e10cSrcweir         ASSERT_EXCEPTION( e );
914*cdf0e10cSrcweir     }
915*cdf0e10cSrcweir }
916*cdf0e10cSrcweir 
917*cdf0e10cSrcweir } //  namespace DataSeriesHelper
918*cdf0e10cSrcweir } //  namespace chart
919