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 "drawingml/lineproperties.hxx"
38 #include "drawingml/chart/seriesconverter.hxx"
39 #include "drawingml/chart/typegroupmodel.hxx"
40 #include <oox/core/xmlfilterbase.hxx>
41 #include "oox/helper/containerhelper.hxx"
42 #include <oox/token/namespaces.hxx>
43 #include <oox/token/properties.hxx>
44 #include <oox/token/tokens.hxx>
50 using namespace ::com::sun::star::beans
;
51 using namespace ::com::sun::star::chart2
;
52 using namespace ::com::sun::star::chart2::data
;
53 using namespace ::com::sun::star::uno
;
57 // chart type service names
58 const sal_Char SERVICE_CHART2_AREA
[] = "com.sun.star.chart2.AreaChartType";
59 const sal_Char SERVICE_CHART2_CANDLE
[] = "com.sun.star.chart2.CandleStickChartType";
60 const sal_Char SERVICE_CHART2_COLUMN
[] = "com.sun.star.chart2.ColumnChartType";
61 const sal_Char SERVICE_CHART2_LINE
[] = "com.sun.star.chart2.LineChartType";
62 const sal_Char SERVICE_CHART2_NET
[] = "com.sun.star.chart2.NetChartType";
63 const sal_Char SERVICE_CHART2_FILLEDNET
[] = "com.sun.star.chart2.FilledNetChartType";
64 const sal_Char SERVICE_CHART2_PIE
[] = "com.sun.star.chart2.PieChartType";
65 const sal_Char SERVICE_CHART2_SCATTER
[] = "com.sun.star.chart2.ScatterChartType";
66 const sal_Char SERVICE_CHART2_BUBBLE
[] = "com.sun.star.chart2.BubbleChartType";
67 const sal_Char SERVICE_CHART2_SURFACE
[] = "com.sun.star.chart2.ColumnChartType"; // Todo
69 namespace csscd
= ::com::sun::star::chart::DataLabelPlacement
;
71 static const TypeGroupInfo spTypeInfos
[] =
73 // type-id type-category service varied-point-color default label pos polar area2d 1stvis xcateg swap stack revers picopt
74 { TYPEID_BAR
, TYPECATEGORY_BAR
, SERVICE_CHART2_COLUMN
, VARPOINTMODE_SINGLE
, csscd::OUTSIDE
, false, true, false, true, false, true, false, true },
75 { TYPEID_HORBAR
, TYPECATEGORY_BAR
, SERVICE_CHART2_COLUMN
, VARPOINTMODE_SINGLE
, csscd::OUTSIDE
, false, true, false, true, true, true, false, true },
76 { TYPEID_LINE
, TYPECATEGORY_LINE
, SERVICE_CHART2_LINE
, VARPOINTMODE_SINGLE
, csscd::RIGHT
, false, false, false, true, false, true, false, false },
77 { TYPEID_AREA
, TYPECATEGORY_LINE
, SERVICE_CHART2_AREA
, VARPOINTMODE_NONE
, csscd::CENTER
, false, true, false, true, false, true, true, false },
78 { TYPEID_STOCK
, TYPECATEGORY_LINE
, SERVICE_CHART2_CANDLE
, VARPOINTMODE_NONE
, csscd::RIGHT
, false, false, false, true, false, true, false, false },
79 { TYPEID_RADARLINE
, TYPECATEGORY_RADAR
, SERVICE_CHART2_NET
, VARPOINTMODE_SINGLE
, csscd::TOP
, true, false, false, true, false, false, false, false },
80 { TYPEID_RADARAREA
, TYPECATEGORY_RADAR
, SERVICE_CHART2_FILLEDNET
, VARPOINTMODE_NONE
, csscd::TOP
, true, true, false, true, false, false, true, false },
81 { TYPEID_PIE
, TYPECATEGORY_PIE
, SERVICE_CHART2_PIE
, VARPOINTMODE_MULTI
, csscd::AVOID_OVERLAP
, true, true, true, true, false, false, false, false },
82 { TYPEID_DOUGHNUT
, TYPECATEGORY_PIE
, SERVICE_CHART2_PIE
, VARPOINTMODE_MULTI
, csscd::AVOID_OVERLAP
, true, true, false, true, false, false, false, false },
83 { TYPEID_OFPIE
, TYPECATEGORY_PIE
, SERVICE_CHART2_PIE
, VARPOINTMODE_MULTI
, csscd::AVOID_OVERLAP
, true, true, true, true, false, false, false, false },
84 { TYPEID_SCATTER
, TYPECATEGORY_SCATTER
, SERVICE_CHART2_SCATTER
, VARPOINTMODE_SINGLE
, csscd::RIGHT
, false, false, false, false, false, false, false, false },
85 { TYPEID_BUBBLE
, TYPECATEGORY_SCATTER
, SERVICE_CHART2_BUBBLE
, VARPOINTMODE_SINGLE
, csscd::RIGHT
, false, true, false, false, false, false, false, false },
86 { TYPEID_SURFACE
, TYPECATEGORY_SURFACE
, SERVICE_CHART2_SURFACE
, VARPOINTMODE_NONE
, csscd::RIGHT
, false, true, false, true, false, false, false, false }
89 static const TypeGroupInfo saUnknownTypeInfo
=
90 { TYPEID_UNKNOWN
, TYPECATEGORY_BAR
, SERVICE_CHART2_COLUMN
, VARPOINTMODE_SINGLE
, csscd::OUTSIDE
, false, true, false, true, false, true, false, true };
92 const TypeGroupInfo
& lclGetTypeInfoFromTypeId( TypeId eTypeId
)
94 for( auto const &rIt
: spTypeInfos
)
96 if( rIt
.meTypeId
== eTypeId
)
99 OSL_ENSURE( eTypeId
== TYPEID_UNKNOWN
, "lclGetTypeInfoFromTypeId - unexpected chart type identifier" );
100 return saUnknownTypeInfo
;
105 const TypeGroupInfo
& GetTypeGroupInfo( TypeId eType
)
107 return lclGetTypeInfoFromTypeId(eType
);
110 UpDownBarsConverter::UpDownBarsConverter( const ConverterRoot
& rParent
, UpDownBarsModel
& rModel
) :
111 ConverterBase
< UpDownBarsModel
>( rParent
, rModel
)
115 UpDownBarsConverter::~UpDownBarsConverter()
119 void UpDownBarsConverter::convertFromModel( const Reference
< XChartType
>& rxChartType
)
121 PropertySet
aTypeProp( rxChartType
);
124 Reference
< XPropertySet
> xWhitePropSet
;
125 if( aTypeProp
.getProperty( xWhitePropSet
, PROP_WhiteDay
) )
127 PropertySet
aPropSet( xWhitePropSet
);
128 getFormatter().convertFrameFormatting( aPropSet
, mrModel
.mxUpBars
, OBJECTTYPE_UPBAR
);
132 Reference
< XPropertySet
> xBlackPropSet
;
133 if( aTypeProp
.getProperty( xBlackPropSet
, PROP_BlackDay
) )
135 PropertySet
aPropSet( xBlackPropSet
);
136 getFormatter().convertFrameFormatting( aPropSet
, mrModel
.mxDownBars
, OBJECTTYPE_DOWNBAR
);
140 TypeGroupConverter::TypeGroupConverter( const ConverterRoot
& rParent
, TypeGroupModel
& rModel
) :
141 ConverterBase
< TypeGroupModel
>( rParent
, rModel
),
144 TypeId eTypeId
= TYPEID_UNKNOWN
;
145 switch( mrModel
.mnTypeId
)
147 #define ENSURE_AXESCOUNT( min, max ) OSL_ENSURE( (min <= (int)mrModel.maAxisIds.size()) && ((int)mrModel.maAxisIds.size() <= max), "TypeGroupConverter::TypeGroupConverter - invalid axes count" )
148 case C_TOKEN( area3DChart
): ENSURE_AXESCOUNT( 2, 3 ); eTypeId
= TYPEID_AREA
; mb3dChart
= true; break;
149 case C_TOKEN( areaChart
): ENSURE_AXESCOUNT( 2, 2 ); eTypeId
= TYPEID_AREA
; mb3dChart
= false; break;
150 case C_TOKEN( bar3DChart
): ENSURE_AXESCOUNT( 2, 3 ); eTypeId
= TYPEID_BAR
; mb3dChart
= true; break;
151 case C_TOKEN( barChart
): ENSURE_AXESCOUNT( 2, 2 ); eTypeId
= TYPEID_BAR
; mb3dChart
= false; break;
152 case C_TOKEN( bubbleChart
): ENSURE_AXESCOUNT( 2, 2 ); eTypeId
= TYPEID_BUBBLE
; mb3dChart
= false; break;
153 case C_TOKEN( doughnutChart
): ENSURE_AXESCOUNT( 0, 0 ); eTypeId
= TYPEID_DOUGHNUT
; mb3dChart
= false; break;
154 case C_TOKEN( line3DChart
): ENSURE_AXESCOUNT( 3, 3 ); eTypeId
= TYPEID_LINE
; mb3dChart
= true; break;
155 case C_TOKEN( lineChart
): ENSURE_AXESCOUNT( 2, 2 ); eTypeId
= TYPEID_LINE
; mb3dChart
= false; break;
156 case C_TOKEN( ofPieChart
): ENSURE_AXESCOUNT( 0, 0 ); eTypeId
= TYPEID_OFPIE
; mb3dChart
= false; break;
157 case C_TOKEN( pie3DChart
): ENSURE_AXESCOUNT( 0, 0 ); eTypeId
= TYPEID_PIE
; mb3dChart
= true; break;
158 case C_TOKEN( pieChart
): ENSURE_AXESCOUNT( 0, 0 ); eTypeId
= TYPEID_PIE
; mb3dChart
= false; break;
159 case C_TOKEN( radarChart
): ENSURE_AXESCOUNT( 2, 2 ); eTypeId
= TYPEID_RADARLINE
; mb3dChart
= false; break;
160 case C_TOKEN( scatterChart
): ENSURE_AXESCOUNT( 2, 2 ); eTypeId
= TYPEID_SCATTER
; mb3dChart
= false; break;
161 case C_TOKEN( stockChart
): ENSURE_AXESCOUNT( 2, 2 ); eTypeId
= TYPEID_STOCK
; mb3dChart
= false; break;
162 case C_TOKEN( surface3DChart
): ENSURE_AXESCOUNT( 3, 3 ); eTypeId
= TYPEID_SURFACE
; mb3dChart
= true; break;
163 case C_TOKEN( surfaceChart
): ENSURE_AXESCOUNT( 2, 3 ); eTypeId
= TYPEID_SURFACE
; mb3dChart
= true; break; // 3D bar chart from all surface charts
164 default: OSL_FAIL( "TypeGroupConverter::TypeGroupConverter - unknown chart type" );
165 #undef ENSURE_AXESCOUNT
168 // special handling for some chart types
172 if( mrModel
.mnBarDir
== XML_bar
)
173 eTypeId
= TYPEID_HORBAR
;
175 case TYPEID_RADARLINE
:
176 if( mrModel
.mnRadarStyle
== XML_filled
)
177 eTypeId
= TYPEID_RADARAREA
;
180 // create a deep 3D bar chart from surface charts
181 mrModel
.mnGrouping
= XML_standard
;
186 // set the chart type info struct for the current chart type
187 maTypeInfo
= lclGetTypeInfoFromTypeId( eTypeId
);
190 TypeGroupConverter::~TypeGroupConverter()
194 bool TypeGroupConverter::isStacked() const
196 return maTypeInfo
.mbSupportsStacking
&& (mrModel
.mnGrouping
== XML_stacked
);
199 bool TypeGroupConverter::isPercent() const
201 return maTypeInfo
.mbSupportsStacking
&& (mrModel
.mnGrouping
== XML_percentStacked
);
204 bool TypeGroupConverter::isWall3dChart() const
206 return mb3dChart
&& (maTypeInfo
.meTypeCategory
!= TYPECATEGORY_PIE
);
209 bool TypeGroupConverter::isDeep3dChart() const
211 return isWall3dChart() && (mrModel
.mnGrouping
== XML_standard
);
214 bool TypeGroupConverter::isSeriesFrameFormat() const
216 return mb3dChart
|| maTypeInfo
.mbSeriesIsFrame2d
;
219 ObjectType
TypeGroupConverter::getSeriesObjectType() const
221 return mb3dChart
? OBJECTTYPE_FILLEDSERIES3D
:
222 (maTypeInfo
.mbSeriesIsFrame2d
? OBJECTTYPE_FILLEDSERIES2D
: OBJECTTYPE_LINEARSERIES2D
);
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 aSeq
.mnPointCount
= nMaxValues
;
295 for( sal_Int32 i
= 0; i
< nMaxValues
; i
++ )
296 aSeq
.maData
[ i
] <<= OUString::number( i
+ 1 );
297 SeriesConverter
aSeriesConv( *this, aModel
);
298 xLabeledSeq
= aSeriesConv
.createCategorySequence( "categories" );
303 void TypeGroupConverter::convertFromModel( const Reference
< XDiagram
>& rxDiagram
,
304 const Reference
< XCoordinateSystem
>& rxCoordSystem
,
305 sal_Int32 nAxesSetIdx
, bool bSupportsVaryColorsByPoint
)
309 // create the chart type object
310 OUString aService
= OUString::createFromAscii( maTypeInfo
.mpcServiceName
);
311 Reference
< XChartType
> xChartType( createInstance( aService
), UNO_QUERY_THROW
);
313 // additional properties
314 PropertySet
aDiaProp( rxDiagram
);
315 PropertySet
aTypeProp( xChartType
);
316 switch( maTypeInfo
.meTypeCategory
)
318 case TYPECATEGORY_BAR
:
320 Sequence
< sal_Int32
> aInt32Seq( 2 );
321 aInt32Seq
[ 0 ] = aInt32Seq
[ 1 ] = mrModel
.mnOverlap
;
322 aTypeProp
.setProperty( PROP_OverlapSequence
, aInt32Seq
);
323 aInt32Seq
[ 0 ] = aInt32Seq
[ 1 ] = mrModel
.mnGapWidth
;
324 aTypeProp
.setProperty( PROP_GapwidthSequence
, aInt32Seq
);
327 case TYPECATEGORY_PIE
:
329 aTypeProp
.setProperty( PROP_UseRings
, maTypeInfo
.meTypeId
== TYPEID_DOUGHNUT
);
330 /* #i85166# starting angle of first pie slice. 3D pie charts
331 use Y rotation setting in view3D element. Of-pie charts do
332 not support pie rotation. */
333 if( !is3dChart() && (maTypeInfo
.meTypeId
!= TYPEID_OFPIE
) )
334 convertPieRotation( aDiaProp
, mrModel
.mnFirstAngle
);
340 // create converter objects for all series models
341 typedef RefVector
< SeriesConverter
> SeriesConvVector
;
342 SeriesConvVector aSeries
;
343 for( TypeGroupModel::SeriesVector::iterator aIt
= mrModel
.maSeries
.begin(), aEnd
= mrModel
.maSeries
.end(); aIt
!= aEnd
; ++aIt
)
344 aSeries
.push_back( std::make_shared
<SeriesConverter
>( *this, **aIt
) );
346 // reverse series order for some unstacked 2D chart types
347 if( maTypeInfo
.mbReverseSeries
&& !mb3dChart
&& !isStacked() && !isPercent() )
348 ::std::reverse( aSeries
.begin(), aSeries
.end() );
350 // decide whether to use varying colors for each data point
351 bool bVaryColorsByPoint
= bSupportsVaryColorsByPoint
&& mrModel
.mbVaryColors
;
352 switch( maTypeInfo
.meVarPointMode
)
354 case VARPOINTMODE_NONE
: bVaryColorsByPoint
= false; break;
355 case VARPOINTMODE_SINGLE
: bVaryColorsByPoint
&= (mrModel
.maSeries
.size() == 1); break;
356 case VARPOINTMODE_MULTI
: break;
359 /* Stock chart needs special processing. Create one 'big' series with
360 data sequences of different roles. */
361 if( maTypeInfo
.meTypeId
== TYPEID_STOCK
)
363 // create the data series object
364 Reference
< XDataSeries
> xDataSeries( createInstance( "com.sun.star.chart2.DataSeries" ), UNO_QUERY
);
365 Reference
< XDataSink
> xDataSink( xDataSeries
, UNO_QUERY
);
368 // create a list of data sequences from all series
369 ::std::vector
< Reference
< XLabeledDataSequence
> > aLabeledSeqVec
;
370 OSL_ENSURE( aSeries
.size() >= 3, "TypeGroupConverter::convertFromModel - too few stock chart series" );
371 int nRoleIdx
= (aSeries
.size() == 3) ? 1 : 0;
372 for( SeriesConvVector::iterator aIt
= aSeries
.begin(), aEnd
= aSeries
.end(); (nRoleIdx
< 4) && (aIt
!= aEnd
); ++nRoleIdx
, ++aIt
)
374 // create a data sequence with a specific role
378 case 0: aRole
= "values-first"; break;
379 case 1: aRole
= "values-max"; break;
380 case 2: aRole
= "values-min"; break;
381 case 3: aRole
= "values-last"; break;
383 Reference
< XLabeledDataSequence
> xDataSeq
= (*aIt
)->createValueSequence( aRole
);
385 aLabeledSeqVec
.push_back( xDataSeq
);
388 // attach labeled data sequences to series and insert series into chart type
389 xDataSink
->setData( ContainerHelper::vectorToSequence( aLabeledSeqVec
) );
391 // formatting of high/low lines
392 aTypeProp
.setProperty( PROP_ShowHighLow
, true );
393 PropertySet
aSeriesProp( xDataSeries
);
394 if( mrModel
.mxHiLowLines
.is() )
395 getFormatter().convertFrameFormatting( aSeriesProp
, mrModel
.mxHiLowLines
, OBJECTTYPE_HILOLINE
);
397 // hi/low-lines cannot be switched off via "ShowHighLow" property (?)
398 aSeriesProp
.setProperty( PROP_LineStyle
, css::drawing::LineStyle_NONE
);
400 // formatting of up/down bars
401 bool bUpDownBars
= mrModel
.mxUpDownBars
.is();
402 aTypeProp
.setProperty( PROP_Japanese
, bUpDownBars
);
403 aTypeProp
.setProperty( PROP_ShowFirst
, bUpDownBars
);
406 UpDownBarsConverter
aUpDownConv( *this, *mrModel
.mxUpDownBars
);
407 aUpDownConv
.convertFromModel( xChartType
);
410 // insert the series into the chart type object
411 insertDataSeries( xChartType
, xDataSeries
, nAxesSetIdx
);
416 for( SeriesConvVector::iterator aIt
= aSeries
.begin(), aEnd
= aSeries
.end(); aIt
!= aEnd
; ++aIt
)
418 SeriesConverter
& rSeriesConv
= **aIt
;
419 Reference
< XDataSeries
> xDataSeries
= rSeriesConv
.createDataSeries( *this, bVaryColorsByPoint
);
420 insertDataSeries( xChartType
, xDataSeries
, nAxesSetIdx
);
422 /* Excel does not use the value of the c:smooth element of the
423 chart type to set a default line smoothing for the data
424 series. Line smoothing is always controlled by the c:smooth
425 element of the respective data series. If the element in the
426 data series is missing, line smoothing is off, regardless of
427 the c:smooth element of the chart type. */
428 #if !OOX_CHART_SMOOTHED_PER_SERIES
429 if( rSeriesConv
.getModel().mbSmooth
)
430 convertLineSmooth( aTypeProp
, true );
435 // add chart type object to coordinate system
436 Reference
< XChartTypeContainer
> xChartTypeCont( rxCoordSystem
, UNO_QUERY_THROW
);
437 xChartTypeCont
->addChartType( xChartType
);
439 // set existence of bar connector lines at diagram (only in stacked 2D bar charts)
440 if( mrModel
.mxSerLines
.is() && !mb3dChart
&& (maTypeInfo
.meTypeCategory
== TYPECATEGORY_BAR
) && (isStacked() || isPercent()) )
441 aDiaProp
.setProperty( PROP_ConnectBars
, true );
445 OSL_FAIL( "TypeGroupConverter::convertFromModel - cannot add chart type" );
449 void TypeGroupConverter::convertMarker( PropertySet
& rPropSet
, sal_Int32 nOoxSymbol
, sal_Int32 nOoxSize
,
450 const ModelRef
< Shape
>& xShapeProps
) const
452 if( !isSeriesFrameFormat() )
454 namespace cssc
= ::com::sun::star::chart2
;
457 cssc::Symbol aSymbol
;
458 aSymbol
.Style
= cssc::SymbolStyle_STANDARD
;
459 switch( nOoxSymbol
) // compare with XclChPropSetHelper::WriteMarkerProperties in xlchart.cxx
461 case XML_auto
: aSymbol
.Style
= cssc::SymbolStyle_AUTO
; break;
462 case XML_none
: aSymbol
.Style
= cssc::SymbolStyle_NONE
; break;
463 case XML_square
: aSymbol
.StandardSymbol
= 0; break; // square
464 case XML_diamond
: aSymbol
.StandardSymbol
= 1; break; // diamond
465 case XML_triangle
: aSymbol
.StandardSymbol
= 3; break; // arrow up
466 case XML_x
: aSymbol
.StandardSymbol
= 10; break; // X, legacy bow tie
467 case XML_star
: aSymbol
.StandardSymbol
= 12; break; // asterisk, legacy sand glass
468 case XML_dot
: aSymbol
.StandardSymbol
= 4; break; // arrow right
469 case XML_dash
: aSymbol
.StandardSymbol
= 13; break; // horizontal bar, legacy arrow down
470 case XML_circle
: aSymbol
.StandardSymbol
= 8; break; // circle, legacy arrow right
471 case XML_plus
: aSymbol
.StandardSymbol
= 11; break; // plus, legacy arrow left
474 // symbol size (points in OOXML, 1/100 mm in Chart2)
475 sal_Int32 nSize
= static_cast< sal_Int32
>( nOoxSize
* (2540.0 / 72.0) + 0.5 );
476 aSymbol
.Size
.Width
= aSymbol
.Size
.Height
= nSize
;
480 Color aFillColor
= xShapeProps
->getFillProperties().maFillColor
;
481 aSymbol
.FillColor
= aFillColor
.getColor(getFilter().getGraphicHelper());
482 rPropSet
.setProperty(PROP_Color
, aSymbol
.FillColor
);
486 rPropSet
.setProperty( PROP_Symbol
, aSymbol
);
490 void TypeGroupConverter::convertLineSmooth( PropertySet
& rPropSet
, bool bOoxSmooth
) const
492 if( !isSeriesFrameFormat() && (maTypeInfo
.meTypeCategory
!= TYPECATEGORY_RADAR
) )
494 namespace cssc
= ::com::sun::star::chart2
;
495 cssc::CurveStyle eCurveStyle
= bOoxSmooth
? cssc::CurveStyle_CUBIC_SPLINES
: cssc::CurveStyle_LINES
;
496 rPropSet
.setProperty( PROP_CurveStyle
, eCurveStyle
);
500 void TypeGroupConverter::convertBarGeometry( PropertySet
& rPropSet
, sal_Int32 nOoxShape
) const
502 if( mb3dChart
&& (maTypeInfo
.meTypeCategory
== TYPECATEGORY_BAR
) )
504 namespace cssc
= ::com::sun::star::chart2
;
506 sal_Int32 nGeom3d
= cssc::DataPointGeometry3D::CUBOID
;
509 case XML_box
: nGeom3d
= cssc::DataPointGeometry3D::CUBOID
; break;
510 case XML_cone
: nGeom3d
= cssc::DataPointGeometry3D::CONE
; break;
511 case XML_coneToMax
: nGeom3d
= cssc::DataPointGeometry3D::CONE
; break;
512 case XML_cylinder
: nGeom3d
= cssc::DataPointGeometry3D::CYLINDER
; break;
513 case XML_pyramid
: nGeom3d
= cssc::DataPointGeometry3D::PYRAMID
; break;
514 case XML_pyramidToMax
: nGeom3d
= cssc::DataPointGeometry3D::PYRAMID
; break;
515 default: OSL_FAIL( "TypeGroupConverter::convertBarGeometry - unknown 3D bar shape type" );
517 rPropSet
.setProperty( PROP_Geometry3D
, nGeom3d
);
521 void TypeGroupConverter::convertPieRotation( PropertySet
& rPropSet
, sal_Int32 nOoxAngle
) const
523 if( maTypeInfo
.meTypeCategory
== TYPECATEGORY_PIE
)
525 // map OOXML [0,360] clockwise (0deg top) to Chart2 counterclockwise (0deg left)
526 sal_Int32 nAngle
= (450 - nOoxAngle
) % 360;
527 rPropSet
.setProperty( PROP_StartingAngle
, nAngle
);
531 void TypeGroupConverter::convertPieExplosion( PropertySet
& rPropSet
, sal_Int32 nOoxExplosion
) const
533 if( maTypeInfo
.meTypeCategory
== TYPECATEGORY_PIE
)
535 // pie explosion restricted to 100% in Chart2, set as double in range [0,1]
536 double fOffset
= getLimitedValue
< double >( nOoxExplosion
/ 100.0, 0.0, 1.0 );
537 rPropSet
.setProperty( PROP_Offset
, fOffset
);
541 // private --------------------------------------------------------------------
543 void TypeGroupConverter::insertDataSeries( const Reference
< XChartType
>& rxChartType
, const Reference
< XDataSeries
>& rxSeries
, sal_Int32 nAxesSetIdx
)
547 PropertySet
aSeriesProp( rxSeries
);
549 // series stacking mode
550 namespace cssc
= ::com::sun::star::chart2
;
551 cssc::StackingDirection eStacking
= cssc::StackingDirection_NO_STACKING
;
552 // stacked overrides deep-3d
553 if( isStacked() || isPercent() )
554 eStacking
= cssc::StackingDirection_Y_STACKING
;
555 else if( isDeep3dChart() )
556 eStacking
= cssc::StackingDirection_Z_STACKING
;
557 aSeriesProp
.setProperty( PROP_StackingDirection
, eStacking
);
559 // additional series properties
560 aSeriesProp
.setProperty( PROP_AttachedAxisIndex
, nAxesSetIdx
);
562 // insert series into container
565 Reference
< XDataSeriesContainer
> xSeriesCont( rxChartType
, UNO_QUERY_THROW
);
566 xSeriesCont
->addDataSeries( rxSeries
);
570 OSL_FAIL( "TypeGroupConverter::insertDataSeries - cannot add data series" );
576 } // namespace drawingml
579 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */