Drawing tree in OCaml GUI, best option?

Thanks very much again for everyone’s reply. I managed to cobble something that’s basically exactly what I had in mind over past few days.

Below is an attached screenshot for people who might be interested in doing something similar and wondering if very feasible.

(The black bars are not part of the graphics, it’s just for censoring as the program is part of a research project that’s not published yet)

The whole program basically loads a file of some kind, runs a parser over it, then produce a tree.

Some technical details

  • Parsing is done on OCaml’s side using mparser
  • All core stuff(e.g. AST manipulation, heavy lifting) is done in OCaml
  • Graphing is done with Javascript libraries dagre(for DAG layout calculation) and cytoscape.js for actual rendering and interactive interface
    • Was using sigma initially for graphing, but moved to cytoscape. The transition was fairly easy cause the libraries were kept in separate OCaml modules
  • Javascript calls are done via js_of_ocaml
  • Threading and synchronisation is done using Lwt, and some related Lwt modules in js_of_ocaml
    • This includes synchronisation between a Javascript event handler and OCaml code, uses Lwt_condition specifically.

Comments on experience

  • Always use class types for binding Javascript libraries in js_of_ocaml, otherwise typing will get very, very weird when you try to use the objects across modules, and also when you type up .mli files
  • (Not specific to Javascript+OCaml context) You will need a light text editor that can deal with large text files if you want to go through the generated Javascript file for debugging. I used vim
  • js_of_ocaml’s Jstable(Javascript hashtable that uses Javascript string as keys) almost kinda work as an associative array, but not really
    • There was an instance where I was trying to make a Javascript object that has a field “foo-bar”, but hyphens can’t be used in field names, so I had to try to make an associative array of some form(you can do this via named indexes in Javascript).
    • So to do this on OCaml’s side, I tried to use Jstable, it worked kinda, except when passed as an object to a Javascript function, it will complain and state that the key is “foo-bar_”
    • I.e. Jstable when passed as object, the key has an extra underscore at the end instead of just the raw string you used

Overall result

  • Have an interface on the left side of the screen that shows a tree that you can select nodes, click, drag, move, zoom etc
  • Have a control panel on the right side(just a list of buttons with event handlers tied to Lwt threads etc) for opening files, etc
  • Core stuff still coded in OCaml(which is fantastic), and Javascript components can be swapped fairly easily

Attached an animated GIF showing it in action with a test graph.


Just out of curiosity, how big is the generated JavaScript file?

Tokei’s output for code base size

 Language            Files        Lines         Code     Comments       Blanks
 OCaml                  15         1755         1490           64          201
 Total                  15         1755         1490           64          201

EDIT: Roughly 200-300 LOC is binding/wrapper of JS libraries.

Sizes of program.bc.js

profile size in bytes size in KiB
dev profile, build command : dune build @js 8961453 8751
minified dev build, minified with uglifyjs 4366132 4264
release profile, build command : dune build -p program @js 513518 501
minified release build, minified with uglifyjs 511684 500

Note: js is a custom alias that has multiple dependencies on rules that deal with file copying, generation etc. One dependency is program.bc.js

EDIT: Added more figures to table


Hello everyone,

So @grayswandyr messaged me a few days ago about publishing of the Javascript bindings and other related OCaml files of the project. Unfortunately the source code will stay private until publication process has been finished, but I reckon I can publish the Javascript bindings and a stripped down version of the knowledge graph module and make a small demo which people can use as a template to make similar GUI software or site.

However, I always find myself completely out of touch on anything related to UI/UX, and have always needed other people’s guidance on the matter from my experience.

So I’d like to ask for suggestions of some particular features or examples that you’d like me to give a shot at in the demo. Feel free to leave a comment or PM me to make suggestions.


The project is finally published, here is the link to the relevant OCaml sources for drawing knowledge graph and HTML. src/cytoscape.ml is the binding to the Cytoscape JS library, src/dagre.ml is the binding to Dagre JS graph layout library.

We have a demo site where you can see it in action. You’ll need to click “Show knowledge graph” to see the display of knowledge graph however.


The demo site looks nice! I have a specific graph layout problem and I’m wondering if i could use some of your work to solve it.

