Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
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/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
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 .
18 : : */
19 : :
20 : :
21 : : #include "ExplicitCategoriesProvider.hxx"
22 : : #include "DiagramHelper.hxx"
23 : : #include "ChartTypeHelper.hxx"
24 : : #include "AxisHelper.hxx"
25 : : #include "CommonConverters.hxx"
26 : : #include "DataSourceHelper.hxx"
27 : : #include "ChartModelHelper.hxx"
28 : : #include "ContainerHelper.hxx"
29 : : #include "macros.hxx"
30 : : #include "NumberFormatterWrapper.hxx"
31 : :
32 : : #include <com/sun/star/chart2/AxisType.hpp>
33 : : #include <com/sun/star/util/NumberFormat.hpp>
34 : : #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
35 : :
36 : : //.............................................................................
37 : : namespace chart
38 : : {
39 : : //.............................................................................
40 : :
41 : : using namespace ::com::sun::star;
42 : : using namespace ::com::sun::star::chart2;
43 : : using ::com::sun::star::uno::Reference;
44 : : using ::com::sun::star::uno::Sequence;
45 : : using ::rtl::OUString;
46 : : using ::std::vector;
47 : :
48 : :
49 : 2746 : ExplicitCategoriesProvider::ExplicitCategoriesProvider( const Reference< chart2::XCoordinateSystem >& xCooSysModel
50 : : , const uno::Reference< frame::XModel >& xChartModel )
51 : : : m_bDirty(true)
52 : : , m_xCooSysModel( xCooSysModel )
53 : : , m_xChartModel( xChartModel )
54 : : , m_xOriginalCategories()
55 : : , m_bIsExplicitCategoriesInited(false)
56 : : , m_bIsDateAxis(false)
57 [ + - ][ + - ]: 2746 : , m_bIsAutoDate(false)
[ + - ][ + - ]
[ + - ]
58 : : {
59 : : try
60 : : {
61 [ + - ]: 2746 : if( xCooSysModel.is() )
62 : : {
63 [ + - ][ + - ]: 2746 : uno::Reference< XAxis > xAxis( xCooSysModel->getAxisByDimension(0,0) );
64 [ + - ]: 2746 : if( xAxis.is() )
65 : : {
66 [ + - ][ + - ]: 2746 : ScaleData aScale( xAxis->getScaleData() );
67 [ + - ]: 2746 : m_xOriginalCategories = aScale.Categories;
68 [ + + ][ + + ]: 2746 : m_bIsAutoDate = (aScale.AutoDateAxis && aScale.AxisType==chart2::AxisType::CATEGORY);
69 [ + - ][ + + ]: 2746 : m_bIsDateAxis = (aScale.AxisType == chart2::AxisType::DATE || m_bIsAutoDate);
[ + - ]
70 : 2746 : }
71 : : }
72 : :
73 [ + + ]: 2746 : if( m_xOriginalCategories.is() )
74 : : {
75 [ + - ]: 2733 : Reference< chart2::XChartDocument > xChartDoc( xChartModel, uno::UNO_QUERY );
76 [ + - ]: 2733 : if( xChartDoc.is() )
77 : : {
78 [ + - ][ + - ]: 2733 : uno::Reference< data::XDataProvider > xDataProvider( xChartDoc->getDataProvider() );
79 : :
80 [ + - ]: 2733 : OUString aCategoriesRange( DataSourceHelper::getRangeFromValues( m_xOriginalCategories ) );
81 [ + - ][ + - ]: 2733 : if( xDataProvider.is() && !aCategoriesRange.isEmpty() )
[ + - ]
82 : : {
83 : 2733 : const bool bFirstCellAsLabel = false;
84 : 2733 : const bool bHasCategories = false;
85 [ + - ]: 2733 : const uno::Sequence< sal_Int32 > aSequenceMapping;
86 : :
87 [ + - ]: 2733 : uno::Reference< data::XDataSource > xColumnCategoriesSource( xDataProvider->createDataSource(
88 : : DataSourceHelper::createArguments( aCategoriesRange, aSequenceMapping, true /*bUseColumns*/
89 [ + - ][ + - ]: 2733 : , bFirstCellAsLabel, bHasCategories ) ) );
[ + - ]
90 : :
91 [ + - ]: 2733 : uno::Reference< data::XDataSource > xRowCategoriesSource( xDataProvider->createDataSource(
92 : : DataSourceHelper::createArguments( aCategoriesRange, aSequenceMapping, false /*bUseColumns*/
93 [ + - ][ + - ]: 2733 : , bFirstCellAsLabel, bHasCategories ) ) );
[ + - ]
94 : :
95 [ + - ][ + - ]: 2733 : if( xColumnCategoriesSource.is() && xRowCategoriesSource.is() )
[ + - ]
96 : : {
97 [ + - ][ + - ]: 2733 : Sequence< Reference< data::XLabeledDataSequence> > aColumns = xColumnCategoriesSource->getDataSequences();
98 [ + - ][ + - ]: 2733 : Sequence< Reference< data::XLabeledDataSequence> > aRows = xRowCategoriesSource->getDataSequences();
99 : :
100 : 2733 : sal_Int32 nColumnCount = aColumns.getLength();
101 : 2733 : sal_Int32 nRowCount = aRows.getLength();
102 [ - + ][ + + ]: 2733 : if( nColumnCount>1 && nRowCount>1 )
103 : : {
104 : : //we have complex categories
105 : : //->split them in the direction of the first series
106 : : //detect whether the first series is a row or a column
107 : 0 : bool bSeriesUsesColumns = true;
108 [ # # ]: 0 : ::std::vector< Reference< XDataSeries > > aSeries( ChartModelHelper::getDataSeries( xChartModel ) );
109 [ # # ]: 0 : if( !aSeries.empty() )
110 : : {
111 [ # # ][ # # ]: 0 : uno::Reference< data::XDataSource > xSeriesSource( aSeries.front(), uno::UNO_QUERY );
112 : 0 : ::rtl::OUString aStringDummy;
113 : : bool bDummy;
114 [ # # ]: 0 : uno::Sequence< sal_Int32 > aSeqDummy;
115 [ # # ]: 0 : DataSourceHelper::readArguments( xDataProvider->detectArguments( xSeriesSource),
116 [ # # ][ # # ]: 0 : aStringDummy, aSeqDummy, bSeriesUsesColumns, bDummy, bDummy );
[ # # ][ # # ]
117 : : }
118 [ # # ]: 0 : if( bSeriesUsesColumns )
119 [ # # ]: 0 : m_aSplitCategoriesList=aColumns;
120 : : else
121 [ # # ]: 0 : m_aSplitCategoriesList=aRows;
122 [ + - ][ + - ]: 2733 : }
123 [ + - ]: 2733 : }
124 : 2733 : }
125 : : }
126 [ + - ]: 2733 : if( !m_aSplitCategoriesList.getLength() )
127 : : {
128 [ + - ]: 2733 : m_aSplitCategoriesList.realloc(1);
129 [ + - ][ + - ]: 2733 : m_aSplitCategoriesList[0]=m_xOriginalCategories;
130 [ # # ]: 2733 : }
131 : : }
132 : : }
133 [ # # ]: 0 : catch( const uno::Exception & ex )
134 : : {
135 : : ASSERT_EXCEPTION( ex );
136 : : }
137 : 2746 : }
138 : :
139 [ + - ][ + - ]: 2746 : ExplicitCategoriesProvider::~ExplicitCategoriesProvider()
[ + - ]
140 : : {
141 [ - + ]: 3728 : }
142 : :
143 : 0 : Reference< chart2::data::XDataSequence > ExplicitCategoriesProvider::getOriginalCategories()
144 : : {
145 [ # # ]: 0 : if( m_xOriginalCategories.is() )
146 : 0 : return m_xOriginalCategories->getValues();
147 : 0 : return 0;
148 : : }
149 : :
150 : 15 : const Sequence< Reference< data::XLabeledDataSequence> >& ExplicitCategoriesProvider::getSplitCategoriesList()
151 : : {
152 : 15 : return m_aSplitCategoriesList;
153 : : }
154 : :
155 : 4745 : bool ExplicitCategoriesProvider::hasComplexCategories() const
156 : : {
157 : 4745 : return m_aSplitCategoriesList.getLength() > 1;
158 : : }
159 : :
160 : 0 : sal_Int32 ExplicitCategoriesProvider::getCategoryLevelCount() const
161 : : {
162 : 0 : sal_Int32 nCount = m_aSplitCategoriesList.getLength();
163 [ # # ]: 0 : if(!nCount)
164 : 0 : nCount = 1;
165 : 0 : return nCount;
166 : : }
167 : :
168 : 0 : std::vector<sal_Int32> lcl_getLimitingBorders( const std::vector< ComplexCategory >& rComplexCategories )
169 : : {
170 [ # # ]: 0 : std::vector<sal_Int32> aLimitingBorders;
171 : 0 : std::vector< ComplexCategory >::const_iterator aIt( rComplexCategories.begin() );
172 : 0 : std::vector< ComplexCategory >::const_iterator aEnd( rComplexCategories.end() );
173 : 0 : sal_Int32 nBorderIndex = 0; /*border below the index*/
174 [ # # ][ # # ]: 0 : for( ; aIt != aEnd; ++aIt )
[ # # ]
175 : : {
176 [ # # ][ # # ]: 0 : ComplexCategory aComplexCategory(*aIt);
177 : 0 : nBorderIndex += aComplexCategory.Count;
178 [ # # ]: 0 : aLimitingBorders.push_back(nBorderIndex);
179 [ # # ]: 0 : }
180 : 0 : return aLimitingBorders;
181 : : }
182 : :
183 : 967 : void ExplicitCategoriesProvider::convertCategoryAnysToText( uno::Sequence< rtl::OUString >& rOutTexts, const uno::Sequence< uno::Any >& rInAnys, Reference< frame::XModel > xChartModel )
184 : : {
185 : 967 : sal_Int32 nCount = rInAnys.getLength();
186 [ + - ]: 967 : if(!nCount)
187 : 967 : return;
188 [ + - ]: 967 : rOutTexts.realloc(nCount);
189 [ + - ]: 967 : Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( xChartModel, uno::UNO_QUERY );
190 : 967 : Reference< util::XNumberFormats > xNumberFormats;
191 [ + - ]: 967 : if( xNumberFormatsSupplier.is() )
192 [ + - ][ + - ]: 967 : xNumberFormats = Reference< util::XNumberFormats >( xNumberFormatsSupplier->getNumberFormats() );
[ + - ]
193 : :
194 : 967 : sal_Int32 nAxisNumberFormat = 0;
195 [ + - ]: 967 : Reference< XCoordinateSystem > xCooSysModel( ChartModelHelper::getFirstCoordinateSystem( xChartModel ) );
196 [ + + ]: 967 : if( xCooSysModel.is() )
197 : : {
198 [ + - ][ + - ]: 965 : Reference< chart2::XAxis > xAxis( xCooSysModel->getAxisByDimension(0,0) );
199 : : nAxisNumberFormat = AxisHelper::getExplicitNumberFormatKeyForAxis(
200 [ + - ]: 965 : xAxis, xCooSysModel, xNumberFormatsSupplier, false );
201 : : }
202 : :
203 : : sal_Int32 nLabelColor;
204 : 967 : bool bColorChanged = false;
205 : :
206 [ + - ]: 967 : NumberFormatterWrapper aNumberFormatterWrapper( xNumberFormatsSupplier );
207 : :
208 [ + + ]: 5312 : for(sal_Int32 nN=0;nN<nCount;nN++)
209 : : {
210 : 4345 : rtl::OUString aText;
211 : 4345 : uno::Any aAny = rInAnys[nN];
212 [ + - ]: 4345 : if( aAny.hasValue() )
213 : : {
214 : 4345 : double fDouble = 0;
215 [ - + ]: 4345 : if( aAny>>=fDouble )
216 : : {
217 [ # # ]: 0 : if( !::rtl::math::isNan(fDouble) )
218 : : aText = aNumberFormatterWrapper.getFormattedString(
219 [ # # ]: 0 : nAxisNumberFormat, fDouble, nLabelColor, bColorChanged );
220 : : }
221 : : else
222 : : {
223 : 4345 : aAny>>=aText;
224 : : }
225 : : }
226 [ + - ]: 4345 : rOutTexts[nN] = aText;
227 [ + - ]: 5312 : }
228 : : }
229 : :
230 : 29 : SplitCategoriesProvider::~SplitCategoriesProvider()
231 : : {
232 [ - + ]: 29 : }
233 : :
234 : : class SplitCategoriesProvider_ForLabeledDataSequences : public SplitCategoriesProvider
235 : : {
236 : : public:
237 : :
238 : 0 : explicit SplitCategoriesProvider_ForLabeledDataSequences(
239 : : const ::com::sun::star::uno::Sequence<
240 : : ::com::sun::star::uno::Reference<
241 : : ::com::sun::star::chart2::data::XLabeledDataSequence> >& rSplitCategoriesList
242 : : , const Reference< frame::XModel >& xChartModel )
243 : : : m_rSplitCategoriesList( rSplitCategoriesList )
244 : 0 : , m_xChartModel( xChartModel )
245 : 0 : {}
246 : 0 : virtual ~SplitCategoriesProvider_ForLabeledDataSequences()
247 [ # # ]: 0 : {}
248 : :
249 : : virtual sal_Int32 getLevelCount() const;
250 : : virtual uno::Sequence< rtl::OUString > getStringsForLevel( sal_Int32 nIndex ) const;
251 : :
252 : : private:
253 : : const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference<
254 : : ::com::sun::star::chart2::data::XLabeledDataSequence> >& m_rSplitCategoriesList;
255 : :
256 : : Reference< frame::XModel > m_xChartModel;
257 : : };
258 : :
259 : 0 : sal_Int32 SplitCategoriesProvider_ForLabeledDataSequences::getLevelCount() const
260 : : {
261 : 0 : return m_rSplitCategoriesList.getLength();
262 : : }
263 : 0 : uno::Sequence< rtl::OUString > SplitCategoriesProvider_ForLabeledDataSequences::getStringsForLevel( sal_Int32 nLevel ) const
264 : : {
265 [ # # ]: 0 : uno::Sequence< rtl::OUString > aRet;
266 : 0 : Reference< data::XLabeledDataSequence > xLabeledDataSequence( m_rSplitCategoriesList[nLevel] );
267 [ # # ]: 0 : if( xLabeledDataSequence.is() )
268 : : {
269 [ # # ][ # # ]: 0 : uno::Reference< data::XDataSequence > xDataSequence( xLabeledDataSequence->getValues() );
270 [ # # ]: 0 : if( xDataSequence.is() )
271 [ # # ][ # # ]: 0 : ExplicitCategoriesProvider::convertCategoryAnysToText( aRet, xDataSequence->getData(), m_xChartModel );
[ # # ][ # # ]
272 : : }
273 : 0 : return aRet;
274 : : }
275 : :
276 : 29 : std::vector< ComplexCategory > lcl_DataSequenceToComplexCategoryVector(
277 : : const uno::Sequence< rtl::OUString >& rStrings
278 : : , const std::vector<sal_Int32>& rLimitingBorders, bool bCreateSingleCategories )
279 : : {
280 [ + - ]: 29 : std::vector< ComplexCategory > aResult;
281 : :
282 : 29 : sal_Int32 nMaxCount = rStrings.getLength();
283 : 29 : OUString aPrevious;
284 : 29 : sal_Int32 nCurrentCount=0;
285 [ + + ]: 170 : for( sal_Int32 nN=0; nN<nMaxCount; nN++ )
286 : : {
287 : 141 : OUString aCurrent = rStrings[nN];
288 [ # # ][ # # ]: 141 : if( bCreateSingleCategories || ::std::find( rLimitingBorders.begin(), rLimitingBorders.end(), nN ) != rLimitingBorders.end() )
[ # # ][ - + ]
[ - + ][ + -
# # # # ]
[ - + ]
289 : : {
290 [ + - ][ + - ]: 141 : aResult.push_back( ComplexCategory(aPrevious,nCurrentCount) );
291 : 141 : nCurrentCount=1;
292 : 141 : aPrevious = aCurrent;
293 : : }
294 : : else
295 : : {
296 [ # # ][ # # ]: 0 : if( !aCurrent.isEmpty() && aPrevious != aCurrent )
[ # # ]
297 : : {
298 [ # # ][ # # ]: 0 : aResult.push_back( ComplexCategory(aPrevious,nCurrentCount) );
299 : 0 : nCurrentCount=1;
300 : 0 : aPrevious = aCurrent;
301 : : }
302 : : else
303 : 0 : nCurrentCount++;
304 : : }
305 : 141 : }
306 [ + - ]: 29 : if( nCurrentCount )
307 [ + - ][ + - ]: 29 : aResult.push_back( ComplexCategory(aPrevious,nCurrentCount) );
308 : :
309 : 29 : return aResult;
310 : : }
311 : :
312 : 58 : sal_Int32 lcl_getCategoryCount( std::vector< ComplexCategory >& rComplexCategories )
313 : : {
314 : 58 : sal_Int32 nCount = 0;
315 [ + - ]: 58 : std::vector< ComplexCategory >::const_iterator aIt( rComplexCategories.begin() );
316 [ + - ]: 58 : std::vector< ComplexCategory >::const_iterator aEnd( rComplexCategories.end() );
317 [ + - ][ + - ]: 398 : for( ; aIt != aEnd; ++aIt )
[ + + ]
318 [ + - ]: 340 : nCount+=aIt->Count;
319 : 58 : return nCount;
320 : : }
321 : :
322 : 29 : Sequence< OUString > lcl_getExplicitSimpleCategories(
323 : : const SplitCategoriesProvider& rSplitCategoriesProvider,
324 : : ::std::vector< ::std::vector< ComplexCategory > >& rComplexCats )
325 : : {
326 [ + - ]: 29 : Sequence< OUString > aRet;
327 : :
328 : 29 : rComplexCats.clear();
329 [ + - ]: 29 : sal_Int32 nLCount = rSplitCategoriesProvider.getLevelCount();
330 [ + + ]: 58 : for( sal_Int32 nL = 0; nL < nLCount; nL++ )
331 : : {
332 [ + - ]: 29 : std::vector<sal_Int32> aLimitingBorders;
333 [ - + ]: 29 : if(nL>0)
334 [ # # ][ # # ]: 0 : aLimitingBorders = lcl_getLimitingBorders( rComplexCats.back() );
335 : : rComplexCats.push_back( lcl_DataSequenceToComplexCategoryVector(
336 [ + - ][ + - ]: 29 : rSplitCategoriesProvider.getStringsForLevel(nL), aLimitingBorders, nL==(nLCount-1) ) );
[ + - ][ + - ]
337 : 29 : }
338 : :
339 : 29 : std::vector< std::vector< ComplexCategory > >::iterator aOuterIt( rComplexCats.begin() );
340 [ + - ]: 29 : std::vector< std::vector< ComplexCategory > >::const_iterator aOuterEnd( rComplexCats.end() );
341 : :
342 : : //ensure that the category count is the same on each level
343 : 29 : sal_Int32 nMaxCategoryCount = 0;
344 : : {
345 [ + - ][ + - ]: 58 : for( aOuterIt=rComplexCats.begin(); aOuterIt != aOuterEnd; ++aOuterIt )
[ + + ]
346 : : {
347 [ + - ][ + - ]: 29 : sal_Int32 nCurrentCount = lcl_getCategoryCount( *aOuterIt );
348 [ + - ]: 29 : nMaxCategoryCount = std::max( nCurrentCount, nMaxCategoryCount );
349 : : }
350 [ + - ][ + - ]: 58 : for( aOuterIt=rComplexCats.begin(); aOuterIt != aOuterEnd; ++aOuterIt )
[ + + ]
351 : : {
352 [ + - ][ + - ]: 29 : sal_Int32 nCurrentCount = lcl_getCategoryCount( *aOuterIt );
353 [ - + ]: 29 : if( nCurrentCount< nMaxCategoryCount )
354 : : {
355 [ # # ][ # # ]: 0 : ComplexCategory& rComplexCategory = aOuterIt->back();
356 : 0 : rComplexCategory.Count += (nMaxCategoryCount-nCurrentCount);
357 : : }
358 : : }
359 : : }
360 : :
361 : : //create a list with an element for every index
362 [ + - ]: 29 : std::vector< std::vector< ComplexCategory > > aComplexCatsPerIndex;
363 [ + - ][ + - ]: 58 : for( aOuterIt=rComplexCats.begin() ; aOuterIt != aOuterEnd; ++aOuterIt )
[ + + ]
364 : : {
365 [ + - ]: 29 : std::vector< ComplexCategory > aSingleLevel;
366 [ + - ]: 29 : std::vector< ComplexCategory >::iterator aIt( aOuterIt->begin() );
367 [ + - ][ + - ]: 29 : std::vector< ComplexCategory >::const_iterator aEnd( aOuterIt->end() );
368 [ + - ][ + - ]: 199 : for( ; aIt != aEnd; ++aIt )
[ + + ]
369 : : {
370 [ + - ][ + - ]: 170 : ComplexCategory aComplexCategory( *aIt );
371 : 170 : sal_Int32 nCount = aComplexCategory.Count;
372 [ + + ]: 311 : while( nCount-- )
373 [ + - ]: 141 : aSingleLevel.push_back(aComplexCategory);
374 [ + - ]: 170 : }
375 [ + - ]: 29 : aComplexCatsPerIndex.push_back( aSingleLevel );
376 : 29 : }
377 : :
378 [ + - ]: 29 : if(nMaxCategoryCount)
379 : : {
380 [ + - ]: 29 : aRet.realloc(nMaxCategoryCount);
381 [ + - ]: 29 : aOuterEnd = aComplexCatsPerIndex.end();
382 [ + - ]: 29 : OUString aSpace(C2U(" "));
383 [ + + ]: 170 : for(sal_Int32 nN=0; nN<nMaxCategoryCount; nN++)
384 : : {
385 : 141 : OUString aText;
386 [ + - ][ + + ]: 282 : for( aOuterIt=aComplexCatsPerIndex.begin() ; aOuterIt != aOuterEnd; ++aOuterIt )
[ + - ]
387 : : {
388 [ + - ][ + - ]: 141 : OUString aAddText = (*aOuterIt)[nN].Text;
389 [ + - ]: 141 : if( !aAddText.isEmpty() )
390 : : {
391 [ - + ]: 141 : if(!aText.isEmpty())
392 : 0 : aText += aSpace;
393 : 141 : aText += aAddText;
394 : : }
395 : 141 : }
396 [ + - ]: 141 : aRet[nN]=aText;
397 : 170 : }
398 : : }
399 : 29 : return aRet;
400 : : }
401 : :
402 : 29 : Sequence< OUString > ExplicitCategoriesProvider::getExplicitSimpleCategories(
403 : : const SplitCategoriesProvider& rSplitCategoriesProvider )
404 : : {
405 [ + - ]: 29 : vector< vector< ComplexCategory > > aComplexCats;
406 [ + - ]: 29 : return lcl_getExplicitSimpleCategories( rSplitCategoriesProvider, aComplexCats );
407 : : }
408 : :
409 : : struct DatePlusIndexComparator
410 : : {
411 : 18402 : inline bool operator() ( const DatePlusIndex& aFirst,
412 : : const DatePlusIndex& aSecond ) const
413 : : {
414 : 18402 : return ( aFirst.fValue < aSecond.fValue );
415 : : }
416 : : };
417 : :
418 : 2603 : bool lcl_fillDateCategories( const uno::Reference< data::XDataSequence >& xDataSequence, std::vector< DatePlusIndex >& rDateCategories, bool bIsAutoDate, Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier )
419 : : {
420 : 2603 : bool bOnlyDatesFound = true;
421 : 2603 : bool bAnyDataFound = false;
422 : :
423 [ + - ]: 2603 : if( xDataSequence.is() )
424 : : {
425 [ + - ][ + - ]: 2603 : uno::Sequence< uno::Any > aValues = xDataSequence->getData();
426 : 2603 : sal_Int32 nCount = aValues.getLength();
427 [ + - ]: 2603 : rDateCategories.reserve(nCount);
428 : 2603 : Reference< util::XNumberFormats > xNumberFormats;
429 [ + - ]: 2603 : if( xNumberFormatsSupplier.is() )
430 [ + - ][ + - ]: 2603 : xNumberFormats = Reference< util::XNumberFormats >( xNumberFormatsSupplier->getNumberFormats() );
[ + - ]
431 : :
432 : 2603 : bool bOwnData = false;
433 : 2603 : bool bOwnDataAnddAxisHasAnyFormat = false;
434 : 2603 : bool bOwnDataAnddAxisHasDateFormat = false;
435 [ + - ]: 2603 : Reference< chart2::XChartDocument > xChartDoc( xNumberFormatsSupplier, uno::UNO_QUERY );
436 [ + - ][ + - ]: 2603 : Reference< XCoordinateSystem > xCooSysModel( ChartModelHelper::getFirstCoordinateSystem( Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ) ) );
437 [ + - ][ + - ]: 2603 : if( xChartDoc.is() && xCooSysModel.is() )
[ + - ]
438 : : {
439 [ + - ][ + - ]: 2603 : if( xChartDoc->hasInternalDataProvider() )
[ + + ]
440 : : {
441 : 2346 : bOwnData = true;
442 [ + - ][ + - ]: 2346 : Reference< beans::XPropertySet > xAxisProps( xCooSysModel->getAxisByDimension(0,0), uno::UNO_QUERY );
[ + - ]
443 : 2346 : sal_Int32 nAxisNumberFormat = 0;
444 [ + - ][ + - ]: 2346 : if( xAxisProps.is() && (xAxisProps->getPropertyValue( C2U("NumberFormat") ) >>= nAxisNumberFormat) )
[ + - ][ + + ]
[ + - ][ + - ]
[ + + # #
# # ][ + - ]
445 : : {
446 : 1 : bOwnDataAnddAxisHasAnyFormat = true;
447 [ + - ]: 1 : bOwnDataAnddAxisHasDateFormat = DiagramHelper::isDateNumberFormat( nAxisNumberFormat, xNumberFormats );
448 : 2346 : }
449 : : }
450 : : }
451 : :
452 [ + + ]: 14407 : for(sal_Int32 nN=0;nN<nCount;nN++)
453 : : {
454 : 11804 : bool bIsDate = false;
455 [ + - ]: 11804 : if( bIsAutoDate )
456 : : {
457 [ + + ]: 11804 : if( bOwnData )
458 [ + + ]: 9384 : bIsDate = bOwnDataAnddAxisHasAnyFormat ? bOwnDataAnddAxisHasDateFormat : true;
459 : : else
460 [ + - ][ + - ]: 2420 : bIsDate = DiagramHelper::isDateNumberFormat( xDataSequence->getNumberFormatKeyByIndex( nN ), xNumberFormats );
[ + - ]
461 : : }
462 : : else
463 : 0 : bIsDate = true;
464 : :
465 : 11804 : bool bContainsEmptyString = false;
466 : 11804 : bool bContainsNan = false;
467 [ + - ]: 11804 : uno::Any aAny = aValues[nN];
468 [ + - ]: 11804 : if( aAny.hasValue() )
469 : : {
470 : 11804 : OUString aTest;
471 : 11804 : double fTest = 0;
472 [ + + ][ + + ]: 11804 : if( (aAny>>=aTest) && aTest.isEmpty() ) //empty String
[ + - ]
473 : 3 : bContainsEmptyString = true;
474 [ - + ][ # # ]: 11801 : else if( (aAny>>=fTest) && ::rtl::math::isNan(fTest) )
[ - + ]
475 : 0 : bContainsNan = true;
476 : :
477 [ + + ][ + - ]: 11804 : if( !bContainsEmptyString && !bContainsNan )
478 : 11804 : bAnyDataFound = true;
479 : : }
480 : 11804 : DatePlusIndex aDatePlusIndex( 1.0, nN );
481 [ - + ][ - + ]: 11804 : if( bIsDate && (aAny >>= aDatePlusIndex.fValue) )
[ + + ]
482 [ # # ]: 0 : rDateCategories.push_back( aDatePlusIndex );
483 : : else
484 : : {
485 [ + - ][ + + ]: 11804 : if( aAny.hasValue() && !bContainsEmptyString )//empty string does not count as non date value!
[ + + ]
486 : 11801 : bOnlyDatesFound=false;
487 : 11804 : ::rtl::math::setNan( &aDatePlusIndex.fValue );
488 [ + - ]: 11804 : rDateCategories.push_back( aDatePlusIndex );
489 : : }
490 : 11804 : }
491 [ + - ][ + - ]: 2603 : ::std::sort( rDateCategories.begin(), rDateCategories.end(), DatePlusIndexComparator() );
492 : : }
493 : :
494 [ + - ][ - + ]: 2603 : return bAnyDataFound && bOnlyDatesFound;
495 : : }
496 : :
497 : 11693 : void ExplicitCategoriesProvider::init()
498 : : {
499 [ + + ]: 11693 : if( m_bDirty )
500 : : {
501 : 2730 : m_aComplexCats.clear();//not one per index
502 : 2730 : m_aDateCategories.clear();
503 : :
504 [ + + ]: 2730 : if( m_xOriginalCategories.is() )
505 : : {
506 [ + - ]: 2717 : if( !hasComplexCategories() )
507 : : {
508 [ + + ]: 2717 : if(m_bIsDateAxis)
509 : : {
510 [ + - ][ + - ]: 2615 : if( ChartTypeHelper::isSupportingDateAxis( AxisHelper::getChartTypeByIndex( m_xCooSysModel, 0 ), 2, 0 ) )
[ + + ]
511 [ + - ][ + - ]: 2603 : m_bIsDateAxis = lcl_fillDateCategories( m_xOriginalCategories->getValues(), m_aDateCategories, m_bIsAutoDate, Reference< util::XNumberFormatsSupplier >( m_xChartModel.get(), uno::UNO_QUERY ) );
[ + - ][ + - ]
512 : : else
513 : 12 : m_bIsDateAxis = false;
514 : : }
515 : : }
516 : : else
517 : : {
518 : 0 : m_bIsDateAxis = false;
519 : : }
520 : : }
521 : : else
522 : 13 : m_bIsDateAxis=false;
523 : 2730 : m_bDirty = false;
524 : : }
525 : 11693 : }
526 : :
527 : :
528 : 3191 : Sequence< ::rtl::OUString > ExplicitCategoriesProvider::getSimpleCategories()
529 : : {
530 [ + + ]: 3191 : if( !m_bIsExplicitCategoriesInited )
531 : : {
532 : 973 : init();
533 : 973 : m_aExplicitCategories.realloc(0);
534 [ + + ]: 973 : if( m_xOriginalCategories.is() )
535 : : {
536 [ + - ]: 967 : if( !hasComplexCategories() )
537 : : {
538 [ + - ][ + - ]: 967 : uno::Reference< data::XDataSequence > xDataSequence( m_xOriginalCategories->getValues() );
539 [ + - ]: 967 : if( xDataSequence.is() )
540 [ + - ][ + - ]: 967 : ExplicitCategoriesProvider::convertCategoryAnysToText( m_aExplicitCategories, xDataSequence->getData(), m_xChartModel );
[ + - ][ + - ]
[ + - ]
541 : : }
542 : : else
543 : : {
544 : : m_aExplicitCategories = lcl_getExplicitSimpleCategories(
545 [ # # ][ # # ]: 0 : SplitCategoriesProvider_ForLabeledDataSequences( m_aSplitCategoriesList, m_xChartModel ), m_aComplexCats );
[ # # ][ # # ]
[ # # ]
546 : : }
547 : : }
548 [ + + ]: 973 : if(!m_aExplicitCategories.getLength())
549 [ + - ][ + - ]: 6 : m_aExplicitCategories = DiagramHelper::generateAutomaticCategoriesFromCooSys( m_xCooSysModel );
[ + - ]
550 : 973 : m_bIsExplicitCategoriesInited = true;
551 : : }
552 : 3191 : return m_aExplicitCategories;
553 : : }
554 : :
555 : 0 : std::vector< ComplexCategory > ExplicitCategoriesProvider::getCategoriesByLevel( sal_Int32 nLevel )
556 : : {
557 : 0 : std::vector< ComplexCategory > aRet;
558 [ # # ]: 0 : init();
559 : 0 : sal_Int32 nMaxIndex = m_aComplexCats.size()-1;
560 [ # # ][ # # ]: 0 : if( nLevel >= 0 && nLevel <= nMaxIndex )
561 [ # # ][ # # ]: 0 : aRet = m_aComplexCats[nMaxIndex-nLevel];
562 : 0 : return aRet;
563 : : }
564 : :
565 : 0 : OUString ExplicitCategoriesProvider::getCategoryByIndex(
566 : : const Reference< XCoordinateSystem >& xCooSysModel
567 : : , const uno::Reference< frame::XModel >& xChartModel
568 : : , sal_Int32 nIndex )
569 : : {
570 [ # # ]: 0 : if( xCooSysModel.is())
571 : : {
572 [ # # ]: 0 : ExplicitCategoriesProvider aExplicitCategoriesProvider( xCooSysModel, xChartModel );
573 [ # # ]: 0 : Sequence< OUString > aCategories( aExplicitCategoriesProvider.getSimpleCategories());
574 [ # # ]: 0 : if( nIndex < aCategories.getLength())
575 [ # # ][ # # ]: 0 : return aCategories[ nIndex ];
[ # # ][ # # ]
[ # # ]
576 : : }
577 : 0 : return OUString();
578 : : }
579 : :
580 : 10720 : bool ExplicitCategoriesProvider::isDateAxis()
581 : : {
582 : 10720 : init();
583 : 10720 : return m_bIsDateAxis;
584 : : }
585 : :
586 : 0 : const std::vector< DatePlusIndex >& ExplicitCategoriesProvider::getDateCategories()
587 : : {
588 : 0 : init();
589 : 0 : return m_aDateCategories;
590 : : }
591 : :
592 : : //.............................................................................
593 : : } //namespace chart
594 : : //.............................................................................
595 : :
596 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|