WPF - Animation of graph algorithms - Part 2

 
12/29/2009
.NET, C#, WPF
2 Comments

In the first part of this series I showed how to implement a data structure for graphs.
Now let's continue with the UI. The UI should be capable of creating graphs consisting of nodes and edges with some mouse clicks. Moreover it should be easy to execute previously created graph algorithms and to show their animations.

The final application

Example

Before starting with the implementation I want to show a simple animation created with the final tool:

Usage

  • By clicking to an empty area a new node is created
  • By clicking at two nodes within one second (not necessarily different nodes) a new edge is created
  • By clicking at a node or edge its properties can be edited in the panel on the right
  • All graph algorithms can be executed by selecting the corresponding entry in the menu

Implementation

Mosts parts of the application are straight forward using the MVVM-pattern, with one exception: 3D elements within a ViewPort3D can not be created by using databinding, they have to be added to the container manually.
As seen in first part data could be attached to nodes and edges. The application uses an IGraph<NodeData,EdgeData> as graph. NodeData and EdgeData contain UI specific information like position and color.

3D Elements

Since the node and edge elements should react on click events, our 3D elements have to derive from UIElement3D. The WPF3DTeam has blogged about how to subclass UIElement3D.
Nodes should be represented by a sphere and edges by a cylinder/torus, therefore I created the following hierarchy:

3DHierarchy

Every time a new node or edge is added to the graph the VisualFactory instantiates the corresponding GraphUIElement. A GraphUIElement has a GeometryModel3D which is a MeshGeometry3D together with a Material.

Whenever the underlying data changes (e.g. new position or color) the GraphUIElement updates itself. When a node should move, a new animation is added to the corresponding DependencyProperty. This all happens under the covers, if you want to create your own graph algorithms (see below) you don't have to care about the internals.

The most complex GraphUIElement is the RegularEdgeUIElement which connects two nodes, the difficulty was to rotate and scale the cylinder to the correct position.

Graph algorithms

The application already contains several graph algorithms like Dijkstra or Kruskal. To create your own algorithms, add a new class to the solution and implement the interface IGraphAlgorithm. After recompiling the solution your algorithm will be listed in the menu.

Creating animations is quite simple, some extension methods make things even easier. In the following example we add two nodes to the graph, then we flash the two nodes for 3 seconds. After flashing is finished, both nodes are moved to another position.

public void Execute(IGraph<NodeData, EdgeData> graph)
{
    graph.Clear();

    this.node1 = graph.AddNode(new NodeData(new Point3D(0, 25, 0)));
    this.node2 = graph.AddNode(new NodeData(new Point3D(0, -25, 0)));

    this.graph.AddEdge(this.node1, this.node2);

    this.node1.Blink(3000);
    this.node2.Blink(3000, this.Callback);
}

private void Callback()
{
    this.node1.Move(new Point3D(25, 0, 0), 4000);
    this.node2.Move(new Point3D(-25, 0, 0), 4000);
}

Animations in WPF are running asynchronously and parallel, that's great as long as animations should run parallel (like the flashing of both nodes). But the nodes should not move until the flashing animation has finished, therefore a callback is registered, it gets executed at the end of the animation.

Documentation

I did not write any documentation apart from XML-comments in the source code. So just have a look at the source. You may modify and extend it as you like.

Downloads

Feedly Feedly Tweet


Related posts


Comments


Daniel

Daniel

7/31/2011

@Nilres: You could also grab the latest sources from: http://wpfgraph.codeplex.com


Nilres

Nilres

7/31/2011

For everyone who has problems with converting these project to Visual Studio 2010: Just remove the import style cop direction from the projectfile with notepad or took the source from the next part :-)