1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: VCartesianGrid.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_chart2.hxx"
33 #include "VCartesianGrid.hxx"
34 #include "TickmarkHelper.hxx"
35 #include "PlottingPositionHelper.hxx"
36 #include "ShapeFactory.hxx"
37 #include "ObjectIdentifier.hxx"
39 #include "CommonConverters.hxx"
40 #include "AxisHelper.hxx"
41 #include <com/sun/star/drawing/PointSequenceSequence.hpp>
42 #include <com/sun/star/drawing/LineStyle.hpp>
47 //.............................................................................
50 //.............................................................................
51 using namespace ::com::sun::star
;
52 using namespace ::com::sun::star::chart2
;
53 using ::com::sun::star::uno::Reference
;
54 using ::com::sun::star::uno::Sequence
;
58 Sequence
< double > P0
;
59 Sequence
< double > P1
;
60 Sequence
< double > P2
;
62 GridLinePoints( const PlottingPositionHelper
* pPosHelper
, sal_Int32 nDimensionIndex
63 , CuboidPlanePosition eLeftWallPos
=CuboidPlanePosition_Left
64 , CuboidPlanePosition eBackWallPos
=CuboidPlanePosition_Back
65 , CuboidPlanePosition eBottomPos
=CuboidPlanePosition_Bottom
);
66 void update( double fScaledTickValue
);
68 sal_Int32 m_nDimensionIndex
;
71 GridLinePoints::GridLinePoints( const PlottingPositionHelper
* pPosHelper
, sal_Int32 nDimensionIndex
72 , CuboidPlanePosition eLeftWallPos
73 , CuboidPlanePosition eBackWallPos
74 , CuboidPlanePosition eBottomPos
)
75 : m_nDimensionIndex(nDimensionIndex
)
77 double MinX
= pPosHelper
->getLogicMinX();
78 double MinY
= pPosHelper
->getLogicMinY();
79 double MinZ
= pPosHelper
->getLogicMinZ();
80 double MaxX
= pPosHelper
->getLogicMaxX();
81 double MaxY
= pPosHelper
->getLogicMaxY();
82 double MaxZ
= pPosHelper
->getLogicMaxZ();
84 pPosHelper
->doLogicScaling( &MinX
,&MinY
,&MinZ
);
85 pPosHelper
->doLogicScaling( &MaxX
,&MaxY
,&MaxZ
);
87 if(!pPosHelper
->isMathematicalOrientationX())
93 if(!pPosHelper
->isMathematicalOrientationY())
99 if(pPosHelper
->isMathematicalOrientationZ())//z axis in draw is reverse to mathematical
105 bool bSwapXY
= pPosHelper
->isSwapXAndY();
111 //P0: point on 'back' wall, not on 'left' wall
112 //P1: point on both walls
113 //P2: point on 'left' wall not on 'back' wall
115 P0
[0]=P1
[0]=P2
[0]= (CuboidPlanePosition_Left
== eLeftWallPos
|| bSwapXY
) ? MinX
: MaxX
;
116 P0
[1]=P1
[1]=P2
[1]= (CuboidPlanePosition_Left
== eLeftWallPos
|| !bSwapXY
) ? MinY
: MaxY
;
117 P0
[2]=P1
[2]=P2
[2]= (CuboidPlanePosition_Back
== eBackWallPos
) ? MinZ
: MaxZ
;
119 if(m_nDimensionIndex
==0)
121 P0
[1]= (CuboidPlanePosition_Left
== eLeftWallPos
|| !bSwapXY
) ? MaxY
: MinY
;
122 P2
[2]= (CuboidPlanePosition_Back
== eBackWallPos
) ? MaxZ
: MinZ
;
123 if( CuboidPlanePosition_Bottom
!= eBottomPos
&& !bSwapXY
)
126 else if(m_nDimensionIndex
==1)
128 P0
[0]= (CuboidPlanePosition_Left
== eLeftWallPos
|| bSwapXY
) ? MaxX
: MinX
;
129 P2
[2]= (CuboidPlanePosition_Back
== eBackWallPos
) ? MaxZ
: MinZ
;
130 if( CuboidPlanePosition_Bottom
!= eBottomPos
&& bSwapXY
)
133 else if(m_nDimensionIndex
==2)
135 P0
[0]= (CuboidPlanePosition_Left
== eLeftWallPos
|| bSwapXY
) ? MaxX
: MinX
;
136 P2
[1]= (CuboidPlanePosition_Left
== eLeftWallPos
|| !bSwapXY
) ? MaxY
: MinY
;
137 if( CuboidPlanePosition_Bottom
!= eBottomPos
)
147 void GridLinePoints::update( double fScaledTickValue
)
149 P0
[m_nDimensionIndex
] = P1
[m_nDimensionIndex
] = P2
[m_nDimensionIndex
] = fScaledTickValue
;
152 void addLine2D( drawing::PointSequenceSequence
& rPoints
, sal_Int32 nIndex
153 , const GridLinePoints
& rScaledLogicPoints
154 , const Reference
< XTransformation
> & xTransformation
157 drawing::Position3D aPA
= SequenceToPosition3D( xTransformation
->transform( rScaledLogicPoints
.P0
) );
158 drawing::Position3D aPB
= SequenceToPosition3D( xTransformation
->transform( rScaledLogicPoints
.P1
) );
160 rPoints
[nIndex
].realloc(2);
161 rPoints
[nIndex
][0].X
= static_cast<sal_Int32
>(aPA
.PositionX
);
162 rPoints
[nIndex
][0].Y
= static_cast<sal_Int32
>(aPA
.PositionY
);
163 rPoints
[nIndex
][1].X
= static_cast<sal_Int32
>(aPB
.PositionX
);
164 rPoints
[nIndex
][1].Y
= static_cast<sal_Int32
>(aPB
.PositionY
);
167 void addLine3D( drawing::PolyPolygonShape3D
& rPoints
, sal_Int32 nIndex
168 , const GridLinePoints
& rBasePoints
169 , const Reference
< XTransformation
> & xTransformation
)
171 drawing::Position3D aPoint
= SequenceToPosition3D( xTransformation
->transform( rBasePoints
.P0
) );
172 AddPointToPoly( rPoints
, aPoint
, nIndex
);
173 aPoint
= SequenceToPosition3D( xTransformation
->transform( rBasePoints
.P1
) );
174 AddPointToPoly( rPoints
, aPoint
, nIndex
);
175 aPoint
= SequenceToPosition3D( xTransformation
->transform( rBasePoints
.P2
) );
176 AddPointToPoly( rPoints
, aPoint
, nIndex
);
179 //---------------------------------------------------------------------------------
180 //---------------------------------------------------------------------------------
181 //---------------------------------------------------------------------------------
182 //---------------------------------------------------------------------------------
184 VCartesianGrid::VCartesianGrid( sal_Int32 nDimensionIndex
, sal_Int32 nDimensionCount
185 , const Sequence
< Reference
< beans::XPropertySet
> > & rGridPropertiesList
)
186 : VAxisOrGridBase( nDimensionIndex
, nDimensionCount
)
187 , m_aGridPropertiesList( rGridPropertiesList
)
189 m_pPosHelper
= new PlottingPositionHelper();
192 VCartesianGrid::~VCartesianGrid()
199 void VCartesianGrid::fillLinePropertiesFromGridModel( ::std::vector
<VLineProperties
>& rLinePropertiesList
200 , const Sequence
< Reference
< beans::XPropertySet
> > & rGridPropertiesList
)
202 rLinePropertiesList
.clear();
203 if( !rGridPropertiesList
.getLength() )
206 VLineProperties aLineProperties
;
207 for( sal_Int32 nN
=0; nN
< rGridPropertiesList
.getLength(); nN
++ )
209 if(!AxisHelper::isGridVisible( rGridPropertiesList
[nN
] ))
210 aLineProperties
.LineStyle
= uno::makeAny( drawing::LineStyle_NONE
);
212 aLineProperties
.initFromPropertySet( rGridPropertiesList
[nN
] );
213 rLinePropertiesList
.push_back(aLineProperties
);
217 void SAL_CALL
VCartesianGrid::createShapes()
219 if(!m_aGridPropertiesList
.getLength())
221 //somehow equal to axis tickmarks
223 //-----------------------------------------
224 //create named group shape
225 Reference
< drawing::XShapes
> xGroupShape_Shapes(
226 this->createGroupShape( m_xLogicTarget
, m_aCID
) );
228 if(!xGroupShape_Shapes
.is())
230 //-----------------------------------------
232 ::std::vector
<VLineProperties
> aLinePropertiesList
;
233 fillLinePropertiesFromGridModel( aLinePropertiesList
, m_aGridPropertiesList
);
235 //-----------------------------------------
236 //create all scaled tickmark values
237 std::auto_ptr
< TickmarkHelper
> apTickmarkHelper( this->createTickmarkHelper() );
238 TickmarkHelper
& aTickmarkHelper
= *apTickmarkHelper
.get();
239 ::std::vector
< ::std::vector
< TickInfo
> > aAllTickInfos
;
240 if( m_aIncrement
.ShiftedPosition
)
241 aTickmarkHelper
.getAllTicksShifted( aAllTickInfos
);
243 aTickmarkHelper
.getAllTicks( aAllTickInfos
);
245 //-----------------------------------------
246 //create tick mark line shapes
247 ::std::vector
< ::std::vector
< TickInfo
> >::iterator aDepthIter
= aAllTickInfos
.begin();
248 const ::std::vector
< ::std::vector
< TickInfo
> >::const_iterator aDepthEnd
= aAllTickInfos
.end();
250 if(aDepthIter
== aDepthEnd
)//no tickmarks at all
254 sal_Int32 nLinePropertiesCount
= aLinePropertiesList
.size();
255 for( sal_Int32 nDepth
=0
256 ; aDepthIter
!= aDepthEnd
&& nDepth
< nLinePropertiesCount
257 ; aDepthIter
++, nDepth
++ )
259 if( !aLinePropertiesList
[nDepth
].isLineVisible() )
262 Reference
< drawing::XShapes
> xTarget( xGroupShape_Shapes
);
265 xTarget
.set( this->createGroupShape( m_xLogicTarget
266 , ObjectIdentifier::addChildParticle( m_aCID
, ObjectIdentifier::createChildParticleWithIndex( OBJECTTYPE_SUBGRID
, nDepth
-1 ) )
269 xTarget
.set( xGroupShape_Shapes
);
275 GridLinePoints
aGridLinePoints( m_pPosHelper
, m_nDimensionIndex
);
277 sal_Int32 nPointCount
= (*aDepthIter
).size();
278 drawing::PointSequenceSequence
aPoints(nPointCount
);
280 ::std::vector
< TickInfo
>::const_iterator aTickIter
= (*aDepthIter
).begin();
281 const ::std::vector
< TickInfo
>::const_iterator aTickEnd
= (*aDepthIter
).end();
282 sal_Int32 nRealPointCount
= 0;
283 for( ; aTickIter
!= aTickEnd
; aTickIter
++ )
285 if( !(*aTickIter
).bPaintIt
)
287 aGridLinePoints
.update( (*aTickIter
).fScaledTickValue
);
288 addLine2D( aPoints
, nRealPointCount
, aGridLinePoints
, m_pPosHelper
->getTransformationScaledLogicToScene() );
291 aPoints
.realloc(nRealPointCount
);
292 m_pShapeFactory
->createLine2D( xTarget
, aPoints
, &aLinePropertiesList
[nDepth
] );
294 //prepare polygon for handle shape:
295 drawing::PointSequenceSequence
aHandlesPoints(1);
296 sal_Int32 nOldHandleCount
= aHandlesPoints
[0].getLength();
297 aHandlesPoints
[0].realloc(nOldHandleCount
+nRealPointCount
);
298 for( sal_Int32 nN
= 0; nN
<nRealPointCount
; nN
++)
299 aHandlesPoints
[0][nOldHandleCount
+nN
] = aPoints
[nN
][1];
301 //create handle shape:
302 VLineProperties aHandleLineProperties
;
303 aHandleLineProperties
.LineStyle
= uno::makeAny( drawing::LineStyle_NONE
);
304 Reference
< drawing::XShape
> xHandleShape
=
305 m_pShapeFactory
->createLine2D( xTarget
, aHandlesPoints
, &aHandleLineProperties
);
306 m_pShapeFactory
->setShapeName( xHandleShape
, C2U("HandlesOnly") );
308 //-----------------------------------------
309 else //if(2!=m_nDimension)
311 GridLinePoints
aGridLinePoints( m_pPosHelper
, m_nDimensionIndex
, m_eLeftWallPos
, m_eBackWallPos
, m_eBottomPos
);
313 sal_Int32 nPointCount
= (*aDepthIter
).size();
314 drawing::PolyPolygonShape3D aPoints
;
315 aPoints
.SequenceX
.realloc(nPointCount
);
316 aPoints
.SequenceY
.realloc(nPointCount
);
317 aPoints
.SequenceZ
.realloc(nPointCount
);
319 ::std::vector
< TickInfo
>::const_iterator aTickIter
= (*aDepthIter
).begin();
320 const ::std::vector
< TickInfo
>::const_iterator aTickEnd
= (*aDepthIter
).end();
321 sal_Int32 nRealPointCount
= 0;
322 sal_Int32 nPolyIndex
= 0;
323 for( ; aTickIter
!= aTickEnd
; aTickIter
++, nPolyIndex
++ )
325 if( !(*aTickIter
).bPaintIt
)
328 aGridLinePoints
.update( (*aTickIter
).fScaledTickValue
);
329 addLine3D( aPoints
, nPolyIndex
, aGridLinePoints
, m_pPosHelper
->getTransformationScaledLogicToScene() );
332 aPoints
.SequenceX
.realloc(nRealPointCount
);
333 aPoints
.SequenceY
.realloc(nRealPointCount
);
334 aPoints
.SequenceZ
.realloc(nRealPointCount
);
335 m_pShapeFactory
->createLine3D( xTarget
, aPoints
, aLinePropertiesList
[nDepth
] );
340 //.............................................................................
342 //.............................................................................