1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "VCartesianGrid.hxx"
21 #include "Tickmarks.hxx"
22 #include <PlottingPositionHelper.hxx>
23 #include <ShapeFactory.hxx>
24 #include <ObjectIdentifier.hxx>
25 #include <CommonConverters.hxx>
26 #include <AxisHelper.hxx>
27 #include <VLineProperties.hxx>
28 #include <GridProperties.hxx>
29 #include <com/sun/star/drawing/PointSequenceSequence.hpp>
30 #include <com/sun/star/drawing/LineStyle.hpp>
37 using namespace ::com::sun::star
;
38 using namespace ::com::sun::star::chart2
;
39 using ::com::sun::star::uno::Reference
;
40 using ::com::sun::star::uno::Sequence
;
46 Sequence
< double > P0
;
47 Sequence
< double > P1
;
48 Sequence
< double > P2
;
50 GridLinePoints( const PlottingPositionHelper
* pPosHelper
, sal_Int32 nDimensionIndex
51 , CuboidPlanePosition eLeftWallPos
=CuboidPlanePosition_Left
52 , CuboidPlanePosition eBackWallPos
=CuboidPlanePosition_Back
53 , CuboidPlanePosition eBottomPos
=CuboidPlanePosition_Bottom
);
54 void update( double fScaledTickValue
);
56 sal_Int32 m_nDimensionIndex
;
61 GridLinePoints::GridLinePoints( const PlottingPositionHelper
* pPosHelper
, sal_Int32 nDimensionIndex
62 , CuboidPlanePosition eLeftWallPos
63 , CuboidPlanePosition eBackWallPos
64 , CuboidPlanePosition eBottomPos
)
65 : m_nDimensionIndex(nDimensionIndex
)
67 double MinX
= pPosHelper
->getLogicMinX();
68 double MinY
= pPosHelper
->getLogicMinY();
69 double MinZ
= pPosHelper
->getLogicMinZ();
70 double MaxX
= pPosHelper
->getLogicMaxX();
71 double MaxY
= pPosHelper
->getLogicMaxY();
72 double MaxZ
= pPosHelper
->getLogicMaxZ();
74 pPosHelper
->doLogicScaling( &MinX
,&MinY
,&MinZ
);
75 pPosHelper
->doLogicScaling( &MaxX
,&MaxY
,&MaxZ
);
77 if(!pPosHelper
->isMathematicalOrientationX())
78 std::swap( MinX
, MaxX
);
79 if(!pPosHelper
->isMathematicalOrientationY())
80 std::swap( MinY
, MaxY
);
81 if(pPosHelper
->isMathematicalOrientationZ())//z axis in draw is reverse to mathematical
82 std::swap( MinZ
, MaxZ
);
83 bool bSwapXY
= pPosHelper
->isSwapXAndY();
85 //P0: point on 'back' wall, not on 'left' wall
86 //P1: point on both walls
87 //P2: point on 'left' wall not on 'back' wall
89 const double v0
= (eLeftWallPos
== CuboidPlanePosition_Left
|| bSwapXY
) ? MinX
: MaxX
;
90 const double v1
= (eLeftWallPos
== CuboidPlanePosition_Left
|| !bSwapXY
) ? MinY
: MaxY
;
91 const double v2
= (eBackWallPos
== CuboidPlanePosition_Back
) ? MinZ
: MaxZ
;
92 P0
= P1
= P2
= { v0
, v1
, v2
};
94 if(m_nDimensionIndex
==0)
96 P0
.getArray()[1] = (eLeftWallPos
== CuboidPlanePosition_Left
|| !bSwapXY
) ? MaxY
: MinY
;
97 P2
.getArray()[2]= (eBackWallPos
== CuboidPlanePosition_Back
) ? MaxZ
: MinZ
;
98 if( eBottomPos
!= CuboidPlanePosition_Bottom
&& !bSwapXY
)
101 else if(m_nDimensionIndex
==1)
103 P0
.getArray()[0]= (eLeftWallPos
== CuboidPlanePosition_Left
|| bSwapXY
) ? MaxX
: MinX
;
104 P2
.getArray()[2]= (eBackWallPos
== CuboidPlanePosition_Back
) ? MaxZ
: MinZ
;
105 if( eBottomPos
!= CuboidPlanePosition_Bottom
&& bSwapXY
)
108 else if(m_nDimensionIndex
==2)
110 P0
.getArray()[0]= (eLeftWallPos
== CuboidPlanePosition_Left
|| bSwapXY
) ? MaxX
: MinX
;
111 P2
.getArray()[1]= (eLeftWallPos
== CuboidPlanePosition_Left
|| !bSwapXY
) ? MaxY
: MinY
;
112 if( eBottomPos
!= CuboidPlanePosition_Bottom
)
122 void GridLinePoints::update( double fScaledTickValue
)
124 P0
.getArray()[m_nDimensionIndex
] = P1
.getArray()[m_nDimensionIndex
] = P2
.getArray()[m_nDimensionIndex
] = fScaledTickValue
;
127 static void addLine2D( drawing::PointSequenceSequence
& rPoints
, sal_Int32 nIndex
128 , const GridLinePoints
& rScaledLogicPoints
129 , const XTransformation2
& rTransformation
132 drawing::Position3D aPA
= rTransformation
.transform( SequenceToPosition3D(rScaledLogicPoints
.P0
) );
133 drawing::Position3D aPB
= rTransformation
.transform( SequenceToPosition3D(rScaledLogicPoints
.P1
) );
135 rPoints
.getArray()[nIndex
]
136 = { { static_cast<sal_Int32
>(aPA
.PositionX
), static_cast<sal_Int32
>(aPA
.PositionY
) },
137 { static_cast<sal_Int32
>(aPB
.PositionX
), static_cast<sal_Int32
>(aPB
.PositionY
) } };
140 static void addLine3D( std::vector
<std::vector
<css::drawing::Position3D
>>& rPoints
, sal_Int32 nIndex
141 , const GridLinePoints
& rBasePoints
142 , const XTransformation2
& rTransformation
)
144 drawing::Position3D aPoint
=rTransformation
.transform( rBasePoints
.P0
);
145 AddPointToPoly( rPoints
, aPoint
, nIndex
);
146 aPoint
= rTransformation
.transform( rBasePoints
.P1
);
147 AddPointToPoly( rPoints
, aPoint
, nIndex
);
148 aPoint
= rTransformation
.transform( rBasePoints
.P2
);
149 AddPointToPoly( rPoints
, aPoint
, nIndex
);
152 VCartesianGrid::VCartesianGrid( sal_Int32 nDimensionIndex
, sal_Int32 nDimensionCount
153 , std::vector
< rtl::Reference
< ::chart::GridProperties
> > aGridPropertiesList
)
154 : VAxisOrGridBase( nDimensionIndex
, nDimensionCount
)
155 , m_aGridPropertiesList( std::move(aGridPropertiesList
) )
157 m_pPosHelper
= new PlottingPositionHelper();
160 VCartesianGrid::~VCartesianGrid()
163 m_pPosHelper
= nullptr;
166 void VCartesianGrid::fillLinePropertiesFromGridModel( std::vector
<VLineProperties
>& rLinePropertiesList
167 , const std::vector
< rtl::Reference
< ::chart::GridProperties
> > & rGridPropertiesList
)
169 rLinePropertiesList
.clear();
170 if( rGridPropertiesList
.empty() )
173 VLineProperties aLineProperties
;
174 for( const auto & rxPropSet
: rGridPropertiesList
)
176 if(!AxisHelper::isGridVisible( rxPropSet
))
177 aLineProperties
.LineStyle
<<= drawing::LineStyle_NONE
;
179 aLineProperties
.initFromPropertySet( rxPropSet
);
180 rLinePropertiesList
.push_back(aLineProperties
);
184 void VCartesianGrid::createShapes()
186 if(m_aGridPropertiesList
.empty())
188 //somehow equal to axis tickmarks
190 //create named group shape
191 rtl::Reference
< SvxShapeGroupAnyD
> xGroupShape_Shapes(
192 createGroupShape( m_xLogicTarget
, m_aCID
) );
194 if(!xGroupShape_Shapes
.is())
197 std::vector
<VLineProperties
> aLinePropertiesList
;
198 fillLinePropertiesFromGridModel( aLinePropertiesList
, m_aGridPropertiesList
);
200 //create all scaled tickmark values
201 std::unique_ptr
< TickFactory
> apTickFactory( createTickFactory() );
202 TickFactory
& aTickFactory
= *apTickFactory
;
203 TickInfoArraysType aAllTickInfos
;
204 aTickFactory
.getAllTicks( aAllTickInfos
);
206 //create tick mark line shapes
208 if(aAllTickInfos
.empty())//no tickmarks at all
211 TickInfoArraysType::iterator aDepthIter
= aAllTickInfos
.begin();
212 const TickInfoArraysType::const_iterator aDepthEnd
= aAllTickInfos
.end();
214 sal_Int32 nLinePropertiesCount
= aLinePropertiesList
.size();
215 for( sal_Int32 nDepth
=0
216 ; aDepthIter
!= aDepthEnd
&& nDepth
< nLinePropertiesCount
217 ; ++aDepthIter
, nDepth
++ )
219 if( !aLinePropertiesList
[nDepth
].isLineVisible() )
222 rtl::Reference
< SvxShapeGroupAnyD
> xTarget( xGroupShape_Shapes
);
225 xTarget
= createGroupShape( m_xLogicTarget
226 , ObjectIdentifier::addChildParticle( m_aCID
, ObjectIdentifier::createChildParticleWithIndex( OBJECTTYPE_SUBGRID
, nDepth
-1 ) )
229 xTarget
= xGroupShape_Shapes
;
235 GridLinePoints
aGridLinePoints( m_pPosHelper
, m_nDimensionIndex
);
237 sal_Int32 nPointCount
= (*aDepthIter
).size();
238 drawing::PointSequenceSequence
aPoints(nPointCount
);
240 sal_Int32 nRealPointCount
= 0;
241 for (auto const& tick
: *aDepthIter
)
245 aGridLinePoints
.update( tick
.fScaledTickValue
);
246 addLine2D( aPoints
, nRealPointCount
, aGridLinePoints
, *m_pPosHelper
->getTransformationScaledLogicToScene() );
249 aPoints
.realloc(nRealPointCount
);
250 ShapeFactory::createLine2D( xTarget
, aPoints
, &aLinePropertiesList
[nDepth
] );
252 //prepare polygon for handle shape:
253 drawing::PointSequenceSequence
aHandlesPoints(1);
254 auto pHandlesPoints
= aHandlesPoints
.getArray();
255 pHandlesPoints
[0].realloc(nRealPointCount
);
256 auto pHandlesPoints0
= pHandlesPoints
[0].getArray();
257 for( sal_Int32 nN
= 0; nN
<nRealPointCount
; nN
++)
258 pHandlesPoints0
[nN
] = aPoints
[nN
][1];
260 //create handle shape:
261 VLineProperties aHandleLineProperties
;
262 aHandleLineProperties
.LineStyle
<<= drawing::LineStyle_NONE
;
263 rtl::Reference
<SvxShapePolyPolygon
> xHandleShape
=
264 ShapeFactory::createLine2D( xTarget
, aHandlesPoints
, &aHandleLineProperties
);
265 ::chart::ShapeFactory::setShapeName( xHandleShape
, u
"HandlesOnly"_ustr
);
267 else //if(2!=m_nDimension)
269 GridLinePoints
aGridLinePoints( m_pPosHelper
, m_nDimensionIndex
, m_eLeftWallPos
, m_eBackWallPos
, m_eBottomPos
);
271 sal_Int32 nPointCount
= (*aDepthIter
).size();
272 std::vector
<std::vector
<css::drawing::Position3D
>> aPoints
;
273 aPoints
.resize(nPointCount
);
275 sal_Int32 nRealPointCount
= 0;
276 sal_Int32 nPolyIndex
= 0;
277 for (auto const& tick
: *aDepthIter
)
285 aGridLinePoints
.update( tick
.fScaledTickValue
);
286 addLine3D( aPoints
, nPolyIndex
, aGridLinePoints
, *m_pPosHelper
->getTransformationScaledLogicToScene() );
290 aPoints
.resize(nRealPointCount
);
291 ShapeFactory::createLine3D( xTarget
, aPoints
, aLinePropertiesList
[nDepth
] );
298 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */