ipydrawio/notebooks/Computable Diagrams.ipynb

295 wiersze
7.1 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Computable Diagrams with `jupyterlab-drawio` \n",
"\n",
"> _ft. [drawio](https://github.com/jgraph/drawio/), [drawio-export](https://github.com/jgraph/draw-image-export2), [puppeteer](https://github.com/puppeteer/puppeteer), and a cast of thousands_\n",
"\n",
"| pull request | demo branch | binder demo | \n",
"|:--:|------|------|\n",
"| [#65][pr] | [@bollwyvl/jupyterlab-drawio][repo] | [![][badge]][binder] |\n",
"\n",
"[pr]: https://github.com/QuantStack/jupyterlab-drawio/pull/65\n",
"[repo]: https://github.com/bollwyvl/jupyterlab-drawio/tree/add-drawio-export\n",
"[badge]: https://mybinder.org/static/images/badge_logo.svg\n",
"[binder]: https://gke.mybinder.org/v2/gh/bollwyvl/jupyterlab-drawio/add-drawio-export?urlpath=lab/tree/Computable+Diagrams.ipynb"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In addition to the live editing experience (see [how it works](./testfiles/How%20it%20works.dio)), the drawio XML format can be created by other tools. Output formats, e.g. SVG, can also be used by different tools."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Before we begin\n",
"\n",
"Start the export server. It will try to install its dependencies, and requires `nodejs`.\n",
"```bash\n",
"!python scripts/drawio_export_demo.py\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import pathlib as P\n",
"\n",
"import IPython.display as D\n",
"import jinja2\n",
"import networkx as nx\n",
"import requests\n",
"from graphviz2drawio import graphviz2drawio"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Load a drawio XML file"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"dio = next(P.Path().glob(\"testfiles/How it works.dio\"))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"### it's really not very pretty"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Make the request params\n",
"\n",
"`drawio-export` partially documents the list of [URL request parameters](https://github.com/jgraph/draw-image-export2#common-parameters) which it accepts. For example, it mentions visible layers... without defining the format. It may be the same as the message format, mostly captured in the [editor widget](./src/editor.ts)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"default_params = {\n",
" \"format\": \"pdf\",\n",
" \"xml\": dio.read_text(),\n",
" \"allPages\": \"1\",\n",
" \"base64\": \"1\",\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Make a request\n",
"\n",
"Happily, the output appears to be stable given the same input. Hooray!"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def get_pdf(**params):\n",
" final_params = dict(default_params)\n",
" final_params.update(params)\n",
" res = requests.post(\"http://localhost:8000\", final_params)\n",
" return res.text"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def show_pdf(**params):\n",
" pdf_text = get_pdf(**params)\n",
" return D.HTML(\n",
" f\"\"\"\n",
" <iframe src=\"data:application/pdf;base64,{pdf_text}\" width=\"100%\" height=\"600px\"></iframe>\n",
" \"\"\",\n",
" )\n",
"\n",
"\n",
"show_pdf()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Generating drawio XML\n",
"\n",
"The only thing I've found that can generate drawio is [graphviz2drawio](https://github.com/hbmartin/graphviz2drawio). So `.dot` it is!\n",
"\n",
"> _...see also: [jupyterlab_graphviz](https://www.npmjs.com/package/@deathbeds/jupyterlab_graphviz)_"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"some_dot = \"\"\"\n",
" digraph g {\n",
" dot -> graphviz -> {svg png};\n",
" {drawioxml svg png} -> drawio -> {svg png html drawioxml};\n",
" inkscape -> {svg png};\n",
" {svg pdf} -> inkscape;\n",
" svg -> drawioxml;\n",
" drawio_export[label=\"drawio-export\"];\n",
" {drawioxml} -> drawio_export -> {pdf png};\n",
" }\n",
"\"\"\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def show_pdf_from_dot(dot=some_dot, **params):\n",
" return show_pdf(xml=graphviz2drawio.convert(dot), **params)\n",
"\n",
"\n",
"show_pdf_from_dot()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Things that speak `dot`"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## networkx"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a_graph = nx.drawing.nx_agraph.to_agraph(nx.generators.atlas.graph_atlas(42))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def show_pdf_from_networkx(graph=a_graph, **params):\n",
" return show_pdf_from_dot(str(graph))\n",
"\n",
"\n",
"show_pdf_from_networkx()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Jinja\n",
"`dot` is a simple, mostly-forgiving language."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"tmpl = jinja2.Template(\n",
" \"\"\"\n",
"graph g {\n",
" layout=circo\n",
" {% for i in range(n) %}\n",
" node_{{i}};\n",
" {% endfor %}\n",
" {% for i in range(n) %}\n",
" node_{{i}} -- {\n",
" node_{{ i % (n // m) }};\n",
" {% if i %}\n",
" node_{{ i - 1 }}\n",
" {% endif %}\n",
" }\n",
" {% endfor %}\n",
"}\n",
"\"\"\",\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"show_pdf_from_dot(tmpl.render(n=20, m=7))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}