I want to visualize trees in which each node carries a ‘time’ in such a way that times always increase as you descend. The trees get very deep but they are thinned such that the width of the tree at any given time remains bounded. I would like to visualize these trees so that the time is the y coordinate and the x coordinate is adjusted so as to fit the width of the tree into a given window, maybe like in a force-directed graph layout. It does not need to be interactive.

Is it easy to reuse some of your code? Where would I have to start?

Do you have a small example of the graph you have in mind?

I think at the very least cytoscape.ml is a good starting point if you find Cytoscape a good option.

The graph layout algorithm is run separately from Cytoscape, so you can always swap to another algorithm easily using a similar design in graph.ml.

I had a look at cytoscape and at graphviz; their layout algorithms unfortunately do not match my requirements. So I guess I would have to make my own layout. But then I can also just export the graph in some way as .dot and use graphviz with precomputed layout…

1 Like

Well writing a layout algorithm would be fairly easy I think.

Is the graph layout the only bit you’re looking for?

EDIT: Read your question again and realised I somewhat misinterpreted it - so uh graph.ml might be useful as it provides a graph implementation that handles arrows and also bi-directional traversal, but really depends on how you plan to represent your graph.

So if I understand you want to represent a tree that is embedded in time ?
I’m not sure I understand the part about “they are thinned such”.
It seems to me like algorithms to plot phylogenies and genealogies might be useful.
https://itol.embl.de/ for instance is pretty good at that.

yes, it’s a tree embedded in time. however, as time progresses, many branches of the tree end without children, so that on average, at any given time, a constant, small number of branches are present. i’ll have a look at the embl library, thanks!

Alright in that case something like this naive implementation could also work (but the output is not very pretty):

interesting project! in fact i my tree is also a biological one: cell lifetimes in a cell culture. i tried cloning an installing your repo but cannot build it.

File "tree/lib/draw.ml", line 69, characters 34-39:
Error: The function applied to this argument has type
         string -> w:float -> h:float -> Cairo.Surface.t
This argument cannot be applied with label ~fname

this appears after some warnings like this one:

File "tree/lib/tree.ml", line 15, characters 13-22:
Error (warning 49): no cmi file was found in path for module Tree__Sig

Famous last words.

I have a project that aims to collect algorithms to layout trees: https://github.com/Drup/tree_layout

I suspect the “Layered” algorithm would be sufficient for your purpose, but you can also find lot’s of different type of tree visualisation here. Formally, what you are looking for is an algorithm for layered trees where the rank of nodes is prescribed. There are several such algorithms.

If you end up implementing something from the literature (or improving on it), I would be happy to add it to the collection! :slight_smile:

1 Like

Yes, the rank is prescribed but i would also want to constrain the width; this may require bending some branches inwards, towards a straight centerline. What I would imagine could work is a constrained force-directed layout where only the width-coordinates are allowed to adapt in order to 1. keep edges non-overlapping and short and 2. keep vertices close to a centerline (in the width coordinate x) and 3. keep vertices separated.

I find force-based layouts usually unreliable and resulting in layouts that are not so nice in practice. What about https://pdfs.semanticscholar.org/5f26/d395668644ed9ffc1b17a7780d01bb253715.pdf ?

We present two new drawing conventions which reduce the layout width to be less than some maximum width while still maintaining the essential layered drawing convention.

Stacktrees are also relevant: http://vis.cs.ucdavis.edu/papers/evevis-evolutionary-vis.pdf


Yes sorry the master branch is very behind right now.
If you want to build you can pull branch devel-john, but apparently there’s a problem with the Cairo version.
But I implemented this as a quick hack, so don’t hesitate to grab the code to adapt it to your needs, but otherwise Drup’s pointers might be more useful.

thanks for all the pointers. the stacktrees do look similar to what i was imagining; the first link you gave seems to deal mainly with integer ranks, which is not exactly my use case.

Yeah I was thinking something else entirely at the time of writing, that didn’t sound right at all. I think I meant to say for a very specific case the algorithm could be simple, but didn’t mean to suggest it’d be easy in general.

And interesting project - I recall seeing it quite recently, I was thinking about replacing Dagre with it as well, but I was too busy to commit to that.