Tulip  5.4.0
Large graphs analysis and drawing
LayoutProperty.h
1 /*
2  *
3  * This file is part of Tulip (http://tulip.labri.fr)
4  *
5  * Authors: David Auber and the Tulip development Team
6  * from LaBRI, University of Bordeaux
7  *
8  * Tulip is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation, either version 3
11  * of the License, or (at your option) any later version.
12  *
13  * Tulip is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  *
18  */
19 
20 #ifndef TULIP_LAYOUT_H
21 #define TULIP_LAYOUT_H
22 
23 #include <tulip/PropertyTypes.h>
24 #include <tulip/Observable.h>
25 #include <tulip/AbstractProperty.h>
26 #include <tulip/PropertyAlgorithm.h>
27 #include <tulip/minmaxproperty.h>
28 
29 namespace tlp {
30 
31 template <>
33  tlp::edge e, tlp::LineType::RealType newValue);
34 
35 template <>
36 std::pair<tlp::Coord, tlp::Coord>
38 
39 class PropertyContext;
40 class Graph;
41 
42 typedef AbstractProperty<tlp::PointType, tlp::LineType> AbstractLayoutProperty;
43 typedef MinMaxProperty<tlp::PointType, tlp::LineType> LayoutMinMaxProperty;
44 
45 /**
46  * @ingroup Graph
47  * @brief A graph property that maps a tlp::Coord value to graph nodes and std::vector<tlp::Coord>
48  * for edges.
49  */
50 class TLP_SCOPE LayoutProperty : public LayoutMinMaxProperty {
51 public:
52  LayoutProperty(Graph *graph, const std::string &name = "" /*, bool updateOnEdgeReversal=true*/);
53 
54  // override some PropertyInterface methods
55  PropertyInterface *clonePrototype(Graph *, const std::string &) const override;
56  static const std::string propertyTypename;
57  const std::string &getTypename() const override {
58  return propertyTypename;
59  }
60 
61  //=======================================
62  // Methods for extra layout information
63  //=======================================
64 
65  /**
66  * Returns the maximum coordinate of the layout, i.e. the top-right corner of the induced bounding
67  *box
68  *
69  * @param subgraph If not null, returns the maximum coordinate for a subgraph layout
70  **/
71  Coord getMax(const Graph *subgraph = nullptr);
72 
73  /**
74  * Returns the minimum coordinate of the layout, i.e. the bottom-left corner of the induced
75  *bounding box
76  *
77  * @param subgraph If not null, returns the minimum coordinate for a subgraph layout
78  **/
79  Coord getMin(const Graph *subgraph = nullptr);
80 
81  //============================================
82  // Functions for layout modification
83  //============================================
84 
85  /**
86  * Translates the current layout according to a movement vector
87  *
88  * @param move a movement vector
89  * @param subgraph If not null, only translates the layout of that subgraph
90  **/
91  void translate(const Vec3f &move, const Graph *subgraph = nullptr);
92 
93  /**
94  * Translates the layout of a set of nodes and edges provided through iterators
95  * according to a movement vector
96  *
97  * @param move a movement vector
98  * @param itNodes an iterator on graph nodes
99  * @param itEdges an iterator on graph edges
100  *
101  * @warning The iterators are not deleted
102  **/
103  void translate(const Vec3f &move, Iterator<node> *itNodes, Iterator<edge> *itEdges);
104 
105  /**
106  * Scales the current layout according to a vector of scale factors (sx, sy, sz).
107  *
108  * @param scaleFactors a vector of scale factors
109  * @param subgraph If not null, only scales the layout of that subgraph
110  **/
111  void scale(const Vec3f &scaleFactors, const Graph *subgraph = nullptr);
112 
113  /**
114  * Scales the layout of a set of nodes and edges provided through iterators
115  * according to a vector of scale factors (sx, sy, sz).
116  *
117  * @param scaleFactors a vector of scale factors
118  * @param itNodes an iterator on graph nodes
119  * @param itEdges an iterator on graph edges
120  *
121  * @warning The iterators are not deleted
122  **/
123  void scale(const Vec3f &scaleFactors, Iterator<node> *itNodes, Iterator<edge> *itEdges);
124 
125  /**
126  * Rotates the layout around the X-axis according to an angle in degrees.
127  *
128  * @param alpha an angle in degrees
129  * @param subgraph If not null, only rotates the layout of that subgraph
130  **/
131  void rotateX(const double &alpha, const Graph *subgraph = nullptr);
132 
133  /**
134  * Rotates the layout around the Y-axis according to an angle in degrees.
135  *
136  * @param alpha an angle in degrees
137  * @param subgraph If not null, only rotates the layout of that subgraph
138  **/
139  void rotateY(const double &alpha, const Graph *subgraph = nullptr);
140 
141  /**
142  * Rotates the layout around the Z-axis according to an angle in degrees.
143  *
144  * @param alpha an angle in degrees
145  * @param subgraph If not null, only rotates the layout of that subgraph
146  **/
147  void rotateZ(const double &alpha, const Graph *subgraph = nullptr);
148 
149  /**
150  * Rotates the layout around the X-axis of the nodes and edges provided
151  * through iterators according to an angle in degrees.
152  *
153  * @param alpha an angle in degrees
154  * @param itNodes an iterator on graph nodes
155  * @param itEdges an iterator on graph edges
156  *
157  * @warning The iterators are not deleted
158  **/
159  void rotateX(const double &alpha, Iterator<node> *itNodes, Iterator<edge> *itEdges);
160 
161  /**
162  * Rotates the layout around the Y-axis of the nodes and edges provided
163  * through iterators according to an angle in degrees.
164  *
165  * @param alpha an angle in degrees
166  * @param itNodes an iterator on graph nodes
167  * @param itEdges an iterator on graph edges
168  *
169  * @warning The iterators are not deleted
170  **/
171  void rotateY(const double &alpha, Iterator<node> *itNodes, Iterator<edge> *itEdges);
172 
173  /**
174  * Rotates the layout around the Z-axis of the nodes and edges provided through
175  * iterators according to an angle in degrees.
176  *
177  * @param alpha an angle in degrees
178  * @param itNodes an iterator on graph nodes
179  * @param itEdges an iterator on graph edges
180  *
181  * @warning The iterators are not deleted
182  **/
183  void rotateZ(const double &alpha, Iterator<node> *itNodes, Iterator<edge> *itEdges);
184 
185  /**
186  * Centers the layout, meaning translating it in order that
187  * the center of its bounding box is (0,0,0)
188  *
189  * @param subgraph If not null, only centers the layout of that subgraph
190  **/
191  void center(const Graph *subgraph = nullptr);
192 
193  /**
194  * Centers the layout to newCenter, meaning translating it in order that
195  * the center of its bounding box is equal to newCenter
196  *
197  * @param newCenter the coordinate of the new layout center
198  * @param subgraph If not null, only centers the layout of that subgraph
199  **/
200  void center(const Vec3f &newCenter, const Graph *subgraph = nullptr);
201 
202  /**
203  * Normalizes the layout, meaning dividing each nodes and edges coordinate by the maximum
204  *magnitude of the whole coordinates set
205  *
206  * @param subgraph If not null, only normalizes the layout of that subgraph
207  **/
208  void normalize(const Graph *subgraph = nullptr);
209 
210  /**
211  * Scales the layout in order to approach an aspect ratio (width / height) of 1.0 .
212  * @param subgraph If not null, only scales the layout of that subgraph
213  **/
214  void perfectAspectRatio(const Graph *subgraph = nullptr);
215 
216  //=======================================================================
217  // Set of function in order to measure the quality of the LayoutAlgorithm
218  //=======================================================================
219 
220  /**
221  * Returns the length of an edge, the bends are taken into account.
222  * Thus, it measure the length of a polyline.
223  *
224  * @param e the graph edge on which to compute its length
225  *
226  * @warning this function only measure the length of the polyline between bends,
227  * when using curves like Bézier etc... the result will not be the length of the curve.
228  **/
229  double edgeLength(const edge e) const;
230 
231  /**
232  * Returns the average edge length of the layout, the bends are taken into account
233  *
234  * @param subgraph If not null, only compute the average edge length for that subgraph
235  **/
236  double averageEdgeLength(const Graph *subgraph = nullptr) const;
237 
238  /**
239  * Returns the average angular resolution of the layout.
240  * It is only defined for 2D drawing, meaning the third coordinate
241  * is omitted
242  *
243  * @param subgraph It not null, only computes the average angular resolution for that subgraph
244  **/
245  double averageAngularResolution(const Graph *subgraph = nullptr) const;
246 
247  /**
248  * Returns the average angular resolution of a node.
249  * It is only defined for 2D drawing, meaning the third coordinate
250  * is omitted
251  *
252  * @param n the graph node on which to compute the angular resolution
253  * @param subgraph If not null, only computes the average angular resolution for the node in that
254  *subgraph
255  **/
256  double averageAngularResolution(const node n, const Graph *subgraph = nullptr) const;
257 
258  /**
259  * Returns a vector of all angular resolution of a node.
260  * It is only defined for 2D drawing, meaning the third coordinate
261  * is omitted
262  *
263  * @param n the graph node on which to compute the angular resolution
264  * @param subgraph If not null, only computes the average angular resolution for the node in that
265  *subgraph
266  **/
267  std::vector<double> angularResolutions(const node n, const Graph *subgraph = nullptr) const;
268 
269  /**
270  * Fixes embedding of the graph according to the layout
271  * ie. sort edges around nodes according to their neighbors/bends position in the layout/
272  * Only works in 2D, the third coordinate is not taken into account.
273  *
274  * @param subgraph It not null, only fixes embedding in that subgraph
275  **/
276  void computeEmbedding(Graph *subgraph = nullptr);
277 
278  /**
279  * Fixes embedding of the node according to the layout
280  * ie. sort edges around the node according to its neighbors/bends position in the layout/
281  * Only work in 2D, the third coordinate is not taken into account.
282  *
283  * @param n the graph node on which to fix embedding
284  * @param subgraph If not null, only fixes the embedding of the node in that subgraph
285  **/
286  void computeEmbedding(const node n, Graph *subgraph = nullptr);
287 
288  /**
289  * Returns the number of crossings in the layout
290  **/
291  // methods removed until we have a working implementation
292  // unsigned int crossingNumber() const;
293 
294  // redefinition of some AbstractProperty methods
295  void setNodeValue(const node, tlp::StoredType<Coord>::ReturnedConstValue v) override;
296  void setEdgeValue(const edge, tlp::StoredType<std::vector<Coord>>::ReturnedConstValue v) override;
297  void setAllNodeValue(tlp::StoredType<Coord>::ReturnedConstValue v) override;
298  void setValueToGraphNodes(tlp::StoredType<Coord>::ReturnedConstValue v,
299  const Graph *graph) override;
300  void setAllEdgeValue(tlp::StoredType<std::vector<Coord>>::ReturnedConstValue v) override;
301  void setValueToGraphEdges(tlp::StoredType<std::vector<Coord>>::ReturnedConstValue v,
302  const Graph *graph) override;
303 
304 protected:
305  void clone_handler(AbstractProperty<tlp::PointType, tlp::LineType> &) override;
306 
307 private:
308  void resetBoundingBox();
309  void rotate(const double &alpha, int rot, Iterator<node> *, Iterator<edge> *);
310  // override Observable::treatEvent
311  void treatEvent(const Event &) override;
312 
313 public:
314  // the number of edges with bends
315  unsigned int nbBendedEdges;
316 };
317 
318 /**
319  * @ingroup Graph
320  * @brief A graph property that maps a std::vector<tlp::Coord> value to graph elements.
321  */
322 class TLP_SCOPE CoordVectorProperty
323  : public AbstractVectorProperty<tlp::CoordVectorType, tlp::PointType> {
324 public:
325  CoordVectorProperty(Graph *g, const std::string &n = "")
326  : AbstractVectorProperty<CoordVectorType, tlp::PointType>(g, n) {}
327  // redefinition of some PropertyInterface methods
328  PropertyInterface *clonePrototype(Graph *, const std::string &) const override;
329  static const std::string propertyTypename;
330  const std::string &getTypename() const override {
331  return propertyTypename;
332  }
333 };
334 
336 } // namespace tlp
337 #endif
This class extends upon PropertyInterface, and adds type-safe methods to get and set the node and edg...
Abstracts the computation of minimal and maximal values on node and edge values of properties...
A graph property that maps a std::vector<tlp::Coord> value to graph elements.
Interface for Tulip iterators. Allows basic iteration operations only.
Definition: Graph.h:43
PropertyInterface describes the interface of a graph property.
The edge struct represents an edge in a Graph object.
Definition: Edge.h:40
The node struct represents a node in a Graph object.
Definition: Node.h:40
Event is the base class for all events used in the Observation mechanism.
Definition: Observable.h:52
void updateEdgeValue(tlp::edge e, typename edgeType::RealType newValue)
Updates the value on an edge, and updates the minimal/maximal cached values if necessary. Should be called by subclasses in order to keep the cache up to date.
A graph property that maps a tlp::Coord value to graph nodes and std::vector<tlp::Coord> for edges...