LibreOffice Module oox (master) 1
axisconverter.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#include <ooxresid.hxx>
22#include <strings.hrc>
23
24#include <com/sun/star/chart/ChartAxisArrangeOrderType.hpp>
25#include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
26#include <com/sun/star/chart/ChartAxisMarkPosition.hpp>
27#include <com/sun/star/chart/ChartAxisPosition.hpp>
28#include <com/sun/star/chart/TimeInterval.hpp>
29#include <com/sun/star/chart/TimeUnit.hpp>
30#include <com/sun/star/chart2/AxisType.hpp>
31#include <com/sun/star/chart2/TickmarkStyle.hpp>
32#include <com/sun/star/chart2/LinearScaling.hpp>
33#include <com/sun/star/chart2/LogarithmicScaling.hpp>
34#include <com/sun/star/chart2/XAxis.hpp>
35#include <com/sun/star/chart2/XCoordinateSystem.hpp>
36#include <com/sun/star/chart2/XTitled.hpp>
42#include <oox/token/namespaces.hxx>
43#include <oox/token/properties.hxx>
44#include <oox/token/tokens.hxx>
46#include <osl/diagnose.h>
47
48namespace oox::drawingml::chart {
49
50using namespace ::com::sun::star::beans;
51using namespace ::com::sun::star::chart2;
52using namespace ::com::sun::star::uno;
53
54namespace {
55
56void lclSetValueOrClearAny( Any& orAny, const std::optional< double >& rofValue )
57{
58 if( rofValue.has_value() ) orAny <<= rofValue.value(); else orAny.clear();
59}
60
61bool lclIsLogarithmicScale( const AxisModel& rAxisModel )
62{
63 return rAxisModel.mofLogBase.has_value() && (2.0 <= rAxisModel.mofLogBase.value()) && (rAxisModel.mofLogBase.value() <= 1000.0);
64}
65
66sal_Int32 lclGetApiTimeUnit( sal_Int32 nTimeUnit )
67{
68 using namespace ::com::sun::star::chart;
69 switch( nTimeUnit )
70 {
71 case XML_days: return TimeUnit::DAY;
72 case XML_months: return TimeUnit::MONTH;
73 case XML_years: return TimeUnit::YEAR;
74 default: OSL_ENSURE( false, "lclGetApiTimeUnit - unexpected time unit" );
75 }
76 return TimeUnit::DAY;
77}
78
79void lclConvertTimeInterval( Any& orInterval, const std::optional< double >& rofUnit, sal_Int32 nTimeUnit )
80{
81 if( rofUnit.has_value() && (1.0 <= rofUnit.value()) && (rofUnit.value() <= SAL_MAX_INT32) )
82 orInterval <<= css::chart::TimeInterval( static_cast< sal_Int32 >( rofUnit.value() ), lclGetApiTimeUnit( nTimeUnit ) );
83 else
84 orInterval.clear();
85}
86
87css::chart::ChartAxisLabelPosition lclGetLabelPosition( sal_Int32 nToken )
88{
89 using namespace ::com::sun::star::chart;
90 switch( nToken )
91 {
92 case XML_high: return ChartAxisLabelPosition_OUTSIDE_END;
93 case XML_low: return ChartAxisLabelPosition_OUTSIDE_START;
94 case XML_nextTo: return ChartAxisLabelPosition_NEAR_AXIS;
95 }
96 return ChartAxisLabelPosition_NEAR_AXIS;
97}
98
99sal_Int32 lclGetTickMark( sal_Int32 nToken )
100{
101 using namespace ::com::sun::star::chart2::TickmarkStyle;
102 switch( nToken )
103 {
104 case XML_in: return INNER;
105 case XML_out: return OUTER;
106 case XML_cross: return INNER | OUTER;
107 }
108 return css::chart2::TickmarkStyle::NONE;
109}
110
115bool isPercent( const RefVector<TypeGroupConverter>& rTypeGroups )
116{
117 if (rTypeGroups.empty())
118 return false;
119
120 for (auto const& typeGroup : rTypeGroups)
121 {
122 TypeGroupConverter& rConv = *typeGroup;
123 if (!rConv.isPercent())
124 return false;
125 }
126
127 return true;
128}
129
130} // namespace
131
133 ConverterBase< AxisModel >( rParent, rModel )
134{
135}
136
138{
139}
140
143 const AxisModel* pCrossingAxis, sal_Int32 nAxesSetIdx,
144 sal_Int32 nAxisIdx, bool bUseFixedInnerSize)
145{
146 if (rTypeGroups.empty())
147 return;
148
149 Reference< XAxis > xAxis;
150 try
151 {
152 namespace cssc = ::com::sun::star::chart;
153 namespace cssc2 = ::com::sun::star::chart2;
154
155 const TypeGroupInfo& rTypeInfo = rTypeGroups.front()->getTypeInfo();
156 ObjectFormatter& rFormatter = getFormatter();
157
158 // create the axis object (always)
159 xAxis.set( createInstance( "com.sun.star.chart2.Axis" ), UNO_QUERY_THROW );
160 PropertySet aAxisProp( xAxis );
161 // #i58688# axis enabled
162 aAxisProp.setProperty( PROP_Show, !mrModel.mbDeleted );
163
164 // axis line, tick, and gridline properties ---------------------------
165
166 // show axis labels
167 aAxisProp.setProperty( PROP_DisplayLabels, mrModel.mnTickLabelPos != XML_none );
168 aAxisProp.setProperty( PROP_LabelPosition, lclGetLabelPosition( mrModel.mnTickLabelPos ) );
169 // no X axis line in radar charts
170 if( (nAxisIdx == API_X_AXIS) && (rTypeInfo.meTypeCategory == TYPECATEGORY_RADAR) )
172 // axis line and tick label formatting
174 // tick label rotation
176
177 // tick mark style
178 aAxisProp.setProperty( PROP_MajorTickmarks, lclGetTickMark( mrModel.mnMajorTickMark ) );
179 aAxisProp.setProperty( PROP_MinorTickmarks, lclGetTickMark( mrModel.mnMinorTickMark ) );
180 aAxisProp.setProperty( PROP_MarkPosition, cssc::ChartAxisMarkPosition_AT_AXIS );
181
182 // main grid
183 PropertySet aGridProp( xAxis->getGridProperties() );
184 aGridProp.setProperty( PROP_Show, mrModel.mxMajorGridLines.is() );
187
188 // sub grid
189 Sequence< Reference< XPropertySet > > aSubGridPropSeq = xAxis->getSubGridProperties();
190 if( aSubGridPropSeq.hasElements() )
191 {
192 PropertySet aSubGridProp( aSubGridPropSeq[ 0 ] );
193 aSubGridProp.setProperty( PROP_Show, mrModel.mxMinorGridLines.is() );
196 }
197
198 // axis type and X axis categories ------------------------------------
199
200 ScaleData aScaleData = xAxis->getScaleData();
201 // set axis type
202 switch( nAxisIdx )
203 {
204 case API_X_AXIS:
205 if( rTypeInfo.mbCategoryAxis )
206 {
207 OSL_ENSURE( (mrModel.mnTypeId == C_TOKEN( catAx )) || (mrModel.mnTypeId == C_TOKEN( dateAx )),
208 "AxisConverter::convertFromModel - unexpected axis model type (must: c:catAx or c:dateAx)" );
209 bool bDateAxis = mrModel.mnTypeId == C_TOKEN( dateAx );
210 // tdf#132076: set axis type to date, if it is a date axis!
211 aScaleData.AxisType = bDateAxis ? cssc2::AxisType::DATE : cssc2::AxisType::CATEGORY;
212 aScaleData.AutoDateAxis = mrModel.mbAuto;
213 /* TODO: create main category axis labels once, while InternalDataProvider
214 can not handle different category names on the primary and secondary category axis. */
215 if( nAxesSetIdx == 0 )
216 aScaleData.Categories = rTypeGroups.front()->createCategorySequence();
217 /* set default ShiftedCategoryPosition values for some charttype,
218 because the XML can contain wrong CrossBetween value, if came from MSO */
219 if( rTypeGroups.front()->is3dChart() && (rTypeInfo.meTypeId == TYPEID_BAR || rTypeInfo.meTypeId == TYPEID_HORBAR || rTypeInfo.meTypeId == TYPEID_STOCK) )
220 aScaleData.ShiftedCategoryPosition = true;
221 else if( rTypeInfo.meTypeId == TYPEID_RADARLINE || rTypeInfo.meTypeId == TYPEID_RADARAREA )
222 aScaleData.ShiftedCategoryPosition = false;
223 else if( pCrossingAxis->mnCrossBetween != -1 ) /*because of backwards compatibility*/
224 aScaleData.ShiftedCategoryPosition = pCrossingAxis->mnCrossBetween == XML_between;
225 else if( rTypeInfo.meTypeCategory == TYPECATEGORY_BAR || rTypeInfo.meTypeId == TYPEID_LINE || rTypeInfo.meTypeId == TYPEID_STOCK )
226 aScaleData.ShiftedCategoryPosition = true;
227 }
228 else
229 {
230 OSL_ENSURE( mrModel.mnTypeId == C_TOKEN( valAx ), "AxisConverter::convertFromModel - unexpected axis model type (must: c:valAx)" );
231 aScaleData.AxisType = cssc2::AxisType::REALNUMBER;
232 }
233 break;
234 case API_Y_AXIS:
235 OSL_ENSURE( mrModel.mnTypeId == C_TOKEN( valAx ), "AxisConverter::convertFromModel - unexpected axis model type (must: c:valAx)" );
236 aScaleData.AxisType = isPercent(rTypeGroups) ? cssc2::AxisType::PERCENT : cssc2::AxisType::REALNUMBER;
237 break;
238 case API_Z_AXIS:
239 OSL_ENSURE( mrModel.mnTypeId == C_TOKEN( serAx ), "AxisConverter::convertFromModel - unexpected axis model type (must: c:serAx)" );
240 OSL_ENSURE( rTypeGroups.front()->isDeep3dChart(), "AxisConverter::convertFromModel - series axis not supported by this chart type" );
241 aScaleData.AxisType = cssc2::AxisType::SERIES;
242 break;
243 }
244
245 // axis scaling and increment -----------------------------------------
246
247 switch( aScaleData.AxisType )
248 {
249 case cssc2::AxisType::CATEGORY:
250 case cssc2::AxisType::SERIES:
251 case cssc2::AxisType::DATE:
252 {
253 /* Determine date axis type from XML type identifier, and not
254 via aScaleData.AxisType, as this value sticks to CATEGORY
255 for automatic category/date axes). */
256 if( mrModel.mnTypeId == C_TOKEN( dateAx ) )
257 {
258 // scaling algorithm
259 aScaleData.Scaling = LinearScaling::create( comphelper::getProcessComponentContext() );
260 // min/max
261 lclSetValueOrClearAny( aScaleData.Minimum, mrModel.mofMin );
262 lclSetValueOrClearAny( aScaleData.Maximum, mrModel.mofMax );
263 // major/minor increment
264 lclConvertTimeInterval( aScaleData.TimeIncrement.MajorTimeInterval, mrModel.mofMajorUnit, mrModel.mnMajorTimeUnit );
265 lclConvertTimeInterval( aScaleData.TimeIncrement.MinorTimeInterval, mrModel.mofMinorUnit, mrModel.mnMinorTimeUnit );
266 // base time unit
267 if( mrModel.monBaseTimeUnit.has_value() )
268 aScaleData.TimeIncrement.TimeResolution <<= lclGetApiTimeUnit( mrModel.monBaseTimeUnit.value() );
269 else
270 aScaleData.TimeIncrement.TimeResolution.clear();
271 }
272 else
273 {
274 // do not overlap text unless the rotation is 0 in xml
275 bool bTextOverlap = false;
276 if (mrModel.mxTextProp.is()
277 && mrModel.mxTextProp->getTextProperties().moRotation.has_value())
278 bTextOverlap
279 = mrModel.mxTextProp->getTextProperties().moRotation.value() == 0;
280 aAxisProp.setProperty(PROP_TextOverlap, bTextOverlap);
281 /* do not break text into several lines unless the rotation is 0 degree,
282 or the rotation is 90 degree and the inner size of the chart is not fixed,
283 or the rotation is 270 degree and the inner size of the chart is not fixed */
284 bool bTextBreak = true;
285 double fRotationAngle = 0.0;
286 if (aAxisProp.getProperty(fRotationAngle, PROP_TextRotation)
287 && fRotationAngle != 0.0)
288 bTextBreak = !bUseFixedInnerSize
289 && (fRotationAngle == 90.0 || fRotationAngle == 270.0);
290 aAxisProp.setProperty(PROP_TextBreak, bTextBreak);
291 // do not stagger labels in two lines
292 aAxisProp.setProperty( PROP_ArrangeOrder, cssc::ChartAxisArrangeOrderType_SIDE_BY_SIDE );
294 }
295 }
296 break;
297 case cssc2::AxisType::REALNUMBER:
298 case cssc2::AxisType::PERCENT:
299 {
300 // scaling algorithm
301 const bool bLogScale = lclIsLogarithmicScale( mrModel );
302 if( bLogScale )
303 aScaleData.Scaling = LogarithmicScaling::create( comphelper::getProcessComponentContext() );
304 else
305 aScaleData.Scaling = LinearScaling::create( comphelper::getProcessComponentContext() );
306 // min/max
307 lclSetValueOrClearAny( aScaleData.Minimum, mrModel.mofMin );
308 lclSetValueOrClearAny( aScaleData.Maximum, mrModel.mofMax );
309 // major increment
310 IncrementData& rIncrementData = aScaleData.IncrementData;
311 if( mrModel.mofMajorUnit.has_value() && aScaleData.Scaling.is() )
312 rIncrementData.Distance <<= aScaleData.Scaling->doScaling( mrModel.mofMajorUnit.value() );
313 else
314 lclSetValueOrClearAny( rIncrementData.Distance, mrModel.mofMajorUnit );
315 // minor increment
316 Sequence< SubIncrement >& rSubIncrementSeq = rIncrementData.SubIncrements;
317 rSubIncrementSeq.realloc( 1 );
318 Any& rIntervalCount = rSubIncrementSeq.getArray()[ 0 ].IntervalCount;
319 rIntervalCount.clear();
320 if( bLogScale )
321 {
322 if( mrModel.mofMinorUnit.has_value() )
323 rIntervalCount <<= sal_Int32( 9 );
324 }
325 else if( mrModel.mofMajorUnit.has_value() && mrModel.mofMinorUnit.has_value() && (0.0 < mrModel.mofMinorUnit.value()) && (mrModel.mofMinorUnit.value() <= mrModel.mofMajorUnit.value()) )
326 {
327 double fCount = mrModel.mofMajorUnit.value() / mrModel.mofMinorUnit.value() + 0.5;
328 if( (1.0 <= fCount) && (fCount < 1001.0) )
329 rIntervalCount <<= static_cast< sal_Int32 >( fCount );
330 }
331 else if( !mrModel.mofMinorUnit.has_value() )
332 {
333 // tdf#114168 If minor unit is not set then set interval to 5, as MS Excel do.
334 rIntervalCount <<= static_cast< sal_Int32 >( 5 );
335 }
336 }
337 break;
338 default:
339 OSL_FAIL( "AxisConverter::convertFromModel - unknown axis type" );
340 }
341
342 /* Do not set a value to the Origin member anymore (already done via
343 new axis properties 'CrossoverPosition' and 'CrossoverValue'). */
344 aScaleData.Origin.clear();
345
346 // axis orientation ---------------------------------------------------
347
348 // #i85167# pie/donut charts need opposite direction at Y axis
349 // #i87747# radar charts need opposite direction at X axis
350 bool bMirrorDirection =
351 ((nAxisIdx == API_Y_AXIS) && (rTypeInfo.meTypeCategory == TYPECATEGORY_PIE)) ||
352 ((nAxisIdx == API_X_AXIS) && (rTypeInfo.meTypeCategory == TYPECATEGORY_RADAR));
353 bool bReverse = (mrModel.mnOrientation == XML_maxMin) != bMirrorDirection;
354 aScaleData.Orientation = bReverse ? cssc2::AxisOrientation_REVERSE : cssc2::AxisOrientation_MATHEMATICAL;
355
356 // write back scaling data
357 xAxis->setScaleData( aScaleData );
358
359 // number format ------------------------------------------------------
360 if( !mrModel.mbDeleted && aScaleData.AxisType != cssc2::AxisType::SERIES )
361 {
363 }
364
365 // position of crossing axis ------------------------------------------
366
367 bool bManualCrossing = mrModel.mofCrossesAt.has_value();
368 cssc::ChartAxisPosition eAxisPos = cssc::ChartAxisPosition_VALUE;
369 if( !bManualCrossing ) switch( mrModel.mnCrossMode )
370 {
371 case XML_min: eAxisPos = cssc::ChartAxisPosition_START; break;
372 case XML_max: eAxisPos = cssc::ChartAxisPosition_END; break;
373 case XML_autoZero: eAxisPos = cssc::ChartAxisPosition_ZERO; break;
374 }
375
376 aAxisProp.setProperty( PROP_CrossoverPosition, eAxisPos );
377
378 // calculate automatic origin depending on scaling mode of crossing axis
379 bool bCrossingLogScale = pCrossingAxis && lclIsLogarithmicScale( *pCrossingAxis );
380 double fCrossingPos = bManualCrossing ? mrModel.mofCrossesAt.value() : (bCrossingLogScale ? 1.0 : 0.0);
381 aAxisProp.setProperty( PROP_CrossoverValue, fCrossingPos );
382
383 // axis title ---------------------------------------------------------
384
385 // in radar charts, title objects may exist, but are not shown
386 if( mrModel.mxTitle.is() && (rTypeGroups.front()->getTypeInfo().meTypeCategory != TYPECATEGORY_RADAR) )
387 {
388 Reference< XTitled > xTitled( xAxis, UNO_QUERY_THROW );
389 if (((nAxisIdx == API_X_AXIS && rTypeInfo.meTypeId != TYPEID_HORBAR)
390 || (nAxisIdx == API_Y_AXIS && rTypeInfo.meTypeId == TYPEID_HORBAR))
391 && (mrModel.mnAxisPos == XML_l || mrModel.mnAxisPos == XML_r))
392 mrModel.mxTitle->mnDefaultRotation = 0;
393 TitleConverter aTitleConv( *this, *mrModel.mxTitle );
394 aTitleConv.convertFromModel( xTitled, OoxResId(STR_DIAGRAM_AXISTITLE), OBJECTTYPE_AXISTITLE, nAxesSetIdx, nAxisIdx );
395 }
396
397 // axis data unit label -----------------------------------------------
398 AxisDispUnitsConverter axisDispUnitsConverter (*this, mrModel.mxDispUnits.getOrCreate());
399 axisDispUnitsConverter.convertFromModel(xAxis);
400 }
401 catch( Exception& )
402 {
403 }
404
405 if( xAxis.is() && rxCoordSystem.is() ) try
406 {
407 // insert axis into coordinate system
408 rxCoordSystem->setAxisByDimension( nAxisIdx, xAxis, nAxesSetIdx );
409 }
410 catch( Exception& )
411 {
412 OSL_FAIL( "AxisConverter::convertFromModel - cannot insert axis into coordinate system" );
413 }
414}
415
417 ConverterBase< AxisDispUnitsModel >( rParent, rModel )
418{
419}
420
422{
423}
424
426{
427 PropertySet aPropSet( rxAxis );
428 if (!mrModel.mnBuiltInUnit.isEmpty() )
429 {
430 aPropSet.setProperty(PROP_DisplayUnits, true);
431 aPropSet.setProperty( PROP_BuiltInUnit, mrModel.mnBuiltInUnit );
432 }
433}
434
435} // namespace oox::drawingml::chart
436
437/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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.
Template for a vector of ref-counted objects with additional accessor functions.
Definition: refvector.hxx:42
LineProperties & getLineProperties()
Definition: shape.hxx:128
AxisConverter(const ConverterRoot &rParent, AxisModel &rModel)
void convertFromModel(const css::uno::Reference< css::chart2::XCoordinateSystem > &rxCoordSystem, RefVector< TypeGroupConverter > &rTypeGroups, const AxisModel *pCrossingAxis, sal_Int32 nAxesSetIdx, sal_Int32 nAxisIdx, bool bUseFixedInnerSize)
Creates a chart2 axis and inserts it into the passed coordinate system.
AxisDispUnitsConverter(const ConverterRoot &rParent, AxisDispUnitsModel &rModel)
void convertFromModel(const css::uno::Reference< css::chart2::XAxis > &rxAxis)
Creates a chart2 axis and inserts it into the passed coordinate system.
Base class of all converter classes.
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.
void convertFrameFormatting(PropertySet &rPropSet, const ModelRef< Shape > &rxShapeProp, ObjectType eObjType, sal_Int32 nSeriesIdx=-1)
Sets frame formatting properties to the passed property set.
void convertFormatting(PropertySet &rPropSet, const ModelRef< Shape > &rxShapeProp, const ModelRef< TextBody > &rxTextProp, ObjectType eObjType)
Sets frame/text formatting properties to the passed property set.
void convertNumberFormat(PropertySet &rPropSet, const NumberFormat &rNumberFormat, bool bAxis, bool bShowPercent=false)
Sets number format properties to the passed property set.
static void convertTextRotation(PropertySet &rPropSet, const ModelRef< TextBody > &rxTextProp, bool bSupportsStacked, sal_Int32 nDefaultRotation=0)
Sets text rotation properties to the passed property set.
void convertFromModel(const css::uno::Reference< css::chart2::XTitled > &rxTitled, const OUString &rAutoTitle, ObjectType eObjType, sal_Int32 nMainIdx=-1, sal_Int32 nSubIdx=-1)
Creates a title text object and attaches it at the passed interface.
@ Exception
Reference< XComponentContext > getProcessComponentContext()
const sal_Int32 API_Y_AXIS
@ TYPECATEGORY_RADAR
Line charts (line, area, stock charts).
@ TYPECATEGORY_PIE
Radar charts (linear or filled).
const sal_Int32 API_X_AXIS
@ OBJECTTYPE_AXIS
Floor in 3D charts.
@ OBJECTTYPE_MINORGRIDLINE
Axis major grid line.
@ OBJECTTYPE_AXISTITLE
Axis line, labels, tick marks.
@ OBJECTTYPE_MAJORGRIDLINE
Axis unit label.
@ TYPEID_LINE
Horizontal bar chart.
@ TYPEID_HORBAR
Vertical bar chart.
@ TYPEID_RADARAREA
Linear radar chart.
const sal_Int32 API_Z_AXIS
XML_none
OUString OoxResId(TranslateId aId)
Definition: ooxresid.cxx:14
std::optional< sal_Int32 > moFillType
FillProperties maLineFill
End line arrow style.
OUString mnBuiltInUnit
Custom unit size on value axis.
Definition: axismodel.hxx:40
AxisDispUnitsRef mxDispUnits
Axis title.
Definition: axismodel.hxx:56
NumberFormat maNumberFormat
Minor grid lines formatting.
Definition: axismodel.hxx:59
sal_Int32 mnAxisPos
Unique axis identifier.
Definition: axismodel.hxx:68
std::optional< sal_Int32 > monBaseTimeUnit
Minimum axis value.
Definition: axismodel.hxx:66
bool mbAuto
Type identifier of this axis.
Definition: axismodel.hxx:83
TitleRef mxTitle
Axis label text formatting.
Definition: axismodel.hxx:55
std::optional< double > mofMax
Logarithmic base for logarithmic axes.
Definition: axismodel.hxx:64
sal_Int32 mnOrientation
Time unit for minor tick marks on date axis.
Definition: axismodel.hxx:78
sal_Int32 mnMinorTickMark
Time unit for major tick marks on date axis.
Definition: axismodel.hxx:76
std::optional< double > mofCrossesAt
Number format for axis tick labels.
Definition: axismodel.hxx:60
sal_Int32 mnMajorTickMark
Tick mark label distance from axis.
Definition: axismodel.hxx:74
sal_Int32 mnMajorTimeUnit
Major tick mark style.
Definition: axismodel.hxx:75
ShapeRef mxMajorGridLines
Axis units label.
Definition: axismodel.hxx:57
ShapeRef mxMinorGridLines
Major grid lines formatting.
Definition: axismodel.hxx:58
sal_Int32 mnTypeId
Number of tick marks to skip.
Definition: axismodel.hxx:82
sal_Int32 mnCrossMode
This value axis crosses between or inside category.
Definition: axismodel.hxx:71
std::optional< double > mofMajorUnit
Position on this axis where another axis crosses.
Definition: axismodel.hxx:61
std::optional< double > mofMinorUnit
Unit for major tick marks on date/value axis.
Definition: axismodel.hxx:62
sal_Int32 mnMinorTimeUnit
Minor tick mark style.
Definition: axismodel.hxx:77
bool mbDeleted
True = automatic selection of text/date axis type.
Definition: axismodel.hxx:84
sal_Int32 mnCrossBetween
Identifier of a crossing axis.
Definition: axismodel.hxx:70
std::optional< double > mofMin
Maximum axis value.
Definition: axismodel.hxx:65
TextBodyRef mxTextProp
Axis line formatting.
Definition: axismodel.hxx:54
sal_Int32 mnTickLabelPos
Axis orientation (value order min to max, or max to min).
Definition: axismodel.hxx:79
Contains info for a chart type related to the OpenOffice.org chart module.
bool mbCategoryAxis
True = only first series visible (e.g. pie charts).
TypeCategory meTypeCategory
Unique chart type identifier.