Pretty Cool Graphs In WPF

I have just finished writing up a new article for www.codeproject.com for which I will write another blog post about. Thing is, when I was looking into parts of that article I wanted to use some graphs in WPF, and had to have a hunt around to see what was out there.

After a look about I found a truly excellent graphing library for WPF which is completely free. It’s a www.codeplex.com project called “GraphSharp” which is freely available at graphsharp.codeplex.com.

I also figured it may be good to show people how to get up and running with GraphSharp in this standalone blog as the new article I published does absolutely no hand holding about the graph creation, as that was not really what the new article is about.

So how do we use GraphSharp then, well we need to do a couple of things

1. Create a customised Vertex type

The 1st step is to define a custom Vertex for the graph such that you can store additional information for each Vertex. This is done as follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace GraphSharpDemo
{
    /// 
    /// A simple identifiable vertex.
    /// 
    [DebuggerDisplay("{ID}-{IsMale}")]
    public class PocVertex
    {
        public string ID { get; private set; }
        public bool IsMale { get; private set; }

        public PocVertex(string id, bool isMale)
        {
            ID = id;
            IsMale = isMale;
        }

        public override string ToString()
        {
            return string.Format("{0}-{1}", ID, IsMale);
        }
    }
}

2. Create a customised Edge type

The next step is to define a custom Edge type, you may want to show some extra information when the Edge is hovered over for example. This is done as follows:

using QuickGraph;
using System.Diagnostics;

namespace GraphSharpDemo
{
    /// 
    /// A simple identifiable edge.
    /// 
    [DebuggerDisplay("{Source.ID} -> {Target.ID}")]
    public class PocEdge : Edge
    {
        public string ID
        {
            get;
            private set;
        }

        public PocEdge(string id, PocVertex source, PocVertex target)
            : base(source, target)
        {
            ID = id;
        }
    }
}

3. Create a customised Graph

If you have custom Vertex/Edge you will need to create a custom Graph that knows about these custom types. Again this is very easily achieved, using the following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using QuickGraph;

namespace GraphSharpDemo
{
    public class PocGraph : BidirectionalGraph
    {
        public PocGraph() { }

        public PocGraph(bool allowParallelEdges)
            : base(allowParallelEdges) { }

        public PocGraph(bool allowParallelEdges, int vertexCapacity)
            : base(allowParallelEdges, vertexCapacity) { }
    }
}

4. Create a customised GraphLayout

Using GraphSharp we also need to create a custom LayoutTyppe for the custom graph, which is done as follows:

public class PocGraphLayout : GraphLayout { }

5. Create a ViewModel

Since we are using WPF, why not follow best practices and use MVVM for it, which obviously means creating a ViewModel. Here is an example ViewModel that can be set as the DataContext for a Window/UserControl that hosts the GraphSharp graphing controls.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using GraphSharp.Controls;

