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