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