draw.io 嵌入简易教程
您可以将 draw.io 作为应用程序嵌入到另一个应用程序中,并将图表数据存储在宿主应用程序中。运行一个基本示例大约需要 15 分钟。
我们以Stack Overflow 上的一个示例页面为模板,创建了一个略作修改的问题版本。双击图表即可在新窗口中打开 draw.io 在线编辑器,对图表进行一些编辑,然后单击“保存”将修改后的图表保存回页面。
您可以重复此过程,稍后继续编辑图表。让我们来看看这个过程的流程以及页面中实现此功能的代码。如果您查看页面源代码,您会在第 1695 行看到:
<img class="drawio" style="cursor:default;" src="data:image/png;base64,iVBORw0KGgoAAAANSUhE....
图片本身以base64 编码的 dataURI形式放置在页面中。这样做是因为本示例中没有实际的后端(刷新页面后更改会丢失),我们没有地方可以写入图片以使其持久化。
图表数据本身嵌入在 PNG 文件的压缩文本部分中。双击图像后,我们会打开一个新窗口,并在该窗口中以嵌入模式加载 draw.io:
<script>
// Edits an image with drawio class on double click
document.addEventListener('dblclick', function(evt)
{
var url = 'https://embed.diagrams.net/?embed=1&ui=atlas&spin=1&modified=unsavedChanges&proto=json';
var source = evt.srcElement || evt.target;
if (source.nodeName == 'IMG' && source.className == 'drawio')
{
if (source.drawIoWindow == null || source.drawIoWindow.closed)
{
// Implements protocol for loading and exporting with embedded XML
var receive = function(evt)
{
if (evt.data.length > 0 && evt.source == source.drawIoWindow)
{
var msg = JSON.parse(evt.data);
// Received if the editor is ready
if (msg.event == 'init')
{
// Sends the data URI with embedded XML to editor
source.drawIoWindow.postMessage(JSON.stringify
{action: 'load', xmlpng: source.getAttribute('src')}), '*');
}
// Received if the user clicks save
else if (msg.event == 'save')
{
// Sends a request to export the diagram as XML with embedded PNG
source.drawIoWindow.postMessage(JSON.stringify(
{action: 'export', format: 'xmlpng', spinKey: 'saving'}), '*');
}
// Received if the export request was processed
else if (msg.event == 'export')
{
// Updates the data URI of the image
source.setAttribute('src', msg.data);
}
// Received if the user clicks exit or after export
if (msg.event == 'exit' || msg.event == 'export')
{
// Closes the editor
window.removeEventListener('message', receive);
source.drawIoWindow.close();
source.drawIoWindow = null;
}
}
};
// Opens the editor
window.addEventListener('message', receive);
source.drawIoWindow = window.open(url);
}
else
{
// Shows existing editor window
source.drawIoWindow.focus();
}
}
});</script>embed=1URL 参数指示 draw.io 以嵌入式模式运行。protocol=json这意味着我们正在使用 JSON 协议进行消息传递。目前请始终使用此模式。postMessage然后用于传递图表数据。
请注意,您可以将图表在 iFrame 中打开,而不是在新窗口中打开,这样可能会使流程对用户来说更加清晰。
在这种情况下,请在函数开头创建一个 iFrame:
var iframe = document.createElement('iframe');iframe.setAttribute('frameborder', '0');var close = function(){
window.removeEventListener('message', receive);
document.body.removeChild(iframe);};在函数末尾,开始监听消息之后,将 iFrame 添加到窗口中:
window.addEventListener('message', receive);iframe.setAttribute('src', editor);document.body.appendChild(iframe);您可能还希望通过 CSS 使 iFrame 完全覆盖初始页面:
iframe {
border:0;
position:fixed;
top:0;
left:0;
right:0;
bottom:0;
width:100%;
height:100%
}当 draw.io 编辑器在新窗口/iFrame 中加载时,它只是一个静态应用程序,没有任何数据。我们使用消息传递协议,在收到 draw.io 发送的“init”消息(表明它已准备就绪)后,将数据加载到 draw.io 中。
在编辑器中编辑图表,完成后点击“保存”。保存后发送的附加消息用于提供更精细的格式请求,在本例中,请求导出为 PNG+XML 格式。在我们的示例中,导出完成后编辑器会自动退出,但您也可以保持编辑器打开状态,等待用户显式退出后再将其关闭。
嵌入 XML 的 PNG 以 base64 dataURI 的形式保存到src图像属性的顶部,这样页面就会更新为新图像。
最后,区分静态的 draw.io 应用和嵌入式模式下的数据流至关重要。我们的在线编辑器以静态应用的形式加载在 draw.io 窗口中,但图表数据完全在客户端窗口之间传递,绝不会发送回 draw.io 应用服务器,也不会从 draw.io 应用服务器获取数据。这意味着您可以完全控制和存储数据,并且仅使用 draw.io 提供的图表绘制功能来编辑和更改这些数据。

