This tutorial uses basic/default graph configuration and visual templates. If you want to customize your graph behaviours and look please read following tutorials.

Note: You can find detailed and commented example projects in the library sources.


There are 2 methods of graph generation available.
1. Create and fill graph data and then call GenerateGraph(graph) method. This approach lets GrapghArea to generate visuals automatically. Method is explaned below.
2. Create and fill graph data. manually create custom VertexControls, EdgeControls and inject them into GraphArea. Assign data graph to GraphArea.Graph property and call GraphArea.RelayoutGraph(). This method allows manual handling of customized objects. Method is explained in the end of the article.

Method 1. Automatic visual handling.

To start using GraphX library you only need to do the following:
1. Define your visual control and data types based on the GraphX core types.
2. Code to create corresponding objects (XAML or code-behind)
3. Generate data graph and invoke generation method

First of all let's define all the classes we will need for the graph operations. This will be:
  • Layout visual object (must derive from GraphArea<TVertex, TEdge, TGraph> class)
  • Graph data object (must derive from QuickGraph's IBidirectionalGraph)
  • Vertex data object (must derive from VertexBase)
  • Edge data object (must derive from EdgeBase<VertexBase>)

PLEASE NOTE: All derived classes must implement parameterless constructors for feature compatibility such as save/load graphs!

For example:
    //Layout visual object
    public class GraphAreaExample : GraphArea<DataVertex, DataEdge, BidirectionalGraph<DataVertex, DataEdge>> { }

    //Graph data object
    public class GraphExample : BidirectionalGraph<DataVertex, DataEdge> { }

    //Vertex data object
    public class DataVertex: VertexBase
    {
        [XmlAttribute("text")]
        [DefaultValue("")]
        public string Text { get; set; }

        public override string ToString()
        {
            return Text;
        }
    }

    //Edge data object
    public class DataEdge: EdgeBase<DataVertex>
    {
        public DataEdge(DataVertex source, DataVertex target, double weight = 1)
			: base(source, target, weight)
	{
	}

        public DataEdge()
            : base(null, null, 1)
        {
        }

        [XmlAttribute("text")]
        [DefaultValue("")]
        public string Text { get; set; }

        public override string ToString()
        {
            return Text;
        }

    }

Now you need to create GraphArea visual object. The best practice is to use ZoomControl included into the GraphX library as the wrapper for our custom GraphAreaExample control. This approach will help us to handle zooming, scaling and other display actions without any problems. For example, in XAML it will look like:
        xmlns:graphxctrl="clr-namespace:GraphX.Controls;assembly=GraphX"
        xmlns:local="clr-namespace:ShowcaseExample"  

                        <graphxctrl:ZoomControl x:Name="gg_zoomctrl">
                            <local:GraphAreaExample x:Name="gg_Area"/>
                        </graphxctrl:ZoomControl>

And the last thing we need to do is to create the data graph, fill it with data and run the generation process.
PLEASE NOTE: All edge and vertex data properties MUST have unique positive number assigned to ID property. Several GraphX features depends on it!

            Random Rand = new Random();

            //Create data graph object
            var graph = new GraphExample();

            //Create and add vertices using some DataSource for ID's
            foreach (var item in DataSource.Take(100))
                graph.AddVertex(new DataVertex() { ID = item.ID, Text = item.Text });

            var vlist = graph.Vertices.ToList();
            //Generate random edges for the vertices
            foreach (var item in vlist)
            {
                if (Rand.Next(0, 50) > 25) continue;
                var vertex2 = vlist[Rand.Next(0, graph.VertexCount - 1)];
                graph.AddEdge(new DataEdge(item, vertex2, Rand.Next(1, 50)) 
                      { Text = string.Format("{0} -> {1}",item, vertex2) });
            }

Now we have data graph object with 100 vertices and aprox. 50 edges.

Optionaly we can setup default graph algorithms and behaviours. Default algorithms are used if no external algorithm of the same type is assigned by the user. For more info you can read Using external calculation algorithms.
//change default layout algorithm to Circular
gg_Area.DefaultLayoutAlgorithm = LayoutAlgorithmTypeEnum.Circular;
//change default overlap removal algorithm
gg_Area.DefaultOverlapRemovalAlgorithm = OverlapRemovalAlgorithmTypeEnum.FSA;
//change default edge routing algorithm
gg_Area.DefaultEdgeRoutingAlgorithm = EdgeRoutingAlgorithmTypeEnum.SimpleER;

To generate and display visual graph all what we need is to call gg_Area.GenerateGraph() method for GraphArea control created in the example above. Optionaly you can use param to specify if you want the edges to be generated after this method call.

    gg_Area.GenerateGraph(graph);

To relayout already built graph you can use method:
    gg_Area.RelayoutGraph(bool generateAllEdges = false);

In the terms of performance edge controls are not created automatically though you can do it by specifying generateAllEdges parameter in the graph generation/relayout methods or manually using GraphArea. GenerateAllEdges() and GraphArea. GenerateEdgesForVertex() to generate all possible edges or edges for specified vertex only.

    gg_Area.GenerateAllEdges();

    gg_Area.GenerateEdgesForVertex(VertexControl, EdgesType.All);

Remeber that edge routing points are calculated in RelayoutGraph() stage but new route points are applied in GenerateAllEdges() or GenerateEdgesForVertex() methods when visual edges are being generated. Individual edge recalculations are performed on each EdgeControl Render pass if current ER algorithm allows such operation.

Method 2. Manual handling of custom visuals.

We will skip needed classes definitions as they are the same as in Method 1.
First of all lets create sample data objects:

            //Create data graph object
            var graph = new GraphExample();

            //Create and add vertices
            graph.AddVertex(new DataVertex() { ID = 1, Text = "Item 1" });
            graph.AddVertex(new DataVertex() { ID = 2, Text = "Item 2" });
            var v1 = graph.Vertices.First();
            var v2 = graph.Vertices.Last();
            var e1 = new DataEdge(v1, v2, 1) { Text = "1 -> 2" }
            graph.AddEdge(e1);

Next we create and add visual objects manually:
             //VC DataContext will be bound to v1 by default. You can control this by specifing additional property in the constructor
             var vc1 = new VertexControl(v1);
             Area.AddVertex(v1, vc1);
             var vc2 = new VertexControl(v2);
             Area.AddVertex(v2, vc2);

             var ec = new EdgeControl(e1, vc1, vc2);
             Area.InsertEdge(e1, ec); //inserts edge into the start of the children list to draw it below vertices


Now the final part:
//Assign data graph
Area.Graph = graph;
//Call realyout. Additional parameters shows that edges must be created or updated if any exists.
Area.RelayoutGraph(true);

Last edited Jul 23, 2013 at 1:30 PM by panthernet, version 22