namespace GraphSharpDemo
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        #region Data
        private string layoutAlgorithmType;
        private PocGraph graph;
        private List layoutAlgorithmTypes = new List<string>();
        #endregion

        #region Ctor
        public MainWindowViewModel()
        {
            Graph = new PocGraph(true);

            List existingVertices = new List();
            existingVertices.Add(new PocVertex("Sacha Barber", true)); //0
            existingVertices.Add(new PocVertex("Sarah Barber", false)); //1
            existingVertices.Add(new PocVertex("Marlon Grech", true)); //2
            existingVertices.Add(new PocVertex("Daniel Vaughan", true)); //3
            existingVertices.Add(new PocVertex("Bea Costa", false)); //4

            foreach (PocVertex vertex in existingVertices)
                Graph.AddVertex(vertex);

            //add some edges to the graph
            AddNewGraphEdge(existingVertices[0], existingVertices[1]);
            AddNewGraphEdge(existingVertices[0], existingVertices[2]);
            AddNewGraphEdge(existingVertices[0], existingVertices[3]);
            AddNewGraphEdge(existingVertices[0], existingVertices[4]);

            AddNewGraphEdge(existingVertices[1], existingVertices[0]);
            AddNewGraphEdge(existingVertices[1], existingVertices[2]);
            AddNewGraphEdge(existingVertices[1], existingVertices[3]);

            AddNewGraphEdge(existingVertices[2], existingVertices[0]);
            AddNewGraphEdge(existingVertices[2], existingVertices[1]);
            AddNewGraphEdge(existingVertices[2], existingVertices[3]);
            AddNewGraphEdge(existingVertices[2], existingVertices[4]);

            AddNewGraphEdge(existingVertices[3], existingVertices[0]);
            AddNewGraphEdge(existingVertices[3], existingVertices[1]);
            AddNewGraphEdge(existingVertices[3], existingVertices[3]);
            AddNewGraphEdge(existingVertices[3], existingVertices[4]);

            AddNewGraphEdge(existingVertices[4], existingVertices[0]);
            AddNewGraphEdge(existingVertices[4], existingVertices[2]);
            AddNewGraphEdge(existingVertices[4], existingVertices[3]);

            string edgeString = string.Format("{0}-{1} Connected", 
                existingVertices[0].ID, existingVertices[0].ID);
            Graph.AddEdge(new PocEdge(edgeString, existingVertices[0], existingVertices[1]));
            Graph.AddEdge(new PocEdge(edgeString, existingVertices[0], existingVertices[1]));
            Graph.AddEdge(new PocEdge(edgeString, existingVertices[0], existingVertices[1]));
            Graph.AddEdge(new PocEdge(edgeString, existingVertices[0], existingVertices[1]));

            //Add Layout Algorithm Types
            layoutAlgorithmTypes.Add("BoundedFR");
            layoutAlgorithmTypes.Add("Circular");
            layoutAlgorithmTypes.Add("CompoundFDP");
            layoutAlgorithmTypes.Add("EfficientSugiyama");
            layoutAlgorithmTypes.Add("FR");
            layoutAlgorithmTypes.Add("ISOM");
            layoutAlgorithmTypes.Add("KK");
            layoutAlgorithmTypes.Add("LinLog");
            layoutAlgorithmTypes.Add("Tree");

            //Pick a default Layout Algorithm Type
            LayoutAlgorithmType = "LinLog";

        }
        #endregion

        #region Private Methods
        private PocEdge AddNewGraphEdge(PocVertex from, PocVertex to)
        {
            string edgeString = string.Format("{0}-{1} Connected", from.ID, to.ID);

            PocEdge newEdge = new PocEdge(edgeString, from, to);
            Graph.AddEdge(newEdge);
            return newEdge;
        }

        #endregion

        #region Public Properties

        public List LayoutAlgorithmTypes
        {
            get { return layoutAlgorithmTypes; }
        }

        public string LayoutAlgorithmType
        {
            get { return layoutAlgorithmType; }
            set
            {
                layoutAlgorithmType = value;
                NotifyPropertyChanged("LayoutAlgorithmType");
            }
        }

        public PocGraph Graph
        {
            get { return graph; }
            set
            {
                graph = value;
                NotifyPropertyChanged("Graph");
            }
        }
        #endregion

        #region INotifyPropertyChanged Implementation

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        #endregion
    }
}

6. Create and host the Graph Controls

So work with the GraphSharp Graph you need to use the GraphSharp UserControls for WPF. Here is what you need to do where I am using the MainWindowViewModel as just shown to bind against:

