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 <= static_cast<int>(mrModel.maAxisIds.size())) && (static_cast<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 behaviour 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 (auto const& elem
: mrModel
.maSeries
)
275 if( elem
->maSources
.has( SeriesModel::CATEGORIES
) && mrModel
.mbCatAxisVisible
)
277 SeriesConverter
aSeriesConv(*this, *elem
);
278 xLabeledSeq
= aSeriesConv
.createCategorySequence( "categories" );
279 if (xLabeledSeq
.is())
282 else if( nMaxValues
<= 0 && elem
->maSources
.has( SeriesModel::VALUES
) )
284 DataSourceModel
*pValues
= elem
->maSources
.get( SeriesModel::VALUES
).get();
285 if( pValues
->mxDataSeq
.is() )
286 nMaxValues
= pValues
->mxDataSeq
->maData
.size();
289 /* n#839727 Create Category Sequence when none are found */
290 if( !xLabeledSeq
.is() && !mrModel
.maSeries
.empty() && mrModel
.mbCatAxisVisible
) {
293 SeriesModel
&aModel
= *mrModel
.maSeries
.get(0);
294 DataSourceModel
&aSrc
= aModel
.maSources
.create( SeriesModel::CATEGORIES
);
295 DataSequenceModel
&aSeq
= aSrc
.mxDataSeq
.create();
296 aSeq
.mnPointCount
= nMaxValues
;
297 for( sal_Int32 i
= 0; i
< nMaxValues
; i
++ )
298 aSeq
.maData
[ i
] <<= OUString::number( i
+ 1 );
299 SeriesConverter
aSeriesConv( *this, aModel
);
300 xLabeledSeq
= aSeriesConv
.createCategorySequence( "categories" );
305 void TypeGroupConverter::convertFromModel( const Reference
< XDiagram
>& rxDiagram
,
306 const Reference
< XCoordinateSystem
>& rxCoordSystem
,
307 sal_Int32 nAxesSetIdx
, bool bSupportsVaryColorsByPoint
)
311 // create the chart type object
312 OUString aService
= OUString::createFromAscii( maTypeInfo
.mpcServiceName
);
313 Reference
< XChartType
> xChartType( createInstance( aService
), UNO_QUERY_THROW
);
315 Reference
< XChartTypeContainer
> xChartTypeContOld( rxCoordSystem
, UNO_QUERY_THROW
);
316 Sequence
< Reference
< XChartType
> > xOldChartTypes( xChartTypeContOld
->getChartTypes() );
317 sal_Int32 nOldChartTypeIdx
= -1;
319 // additional properties
320 PropertySet
aDiaProp( rxDiagram
);
321 PropertySet
aTypeProp( xChartType
);
322 switch( maTypeInfo
.meTypeCategory
)
324 case TYPECATEGORY_BAR
:
326 Sequence
< sal_Int32
> aInt32Seq( 2 );
327 aInt32Seq
[ 0 ] = aInt32Seq
[ 1 ] = mrModel
.mnOverlap
;
328 aTypeProp
.setProperty( PROP_OverlapSequence
, aInt32Seq
);
329 aInt32Seq
[ 0 ] = aInt32Seq
[ 1 ] = mrModel
.mnGapWidth
;
330 aTypeProp
.setProperty( PROP_GapwidthSequence
, aInt32Seq
);
333 case TYPECATEGORY_PIE
:
335 aTypeProp
.setProperty( PROP_UseRings
, maTypeInfo
.meTypeId
== TYPEID_DOUGHNUT
);
336 /* #i85166# starting angle of first pie slice. 3D pie charts
337 use Y rotation setting in view3D element. Of-pie charts do
338 not support pie rotation. */
339 if( !is3dChart() && (maTypeInfo
.meTypeId
!= TYPEID_OFPIE
) )
340 convertPieRotation( aDiaProp
, mrModel
.mnFirstAngle
);
346 // create converter objects for all series models
347 typedef RefVector
< SeriesConverter
> SeriesConvVector
;
348 SeriesConvVector aSeries
;
349 for (auto const& elemSeries
: mrModel
.maSeries
)
350 aSeries
.push_back( std::make_shared
<SeriesConverter
>(*this, *elemSeries
) );
352 // reverse series order for some unstacked 2D chart types
353 if( maTypeInfo
.mbReverseSeries
&& !mb3dChart
&& !isStacked() && !isPercent() )
354 ::std::reverse( aSeries
.begin(), aSeries
.end() );
356 // decide whether to use varying colors for each data point
357 bool bVaryColorsByPoint
= bSupportsVaryColorsByPoint
&& mrModel
.mbVaryColors
;
358 switch( maTypeInfo
.meVarPointMode
)
360 case VARPOINTMODE_NONE
: bVaryColorsByPoint
= false; break;
361 case VARPOINTMODE_SINGLE
: bVaryColorsByPoint
&= (mrModel
.maSeries
.size() == 1); break;
362 case VARPOINTMODE_MULTI
: break;
365 /* Stock chart needs special processing. Create one 'big' series with
366 data sequences of different roles. */
367 if( maTypeInfo
.meTypeId
== TYPEID_STOCK
)
369 // create the data series object
370 Reference
< XDataSeries
> xDataSeries( createInstance( "com.sun.star.chart2.DataSeries" ), UNO_QUERY
);
371 Reference
< XDataSink
> xDataSink( xDataSeries
, UNO_QUERY
);
374 // create a list of data sequences from all series
375 ::std::vector
< Reference
< XLabeledDataSequence
> > aLabeledSeqVec
;
376 OSL_ENSURE( aSeries
.size() >= 3, "TypeGroupConverter::convertFromModel - too few stock chart series" );
377 int nRoleIdx
= (aSeries
.size() == 3) ? 1 : 0;
378 for( auto& rxSeriesConv
: aSeries
)
380 // create a data sequence with a specific role
384 case 0: aRole
= "values-first"; break;
385 case 1: aRole
= "values-max"; break;
386 case 2: aRole
= "values-min"; break;
387 case 3: aRole
= "values-last"; break;
389 Reference
< XLabeledDataSequence
> xDataSeq
= rxSeriesConv
->createValueSequence( aRole
);
391 aLabeledSeqVec
.push_back( xDataSeq
);
398 // attach labeled data sequences to series and insert series into chart type
399 xDataSink
->setData( ContainerHelper::vectorToSequence( aLabeledSeqVec
) );
401 // formatting of high/low lines
402 aTypeProp
.setProperty( PROP_ShowHighLow
, true );
403 PropertySet
aSeriesProp( xDataSeries
);
404 if( mrModel
.mxHiLowLines
.is() )
405 getFormatter().convertFrameFormatting( aSeriesProp
, mrModel
.mxHiLowLines
, OBJECTTYPE_HILOLINE
);
407 // hi/low-lines cannot be switched off via "ShowHighLow" property (?)
408 aSeriesProp
.setProperty( PROP_LineStyle
, css::drawing::LineStyle_NONE
);
410 // formatting of up/down bars
411 bool bUpDownBars
= mrModel
.mxUpDownBars
.is();
412 aTypeProp
.setProperty( PROP_Japanese
, bUpDownBars
);
413 aTypeProp
.setProperty( PROP_ShowFirst
, bUpDownBars
);
416 UpDownBarsConverter
aUpDownConv( *this, *mrModel
.mxUpDownBars
);
417 aUpDownConv
.convertFromModel( xChartType
);
420 // insert the series into the chart type object
421 insertDataSeries( xChartType
, xDataSeries
, nAxesSetIdx
);
426 for( sal_Int32 nCTIdx
=0; nCTIdx
<xOldChartTypes
.getLength(); ++nCTIdx
)
428 if ( xChartType
->getChartType() == xOldChartTypes
[nCTIdx
]->getChartType() )
430 nOldChartTypeIdx
= nCTIdx
;
434 for (auto const& elem
: aSeries
)
436 SeriesConverter
& rSeriesConv
= *elem
;
437 Reference
< XDataSeries
> xDataSeries
= rSeriesConv
.createDataSeries( *this, bVaryColorsByPoint
);
438 insertDataSeries( nOldChartTypeIdx
== -1 ? xChartType
: xOldChartTypes
[nOldChartTypeIdx
], xDataSeries
, nAxesSetIdx
);
440 /* Excel does not use the value of the c:smooth element of the
441 chart type to set a default line smoothing for the data
442 series. Line smoothing is always controlled by the c:smooth
443 element of the respective data series. If the element in the
444 data series is missing, line smoothing is off, regardless of
445 the c:smooth element of the chart type. */
446 #if !OOX_CHART_SMOOTHED_PER_SERIES
447 if( rSeriesConv
.getModel().mbSmooth
)
448 convertLineSmooth( aTypeProp
, true );
453 // add chart type object to coordinate system
454 Reference
< XChartTypeContainer
> xChartTypeCont( rxCoordSystem
, UNO_QUERY_THROW
);
455 if (nOldChartTypeIdx
== -1)
457 xChartTypeCont
->addChartType(xChartType
);
460 // set existence of bar connector lines at diagram (only in stacked 2D bar charts)
461 if( mrModel
.mxSerLines
.is() && !mb3dChart
&& (maTypeInfo
.meTypeCategory
== TYPECATEGORY_BAR
) && (isStacked() || isPercent()) )
462 aDiaProp
.setProperty( PROP_ConnectBars
, true );
466 OSL_FAIL( "TypeGroupConverter::convertFromModel - cannot add chart type" );
470 void TypeGroupConverter::convertMarker( PropertySet
& rPropSet
, sal_Int32 nOoxSymbol
, sal_Int32 nOoxSize
,
471 const ModelRef
< Shape
>& xShapeProps
) const
473 if( !isSeriesFrameFormat() )
475 namespace cssc
= ::com::sun::star::chart2
;
478 cssc::Symbol aSymbol
;
479 aSymbol
.Style
= cssc::SymbolStyle_STANDARD
;
480 switch( nOoxSymbol
) // compare with XclChPropSetHelper::WriteMarkerProperties in xlchart.cxx
482 case XML_auto
: aSymbol
.Style
= cssc::SymbolStyle_AUTO
; break;
483 case XML_none
: aSymbol
.Style
= cssc::SymbolStyle_NONE
; break;
484 case XML_square
: aSymbol
.StandardSymbol
= 0; break; // square
485 case XML_diamond
: aSymbol
.StandardSymbol
= 1; break; // diamond
486 case XML_triangle
: aSymbol
.StandardSymbol
= 3; break; // arrow up
487 case XML_x
: aSymbol
.StandardSymbol
= 10; break; // X, legacy bow tie
488 case XML_star
: aSymbol
.StandardSymbol
= 12; break; // asterisk, legacy sand glass
489 case XML_dot
: aSymbol
.StandardSymbol
= 4; break; // arrow right
490 case XML_dash
: aSymbol
.StandardSymbol
= 13; break; // horizontal bar, legacy arrow down
491 case XML_circle
: aSymbol
.StandardSymbol
= 8; break; // circle, legacy arrow right
492 case XML_plus
: aSymbol
.StandardSymbol
= 11; break; // plus, legacy arrow left
495 // symbol size (points in OOXML, 1/100 mm in Chart2)
496 sal_Int32 nSize
= static_cast< sal_Int32
>( nOoxSize
* (2540.0 / 72.0) + 0.5 );
497 aSymbol
.Size
.Width
= aSymbol
.Size
.Height
= nSize
;
501 Color aFillColor
= xShapeProps
->getFillProperties().maFillColor
;
502 aSymbol
.FillColor
= sal_Int32(aFillColor
.getColor(getFilter().getGraphicHelper()));
503 // tdf#124817: if there is no fill color, use line color of the symbol
504 if( aSymbol
.FillColor
< 0 )
506 Color aLineColor
= xShapeProps
->getLineProperties().maLineFill
.maFillColor
;
507 aSymbol
.BorderColor
= sal_Int32(aLineColor
.getColor(getFilter().getGraphicHelper()));
508 rPropSet
.setProperty(PROP_Color
, aSymbol
.BorderColor
);
511 rPropSet
.setProperty(PROP_Color
, aSymbol
.FillColor
);
515 rPropSet
.setProperty( PROP_Symbol
, aSymbol
);
519 void TypeGroupConverter::convertLineSmooth( PropertySet
& rPropSet
, bool bOoxSmooth
) const
521 if( !isSeriesFrameFormat() && (maTypeInfo
.meTypeCategory
!= TYPECATEGORY_RADAR
) )
523 namespace cssc
= ::com::sun::star::chart2
;
524 cssc::CurveStyle eCurveStyle
= bOoxSmooth
? cssc::CurveStyle_CUBIC_SPLINES
: cssc::CurveStyle_LINES
;
525 rPropSet
.setProperty( PROP_CurveStyle
, eCurveStyle
);
529 void TypeGroupConverter::convertBarGeometry( PropertySet
& rPropSet
, sal_Int32 nOoxShape
) const
531 if( mb3dChart
&& (maTypeInfo
.meTypeCategory
== TYPECATEGORY_BAR
) )
533 namespace cssc
= ::com::sun::star::chart2
;
535 sal_Int32 nGeom3d
= cssc::DataPointGeometry3D::CUBOID
;
538 case XML_box
: nGeom3d
= cssc::DataPointGeometry3D::CUBOID
; break;
539 case XML_cone
: nGeom3d
= cssc::DataPointGeometry3D::CONE
; break;
540 case XML_coneToMax
: nGeom3d
= cssc::DataPointGeometry3D::CONE
; break;
541 case XML_cylinder
: nGeom3d
= cssc::DataPointGeometry3D::CYLINDER
; break;
542 case XML_pyramid
: nGeom3d
= cssc::DataPointGeometry3D::PYRAMID
; break;
543 case XML_pyramidToMax
: nGeom3d
= cssc::DataPointGeometry3D::PYRAMID
; break;
544 default: OSL_FAIL( "TypeGroupConverter::convertBarGeometry - unknown 3D bar shape type" );
546 rPropSet
.setProperty( PROP_Geometry3D
, nGeom3d
);
550 void TypeGroupConverter::convertPieRotation( PropertySet
& rPropSet
, sal_Int32 nOoxAngle
) const
552 if( maTypeInfo
.meTypeCategory
== TYPECATEGORY_PIE
)
554 // map OOXML [0,360] clockwise (0deg top) to Chart2 counterclockwise (0deg left)
555 sal_Int32 nAngle
= (450 - nOoxAngle
) % 360;
556 rPropSet
.setProperty( PROP_StartingAngle
, nAngle
);
560 void TypeGroupConverter::convertPieExplosion( PropertySet
& rPropSet
, sal_Int32 nOoxExplosion
) const
562 if( maTypeInfo
.meTypeCategory
== TYPECATEGORY_PIE
)
564 // pie explosion restricted to 100% in Chart2, set as double in range [0,1]
565 double fOffset
= getLimitedValue
< double >( nOoxExplosion
/ 100.0, 0.0, 1.0 );
566 rPropSet
.setProperty( PROP_Offset
, fOffset
);
570 // private --------------------------------------------------------------------
572 void TypeGroupConverter::insertDataSeries( const Reference
< XChartType
>& rxChartType
, const Reference
< XDataSeries
>& rxSeries
, sal_Int32 nAxesSetIdx
)
576 PropertySet
aSeriesProp( rxSeries
);
578 // series stacking mode
579 namespace cssc
= ::com::sun::star::chart2
;
580 cssc::StackingDirection eStacking
= cssc::StackingDirection_NO_STACKING
;
581 // stacked overrides deep-3d
582 if( isStacked() || isPercent() )
583 eStacking
= cssc::StackingDirection_Y_STACKING
;
584 else if( isDeep3dChart() )
585 eStacking
= cssc::StackingDirection_Z_STACKING
;
586 aSeriesProp
.setProperty( PROP_StackingDirection
, eStacking
);
588 // additional series properties
589 aSeriesProp
.setProperty( PROP_AttachedAxisIndex
, nAxesSetIdx
);
591 // insert series into container
594 Reference
< XDataSeriesContainer
> xSeriesCont( rxChartType
, UNO_QUERY_THROW
);
595 xSeriesCont
->addDataSeries( rxSeries
);
599 OSL_FAIL( "TypeGroupConverter::insertDataSeries - cannot add data series" );
605 } // namespace drawingml
608 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */