1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_chart2.hxx" 30*cdf0e10cSrcweir #include <basegfx/numeric/ftools.hxx> 31*cdf0e10cSrcweir 32*cdf0e10cSrcweir #include "VPolarAngleAxis.hxx" 33*cdf0e10cSrcweir #include "VPolarGrid.hxx" 34*cdf0e10cSrcweir #include "ShapeFactory.hxx" 35*cdf0e10cSrcweir #include "macros.hxx" 36*cdf0e10cSrcweir #include "NumberFormatterWrapper.hxx" 37*cdf0e10cSrcweir #include "PolarLabelPositionHelper.hxx" 38*cdf0e10cSrcweir #include <tools/color.hxx> 39*cdf0e10cSrcweir 40*cdf0e10cSrcweir #include <memory> 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir //............................................................................. 43*cdf0e10cSrcweir namespace chart 44*cdf0e10cSrcweir { 45*cdf0e10cSrcweir //............................................................................. 46*cdf0e10cSrcweir using namespace ::com::sun::star; 47*cdf0e10cSrcweir using namespace ::com::sun::star::chart2; 48*cdf0e10cSrcweir using namespace ::rtl::math; 49*cdf0e10cSrcweir 50*cdf0e10cSrcweir VPolarAngleAxis::VPolarAngleAxis( const AxisProperties& rAxisProperties 51*cdf0e10cSrcweir , const uno::Reference< util::XNumberFormatsSupplier >& xNumberFormatsSupplier 52*cdf0e10cSrcweir , sal_Int32 nDimensionCount ) 53*cdf0e10cSrcweir : VPolarAxis( rAxisProperties, xNumberFormatsSupplier, 0/*nDimensionIndex*/, nDimensionCount ) 54*cdf0e10cSrcweir { 55*cdf0e10cSrcweir } 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir VPolarAngleAxis::~VPolarAngleAxis() 58*cdf0e10cSrcweir { 59*cdf0e10cSrcweir delete m_pPosHelper; 60*cdf0e10cSrcweir m_pPosHelper = NULL; 61*cdf0e10cSrcweir } 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir bool VPolarAngleAxis::createTextShapes_ForAngleAxis( 64*cdf0e10cSrcweir const uno::Reference< drawing::XShapes >& xTarget 65*cdf0e10cSrcweir , EquidistantTickIter& rTickIter 66*cdf0e10cSrcweir , AxisLabelProperties& rAxisLabelProperties 67*cdf0e10cSrcweir , double fLogicRadius 68*cdf0e10cSrcweir , double fLogicZ ) 69*cdf0e10cSrcweir { 70*cdf0e10cSrcweir sal_Int32 nDimensionCount = 2; 71*cdf0e10cSrcweir ShapeFactory aShapeFactory(m_xShapeFactory); 72*cdf0e10cSrcweir 73*cdf0e10cSrcweir FixedNumberFormatter aFixedNumberFormatter( 74*cdf0e10cSrcweir m_xNumberFormatsSupplier, rAxisLabelProperties.nNumberFormatKey ); 75*cdf0e10cSrcweir 76*cdf0e10cSrcweir //------------------------------------------------ 77*cdf0e10cSrcweir //prepare text properties for multipropertyset-interface of shape 78*cdf0e10cSrcweir tNameSequence aPropNames; 79*cdf0e10cSrcweir tAnySequence aPropValues; 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir uno::Reference< beans::XPropertySet > xProps( m_aAxisProperties.m_xAxisModel, uno::UNO_QUERY ); 82*cdf0e10cSrcweir PropertyMapper::getTextLabelMultiPropertyLists( xProps, aPropNames, aPropValues, false ); 83*cdf0e10cSrcweir LabelPositionHelper::doDynamicFontResize( aPropValues, aPropNames, xProps 84*cdf0e10cSrcweir , rAxisLabelProperties.m_aFontReferenceSize ); 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir uno::Any* pColorAny = PropertyMapper::getValuePointer(aPropValues,aPropNames,C2U("CharColor")); 87*cdf0e10cSrcweir sal_Int32 nColor = Color( COL_AUTO ).GetColor(); 88*cdf0e10cSrcweir if(pColorAny) 89*cdf0e10cSrcweir *pColorAny >>= nColor; 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir const uno::Sequence< rtl::OUString >* pLabels = m_bUseTextLabels? &m_aTextLabels : 0; 92*cdf0e10cSrcweir 93*cdf0e10cSrcweir //------------------------------------------------ 94*cdf0e10cSrcweir 95*cdf0e10cSrcweir //TickInfo* pLastVisibleNeighbourTickInfo = NULL; 96*cdf0e10cSrcweir sal_Int32 nTick = 0; 97*cdf0e10cSrcweir 98*cdf0e10cSrcweir for( TickInfo* pTickInfo = rTickIter.firstInfo() 99*cdf0e10cSrcweir ; pTickInfo 100*cdf0e10cSrcweir ; pTickInfo = rTickIter.nextInfo(), nTick++ ) 101*cdf0e10cSrcweir { 102*cdf0e10cSrcweir //don't create labels which does not fit into the rhythm 103*cdf0e10cSrcweir if( nTick%rAxisLabelProperties.nRhythm != 0) 104*cdf0e10cSrcweir continue; 105*cdf0e10cSrcweir 106*cdf0e10cSrcweir //don't create labels for invisible ticks 107*cdf0e10cSrcweir if( !pTickInfo->bPaintIt ) 108*cdf0e10cSrcweir continue; 109*cdf0e10cSrcweir 110*cdf0e10cSrcweir //if NO OVERLAP -> don't create labels where the 111*cdf0e10cSrcweir //anchor position is the same as for the last label 112*cdf0e10cSrcweir //@todo 113*cdf0e10cSrcweir 114*cdf0e10cSrcweir if(!pTickInfo->xTextShape.is()) 115*cdf0e10cSrcweir { 116*cdf0e10cSrcweir //create single label 117*cdf0e10cSrcweir bool bHasExtraColor=false; 118*cdf0e10cSrcweir sal_Int32 nExtraColor=0; 119*cdf0e10cSrcweir 120*cdf0e10cSrcweir rtl::OUString aLabel; 121*cdf0e10cSrcweir if(pLabels) 122*cdf0e10cSrcweir { 123*cdf0e10cSrcweir sal_Int32 nIndex = static_cast< sal_Int32 >(pTickInfo->getUnscaledTickValue()) - 1; //first category (index 0) matches with real number 1.0 124*cdf0e10cSrcweir if( nIndex>=0 && nIndex<pLabels->getLength() ) 125*cdf0e10cSrcweir aLabel = (*pLabels)[nIndex]; 126*cdf0e10cSrcweir } 127*cdf0e10cSrcweir else 128*cdf0e10cSrcweir aLabel = aFixedNumberFormatter.getFormattedString( pTickInfo->getUnscaledTickValue(), nExtraColor, bHasExtraColor ); 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir if(pColorAny) 131*cdf0e10cSrcweir *pColorAny = uno::makeAny(bHasExtraColor?nExtraColor:nColor); 132*cdf0e10cSrcweir 133*cdf0e10cSrcweir double fLogicAngle = pTickInfo->getUnscaledTickValue(); 134*cdf0e10cSrcweir 135*cdf0e10cSrcweir LabelAlignment eLabelAlignment(LABEL_ALIGN_CENTER); 136*cdf0e10cSrcweir PolarLabelPositionHelper aPolarLabelPositionHelper(m_pPosHelper,nDimensionCount,xTarget,&aShapeFactory); 137*cdf0e10cSrcweir sal_Int32 nScreenValueOffsetInRadiusDirection = m_aAxisLabelProperties.m_aMaximumSpaceForLabels.Height/15; 138*cdf0e10cSrcweir awt::Point aAnchorScreenPosition2D( aPolarLabelPositionHelper.getLabelScreenPositionAndAlignmentForLogicValues( 139*cdf0e10cSrcweir eLabelAlignment, fLogicAngle, fLogicRadius, fLogicZ, nScreenValueOffsetInRadiusDirection )); 140*cdf0e10cSrcweir LabelPositionHelper::changeTextAdjustment( aPropValues, aPropNames, eLabelAlignment ); 141*cdf0e10cSrcweir 142*cdf0e10cSrcweir // #i78696# use mathematically correct rotation now 143*cdf0e10cSrcweir const double fRotationAnglePi(rAxisLabelProperties.fRotationAngleDegree * (F_PI / -180.0)); 144*cdf0e10cSrcweir 145*cdf0e10cSrcweir uno::Any aATransformation = ShapeFactory::makeTransformation( aAnchorScreenPosition2D, fRotationAnglePi ); 146*cdf0e10cSrcweir rtl::OUString aStackedLabel = ShapeFactory::getStackedString( aLabel, rAxisLabelProperties.bStackCharacters ); 147*cdf0e10cSrcweir 148*cdf0e10cSrcweir pTickInfo->xTextShape = aShapeFactory.createText( xTarget, aStackedLabel, aPropNames, aPropValues, aATransformation ); 149*cdf0e10cSrcweir } 150*cdf0e10cSrcweir 151*cdf0e10cSrcweir //if NO OVERLAP -> remove overlapping shapes 152*cdf0e10cSrcweir //@todo 153*cdf0e10cSrcweir } 154*cdf0e10cSrcweir return true; 155*cdf0e10cSrcweir } 156*cdf0e10cSrcweir 157*cdf0e10cSrcweir void VPolarAngleAxis::createMaximumLabels() 158*cdf0e10cSrcweir { 159*cdf0e10cSrcweir if( !prepareShapeCreation() ) 160*cdf0e10cSrcweir return; 161*cdf0e10cSrcweir 162*cdf0e10cSrcweir createLabels(); 163*cdf0e10cSrcweir } 164*cdf0e10cSrcweir 165*cdf0e10cSrcweir void VPolarAngleAxis::updatePositions() 166*cdf0e10cSrcweir { 167*cdf0e10cSrcweir //todo: really only update the positions 168*cdf0e10cSrcweir 169*cdf0e10cSrcweir if( !prepareShapeCreation() ) 170*cdf0e10cSrcweir return; 171*cdf0e10cSrcweir 172*cdf0e10cSrcweir createLabels(); 173*cdf0e10cSrcweir } 174*cdf0e10cSrcweir 175*cdf0e10cSrcweir void VPolarAngleAxis::createLabels() 176*cdf0e10cSrcweir { 177*cdf0e10cSrcweir if( !prepareShapeCreation() ) 178*cdf0e10cSrcweir return; 179*cdf0e10cSrcweir 180*cdf0e10cSrcweir double fLogicRadius = m_pPosHelper->getOuterLogicRadius(); 181*cdf0e10cSrcweir double fLogicZ = 1.0;//as defined 182*cdf0e10cSrcweir 183*cdf0e10cSrcweir if( m_aAxisProperties.m_bDisplayLabels ) 184*cdf0e10cSrcweir { 185*cdf0e10cSrcweir //----------------------------------------- 186*cdf0e10cSrcweir //get the transformed screen values for all tickmarks in aAllTickInfos 187*cdf0e10cSrcweir std::auto_ptr< TickFactory > apTickFactory( this->createTickFactory() ); 188*cdf0e10cSrcweir 189*cdf0e10cSrcweir //create tick mark text shapes 190*cdf0e10cSrcweir //@todo: iterate through all tick depth wich should be labeled 191*cdf0e10cSrcweir 192*cdf0e10cSrcweir EquidistantTickIter aTickIter( m_aAllTickInfos, m_aIncrement, 0, 0 ); 193*cdf0e10cSrcweir this->updateUnscaledValuesAtTicks( aTickIter ); 194*cdf0e10cSrcweir 195*cdf0e10cSrcweir removeTextShapesFromTicks(); 196*cdf0e10cSrcweir 197*cdf0e10cSrcweir AxisLabelProperties aAxisLabelProperties( m_aAxisLabelProperties ); 198*cdf0e10cSrcweir aAxisLabelProperties.bOverlapAllowed = true; 199*cdf0e10cSrcweir while( !createTextShapes_ForAngleAxis( m_xTextTarget, aTickIter 200*cdf0e10cSrcweir , aAxisLabelProperties 201*cdf0e10cSrcweir , fLogicRadius, fLogicZ 202*cdf0e10cSrcweir ) ) 203*cdf0e10cSrcweir { 204*cdf0e10cSrcweir }; 205*cdf0e10cSrcweir 206*cdf0e10cSrcweir //no staggering for polar angle axis 207*cdf0e10cSrcweir } 208*cdf0e10cSrcweir } 209*cdf0e10cSrcweir 210*cdf0e10cSrcweir void VPolarAngleAxis::createShapes() 211*cdf0e10cSrcweir { 212*cdf0e10cSrcweir if( !prepareShapeCreation() ) 213*cdf0e10cSrcweir return; 214*cdf0e10cSrcweir 215*cdf0e10cSrcweir double fLogicRadius = m_pPosHelper->getOuterLogicRadius(); 216*cdf0e10cSrcweir double fLogicZ = 1.0;//as defined 217*cdf0e10cSrcweir 218*cdf0e10cSrcweir //----------------------------------------- 219*cdf0e10cSrcweir //create axis main lines 220*cdf0e10cSrcweir drawing::PointSequenceSequence aPoints(1); 221*cdf0e10cSrcweir VPolarGrid::createLinePointSequence_ForAngleAxis( aPoints, m_aAllTickInfos, m_aIncrement, m_aScale, m_pPosHelper, fLogicRadius, fLogicZ ); 222*cdf0e10cSrcweir uno::Reference< drawing::XShape > xShape = m_pShapeFactory->createLine2D( 223*cdf0e10cSrcweir m_xGroupShape_Shapes, aPoints, &m_aAxisProperties.m_aLineProperties ); 224*cdf0e10cSrcweir //because of this name this line will be used for marking the axis 225*cdf0e10cSrcweir m_pShapeFactory->setShapeName( xShape, C2U("MarkHandles") ); 226*cdf0e10cSrcweir 227*cdf0e10cSrcweir //----------------------------------------- 228*cdf0e10cSrcweir //create labels 229*cdf0e10cSrcweir createLabels(); 230*cdf0e10cSrcweir } 231*cdf0e10cSrcweir 232*cdf0e10cSrcweir //............................................................................. 233*cdf0e10cSrcweir } //namespace chart 234*cdf0e10cSrcweir //............................................................................. 235