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_chartview.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 {
162 m_bReCreateAllTickInfos = true;
163 m_aScale = rScale;
164 m_aIncrement = rIncrement;
165 }
166
createAllTickInfos(::std::vector<::std::vector<TickInfo>> & rAllTickInfos)167 void VAxisBase::createAllTickInfos( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos )
168 {
169 std::auto_ptr< TickFactory > apTickFactory( this->createTickFactory() );
170 if( m_aScale.ShiftedCategoryPosition )
171 apTickFactory->getAllTicksShifted( rAllTickInfos );
172 else
173 apTickFactory->getAllTicks( rAllTickInfos );
174 }
175
prepareShapeCreation()176 bool VAxisBase::prepareShapeCreation()
177 {
178 //returns true if all is ready for further shape creation and any shapes need to be created
179 if( !isAnythingToDraw() )
180 return false;
181
182 if( m_bReCreateAllTickInfos )
183 {
184 //-----------------------------------------
185 //create all scaled tickmark values
186 removeTextShapesFromTicks();
187
188 createAllTickInfos(m_aAllTickInfos);
189 m_bReCreateAllTickInfos = false;
190 }
191
192 if( m_xGroupShape_Shapes.is() )
193 return true;
194
195 //-----------------------------------------
196 //create named group shape
197 m_xGroupShape_Shapes = this->createGroupShape( m_xLogicTarget, m_nDimension==2 ? m_aCID : C2U(""));
198
199 if( m_aAxisProperties.m_bDisplayLabels )
200 m_xTextTarget = m_pShapeFactory->createGroup2D( m_xFinalTarget, m_aCID );
201
202 return true;
203 }
204
getIndexOfLongestLabel(const uno::Sequence<rtl::OUString> & rLabels)205 sal_Int32 VAxisBase::getIndexOfLongestLabel( const uno::Sequence< rtl::OUString >& rLabels )
206 {
207 sal_Int32 nRet = 0;
208 sal_Int32 nLength = 0;
209 sal_Int32 nN = 0;
210 for( nN=0; nN<rLabels.getLength(); nN++ )
211 {
212 //todo: get real text width (without creating shape) instead of character count
213 if( rLabels[nN].getLength() > nLength )
214 {
215 nLength = rLabels[nN].getLength();
216 nRet = nN;
217 }
218 }
219 return nRet;
220 }
221
removeTextShapesFromTicks()222 void VAxisBase::removeTextShapesFromTicks()
223 {
224 if( m_xTextTarget.is() )
225 {
226 ::std::vector< ::std::vector< TickInfo > >::iterator aDepthIter = m_aAllTickInfos.begin();
227 const ::std::vector< ::std::vector< TickInfo > >::const_iterator aDepthEnd = m_aAllTickInfos.end();
228 for( ; aDepthIter != aDepthEnd; aDepthIter++ )
229 {
230 ::std::vector< TickInfo >::iterator aTickIter = (*aDepthIter).begin();
231 const ::std::vector< TickInfo >::const_iterator aTickEnd = (*aDepthIter).end();
232 for( ; aTickIter != aTickEnd; aTickIter++ )
233 {
234 TickInfo& rTickInfo = (*aTickIter);
235 if(rTickInfo.xTextShape.is())
236 {
237 m_xTextTarget->remove(rTickInfo.xTextShape);
238 rTickInfo.xTextShape = NULL;
239 }
240 }
241 }
242 }
243 }
244
updateUnscaledValuesAtTicks(TickIter & rIter)245 void VAxisBase::updateUnscaledValuesAtTicks( TickIter& rIter )
246 {
247 Reference< XScaling > xInverseScaling( NULL );
248 if( m_aScale.Scaling.is() )
249 xInverseScaling = m_aScale.Scaling->getInverseScaling();
250
251 for( TickInfo* pTickInfo = rIter.firstInfo()
252 ; pTickInfo; pTickInfo = rIter.nextInfo() )
253 {
254 //xxxxx pTickInfo->updateUnscaledValue( xInverseScaling );
255 }
256 }
257
258 //.............................................................................
259 } //namespace chart
260 //.............................................................................
261