LibreOffice Module chart2 (master) 1
VAxisProperties.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
20#include "VAxisProperties.hxx"
21#include <ViewDefines.hxx>
22#include <Axis.hxx>
23#include <AxisHelper.hxx>
24#include <ChartModelHelper.hxx>
26
27#include <com/sun/star/beans/XPropertySet.hpp>
28#include <com/sun/star/chart/ChartAxisArrangeOrderType.hpp>
29#include <com/sun/star/chart2/AxisType.hpp>
30
32#include <rtl/math.hxx>
33#include <utility>
34
35using namespace ::com::sun::star;
36using namespace ::com::sun::star::chart2;
37
38namespace chart {
39
41 mfLabelDirection(1.0),
42 mfInnerTickDirection(1.0),
43 meAlignment(LABEL_ALIGN_RIGHT_TOP) {}
44
45static sal_Int32 lcl_calcTickLengthForDepth(sal_Int32 nDepth,sal_Int32 nTickmarkStyle)
46{
47 sal_Int32 const nWidth = AXIS2D_TICKLENGTH; //@maybefuturetodo this length could be offered by the model
48 double fPercent = 1.0;
49 switch(nDepth)
50 {
51 case 0:
52 fPercent = 1.0;
53 break;
54 case 1:
55 fPercent = 0.75;//percentage like in the old chart
56 break;
57 case 2:
58 fPercent = 0.5;
59 break;
60 default:
61 fPercent = 0.3;
62 break;
63 }
64 if(nTickmarkStyle==3)//inner and outer tickmarks
65 fPercent*=2.0;
66 return static_cast<sal_Int32>(nWidth*fPercent);
67}
68
69static double lcl_getTickOffset(sal_Int32 nLength,sal_Int32 nTickmarkStyle)
70{
71 double fPercent = 0.0; //0<=fPercent<=1
72 //0.0: completely inner
73 //1.0: completely outer
74 //0.5: half and half
75
76 /*
77 nTickmarkStyle:
78 1: inner tickmarks
79 2: outer tickmarks
80 3: inner and outer tickmarks
81 */
82 switch(nTickmarkStyle)
83 {
84 case 1:
85 fPercent = 0.0;
86 break;
87 case 2:
88 fPercent = 1.0;
89 break;
90 default:
91 fPercent = 0.5;
92 break;
93 }
94 return fPercent*nLength;
95}
96
98 sal_Int32 nDepth ) const
99{
100 /*
101 nTickmarkStyle:
102 1: inner tickmarks
103 2: outer tickmarks
104 3: inner and outer tickmarks
105 */
106 sal_Int32 nTickmarkStyle = 1;
107 if(nDepth==0)
108 {
109 nTickmarkStyle = m_nMajorTickmarks;
110 if(!nTickmarkStyle)
111 {
112 //create major tickmarks as if they were minor tickmarks
113 nDepth = 1;
114 nTickmarkStyle = m_nMinorTickmarks;
115 }
116 }
117 else if( nDepth==1)
118 {
119 nTickmarkStyle = m_nMinorTickmarks;
120 }
121
123 {
124 if( nTickmarkStyle != 0 )
125 nTickmarkStyle = 3; //inner and outer tickmarks
126 }
127
128 TickmarkProperties aTickmarkProperties;
129 aTickmarkProperties.Length = lcl_calcTickLengthForDepth(nDepth,nTickmarkStyle);
130 aTickmarkProperties.RelativePos = static_cast<sal_Int32>(lcl_getTickOffset(aTickmarkProperties.Length,nTickmarkStyle));
131 aTickmarkProperties.aLineProperties = makeLinePropertiesForDepth();
132 return aTickmarkProperties;
133}
134
136 sal_Int32 nTickLength, sal_Int32 nTickStartDistanceToAxis ) const
137{
138 sal_Int32 nTickmarkStyle = (maLabelAlignment.mfLabelDirection == maLabelAlignment.mfInnerTickDirection) ? 2/*outside*/ : 1/*inside*/;
139
140 TickmarkProperties aTickmarkProperties;
141 aTickmarkProperties.Length = nTickLength;// + nTextLevel*( lcl_calcTickLengthForDepth(0,nTickmarkStyle) );
142 aTickmarkProperties.RelativePos = static_cast<sal_Int32>(lcl_getTickOffset(aTickmarkProperties.Length+nTickStartDistanceToAxis,nTickmarkStyle));
143 aTickmarkProperties.aLineProperties = makeLinePropertiesForDepth();
144 return aTickmarkProperties;
145}
146
148{
149 TickmarkProperties aTickmarkProperties;
150 sal_Int32 nTickmarkStyle = 3;//inner and outer tickmarks
151 aTickmarkProperties.Length = lcl_calcTickLengthForDepth( 0/*nDepth*/,nTickmarkStyle );
152 aTickmarkProperties.RelativePos = static_cast<sal_Int32>( lcl_getTickOffset( aTickmarkProperties.Length, nTickmarkStyle ) );
153 return aTickmarkProperties;
154}
155
157 ExplicitCategoriesProvider* pExplicitCategoriesProvider,
158 rtl::Reference<::chart::DataTable> const& xDataTableModel)
159 : m_xAxisModel(std::move(xAxisModel))
161 , m_bIsMainAxis(true)
162 , m_bSwapXAndY(false)
163 , m_eCrossoverType( css::chart::ChartAxisPosition_ZERO )
164 , m_eLabelPos( css::chart::ChartAxisLabelPosition_NEAR_AXIS )
165 , m_eTickmarkPos( css::chart::ChartAxisMarkPosition_AT_LABELS_AND_AXIS )
166 , m_bCrossingAxisHasReverseDirection(false)
167 , m_bCrossingAxisIsCategoryAxes(false)
168 , m_bDisplayDataTable(false)
169 , m_bDataTableAlignAxisValuesWithColumns(false)
170 , m_bDisplayLabels( true )
171 , m_bTryStaggeringFirst( false )
172 , m_nNumberFormatKey(0)
173 , m_nMajorTickmarks(1)
174 , m_nMinorTickmarks(1)
175 , m_nAxisType(AxisType::REALNUMBER)
176 , m_bComplexCategories(false)
177 , m_pExplicitCategoriesProvider(pExplicitCategoriesProvider)
178 , m_bLimitSpaceForLabels(false)
179 , m_xDataTableModel(xDataTableModel)
180{
181}
182
184{
186 if (rAxisProperties.maLabelAlignment.mfLabelDirection < 0)
187 aRet = LABEL_ALIGN_LEFT;
188 return aRet;
189}
190
192{
194 if (rAxisProperties.maLabelAlignment.mfLabelDirection < 0)
195 aRet = LABEL_ALIGN_LEFT;
196 return aRet;
197}
198
200{
202 if (rAxisProperties.maLabelAlignment.mfLabelDirection < 0)
203 aRet = LABEL_ALIGN_TOP;
204 return aRet;
205}
206
208{
209 if( !xAxisProp.is() )
210 return;
211 try
212 {
214 {
215 xAxisProp->getPropertyValue("CrossoverPosition") >>= m_eCrossoverType;
216 if( m_eCrossoverType == css::chart::ChartAxisPosition_VALUE )
217 {
218 double fValue = 0.0;
219 xAxisProp->getPropertyValue("CrossoverValue") >>= fValue;
220
222 fValue = ::rtl::math::round(fValue);
224 }
225 else if( m_eCrossoverType == css::chart::ChartAxisPosition_ZERO )
227
228 xAxisProp->getPropertyValue("LabelPosition") >>= m_eLabelPos;
229 xAxisProp->getPropertyValue("MarkPosition") >>= m_eTickmarkPos;
230 }
231 else
232 {
233 m_eCrossoverType = css::chart::ChartAxisPosition_START;
235 m_eCrossoverType = css::chart::ChartAxisPosition_END;
236 m_eLabelPos = css::chart::ChartAxisLabelPosition_NEAR_AXIS;
237 m_eTickmarkPos = css::chart::ChartAxisMarkPosition_AT_LABELS;
238 }
239 }
240 catch( const uno::Exception& )
241 {
242 TOOLS_WARN_EXCEPTION("chart2", "" );
243 }
244}
245
246void AxisProperties::init( bool bCartesian )
247{
248 if( !m_xAxisModel.is() )
249 return;
250
251 if( m_nDimensionIndex<2 )
253
254 ScaleData aScaleData = m_xAxisModel->getScaleData();
255 if( m_nDimensionIndex==0 )
257 m_nAxisType = aScaleData.AxisType;
258
259 if( bCartesian )
260 {
262 {
264 }
265
266 if( m_nDimensionIndex == 0 && m_nAxisType == AxisType::CATEGORY
269
270 if( m_eCrossoverType == css::chart::ChartAxisPosition_END )
272 else
274
275 if( m_eLabelPos == css::chart::ChartAxisLabelPosition_NEAR_AXIS )
277 else if( m_eLabelPos == css::chart::ChartAxisLabelPosition_NEAR_AXIS_OTHER_SIDE )
279 else if( m_eLabelPos == css::chart::ChartAxisLabelPosition_OUTSIDE_START )
281 else if( m_eLabelPos == css::chart::ChartAxisLabelPosition_OUTSIDE_END )
283
284 if( m_nDimensionIndex==2 )
286 else
287 {
288 bool bIsYAxisPosition = (m_nDimensionIndex==1 && !m_bSwapXAndY)
290 if( bIsYAxisPosition )
291 {
294
296 }
297 else
299 }
300 }
301
302 try
303 {
304 //init LineProperties
306
307 //init display labels
308 m_xAxisModel->getPropertyValue( "DisplayLabels" ) >>= m_bDisplayLabels;
309
310 // Init layout strategy hint for axis labels.
311 // Compatibility option: starting from LibreOffice 5.1 the rotated
312 // layout is preferred to staggering for axis labels.
313 m_xAxisModel->getPropertyValue( "TryStaggeringFirst" ) >>= m_bTryStaggeringFirst;
314
315 //init TickmarkProperties
316 m_xAxisModel->getPropertyValue( "MajorTickmarks" ) >>= m_nMajorTickmarks;
317 m_xAxisModel->getPropertyValue( "MinorTickmarks" ) >>= m_nMinorTickmarks;
318
319 sal_Int32 nMaxDepth = 0;
320 if(m_nMinorTickmarks!=0)
321 nMaxDepth=2;
322 else if(m_nMajorTickmarks!=0)
323 nMaxDepth=1;
324
326 for( sal_Int32 nDepth=0; nDepth<nMaxDepth; nDepth++ )
327 {
328 TickmarkProperties aTickmarkProperties = makeTickmarkProperties( nDepth );
329 m_aTickmarkPropertiesList.push_back( aTickmarkProperties );
330 }
331 }
332 catch( const uno::Exception& )
333 {
334 TOOLS_WARN_EXCEPTION("chart2", "" );
335 }
336
338 {
340
341 if (m_nDimensionIndex == 0)
342 {
343 m_bDisplayLabels = false;
344 }
345
346 }
347}
348
350 : m_aFontReferenceSize( ChartModelHelper::getDefaultPageSize() )
351 , m_aMaximumSpaceForLabels( 0 , 0, m_aFontReferenceSize.Width, m_aFontReferenceSize.Height )
352 , m_nNumberFormatKey(0)
353 , m_eStaggering( AxisLabelStaggering::SideBySide )
354 , m_bLineBreakAllowed( false )
355 , m_bOverlapAllowed( false )
356 , m_bStackCharacters( false )
357 , m_fRotationAngleDegree( 0.0 )
358 , m_nRhythm( 1 )
359{
360
361}
362
364{
365 if(!xAxisModel.is())
366 return;
367
368 try
369 {
370 xAxisModel->getPropertyValue( "TextBreak" ) >>= m_bLineBreakAllowed;
371 xAxisModel->getPropertyValue( "TextOverlap" ) >>= m_bOverlapAllowed;
372 xAxisModel->getPropertyValue( "StackCharacters" ) >>= m_bStackCharacters;
373 xAxisModel->getPropertyValue( "TextRotation" ) >>= m_fRotationAngleDegree;
374
375 css::chart::ChartAxisArrangeOrderType eArrangeOrder;
376 xAxisModel->getPropertyValue( "ArrangeOrder" ) >>= eArrangeOrder;
377 switch(eArrangeOrder)
378 {
379 case css::chart::ChartAxisArrangeOrderType_SIDE_BY_SIDE:
381 break;
382 case css::chart::ChartAxisArrangeOrderType_STAGGER_EVEN:
384 break;
385 case css::chart::ChartAxisArrangeOrderType_STAGGER_ODD:
387 break;
388 default:
390 break;
391 }
392 }
393 catch( const uno::Exception& )
394 {
395 TOOLS_WARN_EXCEPTION("chart2", "" );
396 }
397}
398
400{
402}
403
405{
407 m_bLineBreakAllowed = false;
409}
410
411} //namespace chart
412
413/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static void checkDateAxis(css::chart2::ScaleData &rScale, ExplicitCategoriesProvider *pExplicitCategoriesProvider, bool bChartTypeAllowsDateAxis)
Definition: AxisHelper.cxx:124
static bool isAxisPositioningEnabled()
#define TOOLS_WARN_EXCEPTION(area, stream)
static sal_Int32 lcl_calcTickLengthForDepth(sal_Int32 nDepth, sal_Int32 nTickmarkStyle)
static LabelAlignment lcl_getLabelAlignmentForZAxis(const AxisProperties &rAxisProperties)
const sal_Int32 AXIS2D_TICKLENGTH
Definition: ViewDefines.hxx:30
@ LABEL_ALIGN_RIGHT_TOP
@ LABEL_ALIGN_TOP
@ LABEL_ALIGN_RIGHT
@ LABEL_ALIGN_LEFT
@ LABEL_ALIGN_BOTTOM
static double lcl_getTickOffset(sal_Int32 nLength, sal_Int32 nTickmarkStyle)
static LabelAlignment lcl_getLabelAlignmentForYAxis(const AxisProperties &rAxisProperties)
static LabelAlignment lcl_getLabelAlignmentForXAxis(const AxisProperties &rAxisProperties)
AxisType
double mfInnerTickDirection
which direction the labels are to be drawn.
LabelAlignment meAlignment
which direction the inner tickmarks are to be drawn.
AxisLabelStaggering m_eStaggering
void init(const rtl::Reference< ::chart::Axis > &xAxisModel)
const VLineProperties & makeLinePropertiesForDepth() const
std::optional< double > m_pfMainLinePositionAtOtherAxis
static TickmarkProperties getBiggestTickmarkProperties()
VLineProperties m_aLineProperties
void init(bool bCartesian=false)
AxisLabelAlignment maLabelAlignment
ExplicitCategoriesProvider * m_pExplicitCategoriesProvider
TickmarkProperties makeTickmarkPropertiesForComplexCategories(sal_Int32 nTickLength, sal_Int32 nTickStartDistanceToAxis) const
css::chart::ChartAxisMarkPosition m_eTickmarkPos
void initAxisPositioning(const css::uno::Reference< css::beans::XPropertySet > &xAxisProp)
rtl::Reference<::chart::Axis > m_xAxisModel
TickmarkProperties makeTickmarkProperties(sal_Int32 nDepth) const
std::vector< TickmarkProperties > m_aTickmarkPropertiesList
css::chart::ChartAxisLabelPosition m_eLabelPos
css::chart::ChartAxisPosition m_eCrossoverType
rtl::Reference<::chart::DataTable > m_xDataTableModel
void initFromPropertySet(const css::uno::Reference< css::beans::XPropertySet > &xProp)
sal_Int32 nLength