1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_chart2.hxx"
30 #include "VPolarGrid.hxx"
31 #include "VCartesianGrid.hxx"
32 #include "Tickmarks.hxx"
33 #include "PlottingPositionHelper.hxx"
34 #include "ShapeFactory.hxx"
35 #include "ObjectIdentifier.hxx"
36 #include "macros.hxx"
37 #include "CommonConverters.hxx"
38 #include "Tickmarks_Equidistant.hxx"
39 #include <com/sun/star/drawing/LineStyle.hpp>
40 
41 #include <vector>
42 #include <memory>
43 
44 //.............................................................................
45 namespace chart
46 {
47 //.............................................................................
48 using namespace ::com::sun::star;
49 using namespace ::com::sun::star::chart2;
50 using ::com::sun::star::uno::Reference;
51 
52 VPolarGrid::VPolarGrid( sal_Int32 nDimensionIndex, sal_Int32 nDimensionCount
53                        , const uno::Sequence< Reference< beans::XPropertySet > > & rGridPropertiesList )
54             : VAxisOrGridBase( nDimensionIndex, nDimensionCount )
55             , m_aGridPropertiesList( rGridPropertiesList )
56             , m_pPosHelper( new PolarPlottingPositionHelper() )
57             , m_aIncrements()
58 {
59     PlotterBase::m_pPosHelper = m_pPosHelper;
60 }
61 
62 VPolarGrid::~VPolarGrid()
63 {
64     delete m_pPosHelper;
65     m_pPosHelper = NULL;
66 }
67 
68 void VPolarGrid::setIncrements( const std::vector< ExplicitIncrementData >& rIncrements )
69 {
70     m_aIncrements = rIncrements;
71 }
72 
73 void VPolarGrid::getAllTickInfos( sal_Int32 nDimensionIndex, ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos ) const
74 {
75     TickFactory aTickFactory(
76             m_pPosHelper->getScales()[nDimensionIndex], m_aIncrements[nDimensionIndex] );
77     aTickFactory.getAllTicks( rAllTickInfos );
78 }
79 
80 void VPolarGrid::createLinePointSequence_ForAngleAxis(
81         drawing::PointSequenceSequence& rPoints
82         , ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos
83         , const ExplicitIncrementData& rIncrement
84         , const ExplicitScaleData& rScale
85         , PolarPlottingPositionHelper* pPosHelper
86         , double fLogicRadius, double fLogicZ )
87 {
88     Reference< XScaling > xInverseScaling( NULL );
89     if( rScale.Scaling.is() )
90         xInverseScaling = rScale.Scaling->getInverseScaling();
91 
92     sal_Int32 nTick = 0;
93     EquidistantTickIter aIter( rAllTickInfos, rIncrement, 0, 0 );
94     for( TickInfo* pTickInfo = aIter.firstInfo()
95         ; pTickInfo
96         ; pTickInfo = aIter.nextInfo(), nTick++ )
97     {
98         if(nTick>=rPoints[0].getLength())
99             rPoints[0].realloc(rPoints[0].getLength()+30);
100 
101         //xxxxx pTickInfo->updateUnscaledValue( xInverseScaling );
102         double fLogicAngle = pTickInfo->getUnscaledTickValue();
103 
104         drawing::Position3D aScenePosition3D( pPosHelper->transformAngleRadiusToScene( fLogicAngle, fLogicRadius, fLogicZ ) );
105         rPoints[0][nTick].X = static_cast<sal_Int32>(aScenePosition3D.PositionX);
106         rPoints[0][nTick].Y = static_cast<sal_Int32>(aScenePosition3D.PositionY);
107     }
108     if(rPoints[0].getLength()>1)
109     {
110         rPoints[0].realloc(nTick+1);
111         rPoints[0][nTick].X = rPoints[0][0].X;
112         rPoints[0][nTick].Y = rPoints[0][0].Y;
113     }
114     else
115         rPoints[0].realloc(0);
116 }
117 #ifdef NOTYET
118 void VPolarGrid::create2DAngleGrid( const Reference< drawing::XShapes >& xLogicTarget
119         , ::std::vector< ::std::vector< TickInfo > >& /* rRadiusTickInfos */
120         , ::std::vector< ::std::vector< TickInfo > >& rAngleTickInfos
121         , const ::std::vector<VLineProperties>& rLinePropertiesList )
122 {
123     Reference< drawing::XShapes > xMainTarget(
124         this->createGroupShape( xLogicTarget, m_aCID ) );
125 
126     const ExplicitScaleData&     rAngleScale = m_pPosHelper->getScales()[0];
127     Reference< XScaling > xInverseScaling( NULL );
128     if( rAngleScale.Scaling.is() )
129         xInverseScaling = rAngleScale.Scaling->getInverseScaling();
130 
131     double fLogicInnerRadius = m_pPosHelper->getInnerLogicRadius();
132     double fLogicOuterRadius = m_pPosHelper->getOuterLogicRadius();
133     double fLogicZ      = 1.0;//as defined
134 
135     sal_Int32 nLinePropertiesCount = rLinePropertiesList.size();
136     ::std::vector< ::std::vector< TickInfo > >::iterator aDepthIter             = rAngleTickInfos.begin();
137     sal_Int32 nDepth=0;
138     /*
139     //no subgrids so far for polar angle grid (need different radii)
140     const ::std::vector< ::std::vector< TickInfo > >::const_iterator aDepthEnd  = rAngleTickInfos.end();
141     for( ; aDepthIter != aDepthEnd && nDepth < nLinePropertiesCount
142          ; aDepthIter++, nDepth++ )
143     */
144     if(nLinePropertiesCount)
145     {
146         //create axis main lines
147         drawing::PointSequenceSequence aAllPoints;
148         ::std::vector< TickInfo >::iterator             aTickIter = (*aDepthIter).begin();
149         const ::std::vector< TickInfo >::const_iterator aTickEnd  = (*aDepthIter).end();
150         for( ; aTickIter != aTickEnd; aTickIter++ )
151         {
152             TickInfo& rTickInfo = *aTickIter;
153             if( !rTickInfo.bPaintIt )
154                 continue;
155 
156             //xxxxx rTickInfo.updateUnscaledValue( xInverseScaling );
157             double fLogicAngle = rTickInfo.getUnscaledTickValue();
158 
159             drawing::PointSequenceSequence aPoints(1);
160             aPoints[0].realloc(2);
161             drawing::Position3D aScenePositionStart( m_pPosHelper->transformAngleRadiusToScene( fLogicAngle, fLogicInnerRadius, fLogicZ ) );
162             drawing::Position3D aScenePositionEnd(   m_pPosHelper->transformAngleRadiusToScene( fLogicAngle, fLogicOuterRadius, fLogicZ ) );
163             aPoints[0][0].X = static_cast<sal_Int32>(aScenePositionStart.PositionX);
164             aPoints[0][0].Y = static_cast<sal_Int32>(aScenePositionStart.PositionY);
165             aPoints[0][1].X = static_cast<sal_Int32>(aScenePositionEnd.PositionX);
166             aPoints[0][1].Y = static_cast<sal_Int32>(aScenePositionEnd.PositionY);
167             appendPointSequence( aAllPoints, aPoints );
168         }
169 
170         Reference< drawing::XShape > xShape = m_pShapeFactory->createLine2D(
171                 xMainTarget, aAllPoints, &rLinePropertiesList[nDepth] );
172         //because of this name this line will be used for marking
173         m_pShapeFactory->setShapeName( xShape, C2U("MarkHandles") );
174     }
175 }
176 #endif
177 
178 void VPolarGrid::create2DRadiusGrid( const Reference< drawing::XShapes >& xLogicTarget
179         , ::std::vector< ::std::vector< TickInfo > >& rRadiusTickInfos
180         , ::std::vector< ::std::vector< TickInfo > >& rAngleTickInfos
181         , const ::std::vector<VLineProperties>& rLinePropertiesList )
182 {
183     Reference< drawing::XShapes > xMainTarget(
184         this->createGroupShape( xLogicTarget, m_aCID ) );
185 
186     const ExplicitScaleData&     rRadiusScale = m_pPosHelper->getScales()[1];
187     const ExplicitScaleData&     rAngleScale = m_pPosHelper->getScales()[0];
188     const ExplicitIncrementData& rAngleIncrement = m_aIncrements[0];
189     Reference< XScaling > xInverseRadiusScaling( NULL );
190     if( rRadiusScale.Scaling.is() )
191         xInverseRadiusScaling = rRadiusScale.Scaling->getInverseScaling();
192 
193     sal_Int32 nLinePropertiesCount = rLinePropertiesList.size();
194     ::std::vector< ::std::vector< TickInfo > >::iterator aDepthIter             = rRadiusTickInfos.begin();
195     const ::std::vector< ::std::vector< TickInfo > >::const_iterator aDepthEnd  = rRadiusTickInfos.end();
196     for( sal_Int32 nDepth=0
197         ; aDepthIter != aDepthEnd && nDepth < nLinePropertiesCount
198         ; aDepthIter++, nDepth++ )
199     {
200         if( !rLinePropertiesList[nDepth].isLineVisible() )
201             continue;
202 
203         Reference< drawing::XShapes > xTarget( xMainTarget );
204         if( nDepth > 0 )
205         {
206             xTarget.set( this->createGroupShape( xLogicTarget
207                 , ObjectIdentifier::addChildParticle( m_aCID, ObjectIdentifier::createChildParticleWithIndex( OBJECTTYPE_SUBGRID, nDepth-1 ) )
208                 ) );
209             if(!xTarget.is())
210                 xTarget.set( xMainTarget );
211         }
212 
213         //create axis main lines
214         drawing::PointSequenceSequence aAllPoints;
215         ::std::vector< TickInfo >::iterator             aTickIter = (*aDepthIter).begin();
216         const ::std::vector< TickInfo >::const_iterator aTickEnd  = (*aDepthIter).end();
217         for( ; aTickIter != aTickEnd; aTickIter++ )
218         {
219             TickInfo& rTickInfo = *aTickIter;
220             if( !rTickInfo.bPaintIt )
221                 continue;
222 
223             //xxxxx rTickInfo.updateUnscaledValue( xInverseRadiusScaling );
224             double fLogicRadius = rTickInfo.getUnscaledTickValue();
225             double fLogicZ      = 1.0;//as defined
226 
227             drawing::PointSequenceSequence aPoints(1);
228             VPolarGrid::createLinePointSequence_ForAngleAxis( aPoints, rAngleTickInfos
229                 , rAngleIncrement, rAngleScale, m_pPosHelper, fLogicRadius, fLogicZ );
230             if(aPoints[0].getLength())
231                 appendPointSequence( aAllPoints, aPoints );
232         }
233 
234         Reference< drawing::XShape > xShape = m_pShapeFactory->createLine2D(
235                 xTarget, aAllPoints, &rLinePropertiesList[nDepth] );
236         //because of this name this line will be used for marking
237         m_pShapeFactory->setShapeName( xShape, C2U("MarkHandles") );
238     }
239 }
240 
241 void VPolarGrid::createShapes()
242 {
243     DBG_ASSERT(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is(),"Axis is not proper initialized");
244     if(!(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is()))
245         return;
246     if(!m_aGridPropertiesList.getLength())
247         return;
248 
249     //-----------------------------------------
250     //create all scaled tickmark values
251     ::std::vector< ::std::vector< TickInfo > > aAngleTickInfos;
252     ::std::vector< ::std::vector< TickInfo > > aRadiusTickInfos;
253     getAllTickInfos( 0, aAngleTickInfos );
254     getAllTickInfos( 1, aRadiusTickInfos );
255 
256     //-----------------------------------------
257     ::std::vector<VLineProperties> aLinePropertiesList;
258     VCartesianGrid::fillLinePropertiesFromGridModel( aLinePropertiesList, m_aGridPropertiesList );
259 
260     //-----------------------------------------
261     //create tick mark line shapes
262     if(2==m_nDimension)
263     {
264         if(m_nDimensionIndex==1)
265             this->create2DRadiusGrid( m_xLogicTarget, aRadiusTickInfos, aAngleTickInfos, aLinePropertiesList );
266         //else //no Angle Grid so far as this equals exactly the y axis positions
267         //    this->create2DAngleGrid( m_xLogicTarget, aRadiusTickInfos, aAngleTickInfos, aLinePropertiesList );
268     }
269 }
270 
271 //.............................................................................
272 } //namespace chart
273 //.............................................................................
274