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 2885 : 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 2885 : , m_bIsAutoDate(false)
55 : {
56 : try
57 : {
58 2885 : if( xCooSysModel.is() )
59 : {
60 2885 : uno::Reference< XAxis > xAxis( xCooSysModel->getAxisByDimension(0,0) );
61 2885 : if( xAxis.is() )
62 : {
63 2885 : ScaleData aScale( xAxis->getScaleData() );
64 2885 : m_xOriginalCategories = aScale.Categories;
65 2885 : m_bIsAutoDate = (aScale.AutoDateAxis && aScale.AxisType==chart2::AxisType::CATEGORY);
66 2885 : m_bIsDateAxis = (aScale.AxisType == chart2::AxisType::DATE || m_bIsAutoDate);
67 2885 : }
68 : }
69 :
70 2885 : if( m_xOriginalCategories.is() )
71 : {
72 2662 : uno::Reference< data::XDataProvider > xDataProvider( mrModel.getDataProvider() );
73 :
74 5324 : OUString aCategoriesRange( DataSourceHelper::getRangeFromValues( m_xOriginalCategories ) );
75 2662 : if( xDataProvider.is() && !aCategoriesRange.isEmpty() )
76 : {
77 2660 : const bool bFirstCellAsLabel = false;
78 2660 : const bool bHasCategories = false;
79 2660 : const uno::Sequence< sal_Int32 > aSequenceMapping;
80 :
81 2660 : uno::Reference< data::XDataSource > xColumnCategoriesSource( xDataProvider->createDataSource(
82 : DataSourceHelper::createArguments( aCategoriesRange, aSequenceMapping, true /*bUseColumns*/
83 5320 : , bFirstCellAsLabel, bHasCategories ) ) );
84 :
85 2660 : uno::Reference< data::XDataSource > xRowCategoriesSource( xDataProvider->createDataSource(
86 : DataSourceHelper::createArguments( aCategoriesRange, aSequenceMapping, false /*bUseColumns*/
87 5320 : , bFirstCellAsLabel, bHasCategories ) ) );
88 :
89 2660 : if( xColumnCategoriesSource.is() && xRowCategoriesSource.is() )
90 : {
91 2660 : Sequence< Reference< data::XLabeledDataSequence> > aColumns = xColumnCategoriesSource->getDataSequences();
92 5320 : Sequence< Reference< data::XLabeledDataSequence> > aRows = xRowCategoriesSource->getDataSequences();
93 :
94 2660 : sal_Int32 nColumnCount = aColumns.getLength();
95 2660 : sal_Int32 nRowCount = aRows.getLength();
96 2660 : 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 2660 : }
117 2660 : }
118 : }
119 2662 : if( !m_aSplitCategoriesList.getLength() )
120 : {
121 2662 : m_aSplitCategoriesList.realloc(1);
122 2662 : m_aSplitCategoriesList[0]=m_xOriginalCategories;
123 2662 : }
124 : }
125 : }
126 0 : catch( const uno::Exception & ex )
127 : {
128 : ASSERT_EXCEPTION( ex );
129 : }
130 2885 : }
131 :
132 3906 : ExplicitCategoriesProvider::~ExplicitCategoriesProvider()
133 : {
134 3906 : }
135 :
136 105 : Reference< chart2::data::XDataSequence > ExplicitCategoriesProvider::getOriginalCategories()
137 : {
138 105 : if( m_xOriginalCategories.is() )
139 33 : return m_xOriginalCategories->getValues();
140 72 : return 0;
141 : }
142 :
143 6754 : bool ExplicitCategoriesProvider::hasComplexCategories() const
144 : {
145 6754 : 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 913 : void ExplicitCategoriesProvider::convertCategoryAnysToText( uno::Sequence< OUString >& rOutTexts, const uno::Sequence< uno::Any >& rInAnys, ChartModel& rModel )
172 : {
173 913 : sal_Int32 nCount = rInAnys.getLength();
174 913 : if(!nCount)
175 913 : return;
176 913 : rOutTexts.realloc(nCount);
177 913 : Reference< util::XNumberFormats > xNumberFormats;
178 913 : xNumberFormats = Reference< util::XNumberFormats >( rModel.getNumberFormats() );
179 :
180 913 : sal_Int32 nAxisNumberFormat = 0;
181 1826 : Reference< XCoordinateSystem > xCooSysModel( ChartModelHelper::getFirstCoordinateSystem( rModel ) );
182 913 : if( xCooSysModel.is() )
183 : {
184 913 : Reference< chart2::XAxis > xAxis( xCooSysModel->getAxisByDimension(0,0) );
185 : nAxisNumberFormat = AxisHelper::getExplicitNumberFormatKeyForAxis(
186 913 : xAxis, xCooSysModel, uno::Reference<chart2::XChartDocument>(static_cast< ::cppu::OWeakObject* >(&rModel), uno::UNO_QUERY), false );
187 : }
188 :
189 : sal_Int32 nLabelColor;
190 913 : bool bColorChanged = false;
191 :
192 1826 : NumberFormatterWrapper aNumberFormatterWrapper( rModel.getNumberFormatsSupplier() );
193 :
194 4906 : for(sal_Int32 nN=0;nN<nCount;nN++)
195 : {
196 3993 : OUString aText;
197 7986 : uno::Any aAny = rInAnys[nN];
198 3993 : if( aAny.hasValue() )
199 : {
200 3993 : double fDouble = 0;
201 3993 : if( aAny>>=fDouble )
202 : {
203 19 : if( !::rtl::math::isNan(fDouble) )
204 38 : aText = aNumberFormatterWrapper.getFormattedString(
205 19 : nAxisNumberFormat, fDouble, nLabelColor, bColorChanged );
206 : }
207 : else
208 : {
209 3974 : aAny>>=aText;
210 : }
211 : }
212 3993 : rOutTexts[nN] = aText;
213 4906 : }
214 : }
215 :
216 287 : SplitCategoriesProvider::~SplitCategoriesProvider()
217 : {
218 287 : }
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 287 : std::vector< ComplexCategory > lcl_DataSequenceToComplexCategoryVector(
263 : const uno::Sequence< OUString >& rStrings
264 : , const std::vector<sal_Int32>& rLimitingBorders, bool bCreateSingleCategories )
265 : {
266 287 : std::vector< ComplexCategory > aResult;
267 :
268 287 : sal_Int32 nMaxCount = rStrings.getLength();
269 574 : OUString aPrevious;
270 287 : sal_Int32 nCurrentCount=0;
271 1571 : for( sal_Int32 nN=0; nN<nMaxCount; nN++ )
272 : {
273 1284 : const OUString& aCurrent = rStrings[nN];
274 1284 : if( bCreateSingleCategories || ::std::find( rLimitingBorders.begin(), rLimitingBorders.end(), nN ) != rLimitingBorders.end() )
275 : {
276 1284 : aResult.push_back( ComplexCategory(aPrevious,nCurrentCount) );
277 1284 : nCurrentCount=1;
278 1284 : 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 287 : if( nCurrentCount )
297 268 : aResult.push_back( ComplexCategory(aPrevious,nCurrentCount) );
298 :
299 574 : return aResult;
300 : }
301 :
302 555 : sal_Int32 lcl_getCategoryCount( std::vector< ComplexCategory >& rComplexCategories )
303 : {
304 555 : sal_Int32 nCount = 0;
305 555 : std::vector< ComplexCategory >::const_iterator aIt( rComplexCategories.begin() );
306 555 : std::vector< ComplexCategory >::const_iterator aEnd( rComplexCategories.end() );
307 3659 : for( ; aIt != aEnd; ++aIt )
308 3104 : nCount+=aIt->Count;
309 555 : return nCount;
310 : }
311 :
312 287 : Sequence< OUString > lcl_getExplicitSimpleCategories(
313 : const SplitCategoriesProvider& rSplitCategoriesProvider,
314 : ::std::vector< ::std::vector< ComplexCategory > >& rComplexCats )
315 : {
316 287 : Sequence< OUString > aRet;
317 :
318 287 : rComplexCats.clear();
319 287 : sal_Int32 nLCount = rSplitCategoriesProvider.getLevelCount();
320 574 : for( sal_Int32 nL = 0; nL < nLCount; nL++ )
321 : {
322 287 : std::vector<sal_Int32> aLimitingBorders;
323 287 : if(nL>0)
324 0 : aLimitingBorders = lcl_getLimitingBorders( rComplexCats.back() );
325 : rComplexCats.push_back( lcl_DataSequenceToComplexCategoryVector(
326 287 : rSplitCategoriesProvider.getStringsForLevel(nL), aLimitingBorders, nL==(nLCount-1) ) );
327 287 : }
328 :
329 287 : std::vector< std::vector< ComplexCategory > >::iterator aOuterIt( rComplexCats.begin() );
330 287 : std::vector< std::vector< ComplexCategory > >::const_iterator aOuterEnd( rComplexCats.end() );
331 :
332 : //ensure that the category count is the same on each level
333 287 : sal_Int32 nMaxCategoryCount = 0;
334 : {
335 574 : for( aOuterIt=rComplexCats.begin(); aOuterIt != aOuterEnd; ++aOuterIt )
336 : {
337 287 : sal_Int32 nCurrentCount = lcl_getCategoryCount( *aOuterIt );
338 287 : nMaxCategoryCount = std::max( nCurrentCount, nMaxCategoryCount );
339 : }
340 574 : for( aOuterIt=rComplexCats.begin(); aOuterIt != aOuterEnd; ++aOuterIt )
341 : {
342 287 : if ( !aOuterIt->empty() )
343 : {
344 268 : sal_Int32 nCurrentCount = lcl_getCategoryCount( *aOuterIt );
345 268 : 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 574 : std::vector< std::vector< ComplexCategory > > aComplexCatsPerIndex;
356 574 : for( aOuterIt=rComplexCats.begin() ; aOuterIt != aOuterEnd; ++aOuterIt )
357 : {
358 287 : std::vector< ComplexCategory > aSingleLevel;
359 287 : std::vector< ComplexCategory >::iterator aIt( aOuterIt->begin() );
360 287 : std::vector< ComplexCategory >::const_iterator aEnd( aOuterIt->end() );
361 1839 : for( ; aIt != aEnd; ++aIt )
362 : {
363 1552 : ComplexCategory aComplexCategory( *aIt );
364 1552 : sal_Int32 nCount = aComplexCategory.Count;
365 4388 : while( nCount-- )
366 1284 : aSingleLevel.push_back(aComplexCategory);
367 1552 : }
368 287 : aComplexCatsPerIndex.push_back( aSingleLevel );
369 287 : }
370 :
371 287 : if(nMaxCategoryCount)
372 : {
373 268 : aRet.realloc(nMaxCategoryCount);
374 268 : aOuterEnd = aComplexCatsPerIndex.end();
375 268 : OUString aSpace(" ");
376 1552 : for(sal_Int32 nN=0; nN<nMaxCategoryCount; nN++)
377 : {
378 1284 : OUString aText;
379 2568 : for( aOuterIt=aComplexCatsPerIndex.begin() ; aOuterIt != aOuterEnd; ++aOuterIt )
380 : {
381 1284 : if ( static_cast<size_t>(nN) < aOuterIt->size() )
382 : {
383 1284 : OUString aAddText = (*aOuterIt)[nN].Text;
384 1284 : if( !aAddText.isEmpty() )
385 : {
386 1284 : if(!aText.isEmpty())
387 0 : aText += aSpace;
388 1284 : aText += aAddText;
389 1284 : }
390 : }
391 : }
392 1284 : aRet[nN]=aText;
393 1552 : }
394 : }
395 574 : return aRet;
396 : }
397 :
398 287 : Sequence< OUString > ExplicitCategoriesProvider::getExplicitSimpleCategories(
399 : const SplitCategoriesProvider& rSplitCategoriesProvider )
400 : {
401 287 : vector< vector< ComplexCategory > > aComplexCats;
402 287 : return lcl_getExplicitSimpleCategories( rSplitCategoriesProvider, aComplexCats );
403 : }
404 :
405 : struct DatePlusIndexComparator
406 : {
407 17366 : inline bool operator() ( const DatePlusIndex& aFirst,
408 : const DatePlusIndex& aSecond ) const
409 : {
410 17366 : return ( aFirst.fValue < aSecond.fValue );
411 : }
412 : };
413 :
414 2553 : bool lcl_fillDateCategories( const uno::Reference< data::XDataSequence >& xDataSequence, std::vector< DatePlusIndex >& rDateCategories, bool bIsAutoDate, ChartModel& rModel )
415 : {
416 2553 : bool bOnlyDatesFound = true;
417 2553 : bool bAnyDataFound = false;
418 :
419 2553 : if( xDataSequence.is() )
420 : {
421 2551 : uno::Sequence< uno::Any > aValues = xDataSequence->getData();
422 2551 : sal_Int32 nCount = aValues.getLength();
423 2551 : rDateCategories.reserve(nCount);
424 5102 : Reference< util::XNumberFormats > xNumberFormats;
425 2551 : xNumberFormats = Reference< util::XNumberFormats >( rModel.getNumberFormats() );
426 :
427 2551 : bool bOwnData = false;
428 2551 : bool bOwnDataAnddAxisHasAnyFormat = false;
429 2551 : bool bOwnDataAnddAxisHasDateFormat = false;
430 5102 : Reference< XCoordinateSystem > xCooSysModel( ChartModelHelper::getFirstCoordinateSystem( rModel ) );
431 2551 : if( xCooSysModel.is() )
432 : {
433 2551 : if( rModel.hasInternalDataProvider() )
434 : {
435 2384 : bOwnData = true;
436 2384 : Reference< beans::XPropertySet > xAxisProps( xCooSysModel->getAxisByDimension(0,0), uno::UNO_QUERY );
437 2384 : sal_Int32 nAxisNumberFormat = 0;
438 2384 : if (xAxisProps.is() && (xAxisProps->getPropertyValue(CHART_UNONAME_NUMFMT) >>= nAxisNumberFormat))
439 : {
440 2287 : bOwnDataAnddAxisHasAnyFormat = true;
441 2287 : bOwnDataAnddAxisHasDateFormat = DiagramHelper::isDateNumberFormat( nAxisNumberFormat, xNumberFormats );
442 2384 : }
443 : }
444 : }
445 :
446 13785 : for(sal_Int32 nN=0;nN<nCount;nN++)
447 : {
448 11234 : bool bIsDate = false;
449 11234 : if( bIsAutoDate )
450 : {
451 11234 : if( bOwnData )
452 9871 : bIsDate = !bOwnDataAnddAxisHasAnyFormat || bOwnDataAnddAxisHasDateFormat;
453 : else
454 1363 : bIsDate = DiagramHelper::isDateNumberFormat( xDataSequence->getNumberFormatKeyByIndex( nN ), xNumberFormats );
455 : }
456 : else
457 0 : bIsDate = true;
458 :
459 11234 : bool bContainsEmptyString = false;
460 11234 : uno::Any aAny = aValues[nN];
461 11234 : if( aAny.hasValue() )
462 : {
463 11234 : OUString aTest;
464 11234 : double fTest = 0;
465 11234 : bool bContainsNan = false;
466 11234 : if( (aAny>>=aTest) && aTest.isEmpty() ) //empty String
467 3 : bContainsEmptyString = true;
468 11231 : else if( (aAny>>=fTest) && ::rtl::math::isNan(fTest) )
469 0 : bContainsNan = true;
470 :
471 11234 : if( !bContainsEmptyString && !bContainsNan )
472 11231 : bAnyDataFound = true;
473 : }
474 11234 : DatePlusIndex aDatePlusIndex( 1.0, nN );
475 11234 : if( bIsDate && (aAny >>= aDatePlusIndex.fValue) )
476 0 : rDateCategories.push_back( aDatePlusIndex );
477 : else
478 : {
479 11234 : if( aAny.hasValue() && !bContainsEmptyString )//empty string does not count as non date value!
480 11231 : bOnlyDatesFound=false;
481 11234 : ::rtl::math::setNan( &aDatePlusIndex.fValue );
482 11234 : rDateCategories.push_back( aDatePlusIndex );
483 : }
484 11234 : }
485 5102 : ::std::sort( rDateCategories.begin(), rDateCategories.end(), DatePlusIndexComparator() );
486 : }
487 :
488 2553 : return bAnyDataFound && bOnlyDatesFound;
489 : }
490 :
491 11897 : void ExplicitCategoriesProvider::init()
492 : {
493 11897 : if( m_bDirty )
494 : {
495 2873 : m_aComplexCats.clear();//not one per index
496 2873 : m_aDateCategories.clear();
497 :
498 2873 : if( m_xOriginalCategories.is() )
499 : {
500 2653 : if( !hasComplexCategories() )
501 : {
502 2653 : if(m_bIsDateAxis)
503 : {
504 2564 : if( ChartTypeHelper::isSupportingDateAxis( AxisHelper::getChartTypeByIndex( m_xCooSysModel, 0 ), 2, 0 ) )
505 2553 : m_bIsDateAxis = lcl_fillDateCategories( m_xOriginalCategories->getValues(), m_aDateCategories, m_bIsAutoDate, mrModel );
506 : else
507 11 : m_bIsDateAxis = false;
508 : }
509 : }
510 : else
511 : {
512 0 : m_bIsDateAxis = false;
513 : }
514 : }
515 : else
516 220 : m_bIsDateAxis=false;
517 2873 : m_bDirty = false;
518 : }
519 11897 : }
520 :
521 2359 : Sequence< OUString > ExplicitCategoriesProvider::getSimpleCategories()
522 : {
523 2359 : if( !m_bIsExplicitCategoriesInited )
524 : {
525 1006 : init();
526 1006 : m_aExplicitCategories.realloc(0);
527 1006 : if( m_xOriginalCategories.is() )
528 : {
529 914 : if( !hasComplexCategories() )
530 : {
531 914 : uno::Reference< data::XDataSequence > xDataSequence( m_xOriginalCategories->getValues() );
532 914 : if( xDataSequence.is() )
533 913 : 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 1006 : if(!m_aExplicitCategories.getLength())
542 93 : m_aExplicitCategories = DiagramHelper::generateAutomaticCategoriesFromCooSys( m_xCooSysModel );
543 1006 : m_bIsExplicitCategoriesInited = true;
544 : }
545 2359 : 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 10891 : bool ExplicitCategoriesProvider::isDateAxis()
573 : {
574 10891 : init();
575 10891 : 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 : } //namespace chart
585 :
586 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|