We need a SVG export functionality to lay out a Directed (possibly cyclic) Graph (DG) (we supply the list of edges to reverse to make it a Directed Acyclic Graph (DAG)) as follows:
- more or less square viewport (aspect ratio < 16:9)
- avoid superposing vertices on vertices and edges on vertices; it is not required to minimize edge crossings though
- use orthogonal edges drawn as polylines with arrowhead markers, with the prevalent flow direction left-to-right
- edge connections to/from vertices should attach to specific locations called ports
- do not display the source and sink vertices
- layer the vertices, with layers assigned to columns; horizontally space the columns by 200; vertically space the vertices within one column by 100; both spacings should be set using a parameterized constant in the C++ code (as parameters are not yet available within SVG)
- vertices come in different types (i.e. Mixer, Reactor, Cooler, Divider) and are represented by rectangular icons, available as separate svg files, that must be embedded as image tags:
- each vertex type has a different icon with different size (all are in the range width 60-200, height 60-200px), the icon name can be retrieved with the icon() function, the icon dimensions can be retrieved with iconWidth() and iconHeight() functions
- can be either inbound or outbound, and are located on one of the vertex icon sides (N, S, E or W)
- can receive 1..N connections; when one connection is attached to a port, it is located in the center of the icon side; when more than one is present, they are evenly spread along the edge, in any order
The generated SVG must pass the W3C Markup Validation:
[url removed, login to view]
Separate presentation from structure by relocating all styles in an internal stylesheet within a element and apply them to named classes as required
Locate labels as text using text-anchor on the polyline / image using text-anchor: middle
Make the edges / vertices clickable, pointing to a [url removed, login to view] file where N is retrieved from the ModelDummy::id() property.
Handle edge crossings as in the red connections in the attached [url removed, login to view] file: group the edge path proper with a second underlying path with the same data but stroke:#ffffff;stroke-width:5. In this way the crossed edges look interrupted.
The algorithm desctibed in the [url removed, login to view] file must be implemented in C++2003 using the boost::graph API in the method:
void Graph::printSvg(const char *fileName) const
See the attached code in code directory; compile with:
g++ -Wall -g -D DUMMY -I . [url removed, login to view] [url removed, login to view]
Feel free to change the EdgeBase and VertexBase classes adding any private data you may need, together with its getter / setter as in:
int count(void) const;
We provide 10 test graphs; for all of them, the non-orthogonal layout produced with graphviz's dot is attached (see the attached dot_layouts/*.png).
SP, d, m5, s12, s4 and s6 are simple examples for which a qualitative idea of the desired appearance of the layout is sketched (see the attached desired_layouts/*.jpg)
MT, PS, S and ZS are real-world examples.