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 "VCartesianGrid.hxx"
27 #include "Tickmarks.hxx"
28 #include "PlottingPositionHelper.hxx"
29 #include "ShapeFactory.hxx"
30 #include "ObjectIdentifier.hxx"
31 #include "macros.hxx"
32 #include "CommonConverters.hxx"
33 #include "AxisHelper.hxx"
34 #include <com/sun/star/drawing/PointSequenceSequence.hpp>
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 using ::com::sun::star::uno::Sequence;
48
49 struct GridLinePoints
50 {
51 Sequence< double > P0;
52 Sequence< double > P1;
53 Sequence< double > P2;
54
55 GridLinePoints( const PlottingPositionHelper* pPosHelper, sal_Int32 nDimensionIndex
56 , CuboidPlanePosition eLeftWallPos=CuboidPlanePosition_Left
57 , CuboidPlanePosition eBackWallPos=CuboidPlanePosition_Back
58 , CuboidPlanePosition eBottomPos=CuboidPlanePosition_Bottom );
59 void update( double fScaledTickValue );
60
61 sal_Int32 m_nDimensionIndex;
62 };
63
GridLinePoints(const PlottingPositionHelper * pPosHelper,sal_Int32 nDimensionIndex,CuboidPlanePosition eLeftWallPos,CuboidPlanePosition eBackWallPos,CuboidPlanePosition eBottomPos)64 GridLinePoints::GridLinePoints( const PlottingPositionHelper* pPosHelper, sal_Int32 nDimensionIndex
65 , CuboidPlanePosition eLeftWallPos
66 , CuboidPlanePosition eBackWallPos
67 , CuboidPlanePosition eBottomPos )
68 : m_nDimensionIndex(nDimensionIndex)
69 {
70 double MinX = pPosHelper->getLogicMinX();
71 double MinY = pPosHelper->getLogicMinY();
72 double MinZ = pPosHelper->getLogicMinZ();
73 double MaxX = pPosHelper->getLogicMaxX();
74 double MaxY = pPosHelper->getLogicMaxY();
75 double MaxZ = pPosHelper->getLogicMaxZ();
76
77 pPosHelper->doLogicScaling( &MinX,&MinY,&MinZ );
78 pPosHelper->doLogicScaling( &MaxX,&MaxY,&MaxZ );
79
80 if(!pPosHelper->isMathematicalOrientationX())
81 {
82 double fHelp = MinX;
83 MinX = MaxX;
84 MaxX = fHelp;
85 }
86 if(!pPosHelper->isMathematicalOrientationY())
87 {
88 double fHelp = MinY;
89 MinY = MaxY;
90 MaxY = fHelp;
91 }
92 if(pPosHelper->isMathematicalOrientationZ())//z axis in draw is reverse to mathematical
93 {
94 double fHelp = MinZ;
95 MinZ = MaxZ;
96 MaxZ = fHelp;
97 }
98 bool bSwapXY = pPosHelper->isSwapXAndY();
99
100 P0.realloc(3);
101 P1.realloc(3);
102 P2.realloc(3);
103
104 //P0: point on 'back' wall, not on 'left' wall
105 //P1: point on both walls
106 //P2: point on 'left' wall not on 'back' wall
107
108 P0[0]=P1[0]=P2[0]= (CuboidPlanePosition_Left == eLeftWallPos || bSwapXY) ? MinX : MaxX;
109 P0[1]=P1[1]=P2[1]= (CuboidPlanePosition_Left == eLeftWallPos || !bSwapXY) ? MinY : MaxY;
110 P0[2]=P1[2]=P2[2]= (CuboidPlanePosition_Back == eBackWallPos) ? MinZ : MaxZ;
111
112 if(m_nDimensionIndex==0)
113 {
114 P0[1]= (CuboidPlanePosition_Left == eLeftWallPos || !bSwapXY) ? MaxY : MinY;
115 P2[2]= (CuboidPlanePosition_Back == eBackWallPos) ? MaxZ : MinZ;
116 if( CuboidPlanePosition_Bottom != eBottomPos && !bSwapXY )
117 P2=P1;
118 }
119 else if(m_nDimensionIndex==1)
120 {
121 P0[0]= (CuboidPlanePosition_Left == eLeftWallPos || bSwapXY) ? MaxX : MinX;
122 P2[2]= (CuboidPlanePosition_Back == eBackWallPos) ? MaxZ : MinZ;
123 if( CuboidPlanePosition_Bottom != eBottomPos && bSwapXY )
124 P2=P1;
125 }
126 else if(m_nDimensionIndex==2)
127 {
128 P0[0]= (CuboidPlanePosition_Left == eLeftWallPos || bSwapXY) ? MaxX : MinX;
129 P2[1]= (CuboidPlanePosition_Left == eLeftWallPos || !bSwapXY) ? MaxY : MinY;
130 if( CuboidPlanePosition_Bottom != eBottomPos )
131 {
132 if( !bSwapXY )
133 P0=P1;
134 else
135 P2=P1;
136 }
137 }
138 }
139
update(double fScaledTickValue)140 void GridLinePoints::update( double fScaledTickValue )
141 {
142 P0[m_nDimensionIndex] = P1[m_nDimensionIndex] = P2[m_nDimensionIndex] = fScaledTickValue;
143 }
144
addLine2D(drawing::PointSequenceSequence & rPoints,sal_Int32 nIndex,const GridLinePoints & rScaledLogicPoints,const Reference<XTransformation> & xTransformation)145 void addLine2D( drawing::PointSequenceSequence& rPoints, sal_Int32 nIndex
146 , const GridLinePoints& rScaledLogicPoints
147 , const Reference< XTransformation > & xTransformation
148 )
149 {
150 drawing::Position3D aPA = SequenceToPosition3D( xTransformation->transform( rScaledLogicPoints.P0 ) );
151 drawing::Position3D aPB = SequenceToPosition3D( xTransformation->transform( rScaledLogicPoints.P1 ) );
152
153 rPoints[nIndex].realloc(2);
154 rPoints[nIndex][0].X = static_cast<sal_Int32>(aPA.PositionX);
155 rPoints[nIndex][0].Y = static_cast<sal_Int32>(aPA.PositionY);
156 rPoints[nIndex][1].X = static_cast<sal_Int32>(aPB.PositionX);
157 rPoints[nIndex][1].Y = static_cast<sal_Int32>(aPB.PositionY);
158 }
159
addLine3D(drawing::PolyPolygonShape3D & rPoints,sal_Int32 nIndex,const GridLinePoints & rBasePoints,const Reference<XTransformation> & xTransformation)160 void addLine3D( drawing::PolyPolygonShape3D& rPoints, sal_Int32 nIndex
161 , const GridLinePoints& rBasePoints
162 , const Reference< XTransformation > & xTransformation )
163 {
164 drawing::Position3D aPoint = SequenceToPosition3D( xTransformation->transform( rBasePoints.P0 ) );
165 AddPointToPoly( rPoints, aPoint, nIndex );
166 aPoint = SequenceToPosition3D( xTransformation->transform( rBasePoints.P1 ) );
167 AddPointToPoly( rPoints, aPoint, nIndex );
168 aPoint = SequenceToPosition3D( xTransformation->transform( rBasePoints.P2 ) );
169 AddPointToPoly( rPoints, aPoint, nIndex );
170 }
171
172 //---------------------------------------------------------------------------------
173 //---------------------------------------------------------------------------------
174 //---------------------------------------------------------------------------------
175 //---------------------------------------------------------------------------------
176
VCartesianGrid(sal_Int32 nDimensionIndex,sal_Int32 nDimensionCount,const Sequence<Reference<beans::XPropertySet>> & rGridPropertiesList)177 VCartesianGrid::VCartesianGrid( sal_Int32 nDimensionIndex, sal_Int32 nDimensionCount
178 , const Sequence< Reference< beans::XPropertySet > > & rGridPropertiesList )
179 : VAxisOrGridBase( nDimensionIndex, nDimensionCount )
180 , m_aGridPropertiesList( rGridPropertiesList )
181 {
182 m_pPosHelper = new PlottingPositionHelper();
183 }
184
~VCartesianGrid()185 VCartesianGrid::~VCartesianGrid()
186 {
187 delete m_pPosHelper;
188 m_pPosHelper = NULL;
189 }
190
fillLinePropertiesFromGridModel(::std::vector<VLineProperties> & rLinePropertiesList,const Sequence<Reference<beans::XPropertySet>> & rGridPropertiesList)191 void VCartesianGrid::fillLinePropertiesFromGridModel( ::std::vector<VLineProperties>& rLinePropertiesList
192 , const Sequence< Reference< beans::XPropertySet > > & rGridPropertiesList )
193 {
194 rLinePropertiesList.clear();
195 if( !rGridPropertiesList.getLength() )
196 return;
197
198 VLineProperties aLineProperties;
199 for( sal_Int32 nN=0; nN < rGridPropertiesList.getLength(); nN++ )
200 {
201 if(!AxisHelper::isGridVisible( rGridPropertiesList[nN] ))
202 aLineProperties.LineStyle = uno::makeAny( drawing::LineStyle_NONE );
203 else
204 aLineProperties.initFromPropertySet( rGridPropertiesList[nN] );
205 rLinePropertiesList.push_back(aLineProperties);
206 }
207 };
208
createShapes()209 void VCartesianGrid::createShapes()
210 {
211 if(!m_aGridPropertiesList.getLength())
212 return;
213 //somehow equal to axis tickmarks
214
215 //-----------------------------------------
216 //create named group shape
217 Reference< drawing::XShapes > xGroupShape_Shapes(
218 this->createGroupShape( m_xLogicTarget, m_aCID ) );
219
220 if(!xGroupShape_Shapes.is())
221 return;
222 //-----------------------------------------
223
224 ::std::vector<VLineProperties> aLinePropertiesList;
225 fillLinePropertiesFromGridModel( aLinePropertiesList, m_aGridPropertiesList );
226
227 //-----------------------------------------
228 //create all scaled tickmark values
229 std::auto_ptr< TickFactory > apTickFactory( this->createTickFactory() );
230 TickFactory& aTickFactory = *apTickFactory.get();
231 ::std::vector< ::std::vector< TickInfo > > aAllTickInfos;
232 aTickFactory.getAllTicks( aAllTickInfos );
233
234 //-----------------------------------------
235 //create tick mark line shapes
236 ::std::vector< ::std::vector< TickInfo > >::iterator aDepthIter = aAllTickInfos.begin();
237 const ::std::vector< ::std::vector< TickInfo > >::const_iterator aDepthEnd = aAllTickInfos.end();
238
239 if(aDepthIter == aDepthEnd)//no tickmarks at all
240 return;
241
242
243 sal_Int32 nLinePropertiesCount = aLinePropertiesList.size();
244 for( sal_Int32 nDepth=0
245 ; aDepthIter != aDepthEnd && nDepth < nLinePropertiesCount
246 ; aDepthIter++, nDepth++ )
247 {
248 if( !aLinePropertiesList[nDepth].isLineVisible() )
249 continue;
250
251 Reference< drawing::XShapes > xTarget( xGroupShape_Shapes );
252 if( nDepth > 0 )
253 {
254 xTarget.set( this->createGroupShape( m_xLogicTarget
255 , ObjectIdentifier::addChildParticle( m_aCID, ObjectIdentifier::createChildParticleWithIndex( OBJECTTYPE_SUBGRID, nDepth-1 ) )
256 ) );
257 if(!xTarget.is())
258 xTarget.set( xGroupShape_Shapes );
259 }
260
261 if(2==m_nDimension)
262 {
263
264 GridLinePoints aGridLinePoints( m_pPosHelper, m_nDimensionIndex );
265
266 sal_Int32 nPointCount = (*aDepthIter).size();
267 drawing::PointSequenceSequence aPoints(nPointCount);
268
269 ::std::vector< TickInfo >::const_iterator aTickIter = (*aDepthIter).begin();
270 const ::std::vector< TickInfo >::const_iterator aTickEnd = (*aDepthIter).end();
271 sal_Int32 nRealPointCount = 0;
272 for( ; aTickIter != aTickEnd; aTickIter++ )
273 {
274 if( !(*aTickIter).bPaintIt )
275 continue;
276 aGridLinePoints.update( (*aTickIter).fScaledTickValue );
277 addLine2D( aPoints, nRealPointCount, aGridLinePoints, m_pPosHelper->getTransformationScaledLogicToScene() );
278 nRealPointCount++;
279 }
280 aPoints.realloc(nRealPointCount);
281 m_pShapeFactory->createLine2D( xTarget, aPoints, &aLinePropertiesList[nDepth] );
282
283 //prepare polygon for handle shape:
284 drawing::PointSequenceSequence aHandlesPoints(1);
285 sal_Int32 nOldHandleCount = aHandlesPoints[0].getLength();
286 aHandlesPoints[0].realloc(nOldHandleCount+nRealPointCount);
287 for( sal_Int32 nN = 0; nN<nRealPointCount; nN++)
288 aHandlesPoints[0][nOldHandleCount+nN] = aPoints[nN][1];
289
290 //create handle shape:
291 VLineProperties aHandleLineProperties;
292 aHandleLineProperties.LineStyle = uno::makeAny( drawing::LineStyle_NONE );
293 Reference< drawing::XShape > xHandleShape =
294 m_pShapeFactory->createLine2D( xTarget, aHandlesPoints, &aHandleLineProperties );
295 m_pShapeFactory->setShapeName( xHandleShape, C2U("HandlesOnly") );
296 }
297 //-----------------------------------------
298 else //if(2!=m_nDimension)
299 {
300 GridLinePoints aGridLinePoints( m_pPosHelper, m_nDimensionIndex, m_eLeftWallPos, m_eBackWallPos, m_eBottomPos );
301
302 sal_Int32 nPointCount = (*aDepthIter).size();
303 drawing::PolyPolygonShape3D aPoints;
304 aPoints.SequenceX.realloc(nPointCount);
305 aPoints.SequenceY.realloc(nPointCount);
306 aPoints.SequenceZ.realloc(nPointCount);
307
308 ::std::vector< TickInfo >::const_iterator aTickIter = (*aDepthIter).begin();
309 const ::std::vector< TickInfo >::const_iterator aTickEnd = (*aDepthIter).end();
310 sal_Int32 nRealPointCount = 0;
311 sal_Int32 nPolyIndex = 0;
312 for( ; aTickIter != aTickEnd; aTickIter++, nPolyIndex++ )
313 {
314 if( !(*aTickIter).bPaintIt )
315 continue;
316
317 aGridLinePoints.update( (*aTickIter).fScaledTickValue );
318 addLine3D( aPoints, nPolyIndex, aGridLinePoints, m_pPosHelper->getTransformationScaledLogicToScene() );
319 nRealPointCount+=3;
320 }
321 aPoints.SequenceX.realloc(nRealPointCount);
322 aPoints.SequenceY.realloc(nRealPointCount);
323 aPoints.SequenceZ.realloc(nRealPointCount);
324 m_pShapeFactory->createLine3D( xTarget, aPoints, aLinePropertiesList[nDepth] );
325 }
326 }
327 }
328
329 //.............................................................................
330 } //namespace chart
331 //.............................................................................
332