1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_chart2.hxx" 30 31 #include "PolarLabelPositionHelper.hxx" 32 #include "PlottingPositionHelper.hxx" 33 #include "CommonConverters.hxx" 34 #include <basegfx/vector/b2dvector.hxx> 35 #include <basegfx/vector/b2ivector.hxx> 36 37 #include <com/sun/star/chart/DataLabelPlacement.hpp> 38 39 //............................................................................. 40 namespace chart 41 { 42 //............................................................................. 43 using namespace ::com::sun::star; 44 using namespace ::com::sun::star::chart2; 45 46 PolarLabelPositionHelper::PolarLabelPositionHelper( 47 PolarPlottingPositionHelper* pPosHelper 48 , sal_Int32 nDimensionCount 49 , const uno::Reference< drawing::XShapes >& xLogicTarget 50 , ShapeFactory* pShapeFactory ) 51 : LabelPositionHelper( pPosHelper, nDimensionCount, xLogicTarget, pShapeFactory ) 52 , m_pPosHelper(pPosHelper) 53 { 54 } 55 56 PolarLabelPositionHelper::~PolarLabelPositionHelper() 57 { 58 } 59 60 awt::Point PolarLabelPositionHelper::getLabelScreenPositionAndAlignmentForLogicValues( 61 LabelAlignment& rAlignment 62 , double fLogicValueOnAngleAxis 63 , double fLogicValueOnRadiusAxis 64 , double fLogicZ 65 , sal_Int32 nScreenValueOffsetInRadiusDirection ) const 66 { 67 double fUnitCircleAngleDegree = m_pPosHelper->transformToAngleDegree( fLogicValueOnAngleAxis ); 68 double fUnitCircleRadius = m_pPosHelper->transformToRadius( fLogicValueOnRadiusAxis ); 69 70 return getLabelScreenPositionAndAlignmentForUnitCircleValues( 71 rAlignment, ::com::sun::star::chart::DataLabelPlacement::OUTSIDE 72 , fUnitCircleAngleDegree, 0.0 73 , fUnitCircleRadius, fUnitCircleRadius, fLogicZ, nScreenValueOffsetInRadiusDirection ); 74 } 75 76 awt::Point PolarLabelPositionHelper::getLabelScreenPositionAndAlignmentForUnitCircleValues( 77 LabelAlignment& rAlignment, sal_Int32 nLabelPlacement 78 , double fUnitCircleStartAngleDegree, double fUnitCircleWidthAngleDegree 79 , double fUnitCircleInnerRadius, double fUnitCircleOuterRadius 80 , double fLogicZ 81 , sal_Int32 nScreenValueOffsetInRadiusDirection ) const 82 { 83 bool bCenter = (nLabelPlacement != ::com::sun::star::chart::DataLabelPlacement::OUTSIDE) 84 && (nLabelPlacement != ::com::sun::star::chart::DataLabelPlacement::INSIDE); 85 86 double fAngleDegree = fUnitCircleStartAngleDegree + fUnitCircleWidthAngleDegree/2.0; 87 double fRadius = 0.0; 88 if( !bCenter ) //e.g. for pure pie chart(one ring only) or for angle axis of polyar coordinate system 89 fRadius = fUnitCircleOuterRadius; 90 else 91 fRadius = fUnitCircleInnerRadius + (fUnitCircleOuterRadius-fUnitCircleInnerRadius)/2.0 ; 92 93 awt::Point aRet( this->transformSceneToScreenPosition( 94 m_pPosHelper->transformUnitCircleToScene( fAngleDegree, fRadius, fLogicZ+0.5 ) ) ); 95 96 if(3==m_nDimensionCount && nLabelPlacement == ::com::sun::star::chart::DataLabelPlacement::OUTSIDE) 97 { 98 //check wether the upper or the downer edge is more distant from the center 99 //take the farest point to put the label to 100 101 awt::Point aP0( this->transformSceneToScreenPosition( 102 m_pPosHelper->transformUnitCircleToScene( 0, 0, fLogicZ ) ) ); 103 awt::Point aP1(aRet); 104 awt::Point aP2( this->transformSceneToScreenPosition( 105 m_pPosHelper->transformUnitCircleToScene( fAngleDegree, fRadius, fLogicZ-0.5 ) ) ); 106 107 ::basegfx::B2DVector aV0( aP0.X, aP0.Y ); 108 ::basegfx::B2DVector aV1( aP1.X, aP1.Y ); 109 ::basegfx::B2DVector aV2( aP2.X, aP2.Y ); 110 111 double fL1 = ::basegfx::B2DVector(aV1-aV0).getLength(); 112 double fL2 = ::basegfx::B2DVector(aV2-aV0).getLength(); 113 114 if(fL2>fL1) 115 aRet = aP2; 116 117 //calculate new angle for alignment 118 double fDX = aRet.X-aP0.X; 119 double fDY = aRet.Y-aP0.Y; 120 fDY*=-1.0;//drawing layer has inverse y values 121 if( fDX != 0.0 ) 122 { 123 fAngleDegree = atan(fDY/fDX)*180.0/F_PI; 124 if(fDX<0.0) 125 fAngleDegree+=180.0; 126 } 127 else 128 { 129 if(fDY>0.0) 130 fAngleDegree = 90.0; 131 else 132 fAngleDegree = 270.0; 133 } 134 } 135 //------------------------------ 136 //set LabelAlignment 137 if( !bCenter ) 138 { 139 while(fAngleDegree>360.0) 140 fAngleDegree-=360.0; 141 while(fAngleDegree<0.0) 142 fAngleDegree+=360.0; 143 144 bool bOutside = nLabelPlacement == ::com::sun::star::chart::DataLabelPlacement::OUTSIDE; 145 146 if(fAngleDegree==0.0) 147 rAlignment = LABEL_ALIGN_CENTER; 148 else if(fAngleDegree<=22.5) 149 rAlignment = bOutside ? LABEL_ALIGN_RIGHT : LABEL_ALIGN_LEFT; 150 else if(fAngleDegree<67.5) 151 rAlignment = bOutside ? LABEL_ALIGN_RIGHT_TOP : LABEL_ALIGN_LEFT_BOTTOM; 152 else if(fAngleDegree<112.5) 153 rAlignment = bOutside ? LABEL_ALIGN_TOP : LABEL_ALIGN_BOTTOM; 154 else if(fAngleDegree<=157.5) 155 rAlignment = bOutside ? LABEL_ALIGN_LEFT_TOP : LABEL_ALIGN_RIGHT_BOTTOM; 156 else if(fAngleDegree<=202.5) 157 rAlignment = bOutside ? LABEL_ALIGN_LEFT : LABEL_ALIGN_RIGHT; 158 else if(fAngleDegree<247.5) 159 rAlignment = bOutside ? LABEL_ALIGN_LEFT_BOTTOM : LABEL_ALIGN_RIGHT_TOP; 160 else if(fAngleDegree<292.5) 161 rAlignment = bOutside ? LABEL_ALIGN_BOTTOM : LABEL_ALIGN_TOP; 162 else if(fAngleDegree<337.5) 163 rAlignment = bOutside ? LABEL_ALIGN_RIGHT_BOTTOM : LABEL_ALIGN_LEFT_TOP; 164 else 165 rAlignment = bOutside ? LABEL_ALIGN_RIGHT : LABEL_ALIGN_LEFT; 166 } 167 else 168 { 169 rAlignment = LABEL_ALIGN_CENTER; 170 } 171 172 //add a scaling independent Offset if requested 173 if( nScreenValueOffsetInRadiusDirection != 0) 174 { 175 awt::Point aOrigin( this->transformSceneToScreenPosition( 176 m_pPosHelper->transformUnitCircleToScene( 0.0, 0.0, fLogicZ+0.5 ) ) ); 177 basegfx::B2IVector aDirection( aRet.X- aOrigin.X, aRet.Y- aOrigin.Y ); 178 aDirection.setLength(nScreenValueOffsetInRadiusDirection); 179 aRet.X += aDirection.getX(); 180 aRet.Y += aDirection.getY(); 181 } 182 183 return aRet; 184 } 185 186 //............................................................................. 187 } //namespace chart 188 //............................................................................. 189