Do you have code to do this already, @anon72795300, or is it an idea at present? If you have the code, even in a bad state, you could release it and perhaps some of the rest of us could try documenting it and cleaning it with your help.
This works already. Or atleast it did with the version I worked with. It has been in proprietary code used industrially. There s a test file in the repo which can also serve as an example. Will post a link tomorrow.
My idea was to spin this off and have even been tempted about a pure Ocaml + QML library.
Is it possible to open source just the Qt/QtQuick/QML portions?
If you are talking about the bindings then yes, they are here:
https://github.com/Kakadu/lablqml/blob/master/lib/lablqml.ml
https://github.com/Kakadu/lablqml/blob/master/lib/stubs/object_ml.cpp
The test files I mentioned:
https://github.com/Kakadu/lablqml/blob/master/lib/src_tests/test3.ml
https://github.com/Kakadu/lablqml/blob/master/lib/src_tests/test3.qml
Iâve started a stand alone library too, but havenât pushed it yet.
Ah, @anon72795300 , I didnât understand that you had contributed to the lablqml work. It is shared between you and @Kakadu ?
Thereâs also this:
that lets you run the vizualisation in your browser.
I developed and contributed the binding method I mentioned above. I think I helped a bit along the way of tidying up the repo. Is that what you meant to know?
Yes, thatâs more or less what I wanted to know.
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
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.
Cheers,
Darren
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âŚ
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.
Hi,
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!