kopia lustrzana https://github.com/deathbeds/ipydrawio
296 wiersze
9.8 KiB
Plaintext
296 wiersze
9.8 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "nominated-efficiency",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Diagram Widget\n",
|
|
"\n",
|
|
"The same _renderer_ that powers the [Diagram Document](./Diagram%20Document.ipynb) can be used as a computable _Jupyter Widget_, which offers even more power than the [Diagram Rich Display](./Diagram%20Rich%20Display.ipynb)."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "b925a258-e3ab-4127-8537-f2efc9b0bd59",
|
|
"metadata": {
|
|
"tags": []
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"if __name__ == \"__main__\" and \"pyodide\" in __import__(\"sys\").modules:\n",
|
|
" %pip install -q ipydrawio-widgets"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "cathedral-schema",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from ipydrawio_widgets import Diagram\n",
|
|
"from ipywidgets import (\n",
|
|
" Accordion,\n",
|
|
" Checkbox,\n",
|
|
" FloatSlider,\n",
|
|
" HBox,\n",
|
|
" IntSlider,\n",
|
|
" SelectMultiple,\n",
|
|
" Text,\n",
|
|
" Textarea,\n",
|
|
" VBox,\n",
|
|
" jslink,\n",
|
|
")\n",
|
|
"from traitlets import dlink, link\n",
|
|
"\n",
|
|
"diagram = Diagram(layout={\"min_height\": \"80vh\", \"flex\": \"1\"})\n",
|
|
"box = HBox([diagram])\n",
|
|
"box"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "illegal-islam",
|
|
"metadata": {},
|
|
"source": [
|
|
"## value\n",
|
|
"\n",
|
|
"A `Diagram.source`'s `value` trait is the raw drawio XML. You can use one document for multiple diagrams.\n",
|
|
"\n",
|
|
"> [graphviz2drawio](https://pypi.org/project/graphviz2drawio) is recommended for getting to **give me some drawio XML from my data right now**. "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "printable-ridge",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"Diagram(source=diagram.source, layout={\"min_height\": \"400px\"})"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "behavioral-madonna",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"diagram.source.value = \"\"\"<mxfile version=\"13.6.10\">\n",
|
|
" <diagram id=\"x\" name=\"Page-1\">\n",
|
|
" <mxGraphModel dx=\"1164\" dy=\"293\" grid=\"1\" gridSize=\"10\" guides=\"1\" tooltips=\"1\" connect=\"1\" arrows=\"1\" fold=\"1\" page=\"1\" pageScale=\"1\" pageWidth=\"850\" pageHeight=\"1100\" math=\"0\" shadow=\"0\">\n",
|
|
" <root>\n",
|
|
" <mxCell id=\"0\"/>\n",
|
|
" <mxCell id=\"1\" parent=\"0\"/>\n",
|
|
" <mxCell id=\"2\" value=\"\" style=\"edgeStyle=entityRelationEdgeStyle;startArrow=none;endArrow=none;segment=10;curved=1;\" parent=\"1\" source=\"4\" target=\"5\" edge=\"1\">\n",
|
|
" <mxGeometry relative=\"1\" as=\"geometry\"/>\n",
|
|
" </mxCell>\n",
|
|
" <mxCell id=\"3\" value=\"\" style=\"edgeStyle=entityRelationEdgeStyle;startArrow=none;endArrow=none;segment=10;curved=1;\" parent=\"1\" source=\"4\" target=\"6\" edge=\"1\">\n",
|
|
" <mxGeometry relative=\"1\" as=\"geometry\">\n",
|
|
" <mxPoint x=\"260\" y=\"160\" as=\"sourcePoint\"/>\n",
|
|
" </mxGeometry>\n",
|
|
" </mxCell>\n",
|
|
" <UserObject label=\"The Big Idea\" treeRoot=\"1\" id=\"4\">\n",
|
|
" <mxCell style=\"ellipse;whiteSpace=wrap;html=1;align=center;collapsible=0;container=1;recursiveResize=0;\" parent=\"1\" vertex=\"1\">\n",
|
|
" <mxGeometry x=\"300\" y=\"140\" width=\"100\" height=\"40\" as=\"geometry\"/>\n",
|
|
" </mxCell>\n",
|
|
" </UserObject>\n",
|
|
" <mxCell id=\"5\" value=\"Branch\" style=\"whiteSpace=wrap;html=1;shape=partialRectangle;top=0;left=0;bottom=1;right=0;points=[[0,1],[1,1]];strokeColor=#000000;fillColor=none;align=center;verticalAlign=bottom;routingCenterY=0.5;snapToPoint=1;collapsible=0;container=1;recursiveResize=0;autosize=1;\" parent=\"1\" vertex=\"1\">\n",
|
|
" <mxGeometry x=\"460\" y=\"120\" width=\"80\" height=\"20\" as=\"geometry\"/>\n",
|
|
" </mxCell>\n",
|
|
" <mxCell id=\"6\" value=\"Sub Topic\" style=\"whiteSpace=wrap;html=1;rounded=1;arcSize=50;align=center;verticalAlign=middle;collapsible=0;container=1;recursiveResize=0;strokeWidth=1;autosize=1;spacing=4;\" parent=\"1\" vertex=\"1\">\n",
|
|
" <mxGeometry x=\"460\" y=\"160\" width=\"72\" height=\"26\" as=\"geometry\"/>\n",
|
|
" </mxCell>\n",
|
|
" </root>\n",
|
|
" </mxGraphModel>\n",
|
|
" </diagram>\n",
|
|
"</mxfile>\"\"\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "intimate-jamaica",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"value = Textarea(description=\"value\", rows=20)\n",
|
|
"controls = Accordion([value])\n",
|
|
"controls.set_title(0, \"value\")\n",
|
|
"jslink((diagram.source, \"value\"), (value, \"value\"))\n",
|
|
"box.children = [controls, diagram]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "understanding-notion",
|
|
"metadata": {},
|
|
"source": [
|
|
"There are a number of challenges in using it as a protocol:\n",
|
|
"- includes hostname (ick!)\n",
|
|
"- includes etag\n",
|
|
"- stripping these out creates flicker when updating\n",
|
|
"\n",
|
|
"At present, tools like jinja2, which work directly with XML, or `lxml`, which can work at a higher level, with e.g. XPath. \n",
|
|
"\n",
|
|
"> Stay tuned for better tools for working with this format with e.g. `networkx`"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "dominican-economics",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Interactive state\n",
|
|
"\n",
|
|
"A `Diagram` exposes a number of parts of both the content and interactive state of the editor."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "ready-reviewer",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"zoom = FloatSlider(description=\"zoom\", min=0.01)\n",
|
|
"scroll_x, scroll_y = (\n",
|
|
" FloatSlider(description=f\"scroll {x}\", min=-1e5, max=1e5) for x in \"xy\"\n",
|
|
")\n",
|
|
"current_page = IntSlider(description=\"page\")\n",
|
|
"jslink((diagram, \"zoom\"), (zoom, \"value\"))\n",
|
|
"jslink((diagram, \"scroll_x\"), (scroll_x, \"value\"))\n",
|
|
"jslink((diagram, \"scroll_y\"), (scroll_y, \"value\"))\n",
|
|
"jslink((diagram, \"current_page\"), (current_page, \"value\"))\n",
|
|
"\n",
|
|
"controls.children = [VBox([zoom, scroll_x, scroll_y, current_page]), value]\n",
|
|
"controls._titles = {\"0\": \"ui\", \"1\": \"value\"}"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "alleged-decimal",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"selected_cells = SelectMultiple(description=\"selected\")\n",
|
|
"\n",
|
|
"dlink((diagram, \"cell_ids\"), (selected_cells, \"options\"))\n",
|
|
"link((diagram, \"selected_cells\"), (selected_cells, \"value\"))\n",
|
|
"\n",
|
|
"controls.children = [\n",
|
|
" VBox([zoom, scroll_x, scroll_y, current_page]),\n",
|
|
" VBox([selected_cells]),\n",
|
|
" value,\n",
|
|
"]\n",
|
|
"controls._titles = {\"0\": \"ui\", \"1\": \"selection\", \"2\": \"value\"}\n",
|
|
"\n",
|
|
"HBox([selected_cells])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "sonic-airline",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Page Information\n",
|
|
"`Diagrams` actually describe a \"real thing\", measured in inches."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "cutting-closer",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"page_format = {\n",
|
|
" k: IntSlider(description=k, value=v, min=0, max=1e5)\n",
|
|
" for k, v in diagram.page_format.items()\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"def update_format(*_):\n",
|
|
" diagram.page_format = {k: v.value for k, v in page_format.items()}\n",
|
|
"\n",
|
|
"\n",
|
|
"def update_sliders(*_):\n",
|
|
" for k, v in page_format.items():\n",
|
|
" v.value = diagram.page_format[k]\n",
|
|
"\n",
|
|
"\n",
|
|
"[v.observe(update_format, \"value\") for k, v in page_format.items()]\n",
|
|
"[diagram.observe(update_sliders, \"page_format\")]\n",
|
|
"\n",
|
|
"\n",
|
|
"controls.children = [\n",
|
|
" VBox([zoom, scroll_x, scroll_y, current_page]),\n",
|
|
" VBox([selected_cells]),\n",
|
|
" VBox([*page_format.values()]),\n",
|
|
" value,\n",
|
|
"]\n",
|
|
"controls._titles = {\"0\": \"ui\", \"1\": \"selection\", \"2\": \"page\", \"3\": \"value\"}"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "numerical-truck",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Grid\n",
|
|
"\n",
|
|
"The styling of the on-screen grid is cutomizable. This typically _won't_ be included in export to e.g. SVG."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "simplified-spell",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"grid_enabled = Checkbox(description=\"grid\")\n",
|
|
"grid_size = FloatSlider(description=\"grid size\")\n",
|
|
"grid_color = Text(\"#66666666\", description=\"grid color\")\n",
|
|
"jslink((diagram, \"grid_enabled\"), (grid_enabled, \"value\"))\n",
|
|
"jslink((diagram, \"grid_size\"), (grid_size, \"value\"))\n",
|
|
"jslink((diagram, \"grid_color\"), (grid_color, \"value\"))\n",
|
|
"\n",
|
|
"controls.children = [\n",
|
|
" VBox([zoom, scroll_x, scroll_y, current_page]),\n",
|
|
" VBox([selected_cells]),\n",
|
|
" VBox([*page_format.values()]),\n",
|
|
" VBox([grid_enabled, grid_size, grid_color]),\n",
|
|
" value,\n",
|
|
"]\n",
|
|
"controls._titles = {\"0\": \"ui\", \"1\": \"selection\", \"2\": \"page\", \"3\": \"grid\", \"4\": \"value\"}"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3 (ipykernel)",
|
|
"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.11.3"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|