<Window x:Class="GraphSharpDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:graphsharp="clr-namespace:GraphSharp.Controls;assembly=GraphSharp.Controls"
        xmlns:local="clr-namespace:GraphSharpDemo"
        xmlns:zoom="clr-namespace:WPFExtensions.Controls;assembly=WPFExtensions"        
        Title="GraphSharpDemo" Height="350" Width="525">

        <zoom:ZoomControl  Grid.Row="1"  Zoom="0.2" 
        ZoomBoxOpacity="0.5" Background="#ff656565">
            <local:PocGraphLayout x:Name="graphLayout" Margin="10"
        Graph="{Binding Path=Graph}"
        LayoutAlgorithmType="{Binding Path=LayoutAlgorithmType, Mode=OneWay}"
        OverlapRemovalAlgorithmType="FSA"
        HighlightAlgorithmType="Simple" />

        </zoom:ZoomControl>
</Window>

7. Create Templates For Graph Vertices/Edges

Finally all that is left to do, is create some DataTemplates that will show what you want for your custom Graph Vertices/Edges. Here are some examples for the custom Vertices/Edges above

<DataTemplate x:Key="demoTemplate" DataType="{x:Type local:PocVertex}">
    <StackPanel Orientation="Horizontal" Margin="5">
        <Image x:Name="img" Source="../Images/boy.ico" Width="20" Height="20" />
        <TextBlock Text="{Binding Path=ID, Mode=OneWay}" Foreground="White" />
    </StackPanel>
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding IsMale}" Value="false">
            <Setter TargetName="img" Property="Source"
                        Value="../Images/girl.ico" />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

<Style TargetType="{x:Type graphsharp:VertexControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type graphsharp:VertexControl}">
                <Border BorderBrush="White" 
                        Background="Black"
            BorderThickness="2"
            CornerRadius="10,10,10,10"
            Padding="{TemplateBinding Padding}">
                    <ContentPresenter Content="{TemplateBinding Vertex}" 
                            ContentTemplate="{StaticResource demoTemplate}"/>

                    <Border.Effect>
                        <DropShadowEffect BlurRadius="2" Color="LightGray" 
                            Opacity="0.3" Direction="315"/>
                    </Border.Effect>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style TargetType="{x:Type graphsharp:EdgeControl}">
    <Style.Resources>
        <ToolTip x:Key="ToolTipContent">
            <StackPanel>
                <TextBlock FontWeight="Bold" Text="Edge.ID"/>
                <TextBlock Text="{Binding ID}"/>
            </StackPanel>
        </ToolTip>
    </Style.Resources>
    <Setter Property="ToolTip" Value="{StaticResource ToolTipContent}"/>
</Style>

Putting it all together it looks like this:

image

As always here is a small demo app : GraphSharpDemo.zip

Advertisements

