[This is obsolete copy&paste from my BSc thesis, it might be, however, useful if you want to dig a bit deeper or are just interested...]

With Graphviz4Net users can define a graph and then display it in a WPF application, or provide a custom Layout Builder for other GUI framework (e.g., Windows Forms). Graphviz (and thus Graphviz4Net) is capable of rendering graph clusters, curved edges with labels and arrows on both sides (arrows can have also labels) and much more. With built-in WPF Layout Builder, a graph node can any WPF control and even edges and labels rendering can be customized, although not as much as rendering of nodes.

Public API

Public API that Graphviz4Net provides can be divided up into two parts: graphs representation (the input for Graphviz) and layout processing (the output of Graphviz).

Graph representation

The conversion of graphs into the input format of Graphviz works with interfaces IGraph, ISubGraph and IEdge, nodes may be of any type. However, for convenient use Graphviz4Net offers generic versions of these interfaces and classes that implement them. So the user of Graphviz4Net may implement his own structures, he just have to make them implement the interfaces mentioned above; or he can use the predefined generic classes.

A graph aggregates list of it's nodes and sub-graphs, which aggregate list of their own nodes. Edges are aggregated by a graph object, but not by subgraphs, because edges may cross sub-graph boundaries.

Users may add custom attributes to the resulting DOT graph representation. The only thing which is needed for this is that the element (node, edge or subgraph) implements the IAttributed interface, which defines the Attributes property -- a name-value collection of DOT attributes. The default graph structures supplied with Graphviz4Net implement this interface and also have properties for setting and getting the usual DOT attributes such as Label. These properties provide a type-safe access to the Attributes collection, which can also be modified by hand in non type-safe manner to set up less usual DOT attributes.

Layout builder

When a graph is processed by Graphviz and the output is parsed by Graphviz4Net, we need to convert the layout data to actual elements on the screen or in the generated picture. For this purpose the Builder pattern is employed. Graphviz4Net takes care of parsing the output, but when it has a piece of layout information for example "the position of the node with id 2 is 34, 55", it passes this piece of information to the appropriate method of the Layout Builder and this method can then create an element on the screen or anything else.

Next to the graphical elements building, the Layout Builder is also responsible for supplying the sizes of the graph nodes, so that Graphviz can produce precise layout where nodes and edges do not overlap.

Graphviz4Net has one built-in Layout Builder for WPF applications at the moment (we suppose that it could build Siverlight layouts as well, however it hasn't been tested yet). Users even don't have to directly use this Layout Builder, the whole process of layouting is encapsulated in the GraphLayout WPF control. The only thing needed is to set up the Graph dependency property and provide data templates for nodes types.


DOT parsing

One of the tasks Graphviz4Net has to deal with is parsing of the Graphviz output, which is a text in the DOT language. We developed a parser based on the ANTLR parser generator that is able to parse most of the the DOT language constructs that Graphviz produces as an output (it is a subset of the full DOT language, because we know that some DOT constructs, e.g., comments are never produced by Graphviz).

Graphviz provides also the plain-text output format, which is line oriented language suitable for parsing. However, we found out that this format does not support some features of Graphviz that we wanted to support in our library (e.g., node clusters).

WPF Support

Graphviz generates the layout information in format where lengths are in inches, coordinates are in points (1/72 of an inch) and refer to the center of the element, the origin 0,0 is in the bottom left corner, coordinate values increase up and to the right and curved edges are represented as B-spline points. All these pieces have to be adopted to the WPF formats where, e.g., positions can refer to one of the corners of the element, but not to it's center. There are two possible approaches for this adoption: convert all the values; or make use of the render transformations in WPF to overcome the problem of different coordinate systems, but other values would still have to be converted. In Graphviz4Net we went with the first option, because the render transformations might slow down the application and there is not much difference between the two approaches in the amount of work.

The main work of the WPF Layout Builder is to adopt the values from Graphviz to WPF format. It gets a Canvas instance as a constructor parameter and it places all the elements into this Canvas using the Canvas dependency properties Top and Left. The decision which WPF elements should be used for the graphical representation of each of the elements in the graph is leaved to an Abstract Factory object, which is also a parameter of the constructor of the WPF Layout Builder. In the default implementation of the factory for nodes we just create a ContentPresenter with the Content set to the node type. This enables users of Graphviz4Net to define a data template for each type of a node (remember that nodes may be of any type, so a data structure with complex information or just simple string for label may be used).

The WPF Layout Builder should also provide the sizes of the nodes for Graphviz. For this purpose it uses the WPF layout system. Every instance of the FrameworkElement class has a method Measure(availableSize), in which it should determine it's size requirements by using an availableSize parameter. For the availableSize we use the double.Infinity and thus allow the element to set up any size. Desired size of the element is then accessible via property DesiredSize and the transformed value of this property is given to Graphviz.

Graphviz4Net provides also a WPF control that encapsulates this logic. The control uses standard WPF mechanisms of dependency properties and templates.

Last edited Feb 3, 2012 at 1:45 PM by stevesindelar, version 2


No comments yet.