1*cde9e8dcSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*cde9e8dcSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*cde9e8dcSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*cde9e8dcSAndrew Rist  * distributed with this work for additional information
6*cde9e8dcSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*cde9e8dcSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*cde9e8dcSAndrew Rist  * "License"); you may not use this file except in compliance
9*cde9e8dcSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*cde9e8dcSAndrew Rist  *
11*cde9e8dcSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*cde9e8dcSAndrew Rist  *
13*cde9e8dcSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*cde9e8dcSAndrew Rist  * software distributed under the License is distributed on an
15*cde9e8dcSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*cde9e8dcSAndrew Rist  * KIND, either express or implied.  See the License for the
17*cde9e8dcSAndrew Rist  * specific language governing permissions and limitations
18*cde9e8dcSAndrew Rist  * under the License.
19*cde9e8dcSAndrew Rist  *
20*cde9e8dcSAndrew Rist  *************************************************************/
21*cde9e8dcSAndrew Rist 
22*cde9e8dcSAndrew 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
186cdf0e10cSrcweir         //@todo: iterate through all tick depth wich 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