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 "VPolarGrid.hxx"
27 #include "VCartesianGrid.hxx"
28 #include "Tickmarks.hxx"
29 #include "PlottingPositionHelper.hxx"
30 #include "ShapeFactory.hxx"
31 #include "ObjectIdentifier.hxx"
32 #include "macros.hxx"
33 #include "CommonConverters.hxx"
34 #include "Tickmarks_Equidistant.hxx"
35 #include <com/sun/star/drawing/LineStyle.hpp>
36 
37 #include <vector>
38 #include <memory>
39 
40 //.............................................................................
41 namespace chart
42 {
43 //.............................................................................
44 using namespace ::com::sun::star;
45 using namespace ::com::sun::star::chart2;
46 using ::com::sun::star::uno::Reference;
47 
VPolarGrid(sal_Int32 nDimensionIndex,sal_Int32 nDimensionCount,const uno::Sequence<Reference<beans::XPropertySet>> & rGridPropertiesList)48 VPolarGrid::VPolarGrid( sal_Int32 nDimensionIndex, sal_Int32 nDimensionCount
49                        , const uno::Sequence< Reference< beans::XPropertySet > > & rGridPropertiesList )
50             : VAxisOrGridBase( nDimensionIndex, nDimensionCount )
51             , m_aGridPropertiesList( rGridPropertiesList )
52             , m_pPosHelper( new PolarPlottingPositionHelper() )
53             , m_aIncrements()
54 {
55     PlotterBase::m_pPosHelper = m_pPosHelper;
56 }
57 
~VPolarGrid()58 VPolarGrid::~VPolarGrid()
59 {
60     delete m_pPosHelper;
61     m_pPosHelper = NULL;
62 }
63 
setIncrements(const std::vector<ExplicitIncrementData> & rIncrements)64 void VPolarGrid::setIncrements( const std::vector< ExplicitIncrementData >& rIncrements )
65 {
66     m_aIncrements = rIncrements;
67 }
68 
getAllTickInfos(sal_Int32 nDimensionIndex,::std::vector<::std::vector<TickInfo>> & rAllTickInfos) const69 void VPolarGrid::getAllTickInfos( sal_Int32 nDimensionIndex, ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos ) const
70 {
71     TickFactory aTickFactory(
72             m_pPosHelper->getScales()[nDimensionIndex], m_aIncrements[nDimensionIndex] );
73     aTickFactory.getAllTicks( rAllTickInfos );
74 }
75 
createLinePointSequence_ForAngleAxis(drawing::PointSequenceSequence & rPoints,::std::vector<::std::vector<TickInfo>> & rAllTickInfos,const ExplicitIncrementData & rIncrement,const ExplicitScaleData & rScale,PolarPlottingPositionHelper * pPosHelper,double fLogicRadius,double fLogicZ)76 void VPolarGrid::createLinePointSequence_ForAngleAxis(
77         drawing::PointSequenceSequence& rPoints
78         , ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos
79         , const ExplicitIncrementData& rIncrement
80         , const ExplicitScaleData& rScale
81         , PolarPlottingPositionHelper* pPosHelper
82         , double fLogicRadius, double fLogicZ )
83 {
84     Reference< XScaling > xInverseScaling( NULL );
85     if( rScale.Scaling.is() )
86         xInverseScaling = rScale.Scaling->getInverseScaling();
87 
88     sal_Int32 nTick = 0;
89     EquidistantTickIter aIter( rAllTickInfos, rIncrement, 0, 0 );
90     for( TickInfo* pTickInfo = aIter.firstInfo()
91         ; pTickInfo
92         ; pTickInfo = aIter.nextInfo(), nTick++ )
93     {
94         if(nTick>=rPoints[0].getLength())
95             rPoints[0].realloc(rPoints[0].getLength()+30);
96 
97         //xxxxx pTickInfo->updateUnscaledValue( xInverseScaling );
98         double fLogicAngle = pTickInfo->getUnscaledTickValue();
99 
100         drawing::Position3D aScenePosition3D( pPosHelper->transformAngleRadiusToScene( fLogicAngle, fLogicRadius, fLogicZ ) );
101         rPoints[0][nTick].X = static_cast<sal_Int32>(aScenePosition3D.PositionX);
102         rPoints[0][nTick].Y = static_cast<sal_Int32>(aScenePosition3D.PositionY);
103     }
104     if(rPoints[0].getLength()>1)
105     {
106         rPoints[0].realloc(nTick+1);
107         rPoints[0][nTick].X = rPoints[0][0].X;
108         rPoints[0][nTick].Y = rPoints[0][0].Y;
109     }
110     else
111         rPoints[0].realloc(0);
112 }
113 #ifdef NOTYET
create2DAngleGrid(const Reference<drawing::XShapes> & xLogicTarget,::std::vector<::std::vector<TickInfo>> &,::std::vector<::std::vector<TickInfo>> & rAngleTickInfos,const::std::vector<VLineProperties> & rLinePropertiesList)114 void VPolarGrid::create2DAngleGrid( const Reference< drawing::XShapes >& xLogicTarget
115         , ::std::vector< ::std::vector< TickInfo > >& /* rRadiusTickInfos */
116         , ::std::vector< ::std::vector< TickInfo > >& rAngleTickInfos
117         , const ::std::vector<VLineProperties>& rLinePropertiesList )
118 {
119     Reference< drawing::XShapes > xMainTarget(
120         this->createGroupShape( xLogicTarget, m_aCID ) );
121 
122     const ExplicitScaleData&     rAngleScale = m_pPosHelper->getScales()[0];
123     Reference< XScaling > xInverseScaling( NULL );
124     if( rAngleScale.Scaling.is() )
125         xInverseScaling = rAngleScale.Scaling->getInverseScaling();
126 
127     double fLogicInnerRadius = m_pPosHelper->getInnerLogicRadius();
128     double fLogicOuterRadius = m_pPosHelper->getOuterLogicRadius();
129     double fLogicZ      = 1.0;//as defined
130 
131     sal_Int32 nLinePropertiesCount = rLinePropertiesList.size();
132     ::std::vector< ::std::vector< TickInfo > >::iterator aDepthIter             = rAngleTickInfos.begin();
133     sal_Int32 nDepth=0;
134     /*
135     //no subgrids so far for polar angle grid (need different radii)
136     const ::std::vector< ::std::vector< TickInfo > >::const_iterator aDepthEnd  = rAngleTickInfos.end();
137     for( ; aDepthIter != aDepthEnd && nDepth < nLinePropertiesCount
138          ; aDepthIter++, nDepth++ )
139     */
140     if(nLinePropertiesCount)
141     {
142         //create axis main lines
143         drawing::PointSequenceSequence aAllPoints;
144         ::std::vector< TickInfo >::iterator             aTickIter = (*aDepthIter).begin();
145         const ::std::vector< TickInfo >::const_iterator aTickEnd  = (*aDepthIter).end();
146         for( ; aTickIter != aTickEnd; aTickIter++ )
147         {
148             TickInfo& rTickInfo = *aTickIter;
149             if( !rTickInfo.bPaintIt )
150                 continue;
151 
152             //xxxxx rTickInfo.updateUnscaledValue( xInverseScaling );
153             double fLogicAngle = rTickInfo.getUnscaledTickValue();
154 
155             drawing::PointSequenceSequence aPoints(1);
156             aPoints[0].realloc(2);
157             drawing::Position3D aScenePositionStart( m_pPosHelper->transformAngleRadiusToScene( fLogicAngle, fLogicInnerRadius, fLogicZ ) );
158             drawing::Position3D aScenePositionEnd(   m_pPosHelper->transformAngleRadiusToScene( fLogicAngle, fLogicOuterRadius, fLogicZ ) );
159             aPoints[0][0].X = static_cast<sal_Int32>(aScenePositionStart.PositionX);
160             aPoints[0][0].Y = static_cast<sal_Int32>(aScenePositionStart.PositionY);
161             aPoints[0][1].X = static_cast<sal_Int32>(aScenePositionEnd.PositionX);
162             aPoints[0][1].Y = static_cast<sal_Int32>(aScenePositionEnd.PositionY);
163             appendPointSequence( aAllPoints, aPoints );
164         }
165 
166         Reference< drawing::XShape > xShape = m_pShapeFactory->createLine2D(
167                 xMainTarget, aAllPoints, &rLinePropertiesList[nDepth] );
168         //because of this name this line will be used for marking
169         m_pShapeFactory->setShapeName( xShape, C2U("MarkHandles") );
170     }
171 }
172 #endif
173 
create2DRadiusGrid(const Reference<drawing::XShapes> & xLogicTarget,::std::vector<::std::vector<TickInfo>> & rRadiusTickInfos,::std::vector<::std::vector<TickInfo>> & rAngleTickInfos,const::std::vector<VLineProperties> & rLinePropertiesList)174 void VPolarGrid::create2DRadiusGrid( const Reference< drawing::XShapes >& xLogicTarget
175         , ::std::vector< ::std::vector< TickInfo > >& rRadiusTickInfos
176         , ::std::vector< ::std::vector< TickInfo > >& rAngleTickInfos
177         , const ::std::vector<VLineProperties>& rLinePropertiesList )
178 {
179     Reference< drawing::XShapes > xMainTarget(
180         this->createGroupShape( xLogicTarget, m_aCID ) );
181 
182     const ExplicitScaleData&     rRadiusScale = m_pPosHelper->getScales()[1];
183     const ExplicitScaleData&     rAngleScale = m_pPosHelper->getScales()[0];
184     const ExplicitIncrementData& rAngleIncrement = m_aIncrements[0];
185     Reference< XScaling > xInverseRadiusScaling( NULL );
186     if( rRadiusScale.Scaling.is() )
187         xInverseRadiusScaling = rRadiusScale.Scaling->getInverseScaling();
188 
189     sal_Int32 nLinePropertiesCount = rLinePropertiesList.size();
190     ::std::vector< ::std::vector< TickInfo > >::iterator aDepthIter             = rRadiusTickInfos.begin();
191     const ::std::vector< ::std::vector< TickInfo > >::const_iterator aDepthEnd  = rRadiusTickInfos.end();
192     for( sal_Int32 nDepth=0
193         ; aDepthIter != aDepthEnd && nDepth < nLinePropertiesCount
194         ; aDepthIter++, nDepth++ )
195     {
196         if( !rLinePropertiesList[nDepth].isLineVisible() )
197             continue;
198 
199         Reference< drawing::XShapes > xTarget( xMainTarget );
200         if( nDepth > 0 )
201         {
202             xTarget.set( this->createGroupShape( xLogicTarget
203                 , ObjectIdentifier::addChildParticle( m_aCID, ObjectIdentifier::createChildParticleWithIndex( OBJECTTYPE_SUBGRID, nDepth-1 ) )
204                 ) );
205             if(!xTarget.is())
206                 xTarget.set( xMainTarget );
207         }
208 
209         //create axis main lines
210         drawing::PointSequenceSequence aAllPoints;
211         ::std::vector< TickInfo >::iterator             aTickIter = (*aDepthIter).begin();
212         const ::std::vector< TickInfo >::const_iterator aTickEnd  = (*aDepthIter).end();
213         for( ; aTickIter != aTickEnd; aTickIter++ )
214         {
215             TickInfo& rTickInfo = *aTickIter;
216             if( !rTickInfo.bPaintIt )
217                 continue;
218 
219             //xxxxx rTickInfo.updateUnscaledValue( xInverseRadiusScaling );
220             double fLogicRadius = rTickInfo.getUnscaledTickValue();
221             double fLogicZ      = 1.0;//as defined
222 
223             drawing::PointSequenceSequence aPoints(1);
224             VPolarGrid::createLinePointSequence_ForAngleAxis( aPoints, rAngleTickInfos
225                 , rAngleIncrement, rAngleScale, m_pPosHelper, fLogicRadius, fLogicZ );
226             if(aPoints[0].getLength())
227                 appendPointSequence( aAllPoints, aPoints );
228         }
229 
230         Reference< drawing::XShape > xShape = m_pShapeFactory->createLine2D(
231                 xTarget, aAllPoints, &rLinePropertiesList[nDepth] );
232         //because of this name this line will be used for marking
233         m_pShapeFactory->setShapeName( xShape, C2U("MarkHandles") );
234     }
235 }
236 
createShapes()237 void VPolarGrid::createShapes()
238 {
239     DBG_ASSERT(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is(),"Axis is not proper initialized");
240     if(!(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is()))
241         return;
242     if(!m_aGridPropertiesList.getLength())
243         return;
244 
245     //-----------------------------------------
246     //create all scaled tickmark values
247     ::std::vector< ::std::vector< TickInfo > > aAngleTickInfos;
248     ::std::vector< ::std::vector< TickInfo > > aRadiusTickInfos;
249     getAllTickInfos( 0, aAngleTickInfos );
250     getAllTickInfos( 1, aRadiusTickInfos );
251 
252     //-----------------------------------------
253     ::std::vector<VLineProperties> aLinePropertiesList;
254     VCartesianGrid::fillLinePropertiesFromGridModel( aLinePropertiesList, m_aGridPropertiesList );
255 
256     //-----------------------------------------
257     //create tick mark line shapes
258     if(2==m_nDimension)
259     {
260         if(m_nDimensionIndex==1)
261             this->create2DRadiusGrid( m_xLogicTarget, aRadiusTickInfos, aAngleTickInfos, aLinePropertiesList );
262         //else //no Angle Grid so far as this equals exactly the y axis positions
263         //    this->create2DAngleGrid( m_xLogicTarget, aRadiusTickInfos, aAngleTickInfos, aLinePropertiesList );
264     }
265 }
266 
267 //.............................................................................
268 } //namespace chart
269 //.............................................................................
270