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 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 140 void GridLinePoints::update( double fScaledTickValue ) 141 { 142 P0[m_nDimensionIndex] = P1[m_nDimensionIndex] = P2[m_nDimensionIndex] = fScaledTickValue; 143 } 144 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 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 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 185 VCartesianGrid::~VCartesianGrid() 186 { 187 delete m_pPosHelper; 188 m_pPosHelper = NULL; 189 } 190 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 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