fsteeg.com | notes | tags
∞ /notes/drawing-graphviz-dot-with-zest | 2009-07-31 | graphviz programming eclipse soc zest
Cross-posted to: https://fsteeg.wordpress.com/2009/07/31/drawing-graphviz-dot-with-zest/
In the latest milestone of my Google Summer of Code project at Eclipse, I have added support for dynamic creation of Zest graph instances from DOT input, which allows direct drawing of DOT with Zest. To use this, you first create a DotImport object from the DOT input, which can be given as a String, File, or IFile:DotImport importer = new DotImport("digraph name {1;2;1->2}");From this object, a Zest graph instance can be created in a given parent and with a style:
Graph graph = importer.newGraphInstance(shell, SWT.NONE);Here, the parent is a shell, which if opened will contain the Zest graph created from the DOT input: My original approach to get a graph instance was to take the generated Zest graph subclass (see previous milestones), compile it with a Java compiler and create the instance using reflection. The appeal of this was that the dynamically instantiated graph would be exactly the same thing as what is compiled from the input. So I started two approaches: using the Java 6 compiler API and the internal Eclipse JDT Java compiler. I got it working with the Java 6 compiler API when running as a plain Java application, using some tricks to avoid class reloading problems. Hitting further classloading issues when running in a workbench, I reconsidered this approach, since both possible solutions seemed not ideal. The Java 6 compiler API would introduce a dependency on Java 6. To make a possible inclusion of my code in Zest easy, this seems unfortunate. And more on the practical side: it would no longer run on my Mac (a 32-bit Core Duo). The internal Eclipse JDT compiler API initially seemed like an alternative here, but as I learned from the recent issue of the Eclipse-Magazin (ah, good old print, still useful), usage of internal API is not allowed for projects taking part in the Eclipse release train. So again, to even make an inclusion of my code in Zest possible, this seems to be no solution. So I followed up on the approach I was already using for dynamically getting the DOT graph name and compile errors: parsing the input programmatically with the parser generated by Xtext and getting info from there. In the same manner, the EMF object tree parsed from the DOT input is now interpreted to create and populate the Zest graph. The slight downside of this is that it duplicates how a Zest graph is created from DOT (which in a different way was already present in the Xpand template). On the other hand, this allows to dynamically draw DOT with Zest in a way that feels more lightweight compared to the compiler approach, and it supports all the DOT input features supported by the compiler (described in the posts for the previous milestones). The graph wizard added in milestone 3 now uses this dynamic drawing support to preview the resulting Zest graph when changes are made to the DOT template inside the wizard. With the end of the Google Summer of Code slowly approaching (two more weeks), I am very happy to have this dynamic creation of Zest graphs from DOT in, as this is an aspect of the project that I personally find particularly useful. I have been generating DOT from applications for some different use cases, often involving an Eclipse UI. The dependency on the dot executable and calling that from Java always added a lot of inconvenience. With this, I'll be able to use the two lines of code from above in Eclipse applications to visualize DOT without any non-Java dependencies. I'm excited to start using this in some of my other stuff, and it seems I'm not the only one with this kind of use case. With the previous milestone I have updated from oAW 4.3 to the Eclipse Modeling versions of the oAW components in Galileo. As this results in a dependency on the SVN version of the EMF model visualizer project, the changes for this milestone are only in the dot4zest HEAD and not attached to the corresponding bug. Instructions on how to set this up can be found on the wiki page.