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 #include <basegfx/numeric/ftools.hxx>
27
28 #include "VPolarAngleAxis.hxx"
29 #include "VPolarGrid.hxx"
30 #include "ShapeFactory.hxx"
31 #include "macros.hxx"
32 #include "NumberFormatterWrapper.hxx"
33 #include "PolarLabelPositionHelper.hxx"
34 #include <tools/color.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 namespace ::rtl::math;
45
VPolarAngleAxis(const AxisProperties & rAxisProperties,const uno::Reference<util::XNumberFormatsSupplier> & xNumberFormatsSupplier,sal_Int32 nDimensionCount)46 VPolarAngleAxis::VPolarAngleAxis( const AxisProperties& rAxisProperties
47 , const uno::Reference< util::XNumberFormatsSupplier >& xNumberFormatsSupplier
48 , sal_Int32 nDimensionCount )
49 : VPolarAxis( rAxisProperties, xNumberFormatsSupplier, 0/*nDimensionIndex*/, nDimensionCount )
50 {
51 }
52
~VPolarAngleAxis()53 VPolarAngleAxis::~VPolarAngleAxis()
54 {
55 delete m_pPosHelper;
56 m_pPosHelper = NULL;
57 }
58
createTextShapes_ForAngleAxis(const uno::Reference<drawing::XShapes> & xTarget,EquidistantTickIter & rTickIter,AxisLabelProperties & rAxisLabelProperties,double fLogicRadius,double fLogicZ)59 bool VPolarAngleAxis::createTextShapes_ForAngleAxis(
60 const uno::Reference< drawing::XShapes >& xTarget
61 , EquidistantTickIter& rTickIter
62 , AxisLabelProperties& rAxisLabelProperties
63 , double fLogicRadius
64 , double fLogicZ )
65 {
66 sal_Int32 nDimensionCount = 2;
67 ShapeFactory aShapeFactory(m_xShapeFactory);
68
69 FixedNumberFormatter aFixedNumberFormatter(
70 m_xNumberFormatsSupplier, rAxisLabelProperties.nNumberFormatKey );
71
72 //------------------------------------------------
73 //prepare text properties for multipropertyset-interface of shape
74 tNameSequence aPropNames;
75 tAnySequence aPropValues;
76
77 uno::Reference< beans::XPropertySet > xProps( m_aAxisProperties.m_xAxisModel, uno::UNO_QUERY );
78 PropertyMapper::getTextLabelMultiPropertyLists( xProps, aPropNames, aPropValues, false );
79 LabelPositionHelper::doDynamicFontResize( aPropValues, aPropNames, xProps
80 , rAxisLabelProperties.m_aFontReferenceSize );
81
82 uno::Any* pColorAny = PropertyMapper::getValuePointer(aPropValues,aPropNames,C2U("CharColor"));
83 sal_Int32 nColor = Color( COL_AUTO ).GetColor();
84 if(pColorAny)
85 *pColorAny >>= nColor;
86
87 const uno::Sequence< rtl::OUString >* pLabels = m_bUseTextLabels? &m_aTextLabels : 0;
88
89 //------------------------------------------------
90
91 //TickInfo* pLastVisibleNeighbourTickInfo = NULL;
92 sal_Int32 nTick = 0;
93
94 for( TickInfo* pTickInfo = rTickIter.firstInfo()
95 ; pTickInfo
96 ; pTickInfo = rTickIter.nextInfo(), nTick++ )
97 {
98 //don't create labels which does not fit into the rhythm
99 if( nTick%rAxisLabelProperties.nRhythm != 0)
100 continue;
101
102 //don't create labels for invisible ticks
103 if( !pTickInfo->bPaintIt )
104 continue;
105
106 //if NO OVERLAP -> don't create labels where the
107 //anchor position is the same as for the last label
108 //@todo
109
110 if(!pTickInfo->xTextShape.is())
111 {
112 //create single label
113 bool bHasExtraColor=false;
114 sal_Int32 nExtraColor=0;
115
116 rtl::OUString aLabel;
117 if(pLabels)
118 {
119 sal_Int32 nIndex = static_cast< sal_Int32 >(pTickInfo->getUnscaledTickValue()) - 1; //first category (index 0) matches with real number 1.0
120 if( nIndex>=0 && nIndex<pLabels->getLength() )
121 aLabel = (*pLabels)[nIndex];
122 }
123 else
124 aLabel = aFixedNumberFormatter.getFormattedString( pTickInfo->getUnscaledTickValue(), nExtraColor, bHasExtraColor );
125
126 if(pColorAny)
127 *pColorAny = uno::makeAny(bHasExtraColor?nExtraColor:nColor);
128
129 double fLogicAngle = pTickInfo->getUnscaledTickValue();
130
131 LabelAlignment eLabelAlignment(LABEL_ALIGN_CENTER);
132 PolarLabelPositionHelper aPolarLabelPositionHelper(m_pPosHelper,nDimensionCount,xTarget,&aShapeFactory);
133 sal_Int32 nScreenValueOffsetInRadiusDirection = m_aAxisLabelProperties.m_aMaximumSpaceForLabels.Height/15;
134 awt::Point aAnchorScreenPosition2D( aPolarLabelPositionHelper.getLabelScreenPositionAndAlignmentForLogicValues(
135 eLabelAlignment, fLogicAngle, fLogicRadius, fLogicZ, nScreenValueOffsetInRadiusDirection ));
136 LabelPositionHelper::changeTextAdjustment( aPropValues, aPropNames, eLabelAlignment );
137
138 // #i78696# use mathematically correct rotation now
139 const double fRotationAnglePi(rAxisLabelProperties.fRotationAngleDegree * (F_PI / -180.0));
140
141 uno::Any aATransformation = ShapeFactory::makeTransformation( aAnchorScreenPosition2D, fRotationAnglePi );
142 rtl::OUString aStackedLabel = ShapeFactory::getStackedString( aLabel, rAxisLabelProperties.bStackCharacters );
143
144 pTickInfo->xTextShape = aShapeFactory.createText( xTarget, aStackedLabel, aPropNames, aPropValues, aATransformation );
145 }
146
147 //if NO OVERLAP -> remove overlapping shapes
148 //@todo
149 }
150 return true;
151 }
152
createMaximumLabels()153 void VPolarAngleAxis::createMaximumLabels()
154 {
155 if( !prepareShapeCreation() )
156 return;
157
158 createLabels();
159 }
160
updatePositions()161 void VPolarAngleAxis::updatePositions()
162 {
163 //todo: really only update the positions
164
165 if( !prepareShapeCreation() )
166 return;
167
168 createLabels();
169 }
170
createLabels()171 void VPolarAngleAxis::createLabels()
172 {
173 if( !prepareShapeCreation() )
174 return;
175
176 double fLogicRadius = m_pPosHelper->getOuterLogicRadius();
177 double fLogicZ = 1.0;//as defined
178
179 if( m_aAxisProperties.m_bDisplayLabels )
180 {
181 //-----------------------------------------
182 //get the transformed screen values for all tickmarks in aAllTickInfos
183 std::auto_ptr< TickFactory > apTickFactory( this->createTickFactory() );
184
185 //create tick mark text shapes
186 //@todo: iterate through all tick depth which should be labeled
187
188 EquidistantTickIter aTickIter( m_aAllTickInfos, m_aIncrement, 0, 0 );
189 this->updateUnscaledValuesAtTicks( aTickIter );
190
191 removeTextShapesFromTicks();
192
193 AxisLabelProperties aAxisLabelProperties( m_aAxisLabelProperties );
194 aAxisLabelProperties.bOverlapAllowed = true;
195 while( !createTextShapes_ForAngleAxis( m_xTextTarget, aTickIter
196 , aAxisLabelProperties
197 , fLogicRadius, fLogicZ
198 ) )
199 {
200 };
201
202 //no staggering for polar angle axis
203 }
204 }
205
createShapes()206 void VPolarAngleAxis::createShapes()
207 {
208 if( !prepareShapeCreation() )
209 return;
210
211 double fLogicRadius = m_pPosHelper->getOuterLogicRadius();
212 double fLogicZ = 1.0;//as defined
213
214 //-----------------------------------------
215 //create axis main lines
216 drawing::PointSequenceSequence aPoints(1);
217 VPolarGrid::createLinePointSequence_ForAngleAxis( aPoints, m_aAllTickInfos, m_aIncrement, m_aScale, m_pPosHelper, fLogicRadius, fLogicZ );
218 uno::Reference< drawing::XShape > xShape = m_pShapeFactory->createLine2D(
219 m_xGroupShape_Shapes, aPoints, &m_aAxisProperties.m_aLineProperties );
220 //because of this name this line will be used for marking the axis
221 m_pShapeFactory->setShapeName( xShape, C2U("MarkHandles") );
222
223 //-----------------------------------------
224 //create labels
225 createLabels();
226 }
227
228 //.............................................................................
229 } //namespace chart
230 //.............................................................................
231