1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_chart2.hxx"
26
27 #include "VAxisBase.hxx"
28 #include "ShapeFactory.hxx"
29 #include "CommonConverters.hxx"
30 #include "Tickmarks.hxx"
31 #include "macros.hxx"
32
33 // header for define DBG_ASSERT
34 #include <tools/debug.hxx>
35
36 #include <memory>
37
38 //.............................................................................
39 namespace chart
40 {
41 //.............................................................................
42 using namespace ::com::sun::star;
43 using namespace ::com::sun::star::chart2;
44 using ::com::sun::star::uno::Reference;
45
VAxisBase(sal_Int32 nDimensionIndex,sal_Int32 nDimensionCount,const AxisProperties & rAxisProperties,const uno::Reference<util::XNumberFormatsSupplier> & xNumberFormatsSupplier)46 VAxisBase::VAxisBase( sal_Int32 nDimensionIndex, sal_Int32 nDimensionCount
47 , const AxisProperties& rAxisProperties
48 , const uno::Reference< util::XNumberFormatsSupplier >& xNumberFormatsSupplier )
49 : VAxisOrGridBase( nDimensionIndex, nDimensionCount )
50 , m_xNumberFormatsSupplier( xNumberFormatsSupplier )
51 , m_aAxisProperties( rAxisProperties )
52 , m_bUseTextLabels( false )
53 , m_bReCreateAllTickInfos( true )
54 , m_bRecordMaximumTextSize(false)
55 , m_nMaximumTextWidthSoFar(0)
56 , m_nMaximumTextHeightSoFar(0)
57 {
58 }
59
~VAxisBase()60 VAxisBase::~VAxisBase()
61 {
62 }
63
getDimensionCount()64 sal_Int32 VAxisBase::getDimensionCount()
65 {
66 return m_nDimension;
67 }
68
initAxisLabelProperties(const::com::sun::star::awt::Size & rFontReferenceSize,const::com::sun::star::awt::Rectangle & rMaximumSpaceForLabels)69 void VAxisBase::initAxisLabelProperties( const ::com::sun::star::awt::Size& rFontReferenceSize
70 , const ::com::sun::star::awt::Rectangle& rMaximumSpaceForLabels )
71 {
72 m_aAxisLabelProperties.m_aFontReferenceSize = rFontReferenceSize;
73 m_aAxisLabelProperties.m_aMaximumSpaceForLabels = rMaximumSpaceForLabels;
74
75 if( !m_aAxisProperties.m_bDisplayLabels )
76 return;
77
78 if( AxisType::SERIES==m_aAxisProperties.m_nAxisType )
79 {
80 if( m_aAxisProperties.m_xAxisTextProvider.is() )
81 m_aTextLabels = m_aAxisProperties.m_xAxisTextProvider->getTextualData();
82
83 m_bUseTextLabels = true;
84 if( m_aTextLabels.getLength() == 1 )
85 {
86 //don't show a single series name
87 m_aAxisProperties.m_bDisplayLabels = false;
88 return;
89 }
90 }
91 else if( AxisType::CATEGORY==m_aAxisProperties.m_nAxisType )
92 {
93 if( m_aAxisProperties.m_pExplicitCategoriesProvider )
94 m_aTextLabels = m_aAxisProperties.m_pExplicitCategoriesProvider->getSimpleCategories();
95
96 m_bUseTextLabels = true;
97 }
98
99 m_aAxisLabelProperties.nNumberFormatKey = m_aAxisProperties.m_nNumberFormatKey;
100 m_aAxisLabelProperties.init(m_aAxisProperties.m_xAxisModel);
101 if( m_aAxisProperties.m_bComplexCategories && AxisType::CATEGORY == m_aAxisProperties.m_nAxisType )
102 m_aAxisLabelProperties.eStaggering = SIDE_BY_SIDE;
103 }
104
isDateAxis() const105 bool VAxisBase::isDateAxis() const
106 {
107 return AxisType::DATE == m_aScale.AxisType;
108 }
isComplexCategoryAxis() const109 bool VAxisBase::isComplexCategoryAxis() const
110 {
111 return m_aAxisProperties.m_bComplexCategories && m_bUseTextLabels;
112 }
113
recordMaximumTextSize(const Reference<drawing::XShape> & xShape,double fRotationAngleDegree)114 void VAxisBase::recordMaximumTextSize( const Reference< drawing::XShape >& xShape, double fRotationAngleDegree )
115 {
116 if( m_bRecordMaximumTextSize && xShape.is() )
117 {
118 awt::Size aSize( ShapeFactory::getSizeAfterRotation(
119 xShape, fRotationAngleDegree ) );
120
121 m_nMaximumTextWidthSoFar = std::max( m_nMaximumTextWidthSoFar, aSize.Width );
122 m_nMaximumTextHeightSoFar = std::max( m_nMaximumTextHeightSoFar, aSize.Height );
123 }
124 }
125
estimateMaximumAutoMainIncrementCount()126 sal_Int32 VAxisBase::estimateMaximumAutoMainIncrementCount()
127 {
128 return 10;
129 }
130
setExrtaLinePositionAtOtherAxis(const double & fCrossingAt)131 void VAxisBase::setExrtaLinePositionAtOtherAxis( const double& fCrossingAt )
132 {
133 if( m_aAxisProperties.m_pfExrtaLinePositionAtOtherAxis )
134 delete m_aAxisProperties.m_pfExrtaLinePositionAtOtherAxis;
135 m_aAxisProperties.m_pfExrtaLinePositionAtOtherAxis = new double(fCrossingAt);
136 }
137
isAnythingToDraw()138 sal_Bool VAxisBase::isAnythingToDraw()
139 {
140 if( !m_aAxisProperties.m_xAxisModel.is() )
141 return false;
142
143 DBG_ASSERT(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is(),"Axis is not proper initialized");
144 if(!(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is()))
145 return false;
146
147 uno::Reference< beans::XPropertySet > xProps( m_aAxisProperties.m_xAxisModel, uno::UNO_QUERY );
148 if( xProps.is() )
149 {
150 sal_Bool bShow = sal_False;
151 xProps->getPropertyValue( C2U( "Show" ) ) >>= bShow;
152 if( !bShow )
153 return false;
154 }
155 return true;
156 }
157
setExplicitScaleAndIncrement(const ExplicitScaleData & rScale,const ExplicitIncrementData & rIncrement)158 void VAxisBase::setExplicitScaleAndIncrement(
159 const ExplicitScaleData& rScale
160 , const ExplicitIncrementData& rIncrement )
161 throw (uno::RuntimeException)
162 {
163 m_bReCreateAllTickInfos = true;
164 m_aScale = rScale;
165 m_aIncrement = rIncrement;
166 }
167
createAllTickInfos(::std::vector<::std::vector<TickInfo>> & rAllTickInfos)168 void VAxisBase::createAllTickInfos( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos )
169 {
170 std::auto_ptr< TickFactory > apTickFactory( this->createTickFactory() );
171 if( m_aScale.ShiftedCategoryPosition )
172 apTickFactory->getAllTicksShifted( rAllTickInfos );
173 else
174 apTickFactory->getAllTicks( rAllTickInfos );
175 }
176
prepareShapeCreation()177 bool VAxisBase::prepareShapeCreation()
178 {
179 //returns true if all is ready for further shape creation and any shapes need to be created
180 if( !isAnythingToDraw() )
181 return false;
182
183 if( m_bReCreateAllTickInfos )
184 {
185 //-----------------------------------------
186 //create all scaled tickmark values
187 removeTextShapesFromTicks();
188
189 createAllTickInfos(m_aAllTickInfos);
190 m_bReCreateAllTickInfos = false;
191 }
192
193 if( m_xGroupShape_Shapes.is() )
194 return true;
195
196 //-----------------------------------------
197 //create named group shape
198 m_xGroupShape_Shapes = this->createGroupShape( m_xLogicTarget, m_nDimension==2 ? m_aCID : C2U(""));
199
200 if( m_aAxisProperties.m_bDisplayLabels )
201 m_xTextTarget = m_pShapeFactory->createGroup2D( m_xFinalTarget, m_aCID );
202
203 return true;
204 }
205
getIndexOfLongestLabel(const uno::Sequence<rtl::OUString> & rLabels)206 sal_Int32 VAxisBase::getIndexOfLongestLabel( const uno::Sequence< rtl::OUString >& rLabels )
207 {
208 sal_Int32 nRet = 0;
209 sal_Int32 nLength = 0;
210 sal_Int32 nN = 0;
211 for( nN=0; nN<rLabels.getLength(); nN++ )
212 {
213 //todo: get real text width (without creating shape) instead of character count
214 if( rLabels[nN].getLength() > nLength )
215 {
216 nLength = rLabels[nN].getLength();
217 nRet = nN;
218 }
219 }
220 return nRet;
221 }
222
removeTextShapesFromTicks()223 void VAxisBase::removeTextShapesFromTicks()
224 {
225 if( m_xTextTarget.is() )
226 {
227 ::std::vector< ::std::vector< TickInfo > >::iterator aDepthIter = m_aAllTickInfos.begin();
228 const ::std::vector< ::std::vector< TickInfo > >::const_iterator aDepthEnd = m_aAllTickInfos.end();
229 for( ; aDepthIter != aDepthEnd; aDepthIter++ )
230 {
231 ::std::vector< TickInfo >::iterator aTickIter = (*aDepthIter).begin();
232 const ::std::vector< TickInfo >::const_iterator aTickEnd = (*aDepthIter).end();
233 for( ; aTickIter != aTickEnd; aTickIter++ )
234 {
235 TickInfo& rTickInfo = (*aTickIter);
236 if(rTickInfo.xTextShape.is())
237 {
238 m_xTextTarget->remove(rTickInfo.xTextShape);
239 rTickInfo.xTextShape = NULL;
240 }
241 }
242 }
243 }
244 }
245
updateUnscaledValuesAtTicks(TickIter & rIter)246 void VAxisBase::updateUnscaledValuesAtTicks( TickIter& rIter )
247 {
248 Reference< XScaling > xInverseScaling( NULL );
249 if( m_aScale.Scaling.is() )
250 xInverseScaling = m_aScale.Scaling->getInverseScaling();
251
252 for( TickInfo* pTickInfo = rIter.firstInfo()
253 ; pTickInfo; pTickInfo = rIter.nextInfo() )
254 {
255 //xxxxx pTickInfo->updateUnscaledValue( xInverseScaling );
256 }
257 }
258
259 //.............................................................................
260 } //namespace chart
261 //.............................................................................
262