Giter Club home page Giter Club logo

drawio-embed's Introduction

Welcome to drawio-embed

Version

embed drawio into your website

简介

傻瓜式地在你的网页中嵌入流程图。在一键植入后,开发者只需关心:

  1. 在需要的时候,调用命令唤起 drawio 流程图来编辑
  2. 监听编辑完成后返回的图片数据

快速开始

开箱即用,只需 3 步

import drawioEmbed from "drawio-embed";

// 初始化
const openDrawio = drawioEmbed();

// 监听返回的图片数据
window.addEventListener("drawioImageCreated", evt => {
  const { imageContent, imageType } = evt;
});

// 在需要时打开 drawio 开始编辑
openDrawio();

使用 UMD 方式引入

<script
  defer
  src="https://imaoda.github.io/drawio-embed/umd/drawio-embed.min.js"
  onload="window.openDrawio = drawioEmbed()"
></script>

默认调用 drawio 官网的流程图,服务器在海外,初次访问较慢 (不过初次加载后会建立 service worker 缓存)。当然,有条件的还是可以自己部署一套,部署十分方便,只需 2 步,完成静态资源托管

DIY

黏贴下面代码到本地并用浏览器打开即可,或查看 Demo

<!DOCTYPE html>
<html>
  <body>
    <button onclick="openDrawio()">
      打开编辑 (实际使用时,需判断 drawio 是否初始化好)
    </button>
    <div>png图:</div>
    <img id="png" src="" />
    <div>svg图:<small>(不失真,但需考虑安全性兼容性)</small></div>
    <div id="svg"></div>
  </body>
  <script
    src="https://imaoda.github.io/drawio-embed/umd/drawio-embed.min.js"
    onload="openDrawio = drawioEmbed()"
  ></script>
  <script>
    const pngDom = document.querySelector("#png");
    const svgDom = document.querySelector("#svg");

    // 监听返回的图片
    window.addEventListener(
      "drawioImageCreated",
      ({ imageType, imageContent }) => {
        if (imageType === "png") pngDom.src = imageContent;
        if (imageType === "svg") svgDom.innerHTML = imageContent;
      }
    );
  </script>
</html>

效果如下图:

部署自己的 drawio

默认调用 drawio 官网的流程图,初次访问较慢 (不过初次加载后会建立 service worker 缓存)。当然,如果追求速度和安全性,我们也可以自己部署一套,部署十分方便,只需 2 步,完成静态资源托管

  1. git clone https://github.com/jgraph/drawio
  2. 静态资源托管 src/main/webapp 路径

在初始化的时候,更改配置,指向自己部署的 drawio

const openDrawio = drawioEmbed(yourWebsiteUrl);

Documentation

初始化

import drawioEmbed from "drawio-embed";
const openDrawio = drawioEmbed();

执行 drawioEmbed() 将在你的页面中,插入一个 iframe,iframe 加载流程图,并挪动到可视区域之外

首次初始化之后,再次重复执行 drawioEmbed() 不会再初始化,但依然会返回 openDrawio 的引用

打开流程图编辑器

在页面中,通过初始化时的函数,来唤起 drawio 页面

import drawioEmbed from "drawio-embed";
const openDrawio = drawioEmbed();

// 在特定的时机,打开流程图
button.onclick = () => openDrawio();

此时 drawio 的 iframe 会全屏覆盖你的窗口。

打开流程图编辑器,同时加载一个现有的流程图资源

如果需要打开一个已有的 svg 图片,比如继续编辑上次的内容,可以:

  1. 传递一个 svg 文本
  2. 传递一个网络地址
openDrawio("https://xxx.com/1.svg");
openDrawio("<svg>...</svg>");

注:这里的 svg 图片须为通过本项目导出的 svg,而非任意 svg。 如果需要使用网络地址,则需要同域,或者允许跨域

尝试打开一个尚未加载好的编辑器

编辑器初始化需要一定的时间,如果过早的调用 openDrawio() 打开,可能实际无法打开,原因有:

  1. 流程图的网络资源还在加载
  2. 流程图的内部初始化尚未结束

返回的 Promise 会进入 reject 态,我们借此提醒用户

