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 <ChartTypeHelper.hxx>
21 #include <DiagramHelper.hxx>
22 #include <servicenames_charttypes.hxx>
23 
24 #include <com/sun/star/beans/XPropertySet.hpp>
25 #include <com/sun/star/chart/DataLabelPlacement.hpp>
26 #include <com/sun/star/chart2/AxisType.hpp>
27 #include <com/sun/star/chart2/StackingDirection.hpp>
28 #include <com/sun/star/chart/MissingValueTreatment.hpp>
29 #include <tools/diagnose_ex.h>
30 
31 using namespace ::com::sun::star;
32 using namespace ::com::sun::star::chart2;
33 
34 namespace chart
35 {
36 
37 bool ChartTypeHelper::isSupportingAxisSideBySide(
38     const uno::Reference< chart2::XChartType >& xChartType, sal_Int32 nDimensionCount )
39 {
40     bool bResult = false;
41 
42     if( xChartType.is() &&
43         nDimensionCount < 3 )
44     {
45         bool bFound=false;
46         bool bAmbiguous=false;
47         StackMode eStackMode = DiagramHelper::getStackModeFromChartType( xChartType, bFound, bAmbiguous, nullptr );
48         if( eStackMode == StackMode::NONE && !bAmbiguous )
49         {
50             OUString aChartTypeName = xChartType->getChartType();
51             bResult = ( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_COLUMN) ||
52                         aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BAR) );
53         }
54     }
55 
56     return bResult;
57 }
58 
59 bool ChartTypeHelper::isSupportingGeometryProperties( const uno::Reference< XChartType >& xChartType, sal_Int32 nDimensionCount )
60 {
61     //form tab only for 3D-bar and 3D-column charts.
62 
63     //@todo ask charttype itself --> need model change first
64     if(xChartType.is())
65     {
66         if(nDimensionCount==3)
67         {
68             OUString aChartTypeName = xChartType->getChartType();
69             if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_BAR )
70                 return true;
71             if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_COLUMN )
72                 return true;
73         }
74     }
75     return false;
76 }
77 
78 bool ChartTypeHelper::isSupportingStatisticProperties( const uno::Reference< XChartType >& xChartType, sal_Int32 nDimensionCount )
79 {
80     //3D charts, pie, net and stock do not support statistic properties
81 
82     //@todo ask charttype itself (and series? --> stock chart?)  --> need model change first
83     if(xChartType.is())
84     {
85         if(nDimensionCount==3)
86             return false;
87 
88         OUString aChartTypeName = xChartType->getChartType();
89         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
90             return false;
91         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_NET) )
92             return false;
93         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET) )
94             return false;
95         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) )
96             return false;
97         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE) ) //todo: BubbleChart support error bars and trend lines
98             return false;
99     }
100     return true;
101 }
102 
103 bool ChartTypeHelper::isSupportingRegressionProperties( const uno::Reference< XChartType >& xChartType, sal_Int32 nDimensionCount )
104 {
105     // note: old chart: only scatter chart
106     return isSupportingStatisticProperties( xChartType, nDimensionCount );
107 }
108 
109 bool ChartTypeHelper::isSupportingAreaProperties( const uno::Reference< XChartType >& xChartType, sal_Int32 nDimensionCount )
110 {
111     //2D line charts, net and stock do not support area properties
112 
113     //@todo ask charttype itself --> need model change first
114     if(xChartType.is())
115     {
116          if(nDimensionCount==2)
117         {
118             OUString aChartTypeName = xChartType->getChartType();
119             if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_LINE) )
120                 return false;
121             if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER) )
122                 return false;
123             if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_NET) )
124                 return false;
125             if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) )
126                 return false;
127         }
128     }
129     return true;
130 }
131 
132 bool ChartTypeHelper::isSupportingSymbolProperties( const uno::Reference< XChartType >& xChartType, sal_Int32 nDimensionCount )
133 {
134     //2D line charts, 2D scatter charts and 2D net charts do support symbols
135 
136     //@todo ask charttype itself --> need model change first
137     if(xChartType.is())
138     {
139         if(nDimensionCount==3)
140             return false;
141 
142         OUString aChartTypeName = xChartType->getChartType();
143         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_LINE) )
144             return true;
145         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER) )
146             return true;
147         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_NET) )
148             return true;
149     }
150     return false;
151 }
152 
153 bool ChartTypeHelper::isSupportingMainAxis( const uno::Reference< XChartType >& xChartType, sal_Int32 nDimensionCount, sal_Int32 nDimensionIndex )
154 {
155     //pie charts do not support axis at all
156     //no 3rd axis for 2D charts
157 
158     //@todo ask charttype itself --> need model change first
159     if(xChartType.is())
160     {
161         OUString aChartTypeName = xChartType->getChartType();
162         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
163             return false;
164 
165         if( nDimensionIndex == 2 )
166             return nDimensionCount == 3;
167     }
168     return true;
169 }
170 
171 bool ChartTypeHelper::isSupportingSecondaryAxis( const uno::Reference< XChartType >& xChartType, sal_Int32 nDimensionCount )
172 {
173     //3D, pie and net charts do not support a secondary axis at all
174 
175     //@todo ask charttype itself --> need model change first
176     if(xChartType.is())
177     {
178         if(nDimensionCount==3)
179             return false;
180 
181         OUString aChartTypeName = xChartType->getChartType();
182         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
183             return false;
184         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_NET) )
185             return false;
186         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET) )
187             return false;
188     }
189     return true;
190 }
191 
192 bool ChartTypeHelper::isSupportingOverlapAndGapWidthProperties(
193         const uno::Reference< XChartType >& xChartType, sal_Int32 nDimensionCount )
194 {
195     //2D bar charts do support a this special properties
196 
197     //@todo ask charttype itself --> need model change first
198     if(xChartType.is())
199     {
200         if(nDimensionCount==3)
201             return false;
202 
203         OUString aChartTypeName = xChartType->getChartType();
204         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_COLUMN) )
205             return true;
206         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BAR) )
207             return true;
208     }
209     return false;
210 }
211 
212 bool ChartTypeHelper::isSupportingBarConnectors(
213     const uno::Reference< chart2::XChartType >& xChartType, sal_Int32 nDimensionCount )
214 {
215     //2D bar charts with stacked series support this
216 
217     //@todo ask charttype itself --> need model change first
218     if(xChartType.is())
219     {
220         if(nDimensionCount==3)
221             return false;
222 
223         bool bFound=false;
224         bool bAmbiguous=false;
225         StackMode eStackMode = DiagramHelper::getStackModeFromChartType( xChartType, bFound, bAmbiguous, nullptr );
226         if( eStackMode != StackMode::YStacked || bAmbiguous )
227             return false;
228 
229         OUString aChartTypeName = xChartType->getChartType();
230         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_COLUMN) )
231             return true;
232         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BAR) )
233             return true;  // note: old chart was false here
234     }
235     return false;
236 }
237 
238 uno::Sequence < sal_Int32 > ChartTypeHelper::getSupportedLabelPlacements( const uno::Reference< chart2::XChartType >& xChartType
239                                                                          , bool bSwapXAndY
240                                                                          , const uno::Reference< chart2::XDataSeries >& xSeries )
241 {
242     uno::Sequence < sal_Int32 > aRet;
243     if( !xChartType.is() )
244         return aRet;
245 
246     OUString aChartTypeName = xChartType->getChartType();
247     if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
248     {
249         bool bDonut = false;
250         uno::Reference< beans::XPropertySet > xChartTypeProp( xChartType, uno::UNO_QUERY_THROW );
251         xChartTypeProp->getPropertyValue( "UseRings") >>= bDonut;
252 
253         if(!bDonut)
254         {
255             aRet.realloc(4);
256             sal_Int32* pSeq = aRet.getArray();
257             *pSeq++ = css::chart::DataLabelPlacement::AVOID_OVERLAP;
258             *pSeq++ = css::chart::DataLabelPlacement::OUTSIDE;
259             *pSeq++ = css::chart::DataLabelPlacement::INSIDE;
260             *pSeq++ = css::chart::DataLabelPlacement::CENTER;
261         }
262         else
263         {
264             aRet.realloc(1);
265             sal_Int32* pSeq = aRet.getArray();
266             *pSeq++ = css::chart::DataLabelPlacement::CENTER;
267         }
268     }
269     else if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER)
270         || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_LINE)
271         || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE)
272         )
273     {
274         aRet.realloc(5);
275         sal_Int32* pSeq = aRet.getArray();
276         *pSeq++ = css::chart::DataLabelPlacement::TOP;
277         *pSeq++ = css::chart::DataLabelPlacement::BOTTOM;
278         *pSeq++ = css::chart::DataLabelPlacement::LEFT;
279         *pSeq++ = css::chart::DataLabelPlacement::RIGHT;
280         *pSeq++ = css::chart::DataLabelPlacement::CENTER;
281     }
282     else if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_COLUMN)
283         || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BAR) )
284     {
285 
286         bool bStacked = false;
287         {
288             uno::Reference< beans::XPropertySet > xSeriesProp( xSeries, uno::UNO_QUERY );
289             chart2::StackingDirection eStacking = chart2::StackingDirection_NO_STACKING;
290             xSeriesProp->getPropertyValue( "StackingDirection" ) >>= eStacking;
291             bStacked = (eStacking == chart2::StackingDirection_Y_STACKING);
292         }
293 
294         aRet.realloc( bStacked ? 3 : 6 );
295         sal_Int32* pSeq = aRet.getArray();
296         if(!bStacked)
297         {
298             if(bSwapXAndY)
299             {
300                 *pSeq++ = css::chart::DataLabelPlacement::RIGHT;
301                 *pSeq++ = css::chart::DataLabelPlacement::LEFT;
302             }
303             else
304             {
305                 *pSeq++ = css::chart::DataLabelPlacement::TOP;
306                 *pSeq++ = css::chart::DataLabelPlacement::BOTTOM;
307             }
308         }
309         *pSeq++ = css::chart::DataLabelPlacement::CENTER;
310         if(!bStacked)
311             *pSeq++ = css::chart::DataLabelPlacement::OUTSIDE;
312         *pSeq++ = css::chart::DataLabelPlacement::INSIDE;
313         *pSeq++ = css::chart::DataLabelPlacement::NEAR_ORIGIN;
314     }
315     else if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_AREA) )
316     {
317         aRet.realloc(1);
318         sal_Int32* pSeq = aRet.getArray();
319         *pSeq++ = css::chart::DataLabelPlacement::TOP;
320     }
321     else if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_NET) )
322     {
323         aRet.realloc(6);
324         sal_Int32* pSeq = aRet.getArray();
325         *pSeq++ = css::chart::DataLabelPlacement::OUTSIDE;
326         *pSeq++ = css::chart::DataLabelPlacement::TOP;
327         *pSeq++ = css::chart::DataLabelPlacement::BOTTOM;
328         *pSeq++ = css::chart::DataLabelPlacement::LEFT;
329         *pSeq++ = css::chart::DataLabelPlacement::RIGHT;
330         *pSeq++ = css::chart::DataLabelPlacement::CENTER;
331     }
332     else if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET) )
333     {
334         aRet.realloc(1);
335         sal_Int32* pSeq = aRet.getArray();
336         *pSeq++ = css::chart::DataLabelPlacement::OUTSIDE;
337     }
338     else if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) )
339     {
340         aRet.realloc( 1 );
341         sal_Int32* pSeq = aRet.getArray();
342         *pSeq++ = css::chart::DataLabelPlacement::OUTSIDE;
343     }
344     else
345     {
346         OSL_FAIL( "unknown charttype" );
347     }
348 
349     return aRet;
350 }
351 
352 bool ChartTypeHelper::isSupportingRightAngledAxes( const uno::Reference< chart2::XChartType >& xChartType )
353 {
354     if(xChartType.is())
355     {
356         OUString aChartTypeName = xChartType->getChartType();
357         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
358             return false;
359     }
360     return true;
361 }
362 
363 bool ChartTypeHelper::isSupportingStartingAngle( const uno::Reference< chart2::XChartType >& xChartType )
364 {
365     if(xChartType.is())
366     {
367         OUString aChartTypeName = xChartType->getChartType();
368         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
369             return true;
370     }
371     return false;
372 }
373 bool ChartTypeHelper::isSupportingBaseValue( const uno::Reference< chart2::XChartType >& xChartType )
374 {
375     if(xChartType.is())
376     {
377         OUString aChartTypeName = xChartType->getChartType();
378         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_COLUMN)
379             || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BAR)
380             || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_AREA)
381             )
382             return true;
383     }
384     return false;
385 }
386 
387 bool ChartTypeHelper::isSupportingAxisPositioning( const uno::Reference< chart2::XChartType >& xChartType, sal_Int32 nDimensionCount, sal_Int32 nDimensionIndex )
388 {
389     if(xChartType.is())
390     {
391         OUString aChartTypeName = xChartType->getChartType();
392         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_NET) )
393             return false;
394         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET) )
395             return false;
396     }
397     if( nDimensionCount==3 )
398         return nDimensionIndex<2;
399     return true;
400 }
401 
402 bool ChartTypeHelper::isSupportingDateAxis( const uno::Reference< chart2::XChartType >& xChartType, sal_Int32 nDimensionIndex )
403 {
404     if( nDimensionIndex!=0 )
405         return false;
406     if( xChartType.is() )
407     {
408         sal_Int32 nType = ChartTypeHelper::getAxisType( xChartType, nDimensionIndex );
409         if( nType != AxisType::CATEGORY )
410             return false;
411         OUString aChartTypeName = xChartType->getChartType();
412         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
413             return false;
414         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_NET) )
415             return false;
416         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET) )
417             return false;
418     }
419     return true;
420 }
421 
422 bool ChartTypeHelper::shiftCategoryPosAtXAxisPerDefault( const uno::Reference< chart2::XChartType >& xChartType )
423 {
424     if(xChartType.is())
425     {
426         OUString aChartTypeName = xChartType->getChartType();
427         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_COLUMN)
428             || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BAR)
429             || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) )
430             return true;
431     }
432     return false;
433 }
434 
435 bool ChartTypeHelper::noBordersForSimpleScheme( const uno::Reference< chart2::XChartType >& xChartType )
436 {
437     if(xChartType.is())
438     {
439         OUString aChartTypeName = xChartType->getChartType();
440         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
441             return true;
442     }
443     return false;
444 }
445 
446 sal_Int32 ChartTypeHelper::getDefaultDirectLightColor( bool bSimple, const uno::Reference< chart2::XChartType >& xChartType )
447 {
448     sal_Int32 nRet = static_cast< sal_Int32 >( 0x808080 ); // grey
449     if( xChartType .is() )
450     {
451         OUString aChartType = xChartType->getChartType();
452         if( aChartType == CHART2_SERVICE_NAME_CHARTTYPE_PIE )
453         {
454             if( bSimple )
455                 nRet = static_cast< sal_Int32 >( 0x333333 ); // grey80
456             else
457                 nRet = static_cast< sal_Int32 >( 0xb3b3b3 ); // grey30
458         }
459         else if( aChartType == CHART2_SERVICE_NAME_CHARTTYPE_LINE
460             || aChartType == CHART2_SERVICE_NAME_CHARTTYPE_SCATTER )
461             nRet = static_cast< sal_Int32 >( 0x666666 ); // grey60
462     }
463     return nRet;
464 }
465 
466 sal_Int32 ChartTypeHelper::getDefaultAmbientLightColor( bool bSimple, const uno::Reference< chart2::XChartType >& xChartType )
467 {
468     sal_Int32 nRet = static_cast< sal_Int32 >( 0x999999 ); // grey40
469     if( xChartType .is() )
470     {
471         OUString aChartType = xChartType->getChartType();
472         if( aChartType == CHART2_SERVICE_NAME_CHARTTYPE_PIE )
473         {
474             if( bSimple )
475                 nRet = static_cast< sal_Int32 >( 0xcccccc ); // grey20
476             else
477                 nRet = static_cast< sal_Int32 >( 0x666666 ); // grey60
478         }
479     }
480     return nRet;
481 }
482 
483 drawing::Direction3D ChartTypeHelper::getDefaultSimpleLightDirection( const uno::Reference< chart2::XChartType >& xChartType )
484 {
485     drawing::Direction3D aRet(0.0, 0.0, 1.0);
486     if( xChartType .is() )
487     {
488         OUString aChartType = xChartType->getChartType();
489         if( aChartType == CHART2_SERVICE_NAME_CHARTTYPE_PIE )
490             aRet = drawing::Direction3D(0.0, 0.8, 0.5);
491         else if( aChartType == CHART2_SERVICE_NAME_CHARTTYPE_LINE
492             || aChartType == CHART2_SERVICE_NAME_CHARTTYPE_SCATTER )
493             aRet = drawing::Direction3D(0.9, 0.5, 0.05);
494     }
495     return aRet;
496 }
497 
498 drawing::Direction3D ChartTypeHelper::getDefaultRealisticLightDirection( const uno::Reference< chart2::XChartType >& xChartType )
499 {
500     drawing::Direction3D aRet(0.0, 0.0, 1.0);
501     if( xChartType .is() )
502     {
503         OUString aChartType = xChartType->getChartType();
504         if( aChartType == CHART2_SERVICE_NAME_CHARTTYPE_PIE )
505             aRet = drawing::Direction3D(0.6, 0.6, 0.6);
506         else if( aChartType == CHART2_SERVICE_NAME_CHARTTYPE_LINE
507             || aChartType == CHART2_SERVICE_NAME_CHARTTYPE_SCATTER )
508             aRet = drawing::Direction3D(0.9, 0.5, 0.05);
509     }
510     return aRet;
511 }
512 
513 sal_Int32 ChartTypeHelper::getAxisType( const uno::Reference<
514             XChartType >& xChartType, sal_Int32 nDimensionIndex )
515 {
516     //returned is a constant from constant group css::chart2::AxisType
517 
518     //@todo ask charttype itself --> need model change first
519     if(!xChartType.is())
520         return AxisType::CATEGORY;
521 
522     OUString aChartTypeName = xChartType->getChartType();
523     if(nDimensionIndex==2)//z-axis
524         return AxisType::SERIES;
525     if(nDimensionIndex==1)//y-axis
526         return AxisType::REALNUMBER;
527     if(nDimensionIndex==0)//x-axis
528     {
529         if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER)
530          || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE) )
531             return AxisType::REALNUMBER;
532         return AxisType::CATEGORY;
533     }
534     return AxisType::CATEGORY;
535 }
536 
537 sal_Int32 ChartTypeHelper::getNumberOfDisplayedSeries(
538     const uno::Reference< XChartType >& xChartType,
539     sal_Int32 nNumberOfSeries )
540 {
541     if( xChartType.is() )
542     {
543         try
544         {
545             OUString aChartTypeName = xChartType->getChartType();
546             if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_PIE )
547             {
548                 uno::Reference< beans::XPropertySet > xChartTypeProp( xChartType, uno::UNO_QUERY_THROW );
549                 bool bDonut = false;
550                 if( (xChartTypeProp->getPropertyValue( "UseRings") >>= bDonut)
551                     && !bDonut )
552                 {
553                     return nNumberOfSeries>0 ? 1 : 0;
554                 }
555             }
556         }
557         catch( const uno::Exception & )
558         {
559             DBG_UNHANDLED_EXCEPTION("chart2");
560         }
561     }
562     return nNumberOfSeries;
563 }
564 
565 uno::Sequence < sal_Int32 > ChartTypeHelper::getSupportedMissingValueTreatments( const uno::Reference< XChartType >& xChartType )
566 {
567     uno::Sequence < sal_Int32 > aRet;
568     if( !xChartType.is() )
569         return aRet;
570 
571     bool bFound=false;
572     bool bAmbiguous=false;
573     StackMode eStackMode = DiagramHelper::getStackModeFromChartType( xChartType, bFound, bAmbiguous, nullptr );
574     bool bStacked = bFound && (eStackMode == StackMode::YStacked);
575 
576     OUString aChartTypeName = xChartType->getChartType();
577     if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_COLUMN) ||
578         aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BAR) ||
579         aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE) )
580     {
581         aRet.realloc( 2 );
582         sal_Int32* pSeq = aRet.getArray();
583         *pSeq++ = css::chart::MissingValueTreatment::LEAVE_GAP;
584         *pSeq++ = css::chart::MissingValueTreatment::USE_ZERO;
585     }
586     else if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_AREA) )
587     {
588         aRet.realloc( bStacked ? 1 : 2 );
589         sal_Int32* pSeq = aRet.getArray();
590         *pSeq++ = css::chart::MissingValueTreatment::USE_ZERO;
591         if( !bStacked )
592             *pSeq++ = css::chart::MissingValueTreatment::CONTINUE;
593     }
594     else if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_LINE) ||
595         aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_NET) ||
596         aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET) )
597     {
598         aRet.realloc( bStacked ? 2 : 3 );
599         sal_Int32* pSeq = aRet.getArray();
600         *pSeq++ = css::chart::MissingValueTreatment::LEAVE_GAP;
601         *pSeq++ = css::chart::MissingValueTreatment::USE_ZERO;
602         if( !bStacked )
603             *pSeq++ = css::chart::MissingValueTreatment::CONTINUE;
604     }
605     else if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER) )
606     {
607         aRet.realloc( 3 );
608         sal_Int32* pSeq = aRet.getArray();
609         *pSeq++ = css::chart::MissingValueTreatment::CONTINUE;
610         *pSeq++ = css::chart::MissingValueTreatment::LEAVE_GAP;
611         *pSeq++ = css::chart::MissingValueTreatment::USE_ZERO;
612     }
613     else if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_PIE) ||
614         aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) )
615     {
616         aRet.realloc( 0 );
617     }
618     else
619     {
620         OSL_FAIL( "unknown charttype" );
621     }
622 
623     return aRet;
624 }
625 
626 bool ChartTypeHelper::isSeriesInFrontOfAxisLine( const uno::Reference< XChartType >& xChartType )
627 {
628     if( xChartType.is() )
629     {
630         OUString aChartTypeName = xChartType->getChartType();
631         if( aChartTypeName.match( CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET ) )
632             return false;
633     }
634     return true;
635 }
636 
637 OUString ChartTypeHelper::getRoleOfSequenceForYAxisNumberFormatDetection( const uno::Reference< XChartType >& xChartType )
638 {
639     OUString aRet( "values-y" );
640     if( !xChartType.is() )
641         return aRet;
642     OUString aChartTypeName = xChartType->getChartType();
643     if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) )
644         aRet = xChartType->getRoleOfSequenceForSeriesLabel();
645     return aRet;
646 }
647 
648 OUString ChartTypeHelper::getRoleOfSequenceForDataLabelNumberFormatDetection( const uno::Reference< XChartType >& xChartType )
649 {
650     OUString aRet( "values-y" );
651     if( !xChartType.is() )
652         return aRet;
653     OUString aChartTypeName = xChartType->getChartType();
654     if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK)
655         || aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE) )
656         aRet = xChartType->getRoleOfSequenceForSeriesLabel();
657     return aRet;
658 }
659 
660 bool ChartTypeHelper::shouldLabelNumberFormatKeyBeDetectedFromYAxis( const uno::Reference< XChartType >& xChartType )
661 {
662     bool bRet = true;
663     OUString aChartTypeName = xChartType->getChartType();
664     if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE) )
665         bRet = false;
666     return bRet;
667 }
668 
669 bool ChartTypeHelper::isSupportingOnlyDeepStackingFor3D( const uno::Reference< XChartType >& xChartType )
670 {
671     bool bRet = false;
672     if( !xChartType.is() )
673         return bRet;
674 
675     OUString aChartTypeName = xChartType->getChartType();
676     if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_LINE) ||
677         aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER) ||
678         aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_AREA) )
679     {
680         bRet = true;
681     }
682     return bRet;
683 }
684 
685 } //namespace chart
686 
687 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
688