1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski *
3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file
5*b1cdbd2cSJim Jagielski * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file
7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski *
11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski *
13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the
17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski * under the License.
19*b1cdbd2cSJim Jagielski *
20*b1cdbd2cSJim Jagielski *************************************************************/
21*b1cdbd2cSJim Jagielski
22*b1cdbd2cSJim Jagielski
23*b1cdbd2cSJim Jagielski
24*b1cdbd2cSJim Jagielski #include "oox/drawingml/chart/axisconverter.hxx"
25*b1cdbd2cSJim Jagielski
26*b1cdbd2cSJim Jagielski #include <com/sun/star/chart/ChartAxisArrangeOrderType.hpp>
27*b1cdbd2cSJim Jagielski #include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
28*b1cdbd2cSJim Jagielski #include <com/sun/star/chart/ChartAxisMarkPosition.hpp>
29*b1cdbd2cSJim Jagielski #include <com/sun/star/chart/ChartAxisPosition.hpp>
30*b1cdbd2cSJim Jagielski #include <com/sun/star/chart/TimeInterval.hpp>
31*b1cdbd2cSJim Jagielski #include <com/sun/star/chart/TimeUnit.hpp>
32*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/AxisType.hpp>
33*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/TickmarkStyle.hpp>
34*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/XAxis.hpp>
35*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/XCoordinateSystem.hpp>
36*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/XTitled.hpp>
37*b1cdbd2cSJim Jagielski #include "oox/drawingml/chart/axismodel.hxx"
38*b1cdbd2cSJim Jagielski #include "oox/drawingml/chart/titleconverter.hxx"
39*b1cdbd2cSJim Jagielski #include "oox/drawingml/chart/typegroupconverter.hxx"
40*b1cdbd2cSJim Jagielski #include "oox/drawingml/lineproperties.hxx"
41*b1cdbd2cSJim Jagielski
42*b1cdbd2cSJim Jagielski namespace oox {
43*b1cdbd2cSJim Jagielski namespace drawingml {
44*b1cdbd2cSJim Jagielski namespace chart {
45*b1cdbd2cSJim Jagielski
46*b1cdbd2cSJim Jagielski // ============================================================================
47*b1cdbd2cSJim Jagielski
48*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::beans;
49*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::chart2;
50*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::uno;
51*b1cdbd2cSJim Jagielski
52*b1cdbd2cSJim Jagielski using ::rtl::OUString;
53*b1cdbd2cSJim Jagielski
54*b1cdbd2cSJim Jagielski // ============================================================================
55*b1cdbd2cSJim Jagielski
56*b1cdbd2cSJim Jagielski namespace {
57*b1cdbd2cSJim Jagielski
lclSetValueOrClearAny(Any & orAny,const OptValue<double> & rofValue)58*b1cdbd2cSJim Jagielski inline void lclSetValueOrClearAny( Any& orAny, const OptValue< double >& rofValue )
59*b1cdbd2cSJim Jagielski {
60*b1cdbd2cSJim Jagielski if( rofValue.has() ) orAny <<= rofValue.get(); else orAny.clear();
61*b1cdbd2cSJim Jagielski }
62*b1cdbd2cSJim Jagielski
lclIsLogarithmicScale(const AxisModel & rAxisModel)63*b1cdbd2cSJim Jagielski bool lclIsLogarithmicScale( const AxisModel& rAxisModel )
64*b1cdbd2cSJim Jagielski {
65*b1cdbd2cSJim Jagielski return rAxisModel.mofLogBase.has() && (2.0 <= rAxisModel.mofLogBase.get()) && (rAxisModel.mofLogBase.get() <= 1000.0);
66*b1cdbd2cSJim Jagielski }
67*b1cdbd2cSJim Jagielski
lclGetApiTimeUnit(sal_Int32 nTimeUnit)68*b1cdbd2cSJim Jagielski sal_Int32 lclGetApiTimeUnit( sal_Int32 nTimeUnit )
69*b1cdbd2cSJim Jagielski {
70*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::chart;
71*b1cdbd2cSJim Jagielski switch( nTimeUnit )
72*b1cdbd2cSJim Jagielski {
73*b1cdbd2cSJim Jagielski case XML_days: return TimeUnit::DAY;
74*b1cdbd2cSJim Jagielski case XML_months: return TimeUnit::MONTH;
75*b1cdbd2cSJim Jagielski case XML_years: return TimeUnit::YEAR;
76*b1cdbd2cSJim Jagielski default: OSL_ENSURE( false, "lclGetApiTimeUnit - unexpected time unit" );
77*b1cdbd2cSJim Jagielski }
78*b1cdbd2cSJim Jagielski return TimeUnit::DAY;
79*b1cdbd2cSJim Jagielski }
80*b1cdbd2cSJim Jagielski
lclConvertTimeInterval(Any & orInterval,const OptValue<double> & rofUnit,sal_Int32 nTimeUnit)81*b1cdbd2cSJim Jagielski void lclConvertTimeInterval( Any& orInterval, const OptValue< double >& rofUnit, sal_Int32 nTimeUnit )
82*b1cdbd2cSJim Jagielski {
83*b1cdbd2cSJim Jagielski if( rofUnit.has() && (1.0 <= rofUnit.get()) && (rofUnit.get() <= SAL_MAX_INT32) )
84*b1cdbd2cSJim Jagielski orInterval <<= ::com::sun::star::chart::TimeInterval( static_cast< sal_Int32 >( rofUnit.get() ), lclGetApiTimeUnit( nTimeUnit ) );
85*b1cdbd2cSJim Jagielski else
86*b1cdbd2cSJim Jagielski orInterval.clear();
87*b1cdbd2cSJim Jagielski }
88*b1cdbd2cSJim Jagielski
lclGetLabelPosition(sal_Int32 nToken)89*b1cdbd2cSJim Jagielski ::com::sun::star::chart::ChartAxisLabelPosition lclGetLabelPosition( sal_Int32 nToken )
90*b1cdbd2cSJim Jagielski {
91*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::chart;
92*b1cdbd2cSJim Jagielski switch( nToken )
93*b1cdbd2cSJim Jagielski {
94*b1cdbd2cSJim Jagielski case XML_high: return ChartAxisLabelPosition_OUTSIDE_END;
95*b1cdbd2cSJim Jagielski case XML_low: return ChartAxisLabelPosition_OUTSIDE_START;
96*b1cdbd2cSJim Jagielski case XML_nextTo: return ChartAxisLabelPosition_NEAR_AXIS;
97*b1cdbd2cSJim Jagielski }
98*b1cdbd2cSJim Jagielski return ChartAxisLabelPosition_NEAR_AXIS;
99*b1cdbd2cSJim Jagielski }
100*b1cdbd2cSJim Jagielski
lclGetTickMark(sal_Int32 nToken)101*b1cdbd2cSJim Jagielski sal_Int32 lclGetTickMark( sal_Int32 nToken )
102*b1cdbd2cSJim Jagielski {
103*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::chart2::TickmarkStyle;
104*b1cdbd2cSJim Jagielski switch( nToken )
105*b1cdbd2cSJim Jagielski {
106*b1cdbd2cSJim Jagielski case XML_in: return INNER;
107*b1cdbd2cSJim Jagielski case XML_out: return OUTER;
108*b1cdbd2cSJim Jagielski case XML_cross: return INNER | OUTER;
109*b1cdbd2cSJim Jagielski }
110*b1cdbd2cSJim Jagielski return NONE;
111*b1cdbd2cSJim Jagielski }
112*b1cdbd2cSJim Jagielski
113*b1cdbd2cSJim Jagielski } // namespace
114*b1cdbd2cSJim Jagielski
115*b1cdbd2cSJim Jagielski // ============================================================================
116*b1cdbd2cSJim Jagielski
AxisConverter(const ConverterRoot & rParent,AxisModel & rModel)117*b1cdbd2cSJim Jagielski AxisConverter::AxisConverter( const ConverterRoot& rParent, AxisModel& rModel ) :
118*b1cdbd2cSJim Jagielski ConverterBase< AxisModel >( rParent, rModel )
119*b1cdbd2cSJim Jagielski {
120*b1cdbd2cSJim Jagielski }
121*b1cdbd2cSJim Jagielski
~AxisConverter()122*b1cdbd2cSJim Jagielski AxisConverter::~AxisConverter()
123*b1cdbd2cSJim Jagielski {
124*b1cdbd2cSJim Jagielski }
125*b1cdbd2cSJim Jagielski
convertFromModel(const Reference<XCoordinateSystem> & rxCoordSystem,TypeGroupConverter & rTypeGroup,const AxisModel * pCrossingAxis,sal_Int32 nAxesSetIdx,sal_Int32 nAxisIdx)126*b1cdbd2cSJim Jagielski void AxisConverter::convertFromModel( const Reference< XCoordinateSystem >& rxCoordSystem,
127*b1cdbd2cSJim Jagielski TypeGroupConverter& rTypeGroup, const AxisModel* pCrossingAxis, sal_Int32 nAxesSetIdx, sal_Int32 nAxisIdx )
128*b1cdbd2cSJim Jagielski {
129*b1cdbd2cSJim Jagielski Reference< XAxis > xAxis;
130*b1cdbd2cSJim Jagielski try
131*b1cdbd2cSJim Jagielski {
132*b1cdbd2cSJim Jagielski namespace cssc = ::com::sun::star::chart;
133*b1cdbd2cSJim Jagielski namespace cssc2 = ::com::sun::star::chart2;
134*b1cdbd2cSJim Jagielski
135*b1cdbd2cSJim Jagielski const TypeGroupInfo& rTypeInfo = rTypeGroup.getTypeInfo();
136*b1cdbd2cSJim Jagielski ObjectFormatter& rFormatter = getFormatter();
137*b1cdbd2cSJim Jagielski
138*b1cdbd2cSJim Jagielski // create the axis object (always)
139*b1cdbd2cSJim Jagielski xAxis.set( createInstance( CREATE_OUSTRING( "com.sun.star.chart2.Axis" ) ), UNO_QUERY_THROW );
140*b1cdbd2cSJim Jagielski PropertySet aAxisProp( xAxis );
141*b1cdbd2cSJim Jagielski // #i58688# axis enabled
142*b1cdbd2cSJim Jagielski aAxisProp.setProperty( PROP_Show, !mrModel.mbDeleted );
143*b1cdbd2cSJim Jagielski
144*b1cdbd2cSJim Jagielski // axis line, tick, and gridline properties ---------------------------
145*b1cdbd2cSJim Jagielski
146*b1cdbd2cSJim Jagielski // show axis labels
147*b1cdbd2cSJim Jagielski aAxisProp.setProperty( PROP_DisplayLabels, mrModel.mnTickLabelPos != XML_none );
148*b1cdbd2cSJim Jagielski aAxisProp.setProperty( PROP_LabelPosition, lclGetLabelPosition( mrModel.mnTickLabelPos ) );
149*b1cdbd2cSJim Jagielski // no X axis line in radar charts
150*b1cdbd2cSJim Jagielski if( (nAxisIdx == API_X_AXIS) && (rTypeInfo.meTypeCategory == TYPECATEGORY_RADAR) )
151*b1cdbd2cSJim Jagielski mrModel.mxShapeProp.getOrCreate().getLineProperties().maLineFill.moFillType = XML_noFill;
152*b1cdbd2cSJim Jagielski // axis line and tick label formatting
153*b1cdbd2cSJim Jagielski rFormatter.convertFormatting( aAxisProp, mrModel.mxShapeProp, mrModel.mxTextProp, OBJECTTYPE_AXIS );
154*b1cdbd2cSJim Jagielski // tick label rotation
155*b1cdbd2cSJim Jagielski rFormatter.convertTextRotation( aAxisProp, mrModel.mxTextProp, true );
156*b1cdbd2cSJim Jagielski
157*b1cdbd2cSJim Jagielski // tick mark style
158*b1cdbd2cSJim Jagielski aAxisProp.setProperty( PROP_MajorTickmarks, lclGetTickMark( mrModel.mnMajorTickMark ) );
159*b1cdbd2cSJim Jagielski aAxisProp.setProperty( PROP_MinorTickmarks, lclGetTickMark( mrModel.mnMinorTickMark ) );
160*b1cdbd2cSJim Jagielski aAxisProp.setProperty( PROP_MarkPosition, cssc::ChartAxisMarkPosition_AT_AXIS );
161*b1cdbd2cSJim Jagielski
162*b1cdbd2cSJim Jagielski // main grid
163*b1cdbd2cSJim Jagielski PropertySet aGridProp( xAxis->getGridProperties() );
164*b1cdbd2cSJim Jagielski aGridProp.setProperty( PROP_Show, mrModel.mxMajorGridLines.is() );
165*b1cdbd2cSJim Jagielski if( mrModel.mxMajorGridLines.is() )
166*b1cdbd2cSJim Jagielski rFormatter.convertFrameFormatting( aGridProp, mrModel.mxMajorGridLines, OBJECTTYPE_MAJORGRIDLINE );
167*b1cdbd2cSJim Jagielski
168*b1cdbd2cSJim Jagielski // sub grid
169*b1cdbd2cSJim Jagielski Sequence< Reference< XPropertySet > > aSubGridPropSeq = xAxis->getSubGridProperties();
170*b1cdbd2cSJim Jagielski if( aSubGridPropSeq.hasElements() )
171*b1cdbd2cSJim Jagielski {
172*b1cdbd2cSJim Jagielski PropertySet aSubGridProp( aSubGridPropSeq[ 0 ] );
173*b1cdbd2cSJim Jagielski aSubGridProp.setProperty( PROP_Show, mrModel.mxMinorGridLines.is() );
174*b1cdbd2cSJim Jagielski if( mrModel.mxMinorGridLines.is() )
175*b1cdbd2cSJim Jagielski rFormatter.convertFrameFormatting( aSubGridProp, mrModel.mxMinorGridLines, OBJECTTYPE_MINORGRIDLINE );
176*b1cdbd2cSJim Jagielski }
177*b1cdbd2cSJim Jagielski
178*b1cdbd2cSJim Jagielski // axis type and X axis categories ------------------------------------
179*b1cdbd2cSJim Jagielski
180*b1cdbd2cSJim Jagielski ScaleData aScaleData = xAxis->getScaleData();
181*b1cdbd2cSJim Jagielski // set axis type
182*b1cdbd2cSJim Jagielski switch( nAxisIdx )
183*b1cdbd2cSJim Jagielski {
184*b1cdbd2cSJim Jagielski case API_X_AXIS:
185*b1cdbd2cSJim Jagielski if( rTypeInfo.mbCategoryAxis )
186*b1cdbd2cSJim Jagielski {
187*b1cdbd2cSJim Jagielski OSL_ENSURE( (mrModel.mnTypeId == C_TOKEN( catAx )) || (mrModel.mnTypeId == C_TOKEN( dateAx )),
188*b1cdbd2cSJim Jagielski "AxisConverter::convertFromModel - unexpected axis model type (must: c:catAx or c:dateAx)" );
189*b1cdbd2cSJim Jagielski bool bDateAxis = mrModel.mnTypeId == C_TOKEN( dateAx );
190*b1cdbd2cSJim Jagielski /* Chart2 requires axis type CATEGORY for automatic
191*b1cdbd2cSJim Jagielski category/date axis (even if it is a date axis
192*b1cdbd2cSJim Jagielski currently). */
193*b1cdbd2cSJim Jagielski aScaleData.AxisType = (bDateAxis && !mrModel.mbAuto) ? cssc2::AxisType::DATE : cssc2::AxisType::CATEGORY;
194*b1cdbd2cSJim Jagielski aScaleData.AutoDateAxis = mrModel.mbAuto;
195*b1cdbd2cSJim Jagielski aScaleData.Categories = rTypeGroup.createCategorySequence();
196*b1cdbd2cSJim Jagielski }
197*b1cdbd2cSJim Jagielski else
198*b1cdbd2cSJim Jagielski {
199*b1cdbd2cSJim Jagielski OSL_ENSURE( mrModel.mnTypeId == C_TOKEN( valAx ), "AxisConverter::convertFromModel - unexpected axis model type (must: c:valAx)" );
200*b1cdbd2cSJim Jagielski aScaleData.AxisType = cssc2::AxisType::REALNUMBER;
201*b1cdbd2cSJim Jagielski }
202*b1cdbd2cSJim Jagielski break;
203*b1cdbd2cSJim Jagielski case API_Y_AXIS:
204*b1cdbd2cSJim Jagielski OSL_ENSURE( mrModel.mnTypeId == C_TOKEN( valAx ), "AxisConverter::convertFromModel - unexpected axis model type (must: c:valAx)" );
205*b1cdbd2cSJim Jagielski aScaleData.AxisType = rTypeGroup.isPercent() ? cssc2::AxisType::PERCENT : cssc2::AxisType::REALNUMBER;
206*b1cdbd2cSJim Jagielski break;
207*b1cdbd2cSJim Jagielski case API_Z_AXIS:
208*b1cdbd2cSJim Jagielski OSL_ENSURE( mrModel.mnTypeId == C_TOKEN( serAx ), "AxisConverter::convertFromModel - unexpected axis model type (must: c:serAx)" );
209*b1cdbd2cSJim Jagielski OSL_ENSURE( rTypeGroup.isDeep3dChart(), "AxisConverter::convertFromModel - series axis not supported by this chart type" );
210*b1cdbd2cSJim Jagielski aScaleData.AxisType = cssc2::AxisType::SERIES;
211*b1cdbd2cSJim Jagielski break;
212*b1cdbd2cSJim Jagielski }
213*b1cdbd2cSJim Jagielski
214*b1cdbd2cSJim Jagielski // axis scaling and increment -----------------------------------------
215*b1cdbd2cSJim Jagielski
216*b1cdbd2cSJim Jagielski switch( aScaleData.AxisType )
217*b1cdbd2cSJim Jagielski {
218*b1cdbd2cSJim Jagielski case cssc2::AxisType::CATEGORY:
219*b1cdbd2cSJim Jagielski case cssc2::AxisType::SERIES:
220*b1cdbd2cSJim Jagielski case cssc2::AxisType::DATE:
221*b1cdbd2cSJim Jagielski {
222*b1cdbd2cSJim Jagielski /* Determine date axis type from XML type identifier, and not
223*b1cdbd2cSJim Jagielski via aScaleData.AxisType, as this value sticks to CATEGORY
224*b1cdbd2cSJim Jagielski for automatic category/date axes). */
225*b1cdbd2cSJim Jagielski if( mrModel.mnTypeId == C_TOKEN( dateAx ) )
226*b1cdbd2cSJim Jagielski {
227*b1cdbd2cSJim Jagielski // scaling algorithm
228*b1cdbd2cSJim Jagielski aScaleData.Scaling.set( createInstance( CREATE_OUSTRING( "com.sun.star.chart2.LinearScaling" ) ), UNO_QUERY );
229*b1cdbd2cSJim Jagielski // min/max
230*b1cdbd2cSJim Jagielski lclSetValueOrClearAny( aScaleData.Minimum, mrModel.mofMin );
231*b1cdbd2cSJim Jagielski lclSetValueOrClearAny( aScaleData.Maximum, mrModel.mofMax );
232*b1cdbd2cSJim Jagielski // major/minor increment
233*b1cdbd2cSJim Jagielski lclConvertTimeInterval( aScaleData.TimeIncrement.MajorTimeInterval, mrModel.mofMajorUnit, mrModel.mnMajorTimeUnit );
234*b1cdbd2cSJim Jagielski lclConvertTimeInterval( aScaleData.TimeIncrement.MinorTimeInterval, mrModel.mofMinorUnit, mrModel.mnMinorTimeUnit );
235*b1cdbd2cSJim Jagielski // base time unit
236*b1cdbd2cSJim Jagielski if( mrModel.monBaseTimeUnit.has() )
237*b1cdbd2cSJim Jagielski aScaleData.TimeIncrement.TimeResolution <<= lclGetApiTimeUnit( mrModel.monBaseTimeUnit.get() );
238*b1cdbd2cSJim Jagielski else
239*b1cdbd2cSJim Jagielski aScaleData.TimeIncrement.TimeResolution.clear();
240*b1cdbd2cSJim Jagielski }
241*b1cdbd2cSJim Jagielski else
242*b1cdbd2cSJim Jagielski {
243*b1cdbd2cSJim Jagielski // do not overlap text unless all labels are visible
244*b1cdbd2cSJim Jagielski aAxisProp.setProperty( PROP_TextOverlap, mrModel.mnTickLabelSkip == 1 );
245*b1cdbd2cSJim Jagielski // do not break text into several lines
246*b1cdbd2cSJim Jagielski aAxisProp.setProperty( PROP_TextBreak, false );
247*b1cdbd2cSJim Jagielski // do not stagger labels in two lines
248*b1cdbd2cSJim Jagielski aAxisProp.setProperty( PROP_ArrangeOrder, cssc::ChartAxisArrangeOrderType_SIDE_BY_SIDE );
249*b1cdbd2cSJim Jagielski //! TODO #i58731# show n-th category
250*b1cdbd2cSJim Jagielski }
251*b1cdbd2cSJim Jagielski }
252*b1cdbd2cSJim Jagielski break;
253*b1cdbd2cSJim Jagielski case cssc2::AxisType::REALNUMBER:
254*b1cdbd2cSJim Jagielski case cssc2::AxisType::PERCENT:
255*b1cdbd2cSJim Jagielski {
256*b1cdbd2cSJim Jagielski // scaling algorithm
257*b1cdbd2cSJim Jagielski bool bLogScale = lclIsLogarithmicScale( mrModel );
258*b1cdbd2cSJim Jagielski OUString aScalingService = bLogScale ?
259*b1cdbd2cSJim Jagielski CREATE_OUSTRING( "com.sun.star.chart2.LogarithmicScaling" ) :
260*b1cdbd2cSJim Jagielski CREATE_OUSTRING( "com.sun.star.chart2.LinearScaling" );
261*b1cdbd2cSJim Jagielski aScaleData.Scaling.set( createInstance( aScalingService ), UNO_QUERY );
262*b1cdbd2cSJim Jagielski // min/max
263*b1cdbd2cSJim Jagielski lclSetValueOrClearAny( aScaleData.Minimum, mrModel.mofMin );
264*b1cdbd2cSJim Jagielski lclSetValueOrClearAny( aScaleData.Maximum, mrModel.mofMax );
265*b1cdbd2cSJim Jagielski // major increment
266*b1cdbd2cSJim Jagielski IncrementData& rIncrementData = aScaleData.IncrementData;
267*b1cdbd2cSJim Jagielski if( mrModel.mofMajorUnit.has() && aScaleData.Scaling.is() )
268*b1cdbd2cSJim Jagielski rIncrementData.Distance <<= aScaleData.Scaling->doScaling( mrModel.mofMajorUnit.get() );
269*b1cdbd2cSJim Jagielski else
270*b1cdbd2cSJim Jagielski lclSetValueOrClearAny( rIncrementData.Distance, mrModel.mofMajorUnit );
271*b1cdbd2cSJim Jagielski // minor increment
272*b1cdbd2cSJim Jagielski Sequence< SubIncrement >& rSubIncrementSeq = rIncrementData.SubIncrements;
273*b1cdbd2cSJim Jagielski rSubIncrementSeq.realloc( 1 );
274*b1cdbd2cSJim Jagielski Any& rIntervalCount = rSubIncrementSeq[ 0 ].IntervalCount;
275*b1cdbd2cSJim Jagielski rIntervalCount.clear();
276*b1cdbd2cSJim Jagielski if( bLogScale )
277*b1cdbd2cSJim Jagielski {
278*b1cdbd2cSJim Jagielski if( mrModel.mofMinorUnit.has() )
279*b1cdbd2cSJim Jagielski rIntervalCount <<= sal_Int32( 9 );
280*b1cdbd2cSJim Jagielski }
281*b1cdbd2cSJim Jagielski else if( mrModel.mofMajorUnit.has() && mrModel.mofMinorUnit.has() && (0.0 < mrModel.mofMinorUnit.get()) && (mrModel.mofMinorUnit.get() <= mrModel.mofMajorUnit.get()) )
282*b1cdbd2cSJim Jagielski {
283*b1cdbd2cSJim Jagielski double fCount = mrModel.mofMajorUnit.get() / mrModel.mofMinorUnit.get() + 0.5;
284*b1cdbd2cSJim Jagielski if( (1.0 <= fCount) && (fCount < 1001.0) )
285*b1cdbd2cSJim Jagielski rIntervalCount <<= static_cast< sal_Int32 >( fCount );
286*b1cdbd2cSJim Jagielski }
287*b1cdbd2cSJim Jagielski }
288*b1cdbd2cSJim Jagielski break;
289*b1cdbd2cSJim Jagielski default:
290*b1cdbd2cSJim Jagielski OSL_ENSURE( false, "AxisConverter::convertFromModel - unknown axis type" );
291*b1cdbd2cSJim Jagielski }
292*b1cdbd2cSJim Jagielski
293*b1cdbd2cSJim Jagielski /* Do not set a value to the Origin member anymore (already done via
294*b1cdbd2cSJim Jagielski new axis properties 'CrossoverPosition' and 'CrossoverValue'). */
295*b1cdbd2cSJim Jagielski aScaleData.Origin.clear();
296*b1cdbd2cSJim Jagielski
297*b1cdbd2cSJim Jagielski // axis orientation ---------------------------------------------------
298*b1cdbd2cSJim Jagielski
299*b1cdbd2cSJim Jagielski // #i85167# pie/donut charts need opposite direction at Y axis
300*b1cdbd2cSJim Jagielski // #i87747# radar charts need opposite direction at X axis
301*b1cdbd2cSJim Jagielski bool bMirrorDirection =
302*b1cdbd2cSJim Jagielski ((nAxisIdx == API_Y_AXIS) && (rTypeInfo.meTypeCategory == TYPECATEGORY_PIE)) ||
303*b1cdbd2cSJim Jagielski ((nAxisIdx == API_X_AXIS) && (rTypeInfo.meTypeCategory == TYPECATEGORY_RADAR));
304*b1cdbd2cSJim Jagielski bool bReverse = (mrModel.mnOrientation == XML_maxMin) != bMirrorDirection;
305*b1cdbd2cSJim Jagielski aScaleData.Orientation = bReverse ? cssc2::AxisOrientation_REVERSE : cssc2::AxisOrientation_MATHEMATICAL;
306*b1cdbd2cSJim Jagielski
307*b1cdbd2cSJim Jagielski // write back scaling data
308*b1cdbd2cSJim Jagielski xAxis->setScaleData( aScaleData );
309*b1cdbd2cSJim Jagielski
310*b1cdbd2cSJim Jagielski // number format ------------------------------------------------------
311*b1cdbd2cSJim Jagielski
312*b1cdbd2cSJim Jagielski if( (aScaleData.AxisType == cssc2::AxisType::REALNUMBER) || (aScaleData.AxisType == cssc2::AxisType::PERCENT) )
313*b1cdbd2cSJim Jagielski getFormatter().convertNumberFormat( aAxisProp, mrModel.maNumberFormat );
314*b1cdbd2cSJim Jagielski
315*b1cdbd2cSJim Jagielski // position of crossing axis ------------------------------------------
316*b1cdbd2cSJim Jagielski
317*b1cdbd2cSJim Jagielski bool bManualCrossing = mrModel.mofCrossesAt.has();
318*b1cdbd2cSJim Jagielski cssc::ChartAxisPosition eAxisPos = cssc::ChartAxisPosition_VALUE;
319*b1cdbd2cSJim Jagielski if( !bManualCrossing ) switch( mrModel.mnCrossMode )
320*b1cdbd2cSJim Jagielski {
321*b1cdbd2cSJim Jagielski case XML_min: eAxisPos = cssc::ChartAxisPosition_START; break;
322*b1cdbd2cSJim Jagielski case XML_max: eAxisPos = cssc::ChartAxisPosition_END; break;
323*b1cdbd2cSJim Jagielski case XML_autoZero: eAxisPos = cssc::ChartAxisPosition_VALUE; break;
324*b1cdbd2cSJim Jagielski }
325*b1cdbd2cSJim Jagielski aAxisProp.setProperty( PROP_CrossoverPosition, eAxisPos );
326*b1cdbd2cSJim Jagielski
327*b1cdbd2cSJim Jagielski // calculate automatic origin depending on scaling mode of crossing axis
328*b1cdbd2cSJim Jagielski bool bCrossingLogScale = pCrossingAxis && lclIsLogarithmicScale( *pCrossingAxis );
329*b1cdbd2cSJim Jagielski double fCrossingPos = bManualCrossing ? mrModel.mofCrossesAt.get() : (bCrossingLogScale ? 1.0 : 0.0);
330*b1cdbd2cSJim Jagielski aAxisProp.setProperty( PROP_CrossoverValue, fCrossingPos );
331*b1cdbd2cSJim Jagielski
332*b1cdbd2cSJim Jagielski // axis title ---------------------------------------------------------
333*b1cdbd2cSJim Jagielski
334*b1cdbd2cSJim Jagielski // in radar charts, title objects may exist, but are not shown
335*b1cdbd2cSJim Jagielski if( mrModel.mxTitle.is() && (rTypeGroup.getTypeInfo().meTypeCategory != TYPECATEGORY_RADAR) )
336*b1cdbd2cSJim Jagielski {
337*b1cdbd2cSJim Jagielski Reference< XTitled > xTitled( xAxis, UNO_QUERY_THROW );
338*b1cdbd2cSJim Jagielski TitleConverter aTitleConv( *this, *mrModel.mxTitle );
339*b1cdbd2cSJim Jagielski aTitleConv.convertFromModel( xTitled, CREATE_OUSTRING( "Axis Title" ), OBJECTTYPE_AXISTITLE, nAxesSetIdx, nAxisIdx );
340*b1cdbd2cSJim Jagielski }
341*b1cdbd2cSJim Jagielski }
342*b1cdbd2cSJim Jagielski catch( Exception& )
343*b1cdbd2cSJim Jagielski {
344*b1cdbd2cSJim Jagielski }
345*b1cdbd2cSJim Jagielski
346*b1cdbd2cSJim Jagielski if( xAxis.is() && rxCoordSystem.is() ) try
347*b1cdbd2cSJim Jagielski {
348*b1cdbd2cSJim Jagielski // insert axis into coordinate system
349*b1cdbd2cSJim Jagielski rxCoordSystem->setAxisByDimension( nAxisIdx, xAxis, nAxesSetIdx );
350*b1cdbd2cSJim Jagielski }
351*b1cdbd2cSJim Jagielski catch( Exception& )
352*b1cdbd2cSJim Jagielski {
353*b1cdbd2cSJim Jagielski OSL_ENSURE( false, "AxisConverter::convertFromModel - cannot insert axis into coordinate system" );
354*b1cdbd2cSJim Jagielski }
355*b1cdbd2cSJim Jagielski }
356*b1cdbd2cSJim Jagielski
357*b1cdbd2cSJim Jagielski // ============================================================================
358*b1cdbd2cSJim Jagielski
359*b1cdbd2cSJim Jagielski } // namespace chart
360*b1cdbd2cSJim Jagielski } // namespace drawingml
361*b1cdbd2cSJim Jagielski } // namespace oox
362