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 #include <osl/diagnose.h>
43 #include <oox/token/namespaces.hxx>
44 #include <oox/token/properties.hxx>
45 #include <oox/token/tokens.hxx>
46 #include <tools/UnitConversion.hxx>
47 
48 namespace oox::drawingml::chart {
49 
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;
54 
55 namespace {
56 
57 // chart type service names
58 const char SERVICE_CHART2_AREA[] = "com.sun.star.chart2.AreaChartType";
59 const char SERVICE_CHART2_CANDLE[] = "com.sun.star.chart2.CandleStickChartType";
60 const char SERVICE_CHART2_COLUMN[] = "com.sun.star.chart2.ColumnChartType";
61 const char SERVICE_CHART2_LINE[] = "com.sun.star.chart2.LineChartType";
62 const char SERVICE_CHART2_NET[] = "com.sun.star.chart2.NetChartType";
63 const char SERVICE_CHART2_FILLEDNET[] = "com.sun.star.chart2.FilledNetChartType";
64 const char SERVICE_CHART2_PIE[] = "com.sun.star.chart2.PieChartType";
65 const char SERVICE_CHART2_SCATTER[] = "com.sun.star.chart2.ScatterChartType";
66 const char SERVICE_CHART2_BUBBLE[] = "com.sun.star.chart2.BubbleChartType";
67 const char SERVICE_CHART2_SURFACE[] = "com.sun.star.chart2.ColumnChartType"; // Todo
68 
69 namespace csscd = ::com::sun::star::chart::DataLabelPlacement;
70 
71 const TypeGroupInfo spTypeInfos[] =
72 {
73  // type-id type-category service varied-point-color default label pos polar area2d 1stvis xcateg swap stack picopt
74  { TYPEID_BAR, TYPECATEGORY_BAR, SERVICE_CHART2_COLUMN, VARPOINTMODE_SINGLE, csscd::OUTSIDE, false, true, false, true, false, true, true },
75  { TYPEID_HORBAR, TYPECATEGORY_BAR, SERVICE_CHART2_COLUMN, VARPOINTMODE_SINGLE, csscd::OUTSIDE, false, true, false, true, true, true, true },
76  { TYPEID_LINE, TYPECATEGORY_LINE, SERVICE_CHART2_LINE, VARPOINTMODE_SINGLE, csscd::RIGHT, false, false, false, true, false, true, false },
77  { TYPEID_AREA, TYPECATEGORY_LINE, SERVICE_CHART2_AREA, VARPOINTMODE_NONE, csscd::CENTER, false, true, false, true, false, true, false },
78  { TYPEID_STOCK, TYPECATEGORY_LINE, SERVICE_CHART2_CANDLE, VARPOINTMODE_NONE, csscd::RIGHT, false, false, false, true, false, true, false },
79  { TYPEID_RADARLINE, TYPECATEGORY_RADAR, SERVICE_CHART2_NET, VARPOINTMODE_SINGLE, csscd::OUTSIDE, true, false, false, true, false, false, false },
80  { TYPEID_RADARAREA, TYPECATEGORY_RADAR, SERVICE_CHART2_FILLEDNET, VARPOINTMODE_NONE, csscd::OUTSIDE, true, true, false, true, false, false, false },
81  { TYPEID_PIE, TYPECATEGORY_PIE, SERVICE_CHART2_PIE, VARPOINTMODE_MULTI, csscd::AVOID_OVERLAP, true, true, true, true, false, false, false },
82  { TYPEID_DOUGHNUT, TYPECATEGORY_PIE, SERVICE_CHART2_PIE, VARPOINTMODE_MULTI, csscd::AVOID_OVERLAP, true, true, false, true, false, false, false },
83  { TYPEID_OFPIE, TYPECATEGORY_PIE, SERVICE_CHART2_PIE, VARPOINTMODE_MULTI, csscd::AVOID_OVERLAP, true, true, true, true, false, false, false },
84  { TYPEID_SCATTER, TYPECATEGORY_SCATTER, SERVICE_CHART2_SCATTER, VARPOINTMODE_SINGLE, csscd::RIGHT, 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 },
86  { TYPEID_SURFACE, TYPECATEGORY_SURFACE, SERVICE_CHART2_SURFACE, VARPOINTMODE_NONE, csscd::RIGHT, false, true, false, true, false, false, false }
87 };
88 
89 const TypeGroupInfo saUnknownTypeInfo =
90  { TYPEID_UNKNOWN, TYPECATEGORY_BAR, SERVICE_CHART2_COLUMN, VARPOINTMODE_SINGLE, csscd::OUTSIDE, false, true, false, true, false, true, true };
91 
92 const TypeGroupInfo& lclGetTypeInfoFromTypeId( TypeId eTypeId )
93 {
94  for( auto const &rIt : spTypeInfos)
95  {
96  if( rIt.meTypeId == eTypeId )
97  return rIt;
98  }
99  OSL_ENSURE( eTypeId == TYPEID_UNKNOWN, "lclGetTypeInfoFromTypeId - unexpected chart type identifier" );
100  return saUnknownTypeInfo;
101 }
102 
103 } // namespace
104 
106 {
107  return lclGetTypeInfoFromTypeId(eType);
108 }
109 
111  ConverterBase< UpDownBarsModel >( rParent, rModel )
112 {
113 }
114 
116 {
117 }
118 
120 {
121  PropertySet aTypeProp( rxChartType );
122 
123  // upbar format
124  Reference< XPropertySet > xWhitePropSet;
125  if( aTypeProp.getProperty( xWhitePropSet, PROP_WhiteDay ) )
126  {
127  PropertySet aPropSet( xWhitePropSet );
129  }
130 
131  // downbar format
132  Reference< XPropertySet > xBlackPropSet;
133  if( aTypeProp.getProperty( xBlackPropSet, PROP_BlackDay ) )
134  {
135  PropertySet aPropSet( xBlackPropSet );
137  }
138 }
139 
141  ConverterBase< TypeGroupModel >( rParent, rModel ),
142  mb3dChart( false )
143 {
144  TypeId eTypeId = TYPEID_UNKNOWN;
145  switch( mrModel.mnTypeId )
146  {
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
166  }
167 
168  // special handling for some chart types
169  switch( eTypeId )
170  {
171  case TYPEID_BAR:
172  if( mrModel.mnBarDir == XML_bar )
173  eTypeId = TYPEID_HORBAR;
174  break;
175  case TYPEID_RADARLINE:
176  if( mrModel.mnRadarStyle == XML_filled )
177  eTypeId = TYPEID_RADARAREA;
178  break;
179  case TYPEID_SURFACE:
180  // create a deep 3D bar chart from surface charts
181  mrModel.mnGrouping = XML_standard;
182  break;
183  default:;
184  }
185 
186  // set the chart type info struct for the current chart type
187  maTypeInfo = lclGetTypeInfoFromTypeId( eTypeId );
188 }
189 
191 {
192 }
193 
195 {
196  return maTypeInfo.mbSupportsStacking && (mrModel.mnGrouping == XML_stacked);
197 }
198 
200 {
201  return maTypeInfo.mbSupportsStacking && (mrModel.mnGrouping == XML_percentStacked);
202 }
203 
205 {
207 }
208 
210 {
211  return isWall3dChart() && (mrModel.mnGrouping == XML_standard);
212 }
213 
215 {
217 }
218 
220 {
223 }
224 
226 {
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;
233  return aSeriesTitle;
234 }
235 
237 {
238  // create the coordinate system object
240  Reference< XCoordinateSystem > xCoordSystem;
242  {
243  if( mb3dChart )
244  xCoordSystem = css::chart2::PolarCoordinateSystem3d::create(xContext);
245  else
246  xCoordSystem = css::chart2::PolarCoordinateSystem2d::create(xContext);
247  }
248  else
249  {
250  if( mb3dChart )
251  xCoordSystem = css::chart2::CartesianCoordinateSystem3d::create(xContext);
252  else
253  xCoordSystem = css::chart2::CartesianCoordinateSystem2d::create(xContext);
254  }
255 
256  // swap X and Y axis
258  {
259  PropertySet aPropSet( xCoordSystem );
260  aPropSet.setProperty( PROP_SwapXAndYAxis, true );
261  }
262 
263  return xCoordSystem;
264 }
265 
267 {
268  sal_Int32 nMaxValues = 0;
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)
274  {
275  if( elem->maSources.has( SeriesModel::CATEGORIES ) )
276  {
277  SeriesConverter aSeriesConv(*this, *elem);
278  xLabeledSeq = aSeriesConv.createCategorySequence( "categories" );
279  if (xLabeledSeq.is())
280  break;
281  }
282  else if( nMaxValues <= 0 && elem->maSources.has( SeriesModel::VALUES ) )
283  {
284  DataSourceModel *pValues = elem->maSources.get( SeriesModel::VALUES ).get();
285  if( pValues->mxDataSeq.is() )
286  nMaxValues = pValues->mxDataSeq->maData.size();
287  }
288  }
289  /* n#839727 Create Category Sequence when none are found */
290  if( !xLabeledSeq.is() && !mrModel.maSeries.empty() ) {
291  if( nMaxValues < 0 )
292  nMaxValues = 2;
293  SeriesModel &aModel = *mrModel.maSeries.get(0);
295  {
298  aSeq.mnPointCount = nMaxValues;
299  for( sal_Int32 i = 0; i < nMaxValues; i++ )
300  aSeq.maData[ i ] <<= OUString::number( i + 1 );
301  }
302  SeriesConverter aSeriesConv( *this, aModel );
303  xLabeledSeq = aSeriesConv.createCategorySequence( "categories" );
304  }
305  return xLabeledSeq;
306 }
307 
309  const Reference< XCoordinateSystem >& rxCoordSystem,
310  sal_Int32 nAxesSetIdx, bool bSupportsVaryColorsByPoint )
311 {
312  try
313  {
314  // create the chart type object
315  OUString aService = OUString::createFromAscii( maTypeInfo.mpcServiceName );
316  Reference< XChartType > xChartType( createInstance( aService ), UNO_QUERY_THROW );
317 
318  Reference< XChartTypeContainer > xChartTypeContOld( rxCoordSystem, UNO_QUERY_THROW );
319  Sequence< Reference< XChartType > > xOldChartTypes( xChartTypeContOld->getChartTypes() );
320  sal_Int32 nOldChartTypeIdx = -1;
321 
322  // additional properties
323  PropertySet aDiaProp( rxDiagram );
324  PropertySet aTypeProp( xChartType );
325  switch( maTypeInfo.meTypeCategory )
326  {
327  case TYPECATEGORY_BAR:
328  {
329  Sequence< sal_Int32 > aInt32Seq( 2 );
330  aInt32Seq[ 0 ] = aInt32Seq[ 1 ] = mrModel.mnOverlap;
331  aTypeProp.setProperty( PROP_OverlapSequence, aInt32Seq );
332  aInt32Seq[ 0 ] = aInt32Seq[ 1 ] = 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. */
342  if( !is3dChart() && (maTypeInfo.meTypeId != TYPEID_OFPIE) )
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( ContainerHelper::vectorToSequence( 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 
469 void 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 
518 void 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 
528 void 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 
549 void 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 
559 void 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 
571 void 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: */
sal_Int32 mnRadarStyle
Bar overlap per category (2D bar charts only).
css::uno::Reference< css::chart2::XCoordinateSystem > createCoordinateSystem()
Creates a coordinate system according to the contained chart type.
void convertPieRotation(PropertySet &rPropSet, sal_Int32 nOoxAngle) const
Sets the passed OOXML pie rotation at the passed property set.
sal_Int32 mnTypeId
Split type in pie-to charts.
const char * mpcServiceName
Category this chart type belongs to.
bool is3dChart() const
Returns true, if the chart is three-dimensional.
bool mbPolarCoordSystem
Default data label position (API constant).
bool isStacked() const
Returns true, if the series in this chart type group are stacked on each other (no percentage)...
bool getProperty(Type &orValue, sal_Int32 nPropId) const
Gets the specified property from the property set.
Definition: propertyset.hxx:94
TypeCategory meTypeCategory
Unique chart type identifier.
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.
Base class of all converter classes.
sal_Int32 mnGrouping
Space between bars in bar charts, or space in pie-to charts.
value_type get(sal_Int32 nIndex) const
Returns a reference to the object with the passed index, or 0 on error.
Definition: refvector.hxx:51
css::uno::Reference< css::chart2::data::XLabeledDataSequence > createCategorySequence()
Creates a labeled data sequence object for axis categories.
bool mbSeriesIsFrame2d
True = polar, false = cartesian.
bool mbSupportsStacking
True = X axis and Y axis are swapped.
ObjectType getSeriesObjectType() const
Returns the object type for a series depending on the chart type.
css::uno::Reference< css::uno::XInterface > createInstance(const OUString &rServiceName) const
Creates an instance for the passed service name, using the process service factory.
bool isWall3dChart() const
Returns true, if chart type supports wall and floor format in 3D mode.
void convertFromModel(const css::uno::Reference< css::chart2::XChartType > &rxChartType)
Converts the OOXML up/down bars.
ObjectType
Enumerates different object types for specific automatic formatting behaviour.
bool isDeep3dChart() const
Returns true, if the series in this chart type group are ordered on the Z axis.
bool mb3dChart
TypeGroupConverter(const ConverterRoot &rParent, TypeGroupModel &rModel)
bool has(key_type nKey) const
Returns true, if the object associated to the passed key exists.
Definition: refmap.hxx:51
ShapeRef mxSerLines
Up/down bars in stock charts.
sal_Int32 mnOverlap
Pie-to-pie or pie-to-bar chart.
bool mb3dChart
Extended type info for contained chart type model.
bool mbSwappedAxesSet
True = X axis contains categories.
void convertFrameFormatting(PropertySet &rPropSet, const ModelRef< Shape > &rxShapeProp, ObjectType eObjType, sal_Int32 nSeriesIdx=-1)
Sets frame formatting properties to the passed property set.
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.
UpDownBarsRef mxUpDownBars
Data point label settings for all series.
TypeId
Enumerates different chart types.
::Color getColor(const GraphicHelper &rGraphicHelper,::Color nPhClr=API_RGB_TRANSPARENT) const
Returns the final RGB color value.
Definition: color.cxx:481
Contains info for a chart type related to the OpenOffice.org chart module.
VarPointMode meVarPointMode
Service name of the type.
sal_Int32 mnBarDir
Threshold value in pie-to charts.
css::uno::Reference< css::chart2::data::XLabeledDataSequence > createCategorySequence(const OUString &rRole)
Creates a labeled data sequence object from category data link.
sal_Int32 mnPointCount
Number format for double values.
sal_Int32 mnGapWidth
Space between series in deep 3D charts.
const TypeGroupInfo & GetTypeGroupInfo(TypeId eType)
Bar charts (horizontal or vertical).
const ModelType & getModel() const
#define ENSURE_AXESCOUNT(min, max)
css::uno::Reference< css::uno::XComponentContext > const & getComponentContext() const
Pie-to-pie or pie-to-bar chart.
Linear series in 2D line/radarline/scatter charts.
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.
void convertLineSmooth(PropertySet &rPropSet, bool bOoxSmooth) const
Sets the passed OOXML line smoothing at the passed property set.
bool mbSmooth
True = invert negative data points.
A wrapper for a UNO property set.
Definition: propertyset.hxx:57
Drop lines between data points and X axis.
constexpr auto convertPointToMm100(N n)
ShapeRef mxUpBars
Formatting of down bars.
UpDownBarsConverter(const ConverterRoot &rParent, UpDownBarsModel &rModel)
const PropertyValue * pValues
bool isPercent() const
Returns true, if the series in this chart type group are stacked on each other as percentage...
Line charts (line, area, stock charts).
Radar charts (linear or filled).
void convertBarGeometry(PropertySet &rPropSet, sal_Int32 nOoxShape) const
Sets the passed OOXML bar 3D geometry at the passed property set.
ShapeRef mxHiLowLines
Drop lines connecting data points with X axis.
bool mbSingleSeriesVis
True = 2D type series with area formatting.
bool isSeriesFrameFormat() const
Returns true, if this chart type supports area formatting for its series.
Sequence< sal_Int8 > aSeq
Template for a vector of ref-counted objects with additional accessor functions.
Definition: refvector.hxx:41
sal_Int32 mnFirstAngle
Relative scaling of bubble size (percent).
static css::uno::Sequence< typename VectorType::value_type > vectorToSequence(const VectorType &rVector)
Creates a UNO sequence from a std::vector with copies of all elements.
bool mbVaryColors
True = smooth lines in line charts.
::oox::core::XmlFilterBase & getFilter() const
Returns the filter object of the imported/exported document.
Only supported, if type group contains only one series.
Filled series in 2D bar/area/radararea/bubble/pie/surface charts.
void convertPieExplosion(PropertySet &rPropSet, sal_Int32 nOoxExplosion) const
Sets the passed OOXML pie explosion at the passed property set.
OUString getSingleSeriesTitle() const
Returns series title, if the chart type group contains only one single series.
ModelType & create(KeyType eKey)
Definition: modelbase.hxx:89
High/low lines in line/stock charts.
bool setProperty(sal_Int32 nPropId, const Type &rValue)
Puts the passed value into the property set.
ObjectFormatter & getFormatter() const
Returns the object formatter.
css::uno::Reference< css::chart2::XDataSeries > createDataSeries(const TypeGroupConverter &rTypeGroup, bool bVaryColorsByPoint)
Creates a data series object with initialized source links.