LibreOffice Module oox (master) 1
typegroupconverter.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
21
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/XDiagram.hpp>
35#include <com/sun/star/chart2/data/XDataSink.hpp>
36#include <com/sun/star/drawing/LineStyle.hpp>
37
39#include <osl/diagnose.h>
44#include <oox/token/namespaces.hxx>
45#include <oox/token/properties.hxx>
46#include <oox/token/tokens.hxx>
48
49namespace oox::drawingml::chart {
50
51using namespace ::com::sun::star::beans;
52using namespace ::com::sun::star::chart2;
53using namespace ::com::sun::star::chart2::data;
54using namespace ::com::sun::star::uno;
55
56namespace {
57
58// chart type service names
59const char SERVICE_CHART2_AREA[] = "com.sun.star.chart2.AreaChartType";
60const char SERVICE_CHART2_CANDLE[] = "com.sun.star.chart2.CandleStickChartType";
61const char SERVICE_CHART2_COLUMN[] = "com.sun.star.chart2.ColumnChartType";
62const char SERVICE_CHART2_LINE[] = "com.sun.star.chart2.LineChartType";
63const char SERVICE_CHART2_NET[] = "com.sun.star.chart2.NetChartType";
64const char SERVICE_CHART2_FILLEDNET[] = "com.sun.star.chart2.FilledNetChartType";
65const char SERVICE_CHART2_PIE[] = "com.sun.star.chart2.PieChartType";
66const char SERVICE_CHART2_SCATTER[] = "com.sun.star.chart2.ScatterChartType";
67const char SERVICE_CHART2_BUBBLE[] = "com.sun.star.chart2.BubbleChartType";
68const char SERVICE_CHART2_SURFACE[] = "com.sun.star.chart2.ColumnChartType"; // Todo
69
70namespace csscd = ::com::sun::star::chart::DataLabelPlacement;
71
72const TypeGroupInfo spTypeInfos[] =
73{
74 // type-id type-category service varied-point-color default label pos polar area2d 1stvis xcateg swap stack picopt
75 { TYPEID_BAR, TYPECATEGORY_BAR, SERVICE_CHART2_COLUMN, VARPOINTMODE_SINGLE, csscd::OUTSIDE, false, true, false, true, false, true, true },
76 { TYPEID_HORBAR, TYPECATEGORY_BAR, SERVICE_CHART2_COLUMN, VARPOINTMODE_SINGLE, csscd::OUTSIDE, false, true, false, true, true, true, true },
77 { TYPEID_LINE, TYPECATEGORY_LINE, SERVICE_CHART2_LINE, VARPOINTMODE_SINGLE, csscd::RIGHT, false, false, false, true, false, true, false },
78 { TYPEID_AREA, TYPECATEGORY_LINE, SERVICE_CHART2_AREA, VARPOINTMODE_NONE, csscd::CENTER, false, true, false, true, false, true, false },
79 { TYPEID_STOCK, TYPECATEGORY_LINE, SERVICE_CHART2_CANDLE, VARPOINTMODE_NONE, csscd::RIGHT, false, false, false, true, false, true, false },
80 { TYPEID_RADARLINE, TYPECATEGORY_RADAR, SERVICE_CHART2_NET, VARPOINTMODE_SINGLE, csscd::OUTSIDE, true, false, false, true, false, false, false },
81 { TYPEID_RADARAREA, TYPECATEGORY_RADAR, SERVICE_CHART2_FILLEDNET, VARPOINTMODE_NONE, csscd::OUTSIDE, true, true, false, true, false, false, false },
82 { TYPEID_PIE, TYPECATEGORY_PIE, SERVICE_CHART2_PIE, VARPOINTMODE_MULTI, csscd::AVOID_OVERLAP, true, true, true, true, false, false, false },
83 { TYPEID_DOUGHNUT, TYPECATEGORY_PIE, SERVICE_CHART2_PIE, VARPOINTMODE_MULTI, csscd::AVOID_OVERLAP, true, true, false, true, false, false, false },
84 { TYPEID_OFPIE, TYPECATEGORY_PIE, SERVICE_CHART2_PIE, VARPOINTMODE_MULTI, csscd::AVOID_OVERLAP, true, true, true, true, false, false, false },
85 { TYPEID_SCATTER, TYPECATEGORY_SCATTER, SERVICE_CHART2_SCATTER, VARPOINTMODE_SINGLE, csscd::RIGHT, false, false, false, false, false, false, false },
86 { TYPEID_BUBBLE, TYPECATEGORY_SCATTER, SERVICE_CHART2_BUBBLE, VARPOINTMODE_SINGLE, csscd::RIGHT, false, true, false, false, false, false, false },
87 { TYPEID_SURFACE, TYPECATEGORY_SURFACE, SERVICE_CHART2_SURFACE, VARPOINTMODE_NONE, csscd::RIGHT, false, true, false, true, false, false, false }
88};
89
90const TypeGroupInfo saUnknownTypeInfo =
91 { TYPEID_UNKNOWN, TYPECATEGORY_BAR, SERVICE_CHART2_COLUMN, VARPOINTMODE_SINGLE, csscd::OUTSIDE, false, true, false, true, false, true, true };
92
93const TypeGroupInfo& lclGetTypeInfoFromTypeId( TypeId eTypeId )
94{
95 for( auto const &rIt : spTypeInfos)
96 {
97 if( rIt.meTypeId == eTypeId )
98 return rIt;
99 }
100 OSL_ENSURE( eTypeId == TYPEID_UNKNOWN, "lclGetTypeInfoFromTypeId - unexpected chart type identifier" );
101 return saUnknownTypeInfo;
102}
103
104} // namespace
105
107{
108 return lclGetTypeInfoFromTypeId(eType);
109}
110
112 ConverterBase< UpDownBarsModel >( rParent, rModel )
113{
114}
115
117{
118}
119
121{
122 PropertySet aTypeProp( rxChartType );
123
124 // upbar format
125 Reference< XPropertySet > xWhitePropSet;
126 if( aTypeProp.getProperty( xWhitePropSet, PROP_WhiteDay ) )
127 {
128 PropertySet aPropSet( xWhitePropSet );
130 }
131
132 // downbar format
133 Reference< XPropertySet > xBlackPropSet;
134 if( aTypeProp.getProperty( xBlackPropSet, PROP_BlackDay ) )
135 {
136 PropertySet aPropSet( xBlackPropSet );
138 }
139}
140
142 ConverterBase< TypeGroupModel >( rParent, rModel ),
143 mb3dChart( false )
144{
145 TypeId eTypeId = TYPEID_UNKNOWN;
146 switch( mrModel.mnTypeId )
147 {
148#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" )
149 case C_TOKEN( area3DChart ): ENSURE_AXESCOUNT( 2, 3 ); eTypeId = TYPEID_AREA; mb3dChart = true; break;
150 case C_TOKEN( areaChart ): ENSURE_AXESCOUNT( 2, 2 ); eTypeId = TYPEID_AREA; mb3dChart = false; break;
151 case C_TOKEN( bar3DChart ): ENSURE_AXESCOUNT( 2, 3 ); eTypeId = TYPEID_BAR; mb3dChart = true; break;
152 case C_TOKEN( barChart ): ENSURE_AXESCOUNT( 2, 2 ); eTypeId = TYPEID_BAR; mb3dChart = false; break;
153 case C_TOKEN( bubbleChart ): ENSURE_AXESCOUNT( 2, 2 ); eTypeId = TYPEID_BUBBLE; mb3dChart = false; break;
154 case C_TOKEN( doughnutChart ): ENSURE_AXESCOUNT( 0, 0 ); eTypeId = TYPEID_DOUGHNUT; mb3dChart = false; break;
155 case C_TOKEN( line3DChart ): ENSURE_AXESCOUNT( 3, 3 ); eTypeId = TYPEID_LINE; mb3dChart = true; break;
156 case C_TOKEN( lineChart ): ENSURE_AXESCOUNT( 2, 2 ); eTypeId = TYPEID_LINE; mb3dChart = false; break;
157 case C_TOKEN( ofPieChart ): ENSURE_AXESCOUNT( 0, 0 ); eTypeId = TYPEID_OFPIE; mb3dChart = false; break;
158 case C_TOKEN( pie3DChart ): ENSURE_AXESCOUNT( 0, 0 ); eTypeId = TYPEID_PIE; mb3dChart = true; break;
159 case C_TOKEN( pieChart ): ENSURE_AXESCOUNT( 0, 0 ); eTypeId = TYPEID_PIE; mb3dChart = false; break;
160 case C_TOKEN( radarChart ): ENSURE_AXESCOUNT( 2, 2 ); eTypeId = TYPEID_RADARLINE; mb3dChart = false; break;
161 case C_TOKEN( scatterChart ): ENSURE_AXESCOUNT( 2, 2 ); eTypeId = TYPEID_SCATTER; mb3dChart = false; break;
162 case C_TOKEN( stockChart ): ENSURE_AXESCOUNT( 2, 2 ); eTypeId = TYPEID_STOCK; mb3dChart = false; break;
163 case C_TOKEN( surface3DChart ): ENSURE_AXESCOUNT( 3, 3 ); eTypeId = TYPEID_SURFACE; mb3dChart = true; break;
164 case C_TOKEN( surfaceChart ): ENSURE_AXESCOUNT( 2, 3 ); eTypeId = TYPEID_SURFACE; mb3dChart = true; break; // 3D bar chart from all surface charts
165 default: OSL_FAIL( "TypeGroupConverter::TypeGroupConverter - unknown chart type" );
166#undef ENSURE_AXESCOUNT
167 }
168
169 // special handling for some chart types
170 switch( eTypeId )
171 {
172 case TYPEID_BAR:
173 if( mrModel.mnBarDir == XML_bar )
174 eTypeId = TYPEID_HORBAR;
175 break;
176 case TYPEID_RADARLINE:
177 if( mrModel.mnRadarStyle == XML_filled )
178 eTypeId = TYPEID_RADARAREA;
179 break;
180 case TYPEID_SURFACE:
181 // create a deep 3D bar chart from surface charts
182 mrModel.mnGrouping = XML_standard;
183 break;
184 default:;
185 }
186
187 // set the chart type info struct for the current chart type
188 maTypeInfo = lclGetTypeInfoFromTypeId( eTypeId );
189}
190
192{
193}
194
196{
197 return maTypeInfo.mbSupportsStacking && (mrModel.mnGrouping == XML_stacked);
198}
199
201{
202 return maTypeInfo.mbSupportsStacking && (mrModel.mnGrouping == XML_percentStacked);
203}
204
206{
208}
209
211{
212 return isWall3dChart() && (mrModel.mnGrouping == XML_standard);
213}
214
216{
218}
219
221{
224}
225
227{
228 OUString aSeriesTitle;
229 if( !mrModel.maSeries.empty() && (maTypeInfo.mbSingleSeriesVis || (mrModel.maSeries.size() == 1)) )
230 if( const TextModel* pText = mrModel.maSeries.front()->mxText.get() )
231 if( const DataSequenceModel* pDataSeq = pText->mxDataSeq.get() )
232 if( !pDataSeq->maData.empty() )
233 pDataSeq->maData.begin()->second >>= aSeriesTitle;
234 return aSeriesTitle;
235}
236
238{
239 // create the coordinate system object
243 {
244 if( mb3dChart )
245 xCoordSystem = css::chart2::PolarCoordinateSystem3d::create(xContext);
246 else
247 xCoordSystem = css::chart2::PolarCoordinateSystem2d::create(xContext);
248 }
249 else
250 {
251 if( mb3dChart )
252 xCoordSystem = css::chart2::CartesianCoordinateSystem3d::create(xContext);
253 else
254 xCoordSystem = css::chart2::CartesianCoordinateSystem2d::create(xContext);
255 }
256
257 // swap X and Y axis
259 {
260 PropertySet aPropSet( xCoordSystem );
261 aPropSet.setProperty( PROP_SwapXAndYAxis, true );
262 }
263
264 return xCoordSystem;
265}
266
268{
269 sal_Int32 nMaxValues = 0;
271 /* Find first existing category sequence. The behaviour of Excel 2007 is
272 different to Excel 2003, which always used the category sequence of the
273 first series, even if it was empty. */
274 for (auto const& elem : mrModel.maSeries)
275 {
276 if( elem->maSources.has( SeriesModel::CATEGORIES ) )
277 {
278 SeriesConverter aSeriesConv(*this, *elem);
279 xLabeledSeq = aSeriesConv.createCategorySequence( "categories" );
280 if (xLabeledSeq.is())
281 break;
282 }
283 else if( nMaxValues <= 0 && elem->maSources.has( SeriesModel::VALUES ) )
284 {
285 DataSourceModel *pValues = elem->maSources.get( SeriesModel::VALUES ).get();
286 if( pValues->mxDataSeq.is() )
287 nMaxValues = pValues->mxDataSeq->maData.size();
288 }
289 }
290 /* n#839727 Create Category Sequence when none are found */
291 if( !xLabeledSeq.is() && !mrModel.maSeries.empty() ) {
292 if( nMaxValues < 0 )
293 nMaxValues = 2;
294 SeriesModel &aModel = *mrModel.maSeries.get(0);
296 {
299 aSeq.mnPointCount = nMaxValues;
300 for( sal_Int32 i = 0; i < nMaxValues; i++ )
301 aSeq.maData[ i ] <<= OUString::number( i + 1 );
302 }
303 SeriesConverter aSeriesConv( *this, aModel );
304 xLabeledSeq = aSeriesConv.createCategorySequence( "categories" );
305 }
306 return xLabeledSeq;
307}
308
310 const Reference< XCoordinateSystem >& rxCoordSystem,
311 sal_Int32 nAxesSetIdx, bool bSupportsVaryColorsByPoint )
312{
313 try
314 {
315 // create the chart type object
316 OUString aService = OUString::createFromAscii( maTypeInfo.mpcServiceName );
317 Reference< XChartType > xChartType( createInstance( aService ), UNO_QUERY_THROW );
318
319 Reference< XChartTypeContainer > xChartTypeContOld( rxCoordSystem, UNO_QUERY_THROW );
320 Sequence< Reference< XChartType > > xOldChartTypes( xChartTypeContOld->getChartTypes() );
321 sal_Int32 nOldChartTypeIdx = -1;
322
323 // additional properties
324 PropertySet aDiaProp( rxDiagram );
325 PropertySet aTypeProp( xChartType );
326 switch( maTypeInfo.meTypeCategory )
327 {
328 case TYPECATEGORY_BAR:
329 {
331 aTypeProp.setProperty( PROP_OverlapSequence, aInt32Seq );
332 aInt32Seq = { mrModel.mnGapWidth, mrModel.mnGapWidth };
333 aTypeProp.setProperty( PROP_GapwidthSequence, aInt32Seq );
334 }
335 break;
336 case TYPECATEGORY_PIE:
337 {
338 aTypeProp.setProperty( PROP_UseRings, maTypeInfo.meTypeId == TYPEID_DOUGHNUT );
339 /* #i85166# starting angle of first pie slice. 3D pie charts
340 use Y rotation setting in view3D element. Of-pie charts do
341 not support pie rotation. */
344 }
345 break;
346 default:;
347 }
348
349 // create converter objects for all series models
350 typedef RefVector< SeriesConverter > SeriesConvVector;
351 SeriesConvVector aSeries;
352 for (auto const& elemSeries : mrModel.maSeries)
353 aSeries.push_back( std::make_shared<SeriesConverter>(*this, *elemSeries) );
354
355 // decide whether to use varying colors for each data point
356 bool bVaryColorsByPoint = bSupportsVaryColorsByPoint && mrModel.mbVaryColors;
357 switch( maTypeInfo.meVarPointMode )
358 {
359 case VARPOINTMODE_NONE: bVaryColorsByPoint = false; break;
360 case VARPOINTMODE_SINGLE: bVaryColorsByPoint &= (mrModel.maSeries.size() == 1); break;
361 case VARPOINTMODE_MULTI: break;
362 }
363
364 /* Stock chart needs special processing. Create one 'big' series with
365 data sequences of different roles. */
367 {
368 // create the data series object
369 Reference< XDataSeries > xDataSeries( createInstance( "com.sun.star.chart2.DataSeries" ), UNO_QUERY );
370 Reference< XDataSink > xDataSink( xDataSeries, UNO_QUERY );
371 if( xDataSink.is() )
372 {
373 // create a list of data sequences from all series
374 ::std::vector< Reference< XLabeledDataSequence > > aLabeledSeqVec;
375 OSL_ENSURE( aSeries.size() >= 3, "TypeGroupConverter::convertFromModel - too few stock chart series" );
376 int nRoleIdx = (aSeries.size() == 3) ? 1 : 0;
377 for( auto& rxSeriesConv : aSeries )
378 {
379 // create a data sequence with a specific role
380 OUString aRole;
381 switch( nRoleIdx )
382 {
383 case 0: aRole = "values-first"; break;
384 case 1: aRole = "values-max"; break;
385 case 2: aRole = "values-min"; break;
386 case 3: aRole = "values-last"; break;
387 }
388 Reference< XLabeledDataSequence > xDataSeq = rxSeriesConv->createValueSequence( aRole );
389 if( xDataSeq.is() )
390 aLabeledSeqVec.push_back( xDataSeq );
391
392 ++nRoleIdx;
393 if (nRoleIdx >= 4)
394 break;
395 }
396
397 // attach labeled data sequences to series and insert series into chart type
398 xDataSink->setData( comphelper::containerToSequence( aLabeledSeqVec ) );
399
400 // formatting of high/low lines
401 aTypeProp.setProperty( PROP_ShowHighLow, true );
402 PropertySet aSeriesProp( xDataSeries );
403 if( mrModel.mxHiLowLines.is() )
405 else
406 // hi/low-lines cannot be switched off via "ShowHighLow" property (?)
407 aSeriesProp.setProperty( PROP_LineStyle, css::drawing::LineStyle_NONE );
408
409 // formatting of up/down bars
410 bool bUpDownBars = mrModel.mxUpDownBars.is();
411 aTypeProp.setProperty( PROP_Japanese, bUpDownBars );
412 aTypeProp.setProperty( PROP_ShowFirst, bUpDownBars );
413 if( bUpDownBars )
414 {
415 UpDownBarsConverter aUpDownConv( *this, *mrModel.mxUpDownBars );
416 aUpDownConv.convertFromModel( xChartType );
417 }
418
419 // insert the series into the chart type object
420 insertDataSeries( xChartType, xDataSeries, nAxesSetIdx );
421 }
422 }
423 else
424 {
425 for( sal_Int32 nCTIdx=0; nCTIdx<xOldChartTypes.getLength(); ++nCTIdx )
426 {
427 if ( xChartType->getChartType() == xOldChartTypes[nCTIdx]->getChartType() )
428 {
429 nOldChartTypeIdx = nCTIdx;
430 }
431 }
432
433 for (auto const& elem : aSeries)
434 {
435 SeriesConverter& rSeriesConv = *elem;
436 Reference< XDataSeries > xDataSeries = rSeriesConv.createDataSeries( *this, bVaryColorsByPoint );
437 insertDataSeries( nOldChartTypeIdx == -1 ? xChartType : xOldChartTypes[nOldChartTypeIdx], xDataSeries, nAxesSetIdx );
438
439 /* Excel does not use the value of the c:smooth element of the
440 chart type to set a default line smoothing for the data
441 series. Line smoothing is always controlled by the c:smooth
442 element of the respective data series. If the element in the
443 data series is missing, line smoothing is off, regardless of
444 the c:smooth element of the chart type. */
445#if !OOX_CHART_SMOOTHED_PER_SERIES
446 if( rSeriesConv.getModel().mbSmooth )
447 convertLineSmooth( aTypeProp, true );
448#endif
449 }
450 }
451
452 // add chart type object to coordinate system
453 Reference< XChartTypeContainer > xChartTypeCont( rxCoordSystem, UNO_QUERY_THROW );
454 if (nOldChartTypeIdx == -1)
455 {
456 xChartTypeCont->addChartType(xChartType);
457 }
458
459 // set existence of bar connector lines at diagram (only in stacked 2D bar charts)
461 aDiaProp.setProperty( PROP_ConnectBars, true );
462 }
463 catch( Exception& )
464 {
465 OSL_FAIL( "TypeGroupConverter::convertFromModel - cannot add chart type" );
466 }
467}
468
469void TypeGroupConverter::convertMarker( PropertySet& rPropSet, sal_Int32 nOoxSymbol, sal_Int32 nOoxSize,
470 const ModelRef< Shape >& xShapeProps ) const
471{
472 if( isSeriesFrameFormat() )
473 return;
474
475 namespace cssc = ::com::sun::star::chart2;
476
477 // symbol style
478 cssc::Symbol aSymbol;
479 aSymbol.Style = cssc::SymbolStyle_STANDARD;
480 switch( nOoxSymbol ) // compare with XclChPropSetHelper::WriteMarkerProperties in xlchart.cxx
481 {
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
493 }
494
495 // symbol size (points in OOXML, 1/100 mm in Chart2)
496 sal_Int32 nSize = convertPointToMm100(nOoxSize);
497 aSymbol.Size.Width = aSymbol.Size.Height = nSize;
498
499 if(xShapeProps.is())
500 {
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 )
505 {
506 Color aLineColor = xShapeProps->getLineProperties().maLineFill.maFillColor;
507 aSymbol.BorderColor = sal_Int32(aLineColor.getColor(getFilter().getGraphicHelper()));
508 rPropSet.setProperty(PROP_Color, aSymbol.BorderColor);
509 }
510 else
511 rPropSet.setProperty(PROP_Color, aSymbol.FillColor);
512 }
513
514 // set the property
515 rPropSet.setProperty( PROP_Symbol, aSymbol );
516}
517
518void TypeGroupConverter::convertLineSmooth( PropertySet& rPropSet, bool bOoxSmooth ) const
519{
521 {
522 namespace cssc = ::com::sun::star::chart2;
523 cssc::CurveStyle eCurveStyle = bOoxSmooth ? cssc::CurveStyle_CUBIC_SPLINES : cssc::CurveStyle_LINES;
524 rPropSet.setProperty( PROP_CurveStyle, eCurveStyle );
525 }
526}
527
528void TypeGroupConverter::convertBarGeometry( PropertySet& rPropSet, sal_Int32 nOoxShape ) const
529{
531 return;
532
533 namespace cssc = ::com::sun::star::chart2;
534
535 sal_Int32 nGeom3d = cssc::DataPointGeometry3D::CUBOID;
536 switch( nOoxShape )
537 {
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" );
545 }
546 rPropSet.setProperty( PROP_Geometry3D, nGeom3d );
547}
548
549void TypeGroupConverter::convertPieRotation( PropertySet& rPropSet, sal_Int32 nOoxAngle ) const
550{
552 {
553 // map OOXML [0,360] clockwise (0deg top) to Chart2 counterclockwise (0deg left)
554 sal_Int32 nAngle = (450 - nOoxAngle) % 360;
555 rPropSet.setProperty( PROP_StartingAngle, nAngle );
556 }
557}
558
559void TypeGroupConverter::convertPieExplosion( PropertySet& rPropSet, sal_Int32 nOoxExplosion ) const
560{
562 {
563 // pie explosion restricted to 100% in Chart2, set as double in range [0,1]
564 double fOffset = getLimitedValue< double >( nOoxExplosion / 100.0, 0.0, 1.0 );
565 rPropSet.setProperty( PROP_Offset, fOffset );
566 }
567}
568
569// private --------------------------------------------------------------------
570
571void TypeGroupConverter::insertDataSeries( const Reference< XChartType >& rxChartType, const Reference< XDataSeries >& rxSeries, sal_Int32 nAxesSetIdx )
572{
573 if( !rxSeries.is() )
574 return;
575
576 PropertySet aSeriesProp( rxSeries );
577
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 );
587
588 // additional series properties
589 aSeriesProp.setProperty( PROP_AttachedAxisIndex, nAxesSetIdx );
590
591 // insert series into container
592 try
593 {
594 Reference< XDataSeriesContainer > xSeriesCont( rxChartType, UNO_QUERY_THROW );
595 xSeriesCont->addDataSeries( rxSeries );
596 }
597 catch( Exception& )
598 {
599 OSL_FAIL( "TypeGroupConverter::insertDataSeries - cannot add data series" );
600 }
601}
602
603} // namespace oox
604
605/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const PropertyValue * pValues
constexpr auto convertPointToMm100(N n)
A wrapper for a UNO property set.
Definition: propertyset.hxx:58
bool getProperty(Type &orValue, sal_Int32 nPropId) const
Gets the specified property from the property set.
Definition: propertyset.hxx:94
bool setProperty(sal_Int32 nPropId, const Type &rValue)
Puts the passed value into the property set.
bool has(key_type nKey) const
Returns true, if the object associated to the passed key exists.
Definition: refmap.hxx:52
Template for a vector of ref-counted objects with additional accessor functions.
Definition: refvector.hxx:43
value_type get(sal_Int32 nIndex) const
Returns a reference to the object with the passed index, or 0 on error.
Definition: refvector.hxx:52
::Color getColor(const GraphicHelper &rGraphicHelper, ::Color nPhClr=API_RGB_TRANSPARENT) const
Returns the final RGB color value.
Definition: color.cxx:644
Base class of all converter classes.
const ModelType & getModel() const
::oox::core::XmlFilterBase & getFilter() const
Returns the filter object of the imported/exported document.
ObjectFormatter & getFormatter() const
Returns the object formatter.
css::uno::Reference< css::uno::XInterface > createInstance(const OUString &rServiceName) const
Creates an instance for the passed service name, using the process service factory.
css::uno::Reference< css::uno::XComponentContext > const & getComponentContext() const
ModelType & create(KeyType eKey)
Definition: modelbase.hxx:85
void convertFrameFormatting(PropertySet &rPropSet, const ModelRef< Shape > &rxShapeProp, ObjectType eObjType, sal_Int32 nSeriesIdx=-1)
Sets frame formatting properties to the passed property set.
css::uno::Reference< css::chart2::XDataSeries > createDataSeries(const TypeGroupConverter &rTypeGroup, bool bVaryColorsByPoint)
Creates a data series object with initialized source links.
css::uno::Reference< css::chart2::data::XLabeledDataSequence > createCategorySequence(const OUString &rRole)
Creates a labeled data sequence object from category data link.
void convertBarGeometry(PropertySet &rPropSet, sal_Int32 nOoxShape) const
Sets the passed OOXML bar 3D geometry at the passed property set.
bool is3dChart() const
Returns true, if the chart is three-dimensional.
void convertPieExplosion(PropertySet &rPropSet, sal_Int32 nOoxExplosion) const
Sets the passed OOXML pie explosion at the passed property set.
bool isWall3dChart() const
Returns true, if chart type supports wall and floor format in 3D mode.
void insertDataSeries(const css::uno::Reference< css::chart2::XChartType > &rxChartType, const css::uno::Reference< css::chart2::XDataSeries > &rxSeries, sal_Int32 nAxesSetIdx)
Inserts the passed series into the chart type.
bool isSeriesFrameFormat() const
Returns true, if this chart type supports area formatting for its series.
css::uno::Reference< css::chart2::data::XLabeledDataSequence > createCategorySequence()
Creates a labeled data sequence object for axis categories.
css::uno::Reference< css::chart2::XCoordinateSystem > createCoordinateSystem()
Creates a coordinate system according to the contained chart type.
void convertMarker(PropertySet &rPropSet, sal_Int32 nOoxSymbol, sal_Int32 nOoxSize, const ModelRef< Shape > &xShapeProps) const
Sets the passed OOXML marker style at the passed property set.
TypeGroupConverter(const ConverterRoot &rParent, TypeGroupModel &rModel)
ObjectType getSeriesObjectType() const
Returns the object type for a series depending on the chart type.
bool mb3dChart
Extended type info for contained chart type model.
void convertPieRotation(PropertySet &rPropSet, sal_Int32 nOoxAngle) const
Sets the passed OOXML pie rotation at the passed property set.
OUString getSingleSeriesTitle() const
Returns series title, if the chart type group contains only one single series.
void convertLineSmooth(PropertySet &rPropSet, bool bOoxSmooth) const
Sets the passed OOXML line smoothing at the passed property set.
bool isDeep3dChart() const
Returns true, if the series in this chart type group are ordered on the Z axis.
bool isStacked() const
Returns true, if the series in this chart type group are stacked on each other (no percentage).
void convertFromModel(const css::uno::Reference< css::chart2::XDiagram > &rxDiagram, const css::uno::Reference< css::chart2::XCoordinateSystem > &rxCoordSystem, sal_Int32 nAxesSetIdx, bool bSupportsVaryColorsByPoint)
Converts the OOXML type group model into a chart2 coordinate system.
bool isPercent() const
Returns true, if the series in this chart type group are stacked on each other as percentage.
UpDownBarsConverter(const ConverterRoot &rParent, UpDownBarsModel &rModel)
void convertFromModel(const css::uno::Reference< css::chart2::XChartType > &rxChartType)
Converts the OOXML up/down bars.
DocumentType eType
Sequence< sal_Int8 > aSeq
@ Exception
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
@ TYPECATEGORY_RADAR
Line charts (line, area, stock charts).
@ TYPECATEGORY_SURFACE
Scatter and bubble charts.
@ TYPECATEGORY_SCATTER
Pie and donut charts.
@ TYPECATEGORY_PIE
Radar charts (linear or filled).
@ TYPECATEGORY_LINE
Bar charts (horizontal or vertical).
const TypeGroupInfo & GetTypeGroupInfo(TypeId eType)
ObjectType
Enumerates different object types for specific automatic formatting behaviour.
@ OBJECTTYPE_FILLEDSERIES2D
Linear series in 2D line/radarline/scatter charts.
@ OBJECTTYPE_HILOLINE
Drop lines between data points and X axis.
@ OBJECTTYPE_FILLEDSERIES3D
Filled series in 2D bar/area/radararea/bubble/pie/surface charts.
@ OBJECTTYPE_LINEARSERIES2D
Axis minor grid line.
@ OBJECTTYPE_UPBAR
High/low lines in line/stock charts.
@ OBJECTTYPE_DOWNBAR
Up-bar in line/stock charts.
TypeId
Enumerates different chart types.
@ TYPEID_OFPIE
Doughnut (ring) chart.
@ TYPEID_LINE
Horizontal bar chart.
@ TYPEID_HORBAR
Vertical bar chart.
@ TYPEID_PIE
Filled radar chart.
@ TYPEID_UNKNOWN
Surface chart.
@ TYPEID_BUBBLE
Scatter (XY) chart.
@ TYPEID_RADARAREA
Linear radar chart.
@ TYPEID_SCATTER
Pie-to-pie or pie-to-bar chart.
@ VARPOINTMODE_MULTI
Only supported, if type group contains only one series.
@ VARPOINTMODE_SINGLE
No varied colors supported.
XML_none
bool mb3dChart
@ VALUES
Data point categories.
bool mbSmooth
True = invert negative data points.
Contains info for a chart type related to the OpenOffice.org chart module.
VarPointMode meVarPointMode
Service name of the type.
bool mbSeriesIsFrame2d
True = polar, false = cartesian.
bool mbSingleSeriesVis
True = 2D type series with area formatting.
bool mbSwappedAxesSet
True = X axis contains categories.
bool mbSupportsStacking
True = X axis and Y axis are swapped.
bool mbPolarCoordSystem
Default data label position (API constant).
const char * mpcServiceName
Category this chart type belongs to.
TypeCategory meTypeCategory
Unique chart type identifier.
sal_Int32 mnGapWidth
Space between series in deep 3D charts.
sal_Int32 mnGrouping
Space between bars in bar charts, or space in pie-to charts.
bool mbVaryColors
True = smooth lines in line charts.
sal_Int32 mnRadarStyle
Bar overlap per category (2D bar charts only).
sal_Int32 mnFirstAngle
Relative scaling of bubble size (percent).
ShapeRef mxHiLowLines
Drop lines connecting data points with X axis.
sal_Int32 mnTypeId
Split type in pie-to charts.
sal_Int32 mnOverlap
Pie-to-pie or pie-to-bar chart.
sal_Int32 mnBarDir
Threshold value in pie-to charts.
UpDownBarsRef mxUpDownBars
Data point label settings for all series.
ShapeRef mxSerLines
Up/down bars in stock charts.
ShapeRef mxUpBars
Formatting of down bars.
#define ENSURE_AXESCOUNT(min, max)
constexpr OUStringLiteral PROP_StartingAngle
constexpr OUStringLiteral PROP_LineStyle