deathbeds / ipydrawio

A standalone embedding of the FOSS drawio / mxgraph package into jupyterlab
https://ipydrawio.rtfd.io
Apache License 2.0
51 stars 4 forks source link

Better programmatic drawio XML generation #19

Open bollwyvl opened 3 years ago

bollwyvl commented 3 years ago

Elevator Pitch

Improve programmable creation of mxgraph XML in python.

Motivation

The current demos of generating drawio XML generally use string templating, or are fragile on non-linux platforms due to some under-packaged/hard-to-compile dependencies.

conda-forge now has (presumably) working builds of recent graphviz for windows, and pygraphviz should be coming along soon. This, and a few minor dependencies, are some of the last remaining only-feasible-to-test-on-linux packages used in binder to support graphviz2drawio, which is pretty much the only python-based library out there for generating mxgraph XML.

Through raw .dot, networkx, or pygraphviz directly, this would substantially improve the experience of building (or at least starting) diagrams.

Design Ideas

bollwyvl commented 3 years ago

A relatively quick win here would be an nbconvert exporter that could turn an .ipynb into .dio (or in-place, adding .dio.ipynb).

It's worth exploring:

hbmartin commented 1 month ago

Hello, graphviz2drawio author here! This is a fantastic project and I'd be happy to help directly support this effort. Let me know what you had in mind for further integration and I can take a look at it? Also open to discussing re-licensing.

bollwyvl commented 1 month ago

This repo has suffering in just keeping the lights vs upstreams (jupyterlab, ipywidgets, and drawio), I suppose, so it's difficult to think of what, precisely, I'd had in mind here vs graphviz2drawio beyond do useful things with .dot, which would basically already work over well-known file exchanges.

An initial naive pattern might documentation-only, wrapping the main function of the library in the traitlets observer pattern:

from ipywidgets import Wiget
from traitlets import Unicode

class IPyGraphviz2Drawio(Widget):
    dot = Unicode()
    mdxml = Unicode()

    @observe("dot")
    def _on_dot(self, change):
      self.mdmxl = graphvis2drawio.convert(change.new)

This would be relatively robust over time, so long as that public API didn't change. Indeed, to that point, having proper PEP484 types (and a py.typed file in the distribution) would help for keeping track of changes, if many things will be changing in upcoming releases.

Any deeper integration (e.g. modeling the actual tree in any meaningful way) would expose a lot of potential integration risks further down the line. But indeed, I could imagine an MxGraph that had observable children with properties being fairly interesting.

Additionally, at the interactive timescale, roundtrip speed becomes more relevant. It may be desirable to have an driver pattern, which would use/prefer lxml over stdlib python for parsing/manipulating XML, if available.