76 Comments

  1. Hello Sacha,

    as always a vera, very good post. Thank you!

    (Maybe yhou have to fix some links in your article. The links to Graph# are pre-tagged with “sachabarber.net”.)

    Cheers!

    Stone

    Reply

  2. Dude, thank you! I have been looking at GraphSharp occasionally for over a year but have always discounted it in the past because i couldn’t find any resource on it but you have helped clear the way to do some initial playing with this very interesting but under documented tech!

    Reply

  3. Hello,

    Thank you for this wonderful tutorial!

    Well I am having a problem with the Graph# CompoundLayout:
    I can’t find how to make the parent vertices(those with childs) display their content correctly, so I need your help.
    Thank you

    Reply

  4. Just came across this post and sample code, and I must say, excellent work! This will help me a lot in wrapping my mind around Graph#

    Reply

  5. Hi.

    If you want to make an Edge clickable, I would you do?
    (I make the Vertex clickable already).

    Also, if you want to change dinamically the info of a Vertex, how would you make the graph to refresh (for example, if you click on a vertex, swapping from male to female, it should swap also the image based on the trigger)?

    Thanks a lot for this post! It help me a lot.
    regards
    daniela

    Reply

    1. that’s the sort of question you should ask the graph sharp author over at codeplex. I did not write it

      Reply

  6. Hi
    I’m pretty new with WPF but I think I found an error in your example. Label’s aren’t displaying edge’s id’s.
    I think error is in this binding:

    , but I have no idea how to fix this. 😀

    If You could fix it and eventually make a suggestion how to change color of the edge accordingly to some edge parameter I would be very grateful. 🙂

    Reply

  7. Hi,

    Thank you for this excellent how-to.
    But there is a problem with your edge tooltip the binding is not working…

    Can you tell me how to fix it ?

    Reply

  8. Hi,

    really thanks for the example.
    that’s clear and very useful.

    But now the dl link of the example solution seems down, is it possible to republish it ?

    Thanks to let me know

    Reply

  9. Hi.

    First of all thanks for the great example.

    I’m writing some tool for regex build/debug and one of functionalities of it is to provide a graph of the finite automata it produces. For this purpose I’ve chosen graph#.

    I did some modifications to your in order to make it work with my classes. I have question regarding “EfficientSugiyama” layout algorithm. Is it possible to draw smooth lines instead of elbow lines? I mean some sort of B-Splines?

    Thank you!

    Regards, Greg.

    Reply

  10. Hi, Sacha!
    Could you help me with one problem:
    I did download your code, but when I run the app, I see only black screen… When I move mouse inside the screen, I can see tooltips, but cant see any UI elements at all 😦

    Reply

  11. Dear Sacha!
    It’s great your tutorial. However, it can’t applied for undirected graph. In your code, I replace BidirectionalGraph with UndirectedGraph, and no error, no graph on layout window. Could you explain?
    Thanks a lot!

    Reply

    1. I am not the author of GraphSharp, so you should ask him at his codeplex site. He should know.

      Reply

  12. Great tutorial, but could be graphsharp used in Silverlight applications? Can you help me? I’m really new in Silverlight. Thank you.

    Reply

  13. Thank you very much, it is really helpful for us !

    I wonder something about mouse events, when we create a graph we can automatically drag the vertexes or by clicking the empty are we can move the whole graph,but how all of these work ? I want to add multitouch capabilities to graph#, but I don’t know which methods should I call or which events should I fire.

    Can anyone suggest a solution or at least a way for a solution.

    Thanks.

    Reply

  14. I have a question:
    when I replace the GraphSharp.Controls.dll with the complete GraphSharp.Controls project, recompile it and and use that created assembly the the binding graphsharp:EdgeControl…ID does not longer work. Do you have an idea what that can cause or how to debug such a not working binding.

    Reply

    1. You would need to ask that sort of question to the chap that did GraphSharp which is not me, ask him at codeplex.

      Reply

  15. Thank you for your quick replay – I did that already. What I found for the time being is that the DataItem for the resp. Style changes from DataItem=’PocEdge’ [OK] to DataItem=’MainWindowViewModel’ [faulty].

    Reply

  16. hi, would like to check if you’ve got any idea on how to add in JSON to query from Freebase, at the same time using GraphSharp to present the layout?

    Reply

    1. Well thats really a strange question to do with what is essentially how to lay out a graph in WPF. BUt it would involve creating some service that talked to Freebase via JSON objects being returned which you could then get data from and add as vertices and edges, that is all there is to it really.

      Reply

  17. Hi! I’m new to WPF. Could you please guide me as to how I may get the edges to show data from my custom Edge Type.

    I have weighted graphs, so each Edge type also has an int weight. I would like to show that on the edge…. (not just as a tool tip!)

    Reply

  18. Thanks sacha.
    I know you’re not the author. Its just that you wrote a fantastic tutorial. So I was just looking for pointers.

    Cheers!

    Reply

  19. Hi sacha,
    Do you know if it is possible to use Graph# on an asp.net mvc web application?
    I cant find any guidance about it, and I already asked on codeplex but no one answer.
    Thanks, cheers!

    Reply

    1. Yeah there is no way you could use graph sharp with asp Mvc, no chance. It’s wpf all the way as such not a chance. Hope that clears it up for you

      Reply

  20. Hi Sacha,
    great article! I am planning on displaying a graph that represents versions of documents (with splits and merges and all that). Is it possible to make the vertices linked to the documents so that the user can click them and the document opens?
    Thanks!

    Reply

    1. Sure just have your custom vertex exposé an ICommand which you would bind button to with your custom vertex datatemplate.

      You just need to make sure your custom vertex also has the document URL passed into its constructor. I would recommend using something like josh smiths relaycommand

      Reply

      1. Thanks for the quick reply! Do you know of any tutorials showing how to do this? (My knowledge of this is rather basic, as I have not worked with interfaces before)

  21. Hi Sacha,
    I have been fairly successful in rebuilding your example to the point were I have my own customized graph ready to be displayed.
    I am now trying to integrate the WPF solution into my WordAddIn by adding the MWVM class and the appropriate MainWindow.xaml file.
    Now the first thing I added to the MWVM file was:
    public class DDNAGraphLayout : GraphLayout { }
    Before adding the custom Layouttype, everything compiled nicely. As soon as the custom Layouttype is added, I get a very weird error when trying to build:

    Error 3 The “FindRibbons” task failed unexpectedly.
    System.IO.FileNotFoundException: Could not load file or assembly ‘Analyser, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null’ or one of its dependencies. The system cannot find the file specified.
    […]
    Now Analyser is my namespace, that part I understand. Is this error related to me trying to “attach” the graph# solution to my WordAddIn, or am I missing some references?

    Thanks for any help, this really puzzles me.

    Reply

  22. Hey Sasha,
    As usual your post are explained beautifully. I have one question related to graphsharp. Can we use GraphSharp to display a huge volume of twitter data (friends/ followers) links ?

    Reply

    1. Thanks. Though for your specific graphsharp question you may need to ask that on graphsharp codeplex site and ask its author, I did not write it

      Reply

  23. Hi Sacha, Thanks for such a nice post. I have done everything you wrote but I am not able to see any graph on my window. Only the background with zoom control is coming up.

    Reply

      1. Thanks for you fast response Sacha.. But this looks more difficult to understand for me. I am a newbie in graph#. Could you please guide me on how to proceed. I think have copied the code in some other file. Where am I supposed to write the third last block of codes?

  24. I heard that it was possible to get only the coordinate of each vertex without drawing it on a WPF application. I saw on the graphsharp forum that I had to use this kind of code to make it, but I only get NaN returns. Do you have any idea ?

    var g = new BidirectionalGraph<VertexControl, IEdge>();
    // some code building the graph

    LayeredTopologicalSortAlgorithm<VertexControl, IEdge> algo = new LayeredTopologicalSortAlgorithm<VertexControl, IEdge>(g);
    algo.Compute();

    var graphLayout = new GraphLayout<VertexControl, IEdge, BidirectionalGraph<VertexControl, IEdge>>();
    graphLayout.Graph = g;

    VertexControl vertex = g.Vertices.ElementAt(1);
    double x = GraphCanvas.GetX(graphLayout.GetVertexControl(vertex)); // NaN
    double y = GraphCanvas.GetY(graphLayout.GetVertexControl(vertex)); // NaN

    Reply

    1. You may have to ask this on the GraphSharp codeplex site. I did not write it, I just posted how to use it here. Sorry

      Reply

  25. Hey i am trying your article and it almost works. I just dont know where to save your data-template. Can you pls explain this to me?

    Thx in advance
    David

    Reply

  26. HI, love this article. It was really helpful with my application, which visualize some algorithms like Dijkstra or A* 🙂
    But i have a little question 🙂
    I wrote my own graph parts, but I’m quite new to WPF, how can i add a label on middle of Edge? I can do Binding and stuff, just can’t figure out how to add it in a first place.
    Thanks upfront 🙂

    Reply

    1. You would have to change the DataTemplate for the edge. This would either be here or in the GraphSharp code

      Reply

  27. Hello,this article is useful. In the end of this article has a link to the source code,is it right?
    I click it, but it show error,maybe the link is missing,can you update that. Thank you in advance

    Reply

  28. Hi i’m new on WPF. can some one tell me where should i put the code from section 7. Create Templates For Graph Vertices/Edges in my project ?

    Reply

  29. Hello i have to simulate a Chord protokoll search and i want to colour specific edge for searching simulation?

    How is this possbile?

    Thank you in advance

    Reply

    1. So for this example I would do this

      1. Add extra property to the POCEdge class

      [DebuggerDisplay("{Source.ID} -> {Target.ID}")]
          public class PocEdge : Edge
          {
              public string ID
              {
                  get;
                  private set;
              }
      
              public Color BrushColor
              {
                  get;
                  private set;
              }
      
              public PocEdge(string id, PocVertex source, PocVertex target, Color brushColor)
                  : base(source, target)
              {
                  ID = id;
                  BrushColor = brushColor;
              }
          }
      

      2. Then I would modify the style to include the color for edge

      <Style TargetType="{x:Type graphsharp:EdgeControl}">
          <Style.Resources>
              <ToolTip x:Key="ToolTipContent">
                  <StackPanel>
                      <TextBlock FontWeight="Bold" Text="Edge.ID"/>
                      <TextBlock Text="{Binding ID}"/>
                  </StackPanel>
              </ToolTip>
          </Style.Resources>
          <Setter Property="ToolTip" Value="{StaticResource ToolTipContent}"/>
          <Setter Property="Foreground" Value="{Binding BrushColor}"/>
      </Style>
      
      

      This will in turn set the Foreground of the underlying graphSharp EdgeControl which is declared like this

      <Style TargetType="{x:Type Controls:EdgeControl}">
              <Setter Property="Template">
                  <Setter.Value>
                      <ControlTemplate TargetType="{x:Type Controls:EdgeControl}">
                          <Path Stroke="{TemplateBinding Foreground}"
                                StrokeThickness="{TemplateBinding StrokeThickness}"
                                MinWidth="1"
                                MinHeight="1"
                                ToolTip="{TemplateBinding ToolTip}"
                                x:Name="edgePath">
                              <Path.Data>
                                  <PathGeometry>
                                      <PathGeometry.Figures>
                                          <MultiBinding Converter="{StaticResource routeToPathConverter}">
                                              <Binding RelativeSource="{RelativeSource TemplatedParent}"
                                                       Path="Source.(Controls:GraphCanvas.X)" />
                                              <Binding RelativeSource="{RelativeSource TemplatedParent}"
                                                       Path="Source.(Controls:GraphCanvas.Y)" />
                                              <Binding RelativeSource="{RelativeSource TemplatedParent}"
                                                       Path="Source.ActualWidth" />
                                              <Binding RelativeSource="{RelativeSource TemplatedParent}"
                                                       Path="Source.ActualHeight" />
                                              <Binding RelativeSource="{RelativeSource TemplatedParent}"
                                                       Path="Target.(Controls:GraphCanvas.X)" />
                                              <Binding RelativeSource="{RelativeSource TemplatedParent}"
                                                       Path="Target.(Controls:GraphCanvas.Y)" />
                                              <Binding RelativeSource="{RelativeSource TemplatedParent}"
                                                       Path="Target.ActualWidth" />
                                              <Binding RelativeSource="{RelativeSource TemplatedParent}"
                                                       Path="Target.ActualHeight" />
                                              <Binding RelativeSource="{RelativeSource TemplatedParent}"
                                                       Path="RoutePoints" />
                                          </MultiBinding>
                                      </PathGeometry.Figures>
                                  </PathGeometry>
                              </Path.Data>
                          </Path>
                      </ControlTemplate>
                  </Setter.Value>
              </Setter>
              <Setter Property="Controls:GraphElementBehaviour.HighlightTrigger"
                      Value="{Binding RelativeSource={RelativeSource Self}, Path=IsMouseOver}" />
              <Setter Property="MinWidth"
                      Value="1" />
              <Setter Property="MinHeight"
                      Value="1" />
              <Setter Property="Background"
                      Value="Red" />
              <Setter Property="Foreground"
                      Value="Silver" />
              <Setter Property="Opacity"
                      Value="0.5" />
              <Style.Triggers>
                  <Trigger Property="Controls:GraphElementBehaviour.IsHighlighted"
                           Value="True">
                      <Setter Property="Foreground"
                              Value="Black" />
                  </Trigger>
                  <Trigger Property="Controls:GraphElementBehaviour.IsSemiHighlighted"
                           Value="True">
                      <Setter Property="Foreground"
                              Value="Yellow" />
                  </Trigger>
                  <MultiTrigger>
                      <MultiTrigger.Conditions>
                          <Condition Property="Controls:GraphElementBehaviour.IsSemiHighlighted"
                                     Value="True" />
                          <Condition Property="Controls:GraphElementBehaviour.SemiHighlightInfo"
                                     Value="InEdge" />
                      </MultiTrigger.Conditions>
                      <Setter Property="Foreground"
                              Value="Red" />
                  </MultiTrigger>
                  <MultiTrigger>
                      <MultiTrigger.Conditions>
                          <Condition Property="Controls:GraphElementBehaviour.IsSemiHighlighted"
                                     Value="True" />
                          <Condition Property="Controls:GraphElementBehaviour.SemiHighlightInfo"
                                     Value="OutEdge" />
                      </MultiTrigger.Conditions>
                      <Setter Property="Foreground"
                              Value="Blue" />
                  </MultiTrigger>
              </Style.Triggers>
          </Style>
      
      

      I am hoping this will work

      Reply

  30. Hello now i have a other problem 😦

    I have tried do use the demo above but it is not working

    namespace GraphSharpDemo
    {
    ///
    /// Interaction logic for Window1.xaml
    ///
    public partial class Window1 : Window
    {
    private MainWindowViewModel s;

    public Window1()
    {

    InitializeComponent();

    s = new MainWindowViewModel();

    this.DataContext = s;
    }

    }

    public class PocVertex
    {
    public string ID { get; private set; }
    public bool IsMale { get; private set; }

    public PocVertex(string id, bool isMale)
    {
    ID = id;
    IsMale = isMale;
    }

    public override string ToString()
    {
    return string.Format(“{0}-{1}”, ID, IsMale);
    }
    }

    public class PocEdge : Edge
    {
    public string ID
    {
    get;
    private set;
    }

    public PocEdge(string id, PocVertex source, PocVertex target)
    : base(source, target)
    {
    ID = id;
    }
    }

    public class PocGraph : BidirectionalGraph
    {
    public PocGraph() { }

    public PocGraph(bool allowParallelEdges)
    : base(allowParallelEdges) { }

    public PocGraph(bool allowParallelEdges, int vertexCapacity)
    : base(allowParallelEdges, vertexCapacity) { }
    }

    public class PocGraphLayout : GraphLayout { }

    public class MainWindowViewModel : System.ComponentModel.INotifyPropertyChanged
    {
    #region Data
    private string layoutAlgorithmType;
    private PocGraph graph;
    private List layoutAlgorithmTypes = new List();
    #endregion

    #region Ctor
    public MainWindowViewModel()
    {
    Graph = new PocGraph(true);

    List existingVertices = new List();
    existingVertices.Add(new PocVertex(“Sacha Barber”, true)); //0
    existingVertices.Add(new PocVertex(“Sarah Barber”, false)); //1
    existingVertices.Add(new PocVertex(“Marlon Grech”, true)); //2
    existingVertices.Add(new PocVertex(“Daniel Vaughan”, true)); //3
    existingVertices.Add(new PocVertex(“Bea Costa”, false)); //4

    foreach (PocVertex vertex in existingVertices)
    Graph.AddVertex(vertex);

    //add some edges to the graph
    AddNewGraphEdge(existingVertices[0], existingVertices[1]);
    AddNewGraphEdge(existingVertices[0], existingVertices[2]);
    AddNewGraphEdge(existingVertices[0], existingVertices[3]);
    AddNewGraphEdge(existingVertices[0], existingVertices[4]);

    AddNewGraphEdge(existingVertices[1], existingVertices[0]);
    AddNewGraphEdge(existingVertices[1], existingVertices[2]);
    AddNewGraphEdge(existingVertices[1], existingVertices[3]);

    AddNewGraphEdge(existingVertices[2], existingVertices[0]);
    AddNewGraphEdge(existingVertices[2], existingVertices[1]);
    AddNewGraphEdge(existingVertices[2], existingVertices[3]);
    AddNewGraphEdge(existingVertices[2], existingVertices[4]);

    AddNewGraphEdge(existingVertices[3], existingVertices[0]);
    AddNewGraphEdge(existingVertices[3], existingVertices[1]);
    AddNewGraphEdge(existingVertices[3], existingVertices[3]);
    AddNewGraphEdge(existingVertices[3], existingVertices[4]);

    AddNewGraphEdge(existingVertices[4], existingVertices[0]);
    AddNewGraphEdge(existingVertices[4], existingVertices[2]);
    AddNewGraphEdge(existingVertices[4], existingVertices[3]);

    string edgeString = string.Format(“{0}-{1} Connected”,
    existingVertices[0].ID, existingVertices[0].ID);
    Graph.AddEdge(new PocEdge(edgeString, existingVertices[0], existingVertices[1]));
    Graph.AddEdge(new PocEdge(edgeString, existingVertices[0], existingVertices[1]));
    Graph.AddEdge(new PocEdge(edgeString, existingVertices[0], existingVertices[1]));
    Graph.AddEdge(new PocEdge(edgeString, existingVertices[0], existingVertices[1]));

    //Add Layout Algorithm Types
    layoutAlgorithmTypes.Add(“BoundedFR”);
    layoutAlgorithmTypes.Add(“Circular”);
    layoutAlgorithmTypes.Add(“CompoundFDP”);
    layoutAlgorithmTypes.Add(“EfficientSugiyama”);
    layoutAlgorithmTypes.Add(“FR”);
    layoutAlgorithmTypes.Add(“ISOM”);
    layoutAlgorithmTypes.Add(“KK”);
    layoutAlgorithmTypes.Add(“LinLog”);
    layoutAlgorithmTypes.Add(“Tree”);

    //Pick a default Layout Algorithm Type
    LayoutAlgorithmType = “LinLog”;

    }
    #endregion

    #region Private Methods
    private PocEdge AddNewGraphEdge(PocVertex from, PocVertex to)
    {
    string edgeString = string.Format(“{0}-{1} Connected”, from.ID, to.ID);

    PocEdge newEdge = new PocEdge(edgeString, from, to);
    Graph.AddEdge(newEdge);
    return newEdge;
    }

    #endregion

    #region Public Properties

    public List LayoutAlgorithmTypes
    {
    get { return layoutAlgorithmTypes; }
    }

    public string LayoutAlgorithmType
    {
    get { return layoutAlgorithmType; }
    set
    {
    layoutAlgorithmType = value;
    NotifyPropertyChanged(“LayoutAlgorithmType”);
    }
    }

    public PocGraph Graph
    {
    get { return graph; }
    set
    {
    graph = value;
    NotifyPropertyChanged(“Graph”);
    }
    }
    #endregion

    #region INotifyPropertyChanged Implementation

    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String info)
    {
    if (PropertyChanged != null)
    {
    PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(info));
    }
    }

    #endregion
    }
    }

    XAML Code:

    Thank you i advance i have controlled all but found no error.

    The only what i have seeing is the greay background with zoom but no nodes and edges

    Reply

      1. Christian in order for you XAML to show up when you post it as a comment you need to replace “<” and “>” with the html entity encoding for those symbols and put that all in a “<pre>” “</pre>” tag.

        I cant see any of your XAML unless you do that

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s