当前位置:首页 > draw.io教程

draw.io 嵌入简易教程

drawio6年前 (2020-05-01)draw.io教程10

您可以将 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=1 URL 参数指示 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 提供的图表绘制功能来编辑和更改这些数据。