kopia lustrzana https://github.com/deathbeds/ipydrawio
295 wiersze
7.1 KiB
Plaintext
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
|
|
}
|