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