1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "drawingml/chart/typegroupconverter.hxx"
22 #include <com/sun/star/chart/DataLabelPlacement.hpp>
23 #include <com/sun/star/chart2/CartesianCoordinateSystem2d.hpp>
24 #include <com/sun/star/chart2/CartesianCoordinateSystem3d.hpp>
25 #include <com/sun/star/chart2/PolarCoordinateSystem2d.hpp>
26 #include <com/sun/star/chart2/PolarCoordinateSystem3d.hpp>
27 #include <com/sun/star/chart2/CurveStyle.hpp>
28 #include <com/sun/star/chart2/DataPointGeometry3D.hpp>
29 #include <com/sun/star/chart2/StackingDirection.hpp>
30 #include <com/sun/star/chart2/Symbol.hpp>
31 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
32 #include <com/sun/star/chart2/XCoordinateSystem.hpp>
33 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
34 #include <com/sun/star/chart2/data/XDataSink.hpp>
35 #include <com/sun/star/drawing/LineStyle.hpp>
36 #include <osl/diagnose.h>
37 #include "oox/drawingml/lineproperties.hxx"
38 #include "drawingml/chart/seriesconverter.hxx"
39 #include "drawingml/chart/typegroupmodel.hxx"
40 #include "oox/helper/containerhelper.hxx"
46 using namespace ::com::sun::star::beans
;
47 using namespace ::com::sun::star::chart2
;
48 using namespace ::com::sun::star::chart2::data
;
49 using namespace ::com::sun::star::uno
;
53 // chart type service names
54 const sal_Char SERVICE_CHART2_AREA
[] = "com.sun.star.chart2.AreaChartType";
55 const sal_Char SERVICE_CHART2_CANDLE
[] = "com.sun.star.chart2.CandleStickChartType";
56 const sal_Char SERVICE_CHART2_COLUMN
[] = "com.sun.star.chart2.ColumnChartType";
57 const sal_Char SERVICE_CHART2_LINE
[] = "com.sun.star.chart2.LineChartType";
58 const sal_Char SERVICE_CHART2_NET
[] = "com.sun.star.chart2.NetChartType";
59 const sal_Char SERVICE_CHART2_FILLEDNET
[] = "com.sun.star.chart2.FilledNetChartType";
60 const sal_Char SERVICE_CHART2_PIE
[] = "com.sun.star.chart2.PieChartType";
61 const sal_Char SERVICE_CHART2_SCATTER
[] = "com.sun.star.chart2.ScatterChartType";
62 const sal_Char SERVICE_CHART2_BUBBLE
[] = "com.sun.star.chart2.BubbleChartType";
63 const sal_Char SERVICE_CHART2_SURFACE
[] = "com.sun.star.chart2.ColumnChartType"; // Todo
65 namespace csscd
= ::com::sun::star::chart::DataLabelPlacement
;
67 static const TypeGroupInfo spTypeInfos
[] =
69 // type-id type-category service varied-point-color default label pos comb2d supp3d polar area2d 1stvis xcateg swap stack revers betw picopt
70 { TYPEID_BAR
, TYPECATEGORY_BAR
, SERVICE_CHART2_COLUMN
, VARPOINTMODE_SINGLE
, csscd::OUTSIDE
, true, true, false, true, false, true, false, true, false, true, true },
71 { TYPEID_HORBAR
, TYPECATEGORY_BAR
, SERVICE_CHART2_COLUMN
, VARPOINTMODE_SINGLE
, csscd::OUTSIDE
, false, true, false, true, false, true, true, true, false, true, true },
72 { TYPEID_LINE
, TYPECATEGORY_LINE
, SERVICE_CHART2_LINE
, VARPOINTMODE_SINGLE
, csscd::RIGHT
, true, true, false, false, false, true, false, true, false, true, false },
73 { TYPEID_AREA
, TYPECATEGORY_LINE
, SERVICE_CHART2_AREA
, VARPOINTMODE_NONE
, csscd::CENTER
, true, true, false, true, false, true, false, true, true, false, false },
74 { TYPEID_STOCK
, TYPECATEGORY_LINE
, SERVICE_CHART2_CANDLE
, VARPOINTMODE_NONE
, csscd::RIGHT
, true, false, false, false, false, true, false, true, false, true, false },
75 { TYPEID_RADARLINE
, TYPECATEGORY_RADAR
, SERVICE_CHART2_NET
, VARPOINTMODE_SINGLE
, csscd::TOP
, false, false, true, false, false, true, false, false, false, false, false },
76 { TYPEID_RADARAREA
, TYPECATEGORY_RADAR
, SERVICE_CHART2_FILLEDNET
, VARPOINTMODE_NONE
, csscd::TOP
, false, false, true, true, false, true, false, false, true, false, false },
77 { TYPEID_PIE
, TYPECATEGORY_PIE
, SERVICE_CHART2_PIE
, VARPOINTMODE_MULTI
, csscd::AVOID_OVERLAP
, false, true, true, true, true, true, false, false, false, false, false },
78 { TYPEID_DOUGHNUT
, TYPECATEGORY_PIE
, SERVICE_CHART2_PIE
, VARPOINTMODE_MULTI
, csscd::AVOID_OVERLAP
, false, true, true, true, false, true, false, false, false, false, false },
79 { TYPEID_OFPIE
, TYPECATEGORY_PIE
, SERVICE_CHART2_PIE
, VARPOINTMODE_MULTI
, csscd::AVOID_OVERLAP
, false, true, true, true, true, true, false, false, false, false, false },
80 { TYPEID_SCATTER
, TYPECATEGORY_SCATTER
, SERVICE_CHART2_SCATTER
, VARPOINTMODE_SINGLE
, csscd::RIGHT
, true, true, false, false, false, false, false, false, false, false, false },
81 { TYPEID_BUBBLE
, TYPECATEGORY_SCATTER
, SERVICE_CHART2_BUBBLE
, VARPOINTMODE_SINGLE
, csscd::RIGHT
, false, false, false, true, false, false, false, false, false, false, false },
82 { TYPEID_SURFACE
, TYPECATEGORY_SURFACE
, SERVICE_CHART2_SURFACE
, VARPOINTMODE_NONE
, csscd::RIGHT
, false, true, false, true, false, true, false, false, false, false, false }
85 static const TypeGroupInfo saUnknownTypeInfo
=
86 { TYPEID_UNKNOWN
, TYPECATEGORY_BAR
, SERVICE_CHART2_COLUMN
, VARPOINTMODE_SINGLE
, csscd::OUTSIDE
, true, true, false, true, false, true, false, true, false, true, true };
88 const TypeGroupInfo
& lclGetTypeInfoFromTypeId( TypeId eTypeId
)
90 const TypeGroupInfo
* pEnd
= STATIC_ARRAY_END( spTypeInfos
);
91 for( const TypeGroupInfo
* pIt
= spTypeInfos
; pIt
!= pEnd
; ++pIt
)
92 if( pIt
->meTypeId
== eTypeId
)
94 OSL_ENSURE( eTypeId
== TYPEID_UNKNOWN
, "lclGetTypeInfoFromTypeId - unexpected chart type identifier" );
95 return saUnknownTypeInfo
;
100 const TypeGroupInfo
& GetTypeGroupInfo( TypeId eType
)
102 return lclGetTypeInfoFromTypeId(eType
);
105 UpDownBarsConverter::UpDownBarsConverter( const ConverterRoot
& rParent
, UpDownBarsModel
& rModel
) :
106 ConverterBase
< UpDownBarsModel
>( rParent
, rModel
)
110 UpDownBarsConverter::~UpDownBarsConverter()
114 void UpDownBarsConverter::convertFromModel( const Reference
< XChartType
>& rxChartType
)
116 PropertySet
aTypeProp( rxChartType
);
119 Reference
< XPropertySet
> xWhitePropSet
;
120 if( aTypeProp
.getProperty( xWhitePropSet
, PROP_WhiteDay
) )
122 PropertySet
aPropSet( xWhitePropSet
);
123 getFormatter().convertFrameFormatting( aPropSet
, mrModel
.mxUpBars
, OBJECTTYPE_UPBAR
);
127 Reference
< XPropertySet
> xBlackPropSet
;
128 if( aTypeProp
.getProperty( xBlackPropSet
, PROP_BlackDay
) )
130 PropertySet
aPropSet( xBlackPropSet
);
131 getFormatter().convertFrameFormatting( aPropSet
, mrModel
.mxDownBars
, OBJECTTYPE_DOWNBAR
);
135 TypeGroupConverter::TypeGroupConverter( const ConverterRoot
& rParent
, TypeGroupModel
& rModel
) :
136 ConverterBase
< TypeGroupModel
>( rParent
, rModel
),
139 TypeId eTypeId
= TYPEID_UNKNOWN
;
140 switch( mrModel
.mnTypeId
)
142 #define ENSURE_AXESCOUNT( min, max ) OSL_ENSURE( (min <= (int)mrModel.maAxisIds.size()) && ((int)mrModel.maAxisIds.size() <= max), "TypeGroupConverter::TypeGroupConverter - invalid axes count" )
143 case C_TOKEN( area3DChart
): ENSURE_AXESCOUNT( 2, 3 ); eTypeId
= TYPEID_AREA
; mb3dChart
= true; break;
144 case C_TOKEN( areaChart
): ENSURE_AXESCOUNT( 2, 2 ); eTypeId
= TYPEID_AREA
; mb3dChart
= false; break;
145 case C_TOKEN( bar3DChart
): ENSURE_AXESCOUNT( 2, 3 ); eTypeId
= TYPEID_BAR
; mb3dChart
= true; break;
146 case C_TOKEN( barChart
): ENSURE_AXESCOUNT( 2, 2 ); eTypeId
= TYPEID_BAR
; mb3dChart
= false; break;
147 case C_TOKEN( bubbleChart
): ENSURE_AXESCOUNT( 2, 2 ); eTypeId
= TYPEID_BUBBLE
; mb3dChart
= false; break;
148 case C_TOKEN( doughnutChart
): ENSURE_AXESCOUNT( 0, 0 ); eTypeId
= TYPEID_DOUGHNUT
; mb3dChart
= false; break;
149 case C_TOKEN( line3DChart
): ENSURE_AXESCOUNT( 3, 3 ); eTypeId
= TYPEID_LINE
; mb3dChart
= true; break;
150 case C_TOKEN( lineChart
): ENSURE_AXESCOUNT( 2, 2 ); eTypeId
= TYPEID_LINE
; mb3dChart
= false; break;
151 case C_TOKEN( ofPieChart
): ENSURE_AXESCOUNT( 0, 0 ); eTypeId
= TYPEID_OFPIE
; mb3dChart
= false; break;
152 case C_TOKEN( pie3DChart
): ENSURE_AXESCOUNT( 0, 0 ); eTypeId
= TYPEID_PIE
; mb3dChart
= true; break;
153 case C_TOKEN( pieChart
): ENSURE_AXESCOUNT( 0, 0 ); eTypeId
= TYPEID_PIE
; mb3dChart
= false; break;
154 case C_TOKEN( radarChart
): ENSURE_AXESCOUNT( 2, 2 ); eTypeId
= TYPEID_RADARLINE
; mb3dChart
= false; break;
155 case C_TOKEN( scatterChart
): ENSURE_AXESCOUNT( 2, 2 ); eTypeId
= TYPEID_SCATTER
; mb3dChart
= false; break;
156 case C_TOKEN( stockChart
): ENSURE_AXESCOUNT( 2, 2 ); eTypeId
= TYPEID_STOCK
; mb3dChart
= false; break;
157 case C_TOKEN( surface3DChart
): ENSURE_AXESCOUNT( 3, 3 ); eTypeId
= TYPEID_SURFACE
; mb3dChart
= true; break;
158 case C_TOKEN( surfaceChart
): ENSURE_AXESCOUNT( 2, 3 ); eTypeId
= TYPEID_SURFACE
; mb3dChart
= true; break; // 3D bar chart from all surface charts
159 default: OSL_FAIL( "TypeGroupConverter::TypeGroupConverter - unknown chart type" );
160 #undef ENSURE_AXESCOUNT
163 // special handling for some chart types
167 if( mrModel
.mnBarDir
== XML_bar
)
168 eTypeId
= TYPEID_HORBAR
;
170 case TYPEID_RADARLINE
:
171 if( mrModel
.mnRadarStyle
== XML_filled
)
172 eTypeId
= TYPEID_RADARAREA
;
175 // create a deep 3D bar chart from surface charts
176 mrModel
.mnGrouping
= XML_standard
;
181 // set the chart type info struct for the current chart type
182 maTypeInfo
= lclGetTypeInfoFromTypeId( eTypeId
);
185 TypeGroupConverter::~TypeGroupConverter()
189 bool TypeGroupConverter::isStacked() const
191 return maTypeInfo
.mbSupportsStacking
&& (mrModel
.mnGrouping
== XML_stacked
);
194 bool TypeGroupConverter::isPercent() const
196 return maTypeInfo
.mbSupportsStacking
&& (mrModel
.mnGrouping
== XML_percentStacked
);
199 bool TypeGroupConverter::isWall3dChart() const
201 return mb3dChart
&& (maTypeInfo
.meTypeCategory
!= TYPECATEGORY_PIE
);
204 bool TypeGroupConverter::isDeep3dChart() const
206 return isWall3dChart() && (mrModel
.mnGrouping
== XML_standard
);
209 bool TypeGroupConverter::isSeriesFrameFormat() const
211 return mb3dChart
|| maTypeInfo
.mbSeriesIsFrame2d
;
214 ObjectType
TypeGroupConverter::getSeriesObjectType() const
216 return mb3dChart
? OBJECTTYPE_FILLEDSERIES3D
:
217 (maTypeInfo
.mbSeriesIsFrame2d
? OBJECTTYPE_FILLEDSERIES2D
: OBJECTTYPE_LINEARSERIES2D
);
220 bool TypeGroupConverter::isReverseSeries() const
222 return maTypeInfo
.mbReverseSeries
&& !mb3dChart
&& !isStacked() && !isPercent();
225 OUString
TypeGroupConverter::getSingleSeriesTitle() const
227 OUString aSeriesTitle
;
228 if( !mrModel
.maSeries
.empty() && (maTypeInfo
.mbSingleSeriesVis
|| (mrModel
.maSeries
.size() == 1)) )
229 if( const TextModel
* pText
= mrModel
.maSeries
.front()->mxText
.get() )
230 if( const DataSequenceModel
* pDataSeq
= pText
->mxDataSeq
.get() )
231 if( !pDataSeq
->maData
.empty() )
232 pDataSeq
->maData
.begin()->second
>>= aSeriesTitle
;
236 Reference
< XCoordinateSystem
> TypeGroupConverter::createCoordinateSystem()
238 // create the coordinate system object
239 Reference
< css::uno::XComponentContext
> xContext
= getComponentContext();
240 Reference
< XCoordinateSystem
> xCoordSystem
;
241 if( maTypeInfo
.mbPolarCoordSystem
)
244 xCoordSystem
= css::chart2::PolarCoordinateSystem3d::create(xContext
);
246 xCoordSystem
= css::chart2::PolarCoordinateSystem2d::create(xContext
);
251 xCoordSystem
= css::chart2::CartesianCoordinateSystem3d::create(xContext
);
253 xCoordSystem
= css::chart2::CartesianCoordinateSystem2d::create(xContext
);
257 if( maTypeInfo
.mbSwappedAxesSet
)
259 PropertySet
aPropSet( xCoordSystem
);
260 aPropSet
.setProperty( PROP_SwapXAndYAxis
, true );
266 Reference
< XLabeledDataSequence
> TypeGroupConverter::createCategorySequence()
268 sal_Int32 nMaxValues
= 0;
269 Reference
< XLabeledDataSequence
> xLabeledSeq
;
270 /* Find first existing category sequence. The bahaviour of Excel 2007 is
271 different to Excel 2003, which always used the category sequence of the
272 first series, even if it was empty. */
273 for( TypeGroupModel::SeriesVector::iterator aIt
= mrModel
.maSeries
.begin(), aEnd
= mrModel
.maSeries
.end(); !xLabeledSeq
.is() && (aIt
!= aEnd
); ++aIt
)
275 if( (*aIt
)->maSources
.has( SeriesModel::CATEGORIES
) )
277 SeriesConverter
aSeriesConv( *this, **aIt
);
278 xLabeledSeq
= aSeriesConv
.createCategorySequence( "categories" );
280 else if( nMaxValues
<= 0 && (*aIt
)->maSources
.has( SeriesModel::VALUES
) )
282 DataSourceModel
*pValues
= (*aIt
)->maSources
.get( SeriesModel::VALUES
).get();
283 if( pValues
->mxDataSeq
.is() )
284 nMaxValues
= pValues
->mxDataSeq
.get()->maData
.size();
287 /* n#839727 Create Category Sequence when none are found */
288 if( !xLabeledSeq
.is() && mrModel
.maSeries
.size() > 0 ) {
291 SeriesModel
&aModel
= *mrModel
.maSeries
.get(0);
292 DataSourceModel
&aSrc
= aModel
.maSources
.create( SeriesModel::CATEGORIES
);
293 DataSequenceModel
&aSeq
= aSrc
.mxDataSeq
.create();
294 for( sal_Int32 i
= 0; i
< nMaxValues
; i
++ )
295 aSeq
.maData
[ i
] <<= OUString::number( i
+ 1 );
296 SeriesConverter
aSeriesConv( *this, aModel
);
297 xLabeledSeq
= aSeriesConv
.createCategorySequence( "categories" );
302 void TypeGroupConverter::convertFromModel( const Reference
< XDiagram
>& rxDiagram
,
303 const Reference
< XCoordinateSystem
>& rxCoordSystem
,
304 sal_Int32 nAxesSetIdx
, bool bSupportsVaryColorsByPoint
)
308 // create the chart type object
309 OUString aService
= OUString::createFromAscii( maTypeInfo
.mpcServiceName
);
310 Reference
< XChartType
> xChartType( createInstance( aService
), UNO_QUERY_THROW
);
312 // additional properties
313 PropertySet
aDiaProp( rxDiagram
);
314 PropertySet
aTypeProp( xChartType
);
315 switch( maTypeInfo
.meTypeCategory
)
317 case TYPECATEGORY_BAR
:
319 Sequence
< sal_Int32
> aInt32Seq( 2 );
320 aInt32Seq
[ 0 ] = aInt32Seq
[ 1 ] = mrModel
.mnOverlap
;
321 aTypeProp
.setProperty( PROP_OverlapSequence
, aInt32Seq
);
322 aInt32Seq
[ 0 ] = aInt32Seq
[ 1 ] = mrModel
.mnGapWidth
;
323 aTypeProp
.setProperty( PROP_GapwidthSequence
, aInt32Seq
);
326 case TYPECATEGORY_PIE
:
328 aTypeProp
.setProperty( PROP_UseRings
, maTypeInfo
.meTypeId
== TYPEID_DOUGHNUT
);
329 /* #i85166# starting angle of first pie slice. 3D pie charts
330 use Y rotation setting in view3D element. Of-pie charts do
331 not support pie rotation. */
332 if( !is3dChart() && (maTypeInfo
.meTypeId
!= TYPEID_OFPIE
) )
333 convertPieRotation( aDiaProp
, mrModel
.mnFirstAngle
);
339 // create converter objects for all series models
340 typedef RefVector
< SeriesConverter
> SeriesConvVector
;
341 SeriesConvVector aSeries
;
342 for( TypeGroupModel::SeriesVector::iterator aIt
= mrModel
.maSeries
.begin(), aEnd
= mrModel
.maSeries
.end(); aIt
!= aEnd
; ++aIt
)
343 aSeries
.push_back( SeriesConvVector::value_type( new SeriesConverter( *this, **aIt
) ) );
345 // reverse series order for some unstacked 2D chart types
346 if( isReverseSeries() )
347 ::std::reverse( aSeries
.begin(), aSeries
.end() );
349 // decide whether to use varying colors for each data point
350 bool bVaryColorsByPoint
= bSupportsVaryColorsByPoint
&& mrModel
.mbVaryColors
;
351 switch( maTypeInfo
.meVarPointMode
)
353 case VARPOINTMODE_NONE
: bVaryColorsByPoint
= false; break;
354 case VARPOINTMODE_SINGLE
: bVaryColorsByPoint
&= (mrModel
.maSeries
.size() == 1); break;
355 case VARPOINTMODE_MULTI
: break;
358 /* Stock chart needs special processing. Create one 'big' series with
359 data sequences of different roles. */
360 if( maTypeInfo
.meTypeId
== TYPEID_STOCK
)
362 // create the data series object
363 Reference
< XDataSeries
> xDataSeries( createInstance( "com.sun.star.chart2.DataSeries" ), UNO_QUERY
);
364 Reference
< XDataSink
> xDataSink( xDataSeries
, UNO_QUERY
);
367 // create a list of data sequences from all series
368 ::std::vector
< Reference
< XLabeledDataSequence
> > aLabeledSeqVec
;
369 OSL_ENSURE( aSeries
.size() >= 3, "TypeGroupConverter::convertFromModel - too few stock chart series" );
370 int nRoleIdx
= (aSeries
.size() == 3) ? 1 : 0;
371 for( SeriesConvVector::iterator aIt
= aSeries
.begin(), aEnd
= aSeries
.end(); (nRoleIdx
< 4) && (aIt
!= aEnd
); ++nRoleIdx
, ++aIt
)
373 // create a data sequence with a specific role
377 case 0: aRole
= "values-first"; break;
378 case 1: aRole
= "values-max"; break;
379 case 2: aRole
= "values-min"; break;
380 case 3: aRole
= "values-last"; break;
382 Reference
< XLabeledDataSequence
> xDataSeq
= (*aIt
)->createValueSequence( aRole
);
384 aLabeledSeqVec
.push_back( xDataSeq
);
387 // attach labeled data sequences to series and insert series into chart type
388 xDataSink
->setData( ContainerHelper::vectorToSequence( aLabeledSeqVec
) );
390 // formatting of high/low lines
391 aTypeProp
.setProperty( PROP_ShowHighLow
, true );
392 PropertySet
aSeriesProp( xDataSeries
);
393 if( mrModel
.mxHiLowLines
.is() )
394 getFormatter().convertFrameFormatting( aSeriesProp
, mrModel
.mxHiLowLines
, OBJECTTYPE_HILOLINE
);
396 // hi/low-lines cannot be switched off via "ShowHighLow" property (?)
397 aSeriesProp
.setProperty( PROP_LineStyle
, ::com::sun::star::drawing::LineStyle_NONE
);
399 // formatting of up/down bars
400 bool bUpDownBars
= mrModel
.mxUpDownBars
.is();
401 aTypeProp
.setProperty( PROP_Japanese
, bUpDownBars
);
402 aTypeProp
.setProperty( PROP_ShowFirst
, bUpDownBars
);
405 UpDownBarsConverter
aUpDownConv( *this, *mrModel
.mxUpDownBars
);
406 aUpDownConv
.convertFromModel( xChartType
);
409 // insert the series into the chart type object
410 insertDataSeries( xChartType
, xDataSeries
, nAxesSetIdx
);
415 for( SeriesConvVector::iterator aIt
= aSeries
.begin(), aEnd
= aSeries
.end(); aIt
!= aEnd
; ++aIt
)
417 SeriesConverter
& rSeriesConv
= **aIt
;
418 Reference
< XDataSeries
> xDataSeries
= rSeriesConv
.createDataSeries( *this, bVaryColorsByPoint
);
419 insertDataSeries( xChartType
, xDataSeries
, nAxesSetIdx
);
421 /* Excel does not use the value of the c:smooth element of the
422 chart type to set a default line smoothing for the data
423 series. Line smoothing is always controlled by the c:smooth
424 element of the respective data series. If the element in the
425 data series is missing, line smoothing is off, regardless of
426 the c:smooth element of the chart type. */
427 #if !OOX_CHART_SMOOTHED_PER_SERIES
428 if( rSeriesConv
.getModel().mbSmooth
)
429 convertLineSmooth( aTypeProp
, true );
434 // add chart type object to coordinate system
435 Reference
< XChartTypeContainer
> xChartTypeCont( rxCoordSystem
, UNO_QUERY_THROW
);
436 xChartTypeCont
->addChartType( xChartType
);
438 // set existence of bar connector lines at diagram (only in stacked 2D bar charts)
439 if( mrModel
.mxSerLines
.is() && !mb3dChart
&& (maTypeInfo
.meTypeCategory
== TYPECATEGORY_BAR
) && (isStacked() || isPercent()) )
440 aDiaProp
.setProperty( PROP_ConnectBars
, true );
444 OSL_FAIL( "TypeGroupConverter::convertFromModel - cannot add chart type" );
448 void TypeGroupConverter::convertMarker( PropertySet
& rPropSet
, sal_Int32 nOoxSymbol
, sal_Int32 nOoxSize
,
449 ModelRef
< Shape
> xShapeProps
) const
451 if( !isSeriesFrameFormat() )
453 namespace cssc
= ::com::sun::star::chart2
;
456 cssc::Symbol aSymbol
;
457 aSymbol
.Style
= cssc::SymbolStyle_STANDARD
;
458 switch( nOoxSymbol
) // compare with XclChPropSetHelper::WriteMarkerProperties in xlchart.cxx
460 case XML_auto
: aSymbol
.Style
= cssc::SymbolStyle_AUTO
; break;
461 case XML_none
: aSymbol
.Style
= cssc::SymbolStyle_NONE
; break;
462 case XML_square
: aSymbol
.StandardSymbol
= 0; break; // square
463 case XML_diamond
: aSymbol
.StandardSymbol
= 1; break; // diamond
464 case XML_triangle
: aSymbol
.StandardSymbol
= 3; break; // arrow up
465 case XML_x
: aSymbol
.StandardSymbol
= 10; break; // X, legacy bow tie
466 case XML_star
: aSymbol
.StandardSymbol
= 12; break; // asterisk, legacy sand glass
467 case XML_dot
: aSymbol
.StandardSymbol
= 4; break; // arrow right
468 case XML_dash
: aSymbol
.StandardSymbol
= 13; break; // horizontal bar, legacy arrow down
469 case XML_circle
: aSymbol
.StandardSymbol
= 8; break; // circle, legacy arrow right
470 case XML_plus
: aSymbol
.StandardSymbol
= 11; break; // plus, legacy arrow left
473 // symbol size (points in OOXML, 1/100 mm in Chart2)
474 sal_Int32 nSize
= static_cast< sal_Int32
>( nOoxSize
* (2540.0 / 72.0) + 0.5 );
475 aSymbol
.Size
.Width
= aSymbol
.Size
.Height
= nSize
;
479 Color aFillColor
= xShapeProps
->getFillProperties().maFillColor
;
480 aSymbol
.FillColor
= aFillColor
.getColor(getFilter().getGraphicHelper());
481 rPropSet
.setProperty(PROP_Color
, aSymbol
.FillColor
);
485 rPropSet
.setProperty( PROP_Symbol
, aSymbol
);
489 void TypeGroupConverter::convertLineSmooth( PropertySet
& rPropSet
, bool bOoxSmooth
) const
491 if( !isSeriesFrameFormat() && (maTypeInfo
.meTypeCategory
!= TYPECATEGORY_RADAR
) )
493 namespace cssc
= ::com::sun::star::chart2
;
494 cssc::CurveStyle eCurveStyle
= bOoxSmooth
? cssc::CurveStyle_CUBIC_SPLINES
: cssc::CurveStyle_LINES
;
495 rPropSet
.setProperty( PROP_CurveStyle
, eCurveStyle
);
499 void TypeGroupConverter::convertBarGeometry( PropertySet
& rPropSet
, sal_Int32 nOoxShape
) const
501 if( mb3dChart
&& (maTypeInfo
.meTypeCategory
== TYPECATEGORY_BAR
) )
503 namespace cssc
= ::com::sun::star::chart2
;
505 sal_Int32 nGeom3d
= cssc::DataPointGeometry3D::CUBOID
;
508 case XML_box
: nGeom3d
= cssc::DataPointGeometry3D::CUBOID
; break;
509 case XML_cone
: nGeom3d
= cssc::DataPointGeometry3D::CONE
; break;
510 case XML_coneToMax
: nGeom3d
= cssc::DataPointGeometry3D::CONE
; break;
511 case XML_cylinder
: nGeom3d
= cssc::DataPointGeometry3D::CYLINDER
; break;
512 case XML_pyramid
: nGeom3d
= cssc::DataPointGeometry3D::PYRAMID
; break;
513 case XML_pyramidToMax
: nGeom3d
= cssc::DataPointGeometry3D::PYRAMID
; break;
514 default: OSL_FAIL( "TypeGroupConverter::convertBarGeometry - unknown 3D bar shape type" );
516 rPropSet
.setProperty( PROP_Geometry3D
, nGeom3d
);
520 void TypeGroupConverter::convertPieRotation( PropertySet
& rPropSet
, sal_Int32 nOoxAngle
) const
522 if( maTypeInfo
.meTypeCategory
== TYPECATEGORY_PIE
)
524 // map OOXML [0,360] clockwise (0deg top) to Chart2 counterclockwise (0deg left)
525 sal_Int32 nAngle
= (450 - nOoxAngle
) % 360;
526 rPropSet
.setProperty( PROP_StartingAngle
, nAngle
);
530 void TypeGroupConverter::convertPieExplosion( PropertySet
& rPropSet
, sal_Int32 nOoxExplosion
) const
532 if( maTypeInfo
.meTypeCategory
== TYPECATEGORY_PIE
)
534 // pie explosion restricted to 100% in Chart2, set as double in range [0,1]
535 double fOffset
= getLimitedValue
< double >( nOoxExplosion
/ 100.0, 0.0, 1.0 );
536 rPropSet
.setProperty( PROP_Offset
, fOffset
);
540 // private --------------------------------------------------------------------
542 void TypeGroupConverter::insertDataSeries( const Reference
< XChartType
>& rxChartType
, const Reference
< XDataSeries
>& rxSeries
, sal_Int32 nAxesSetIdx
)
546 PropertySet
aSeriesProp( rxSeries
);
548 // series stacking mode
549 namespace cssc
= ::com::sun::star::chart2
;
550 cssc::StackingDirection eStacking
= cssc::StackingDirection_NO_STACKING
;
551 // stacked overrides deep-3d
552 if( isStacked() || isPercent() )
553 eStacking
= cssc::StackingDirection_Y_STACKING
;
554 else if( isDeep3dChart() )
555 eStacking
= cssc::StackingDirection_Z_STACKING
;
556 aSeriesProp
.setProperty( PROP_StackingDirection
, eStacking
);
558 // additional series properties
559 aSeriesProp
.setProperty( PROP_AttachedAxisIndex
, nAxesSetIdx
);
561 // insert series into container
564 Reference
< XDataSeriesContainer
> xSeriesCont( rxChartType
, UNO_QUERY_THROW
);
565 xSeriesCont
->addDataSeries( rxSeries
);
569 OSL_FAIL( "TypeGroupConverter::insertDataSeries - cannot add data series" );
575 } // namespace drawingml
578 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */