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 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 60 VAxisBase::~VAxisBase() 61 { 62 } 63 64 sal_Int32 VAxisBase::getDimensionCount() 65 { 66 return m_nDimension; 67 } 68 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 105 bool VAxisBase::isDateAxis() const 106 { 107 return AxisType::DATE == m_aScale.AxisType; 108 } 109 bool VAxisBase::isComplexCategoryAxis() const 110 { 111 return m_aAxisProperties.m_bComplexCategories && m_bUseTextLabels; 112 } 113 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 126 sal_Int32 VAxisBase::estimateMaximumAutoMainIncrementCount() 127 { 128 return 10; 129 } 130 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 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 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 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 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 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 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 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