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