Labels in .dot file must be integers?

Jan 24, 2012 at 12:49 PM

I was trying to have graphviz parse the example "digraph G {Hello->World}", and then have Graphviz4Net parse that, but it seems that Graphviz4Net doesn't handle string labels. Is that correct? Or am I doing something wrong?

Here is the actual string to parse:

$ echo "digraph G {Hello->World}" | dot -Tdot

digraph G { node [label="\N"]; graph [bb="0,0,80,112"]; Hello [pos="40,93", width=1, height="0.51389"]; World [pos="40,19", width="1.1111", height="0.51389"]; Hello -> World [pos="e,40,37.667 40,74.327 40,66.264 40,56.648 40,47.711"];}



Coordinator
Jan 25, 2012 at 12:32 PM

Hi,

yes Graphviz4Net.Core cannot handle string ids. Originally it was developed just for the purposes of the WPF component. In this scenario user is expected to create the graph as .NET objects, these are then internally converted to DOT file which is processed by dot and then the result parsed. Hence the ids were not meant to be visible to a user whatsoever. I decided to use integral numbers because the parsing is then faster (when parser comes to an edge, it must find the endpoints, and when ids are numbers, the nodes can simply be stored in array and the id itself is index into this array). 

So this was about the current state of Graphviz4Net.Core. Now what are your options:

  • the easies option is to change ids to numbers,
  • another option is to wait a bit for a patch of Graphviz4Net. Restricting ids to numbers is probably not a good idea, I must admit, and it won't be that difficult to provide implementation which can handle general ids (although for a price of slight performance penalty). So I am going to do it and submit new version in a few following days (I'd like to do it right now, but I have to do other things unfortunately).

Anyway thanks for the feedback and please don't hesitate to ask any other questions or request any other reasonable features for Graphviz4Net. Also, if you are tight on time and e.g. need this feature today, you can try to implement it by yourself and I'd be more than happy to accept your patch afterwards.

Steves

Jan 25, 2012 at 8:39 PM

Thanks for the feedback! Yes, I did look at the code, and started changing all of the arrays and lists to Dictionary<string,object> and that looks like it would be straightforward. But it got deeper and deeper, and I was afraid that I might miss an assumption on ordering. I'd be glad to send my patch as it is, but it is not complete. A dictionary lookup should not be noticeably slower than an array access---the dictionary just has the cost of a hash function more, I suspect. And you save time now because you don't have to convert the string to a number. Should run pretty much as it did.

I had switched to re-writing some Python code I found that properly handled the symbols into C#, but if you can get to this fairly quickly, I'd rather use Graphviz4Net as it has much more potential all around. Great project!

Note that symbols can be either a string of alpha-numeric characters, or a string beginning/ending with double-quotes. 

I'd be glad to test out any updates.

Thanks again!

-Doug

Coordinator
Jan 27, 2012 at 6:41 PM

Hi Doug,

a few minutes ago I've committed a patch that allows ids of general type for DotVertex class. Now it's only a matter of implementing DotGraphBuilder abstract class, which I am hopefully going to do later...

Steves

Jan 30, 2012 at 10:16 AM

Excellent! I am looking over the changes today.

Feb 2, 2012 at 10:36 PM
Edited Feb 3, 2012 at 2:43 AM

I tried testing by adding this to Utils.cs:

        public static Graphviz4Net.Dot.DotGraph Parse(string content)
        {
            var antlrStream = new Antlr.Runtime.ANTLRStringStream(content);
            var lexer = new Graphviz4Net.Dot.AntlrParser.DotGrammarLexer(antlrStream);
            var tokenStream = new Antlr.Runtime.CommonTokenStream(lexer);
            var parser = new Graphviz4Net.Dot.AntlrParser.DotGrammarParser(tokenStream);
            var builder = new Graphviz4Net.Dot.AntlrParser.StringDotGraphBuilder();
            parser.Builder = builder;
            parser.dot();
            return builder.DotGraph;
        }

and called it with:

        string s = @"digraph {
        node [label=""\N""];
        graph [bb=""0,0,74,112""];
        Hello [pos=""37,93"", width=""0.91667"", height=""0.52778""];
        World [pos=""37,19"", width=""1.0278"", height=""0.52778""];
        Hello -> World [pos=""e,37,38.249 37,73.943 37,66.149 37,56.954 37,48.338""];
}";
        Parse(s);

But, I get an error where DotGraphBuilder is not creating a this.DotGraph. Any ideas what might be going on? Can you test with above, or show me how you are testing?

Thanks!

Coordinator
Feb 3, 2012 at 12:27 PM

Aaaagh, silly bug, hopefully fixed by the latest commit. Btw. now you don't need to write all that code by hand:

var parser = AntlrParserAdapter<string>.GetParser();           

var result = parser.Parse("Your string....");

Feb 3, 2012 at 12:47 PM
Edited Feb 3, 2012 at 12:48 PM

Thanks! That did it. BTW, just to show how useful your code is, here I am using dropping your DLL into a folder, and using in Python:

>>> import Graphviz4Net
>>> parser = Graphviz4Net.Dot.AntlrParser.AntlrParserAdapter[str].GetParser()
>>> p = parser.Parse("""digraph {
        node [label="\\N"];
        graph [bb="0,0,74,112"];
        Hello [pos="37,93", width="0.91667", height="0.52778"];
        World [pos="37,19", width="1.0278", height="0.52778"];
        Hello -> World [pos="e,37,38.249 37,73.943 37,66.149 37,56.954 37,48.338"];
} """)
>>> p.Vertices[0].Position
<System.Windows.Point object at 0x000000000000002F [37,93]>

I'm using this interactively on Linux, Mac, and Windows under Mono using IronPython, with Gtk#. Fantastic! Thanks again! (See http://calicoproject.org/ for more info)

Coordinator
Feb 3, 2012 at 1:04 PM

Wow, that's really cool! I am really glad that the project is useful for you.