31

I noticed that Visual Studio can generate graphs using something called DGML.

I would like to generate a graph like the following one in my C# application.

http://bishoponvsto.files.wordpress.com/2010/02/dgml-graph1.jpg

It does not have to be interactive like the VS. I just want to generate a static such image and save it as a general graphics file, such as PNG.

Is there any free .NET library for this?

bluevector
  • 3,485
  • 1
  • 15
  • 18
Damn Vegetables
  • 11,484
  • 13
  • 80
  • 135

4 Answers4

39

A little late, but it's actually relatively easy to implement yourself:

public class DGMLWriter
{
    public struct Graph
    {
        public Node[] Nodes;
        public Link[] Links;
    }

    public struct Node
    {
        [XmlAttribute]
        public string Id;
        [XmlAttribute]
        public string Label;

        public Node(string id, string label)
        {
            this.Id = id;
            this.Label = label;
        }
    }

    public struct Link
    {
        [XmlAttribute]
        public string Source;
        [XmlAttribute]
        public string Target;
        [XmlAttribute]
        public string Label;

        public Link(string source, string target, string label)
        {
            this.Source = source;
            this.Target = target;
            this.Label = label;
        }
    }

    public List<Node> Nodes { get; protected set; }
    public List<Link> Links { get; protected set; }

    public DGMLWriter()
    {
        Nodes = new List<Node>();
        Links = new List<Link>();
    }

    public void AddNode(Node n)
    {
        this.Nodes.Add(n);
    }

    public void AddLink(Link l)
    {
        this.Links.Add(l);
    }

    public void Serialize(string xmlpath)
    {
        Graph g = new Graph();
        g.Nodes = this.Nodes.ToArray();
        g.Links = this.Links.ToArray();

        XmlRootAttribute root = new XmlRootAttribute("DirectedGraph");
        root.Namespace = "http://schemas.microsoft.com/vs/2009/dgml";
        XmlSerializer serializer = new XmlSerializer(typeof(Graph), root);
        XmlWriterSettings settings = new XmlWriterSettings();
        settings.Indent = true;
        using (XmlWriter xmlWriter = XmlWriter.Create(xmlpath, settings))
        {
            serializer.Serialize(xmlWriter, g);
        }
    }
}
Peter
  • 2,654
  • 2
  • 33
  • 44
Simon Ejsing
  • 1,455
  • 11
  • 16
  • 1
    I was looking for simple way to generate basic state machine diagram from my workflow file. This is, by far, simplest way to achieve that. – Filip Sep 17 '13 at 15:13
  • 1
    Agreed that this is a great answer! I can open the resulting dgml in Visual Studio, but does anyone know how to display the dgml on a windows form? Thanks! – Justin Kauffman Feb 24 '17 at 08:04
  • 3
    The xmlWriter should be disposed of! – t0b4cc0 Feb 22 '19 at 16:08
  • Great answer, hardly had to do anything to get this to support groups https://learn.microsoft.com/en-us/visualstudio/modeling/customize-code-maps-by-editing-the-dgml-files?view=vs-2019#OrganizeNodes – Max Young Oct 27 '19 at 15:29
3

I have used NodeXL in the past, for generating workflow graphs within a web application, but it is suitable for desktop applications and interaction as well.

The description might confuse you a bit, making you think it's just for Excel. Not at all, you can use it's object model directly and graph whatever you want from .NET.

Pablo Romeo
  • 11,298
  • 2
  • 30
  • 58
  • +1 NodeXL's WPF control is very robust. It's great for representing related data graphically. Thanks for the reference! – Cameron Tinker May 13 '13 at 17:21
  • The description is in deed confusing. Does that mean it would work on a system that does not have Excel installed? – Damn Vegetables Jan 23 '14 at 05:43
  • Yes, that's correct, I didn't have Excel installed either. Now, this was a from a few years ago. Nowadays I would probably use D3 for this or a component using d3, such as Dagre, recommended here: http://stackoverflow.com/a/20342129/1373170 – Pablo Romeo Jan 23 '14 at 19:46
3

For anybody coming along after the fact, there is now a NuGet Package (GitHub) that makes it easier to create DGML files, including support styling and additional property metadata. I used Simon's answer initially (which worked great for my initial needs) and then stumbled on the NuGet package when looking for ways to improve my output. Hope it helps.

For anybody interested in a handy combination of tools, I've been using this in conjunction with DgmlImage (NuGet Package; note, this exposes itself as an executable in the tools directory of the package, so I manually extracted it to somewhere I could call it easily), NDepend (commercial but incredibly handy software, I believe free to open source projects), and LINQPad (free, but worth the license in my opinion) to generate diagrams from ad-hoc queries against a fairly complex codebase while trying to design a major refactor. It has been fantastic being able to ask questions about the codebase using simple LINQ queries, generate diagrams, and display the results in rapid succession. Note that I am not affiliated with any of these projects/products, I've just had such a wonderful experience using this combination of tools that I thought I'd recommend it to anybody trying to something similar.

TheXenocide
  • 1,060
  • 8
  • 22
  • 1
    The first link DgmlBuilder, looks great! I'm even considering using it for visualising general hierarchical data, the NodeBuilder pattern they have there looks compelling. – Alex KeySmith Feb 13 '20 at 11:41
  • 1
    Nice, looks handy. Note if you have code running inside Visual Studio you can use the official Microsoft.VisualStudio.GraphMode (see https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.graphmodel) – Chris Mar 02 '20 at 19:06
1

Did not try it by myself, but read some recommendations for Graph#.

The original code was formerly at Codeplex, but since this is closed at 01/07/2021, here is a Github link which finds several forks:

https://github.com/search?p=1&q=graphsharp&type=Repositories

(Thanks to @ergohack for providing it.)

Doc Brown
  • 19,739
  • 7
  • 52
  • 88