GraphSharp Tutorials
来源:互联网 发布:网络培训学校 编辑:程序博客网 时间:2024/05/23 19:21
本文转自http://sachabarber.net/?p=815 created by Sacha Barber
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 atgraphsharp.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{ /// <summary> /// A simple identifiable vertex. /// </summary> [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{ /// <summary> /// A simple identifiable edge. /// </summary> [DebuggerDisplay("{Source.ID} -> {Target.ID}")] public class PocEdge : Edge<PocVertex> { 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<PocVertex, PocEdge> { 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<PocVertex, PocEdge, PocGraph> { }
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<String> layoutAlgorithmTypes = new List<string>(); #endregion #region Ctor public MainWindowViewModel() { Graph = new PocGraph(true); List<PocVertex> existingVertices = new List<PocVertex>(); 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<String> 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:
As always here is a small demo app : GraphSharpDemo.zip
46 thoughts on “Pretty Cool Graphs In WPF”
- GraphSharp Tutorials
- GraphSharp 简介一
- Tutorials
- Tutorials
- Tutorials
- Tutorials
- Tutorials
- Appfuse tutorials
- log4j Tutorials
- Box2D Tutorials
- Tutorials (SSRS)
- iPhone Tutorials
- Good tutorials
- ODI Tutorials
- HTK tutorials
- Lucene Tutorials
- Android Tutorials
- ROS Tutorials
- PXE 安装WinXP,Win7,Linux Serial 小记
- 解决项目打jar包后无法获取配置文件的路径问题
- 专家亲历中纪委会议称王岐山强调不说套话
- 三星uboot1.1.6源码分析——start.s(4)——从NAND复制源码到RAM(3)
- [入门篇]Jquery读取.Net WebService Json数据
- GraphSharp Tutorials
- 修改电脑域账户密码后登陆失败
- 理论学习:十八大报告要点专家解读
- Oracle 11g RAC oc4j/gsd Offline
- 从客户端.....中检测到有潜在危险的 Request.Form 值
- hadoop 命令
- QT 如何设置 QPushButton 的背景色
- Linux常用命令大全
- Linux内核编译选项-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
I will fix that
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!
Martin Yeah I had to dig into Graph# but its cool to work with
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
Nice post. Read & Bookmarked :] Thanks!
Ituition, glad it helped
Great Article for begginners! Hepled me a lot!
Igor, glad it helps
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#
Hiha you are welcome, Graph# rocks man
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
that’s the sort of question you should ask the graph sharp author over at codeplex. I did not write it
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.
I mean Text=”{Binding ID}” in style to graphsharp:EdgeControl.
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 ?
Not sure what is wrong there, may have to ask the author of Graph Sharp over at codeplex.
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
It seems ok now
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.
Greg
I did not write graph#, you need to ask the author over at its codeplex site.
Problem solved here:
http://graphsharp.codeplex.com/Thread/View.aspx?ThreadId=70832
Need the last version of Graphsharp build from source
Cool nice one gomino
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
No idea what that could be to be honest
Not very good … Ok. I’ll have to ask the developers…
But still thanks! Good post!
You are the greatest.
No sure about that, but thanks
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!
I am not the author of GraphSharp, so you should ask him at his codeplex site. He should know.
Thanks Sacha!
Great tutorial, but could be graphsharp used in Silverlight applications? Can you help me? I’m really new in Silverlight. Thank you.
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.
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.
You would need to ask that sort of question to the chap that did GraphSharp which is not me, ask him at codeplex.
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].
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?
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.
Great tutorial!
Thanks
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!)
Faizan
I am not the author of GraphShaarp, you should really ask the author of GraphSharp over at his codeplex site : http://graphsharp.codeplex.com/
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!
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!
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
Ok, thanks sacha! Cheers