opneDrawio().catch(() => {
  console.log("编辑器还在初始化中,请稍后再打开...");
});

另外,如果需要精细控制,可以:

  1. 监听 drawioLoaded 事件,该事件只会触发一次,表明流程图编辑器已经 ready
  2. openDrawio.isLoaded() 判断流程图编辑器是否已经加载好

获取流程图编辑器导出的图片

在 drawio 编辑界面,点击右上角的「保存」按钮,可将编辑的流程图导出,同时会默认自动关闭编辑器窗口

如果不想点保存自动关闭,可在流程图 url 上加上 hold=1 的 query

  1. window 绑定监听 drawioImageCreated 事件
  2. 在触发事件时,提取其中的数据
window.addEventListener("drawioImageCreated", evt => {
  const { imageType, imageContent } = evt;
  switch (imageType) {
    case "png":
      console.log("base64 格式的 png 图片信息", imageContent);
      break;
    case "svg":
      console.log("svg 标签文本", imageContent); // <svg>...</svg>
      break;
  }
});

一次用户保存,会在两个 eventLoop 里派发出两个 drawioImageCreated 事件,通过 imageType 来区分类别

  1. 导出 PNG
  2. 导出 SVG

开发者可根据实际需求,选择性监听

关闭流程图编辑器

通常,用户在编辑时,如果点击了「保存」或者「取消」按钮,会自动关闭编辑器。当然我们也可以主动控制其关闭

openDrawio.close();

TypeScript

drawio-embed include Typescript definitions

import drawioEmbed from "drawio-embed";
const openDrawio = drawioEmbed();
openDrawio.close();

浅析原理

tips: 下文的配图由 drawio 流程图绘制完成

嵌入方案

drawio 流程图在初始化后以 iframe 的形式嵌入,仿佛是一个附属的应用程序,有两个状态:

  1. 隐藏:iframe 在视野不可见
  2. 显示:iframe 在视野可见,并且绝对定位置于页面顶部

页面与流程图的通信

页面和流程图是父子 frame 的关系,因此采用 postMessage 进行双向通信。postMessage 仅支持字符串,因此复杂的数据结构通过 JSON 来序列化/反序列化,我们在协议里约定了协议名和协议体

基础的通信的协议有:

协议名 含义 来源方
init 流程图加载完 流程图
save 用户点击了保存键 流程图
exit 用户点击了取消键 流程图
export 有图片数据导出 流程图
load 请求加载图片 父页面
export 请求导出图片 父页面
spinner 显示/隐藏 loading 父页面

基于协议,可以「桥接」两个进程,虽然能实现通信,但对开发者来说,维护起来代码量会增加不少。 drawio-embed 在这里充当了通信的代理者,让整个流程变得更简化,只需关注结果。除此之外,drawio-embed 还做了一个事情,实现了协议和流程图的生命周期的一致性,因此开发者无需根据协议同时去关注数据和 UI 的变更。

流程图的生命周期

本环节揭示了流程图创建、显示、隐藏、输入、输出的过程

主要涵盖以下的过程:

  1. 父页面初始加载,并隐藏
  2. 监听 load 事件自动打开流程图
  3. 监听 save/exit 事件自动隐藏流程图
  4. 监听 export 事件,合成新的 Event,发送给父页面
  5. 维护流程图的开启/关闭状态

巧妙地组装 svg

drawio-embed 最具有特色的地方,在于构建出一个组装的 svg,它的优势在于:

  1. 像一个普通的 svg 图片一样被各种预览工具打开,如 chrome、微信 webview
  2. 能携带 mxfile 编辑数据,在 drawio 中恢复编辑

drawio-embed 导出的 svg 数据能够兼顾展示和恢复编辑的需求,无需开发者自行关联。

对于导出的 svg 数据,只需 openDrawio(svg) 即可打开流程图编辑器,恢复编辑,支持网络地址或本地资源,对于网络地址,会先 fetch 到内容再导入到流程图里

Author

👤 wangyongfeng

Show your support

Give a ⭐️ if this project helped you!

drawio-embed's People

Contributors

imaoda avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

drawio-embed's Issues

导出格式

这个导出的文件格式可以修改吗 比如.io

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.