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