├── .github └── workflows │ └── CI.yml ├── .gitignore ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── public ├── favicon.ico └── index.html ├── src ├── App.vue ├── assets │ ├── images │ │ └── home.png │ └── logo.png ├── components │ ├── editor.vue │ ├── imageLoad.vue │ ├── info.vue │ ├── node.vue │ ├── node_detail.vue │ ├── node_form.vue │ ├── node_menu.vue │ ├── uploadData.vue │ └── utils.js ├── data │ ├── data_A.js │ ├── data_A.json │ ├── data_B.js │ ├── data_B.json │ ├── data_B.yaml │ ├── data_C.js │ ├── data_C.json │ ├── data_D.js │ ├── data_D.json │ └── detail_data.js ├── main.js ├── style │ ├── iconfont.css │ └── index.css └── utils │ ├── canvg.js │ └── jsplumb.js └── vue.config.js /.github/workflows/CI.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: CI 4 | 5 | # Controls when the workflow will run 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the V1.0-beat branch 8 | push: 9 | branches: [ master ] 10 | pull_request: 11 | branches: [ master ] 12 | 13 | # Allows you to run this workflow manually from the Actions tab 14 | workflow_dispatch: 15 | 16 | # jobs 表示要执行的一项或者多项任务 17 | jobs: 18 | # 任务名,可自定义 19 | build-and-deploy: 20 | # runs-on字段指定运行所需要的虚拟机环境。它是必填字段。目前可用的虚拟机如下。 21 | runs-on: ubuntu-latest 22 | # steps表示执行步骤 23 | steps: 24 | # 检出代码,这里用了 actions/checkout@master 库来完成 25 | - name: Checkout 26 | uses: actions/checkout@master 27 | # 这里展示了如何执行多条命令 28 | - name: Install and Build 29 | run: | 30 | yarn 31 | yarn build 32 | # 这里引用了别人写好的发布库,具体参数信息可以查阅上面的链接 33 | - name: Deploy to GitHub Pages 34 | uses: JamesIves/github-pages-deploy-action@4.0.0 35 | with: 36 | branch: gh-pages 37 | folder: dist 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | pnpm-debug.log* 14 | 15 | # Editor directories and files 16 | .idea 17 | .vscode 18 | *.suo 19 | *.ntvs* 20 | *.njsproj 21 | *.sln 22 | *.sw? 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Easy editor 2 | 3 | ## 项目介绍 4 | 5 | `Easy Editor` 是基于 VUE+ElementUI+JsPlumb 的拓扑编辑器,通过该编辑器你可以实现拓扑图绘制,拓扑图的修改等功能 6 | 7 | **节点拖拽功能实现流程** 8 | 9 | 通过 vuedraggable 插件来实现左侧菜单的拖拽,拖拽结束后回调 end 方法,根据鼠标所在的位置添加一个节点信息,使用 jsplumb 来管理该节点,设置该节点可拖拽、连线 并注册相关的事件。 10 | 11 | ## 效果图 12 | 13 | ![https://gitee.com/save_money/Easy-Editor/raw/master/src/assets/images/home.png](https://gitee.com/save_money/Easy-Editor/raw/master/src/assets/images/home.png) 14 | 15 | ## 功能 16 | 17 | - 支持拖拽添加节点 18 | - 鼠标移入到节点中显示 编辑、删除 操作 19 | - 鼠标单击线可进行设置条件,双击可进行连线删除 20 | - 支持预设的流程图案例切换展示 21 | - 支持画布拖拽,控制画布网格背景 22 | - 支持放大缩小 23 | - 支持一键生成流程图图片 24 | - 支持数据文件导入(目前只支持yaml文件和json文件) 25 | - 支持显示节点内部详情 26 | - 支持节点间回环连接,但不支持节点线连接自己 27 | 28 | ## 操作说明 29 | 30 | - 左侧菜单子节点可以拖拽,将其拖拽到右侧画板中松开鼠标即可添加一个节点 31 | - 鼠标点击画板中的节点上,画布右侧出现可编辑的节点详情表单,上方工具栏删除按钮功能开启,点击对应的图标可进行删除、编辑操作 32 | - 节点分为 3 部分,节点图标在左侧,文字在中间,状态图标在右侧,鼠标从节点图标上可以拖拽出连线,可以连接其他节点,拖动图标意外位置可以改变节点在页面的位置 33 | 34 | ## 使用说明 35 | 36 | - 【自定义节点】:左侧的节点名称以及图标可以自定义,在 node_menu.vue 页面 menuList 变量中 37 | - 【节点添加】:左侧的菜单栏展开时,子节点可以拖拽到右侧画布中即可添加 38 | - 【节点修改】:鼠标移动到画布中节点上,画布右侧显示用户【修改】节点的表单 39 | - 【连线添加】:将鼠标从画布节点的左侧图标上拖动时可以拖拽出连线,然后将鼠标移动到其他节点上即可连接 40 | - 【连线删除】:双击画布中节点之间的连线,可以进行连线删除 41 | 42 | ## 流程图数据格式 43 | 44 | ```json 45 | { 46 | "name": "流程C", 47 | "nodeList": [ 48 | { 49 | "id": "nodeA", 50 | "name": "流程B-节点A", 51 | "type": "task", 52 | "left": "18px", 53 | "top": "223px", 54 | "ico": "el-icon-user-solid", 55 | "state": "success" 56 | }, 57 | { 58 | "id": "nodeB", 59 | "type": "task", 60 | "name": "流程B-节点B", 61 | "left": "351px", 62 | "top": "96px", 63 | "ico": "el-icon-goods", 64 | "state": "error" 65 | }, 66 | { 67 | "id": "nodeC", 68 | "name": "流程B-节点C", 69 | "type": "task", 70 | "left": "354px", 71 | "top": "351px", 72 | "ico": "el-icon-present", 73 | "state": "warning" 74 | }, 75 | { 76 | "id": "nodeD", 77 | "name": "流程B-节点D", 78 | "type": "task", 79 | "left": "723px", 80 | "top": "215px", 81 | "ico": "el-icon-present", 82 | "state": "running" 83 | } 84 | ], 85 | "lineList": [ 86 | { 87 | "from": "nodeA", 88 | "to": "nodeB", 89 | "label": "条件AB", 90 | "connector": "Bezier", 91 | "paintStyle": { "strokeWidth": 2, "stroke": "#1879FF" } 92 | }, 93 | { 94 | "from": "nodeB", 95 | "to": "nodeC", 96 | "label": "条件B" 97 | "connector": "Bezier", 98 | "paintStyle": { "strokeWidth": 2, "stroke": "#1879FF" } 99 | } 100 | ] 101 | } 102 | ``` 103 | 104 | ### data 参数说明 105 | 106 | | 参数 | 描述 | 107 | | :--: | :--------: | 108 | | name | 流程图名称 | 109 | 110 | ### nodeList 参数说明 111 | 112 | | 参数 | 描述 | 可选值 | 113 | | :---: | :-------------------: | :------------------------------: | 114 | | id | 标识唯一的节点 | | 115 | | name | 节点名称 | | 116 | | type | 节点类型 | | 117 | | left | 节点在页面上的 X 坐标 | | 118 | | top | 节点在页面上的 Y 坐标 | | 119 | | ico | 节点显示的图标 | element上的icon名 | 120 | | state | 节点状态 | success、error、warning、running | 121 | 122 | ### lineList 参数说明 123 | 124 | | 参数 | 描述 | 可选值 | 125 | | :--------: | :-----------------: | :----------------------------------------------------------: | 126 | | from | 连线的起始节点的 ID | | 127 | | to | 连线的终点节点 ID | | 128 | | label | 连线说明 | | 129 | | connector | 连线风格 | StateMachine、Flowchart,Bezier、Straight(默认为Flowchart) | 130 | | paintStyle | 连线样式 | 如:{ "strokeWidth": 2, "stroke": "#1879FF" } strokeWidth为连线宽度,stroke为连线颜色 | 131 | 132 | ## **自定义节点列表数据格式** 133 | 134 | 自定义的节点列表数据写在node_menu.vue文件中的menuList变量中 135 | 136 | ```js 137 | menuList: [ 138 | { 139 | id: "1", 140 | type: "group", 141 | name: "接口节点", 142 | ico: "el-icon-video-play", 143 | children: [ 144 | { 145 | id: "11", 146 | level: "1-1", 147 | type: "task1", 148 | name: "数据接入", 149 | ico: "el-icon-time", 150 | state: "success", 151 | // 自定义覆盖样式 152 | style: { 153 | "backgroundColor": "red" 154 | } 155 | }, { 156 | id: "12", 157 | level: "1-2", 158 | type: "task2", 159 | name: "接口调用", 160 | ico: "el-icon-odometer", 161 | state: "success", 162 | // 自定义覆盖样式 163 | style: {} 164 | } 165 | ] 166 | }, 167 | { 168 | id: "2", 169 | type: "group", 170 | name: "工具节点", 171 | ico: "el-icon-video-pause", 172 | children: [ 173 | { 174 | id: "21", 175 | level: "2-1", 176 | type: "end", 177 | name: "流程结束", 178 | ico: "el-icon-caret-right", 179 | state: "success", 180 | // 自定义覆盖样式 181 | style: {} 182 | }, { 183 | id: "22", 184 | level: "2-2", 185 | type: "over", 186 | name: "数据重置", 187 | ico: "el-icon-shopping-cart-full", 188 | state: "success", 189 | // 自定义覆盖样式 190 | style: {} 191 | } 192 | ] 193 | } 194 | ] 195 | ``` 196 | 197 | ### menuList参数说明 198 | 199 | | 参数 | 描述 | 可选值 | 200 | | :------: | :------------------: | :------------------------------------: | 201 | | id | 节点分组的id名 | | 202 | | type | 类别 | group | 203 | | name | 节点分组的名称 | | 204 | | ico | 节点分组的图标 | element-ui中的icon名或iconfont上的名称 | 205 | | children | 节点分组下的所有节点 | | 206 | 207 | ### children参数说明 208 | 209 | | 参数 | 描述 | 可选值 | 210 | | :---: | :------------: | :----------------------------------------------------: | 211 | | id | 节点分组的id名 | | 212 | | level | 节点层级 | | 213 | | type | 节点类别 | 注意:这里的type值需要是唯一的,否则无法正常新增节点元素 | 214 | | name | 节点分组的图标 | element-ui中的icon名或iconfont上的名称 | 215 | | state | 节点状态 | success、error、warning、running | 216 | | style | 自定义覆盖样式 | | 217 | 218 | ## 使用方式: 219 | 220 | #### 一、以独立项目使用 221 | 222 | ```bash 223 | # 下载工程 224 | git clone https://gitee.com/save_money/Easy-Editor.git 225 | 226 | # 安装依赖包 227 | npm install 228 | 229 | # 启动 230 | npm run dev 231 | 232 | # 访问地址 233 | http://localhost:8080 234 | ``` 235 | 236 | ##### 237 | 238 | ## Gitee 239 | 240 | 241 | 242 | 243 | 244 | ## 参考资料 245 | 246 | | 名称 | 地址 | 说明 | 247 | | --------------- | ------------------------------------------------------------ | ------------ | 248 | | jsplumb | | 官网API文档 | 249 | | vue-codemirror | | 代码编辑器 | 250 | | vuedraggable | <> | 节点拖拽 | 251 | | vue-json-viewer | | json数据查看 | 252 | | domtoimage | | web截图工具 | 253 | | js-yaml | | yaml数据转换 | 254 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Easyeditor", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "cache-loader": "^4.1.0", 12 | "canvg": "^3.0.6", 13 | "core-js": "^3.6.5", 14 | "dom-to-image": "^2.6.0", 15 | "element-ui": "^2.13.2", 16 | "html2canvas": "^1.0.0-rc.5", 17 | "jquery": "^3.5.1", 18 | "js-yaml": "^3.14.0", 19 | "jsplumb": "^2.13.2", 20 | "less": "^3.11.3", 21 | "less-loader": "^6.1.0", 22 | "loadsh": "0.0.4", 23 | "vue": "^2.6.11", 24 | "vue-codemirror": "^4.0.6", 25 | "vue-json-viewer": "^2.2.12", 26 | "vuedraggable": "^2.23.2" 27 | }, 28 | "devDependencies": { 29 | "@vue/cli-plugin-babel": "~4.4.0", 30 | "@vue/cli-plugin-eslint": "~4.4.0", 31 | "@vue/cli-service": "~4.4.0", 32 | "babel-eslint": "^10.1.0", 33 | "eslint": "^6.7.2", 34 | "eslint-plugin-vue": "^6.2.2", 35 | "vue-template-compiler": "^2.6.11" 36 | }, 37 | "eslintConfig": { 38 | "root": true, 39 | "env": { 40 | "node": true 41 | }, 42 | "extends": [ 43 | "plugin:vue/essential", 44 | "eslint:recommended" 45 | ], 46 | "parserOptions": { 47 | "parser": "babel-eslint" 48 | }, 49 | "rules": {} 50 | }, 51 | "browserslist": [ 52 | "> 1%", 53 | "last 2 versions", 54 | "not dead" 55 | ] 56 | } 57 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jason-chen-coder/JsPlumb-EasyFlowEditor/620a93f0c77cf7eb438f3bb2bfc0f7ea653557cf/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Easy editor 12 | 13 | 14 | 15 | 19 |
20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | -------------------------------------------------------------------------------- /src/assets/images/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jason-chen-coder/JsPlumb-EasyFlowEditor/620a93f0c77cf7eb438f3bb2bfc0f7ea653557cf/src/assets/images/home.png -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jason-chen-coder/JsPlumb-EasyFlowEditor/620a93f0c77cf7eb438f3bb2bfc0f7ea653557cf/src/assets/logo.png -------------------------------------------------------------------------------- /src/components/editor.vue: -------------------------------------------------------------------------------- 1 | 148 | 149 | 836 | -------------------------------------------------------------------------------- /src/components/imageLoad.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 54 | -------------------------------------------------------------------------------- /src/components/info.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 54 | -------------------------------------------------------------------------------- /src/components/node.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 82 | -------------------------------------------------------------------------------- /src/components/node_detail.vue: -------------------------------------------------------------------------------- 1 | 29 | 54 | -------------------------------------------------------------------------------- /src/components/node_form.vue: -------------------------------------------------------------------------------- 1 | 59 | 60 | 161 | 162 | 199 | -------------------------------------------------------------------------------- /src/components/node_menu.vue: -------------------------------------------------------------------------------- 1 | 52 | 247 | -------------------------------------------------------------------------------- /src/components/uploadData.vue: -------------------------------------------------------------------------------- 1 | 39 | 129 | -------------------------------------------------------------------------------- /src/components/utils.js: -------------------------------------------------------------------------------- 1 | // 是否具有该线 2 | export function hasLine (data, from, to) { 3 | for (let i = 0; i < data.lineList.length; i++) { 4 | let line = data.lineList[i] 5 | if (line.from === from && line.to === to) { 6 | return true 7 | } 8 | } 9 | return false 10 | } 11 | 12 | // 是否含有相反的线 13 | export function hashOppositeLine (data, from, to) { 14 | return hasLine(data, to, from) 15 | } 16 | 17 | // 获取连线 18 | export function getConnector (jsp, from, to) { 19 | let connection = jsp.getConnections({ 20 | source: from, 21 | target: to 22 | })[0] 23 | return connection 24 | } 25 | 26 | // 获取唯一标识 27 | export function uuid () { 28 | return Math.random().toString(36).substr(3, 10) 29 | } -------------------------------------------------------------------------------- /src/data/data_A.js: -------------------------------------------------------------------------------- 1 | 2 | export var data_A = { 3 | "name": "流程A", 4 | "nodeList": [ 5 | { 6 | "id": "nodeA", 7 | "name": "流程A-节点A", 8 | "type": "task", 9 | "left": "26px", 10 | "top": "161px", 11 | "ico": "icon-daqilitiguancex iconfont", 12 | "state": "warning" 13 | }, 14 | { 15 | "id": "nodeB", 16 | "name": "流程A-节点B", 17 | "type": "task", 18 | "left": "340px", 19 | "top": "161px", 20 | "ico": "icon-VE iconfont", 21 | "state": "warning" 22 | }, 23 | { 24 | "id": "nodeC", 25 | "name": "流程A-节点C", 26 | "type": "task", 27 | "left": "739px", 28 | "top": "161px", 29 | "ico": "icon-rongqi iconfont", 30 | "state": "warning" 31 | } 32 | ], 33 | "lineList": [{ 34 | "from": "nodeA", 35 | "to": "nodeB", 36 | "label": "条件AB", 37 | "connector": "Bezier", 38 | // "paintStyle": { "strokeWidth": 2, "stroke": "#1879FF" } 39 | }, { 40 | "from": "nodeB", 41 | "to": "nodeC" 42 | }] 43 | } 44 | 45 | -------------------------------------------------------------------------------- /src/data/data_A.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "流程A", 3 | "nodeList": [ 4 | { 5 | "id": "nodeA", 6 | "name": "流程A-节点A", 7 | "type": "task", 8 | "left": "26px", 9 | "top": "161px", 10 | "ico": "icon-daqilitiguancex iconfont", 11 | "state": "warning" 12 | }, 13 | { 14 | "id": "nodeB", 15 | "name": "流程A-节点B", 16 | "type": "task", 17 | "left": "340px", 18 | "top": "161px", 19 | "ico": "icon-VE iconfont", 20 | "state": "warning" 21 | }, 22 | { 23 | "id": "nodeC", 24 | "name": "流程A-节点C", 25 | "type": "task", 26 | "left": "739px", 27 | "top": "161px", 28 | "ico": "icon-rongqi iconfont", 29 | "state": "warning" 30 | } 31 | ], 32 | "lineList": [ 33 | { 34 | "from": "nodeA", 35 | "to": "nodeB", 36 | "label": "条件AB", 37 | "connector": "Bezier", 38 | "anchors": ["Top", "Bottom"], 39 | "paintStyle": { "strokeWidth": 2, "stroke": "#1879FF" } 40 | }, 41 | { 42 | "from": "nodeB", 43 | "to": "nodeC" 44 | } 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /src/data/data_B.js: -------------------------------------------------------------------------------- 1 | export var data_B = { 2 | "name": "流程B", 3 | "nodeList": [ 4 | { 5 | "id": "nodeA", 6 | "name": "流程B-节点A", 7 | "type": "task", 8 | "left": "128px", 9 | "top": "223px", 10 | "ico": "el-icon-user-solid", 11 | "state": "success" 12 | }, 13 | { 14 | "id": "nodeB", 15 | "type": "task", 16 | "name": "流程B-节点B", 17 | "left": "351px", 18 | "top": "96px", 19 | "ico": "el-icon-goods", 20 | "state": "error" 21 | }, 22 | { 23 | "id": "nodeC", 24 | "name": "流程B-节点C", 25 | "type": "task", 26 | "left": "354px", 27 | "top": "351px", 28 | "ico": "el-icon-present", 29 | "state": "warning" 30 | }, { 31 | "id": "nodeD", 32 | "name": "流程B-节点D", 33 | "type": "task", 34 | "left": "723px", 35 | "top": "215px", 36 | "ico": "el-icon-present", 37 | "state": "running" 38 | } 39 | ], 40 | "lineList": [{ 41 | "from": "nodeA", 42 | "to": "nodeB", 43 | "label": "条件A" 44 | }, { 45 | "from": "nodeA", 46 | "to": "nodeC", 47 | "label": "条件B" 48 | }, { 49 | "from": "nodeB", 50 | "to": "nodeD" 51 | }, { 52 | "from": "nodeC", 53 | "to": "nodeD" 54 | } 55 | ] 56 | } 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/data/data_B.json: -------------------------------------------------------------------------------- 1 | { 2 | " name": "流程B", 3 | "nodeList": [ 4 | { 5 | "id": "nodeA", 6 | "name": "流程B-节点A", 7 | "type": "task", 8 | "left": "128px", 9 | "top": "223px", 10 | "ico": "el-icon-user-solid", 11 | "state": "success" 12 | }, 13 | { 14 | "id": "nodeB", 15 | "type": "task", 16 | "name": "流程B-节点B", 17 | "left": "351px", 18 | "top": "96px", 19 | "ico": "el-icon-goods", 20 | "state": "error" 21 | }, 22 | { 23 | "id": "nodeC", 24 | "name": "流程B-节点C", 25 | "type": "task", 26 | "left": "354px", 27 | "top": "351px", 28 | "ico": "el-icon-present", 29 | "state": "warning" 30 | }, 31 | { 32 | "id": "nodeD", 33 | "name": "流程B-节点D", 34 | "type": "task", 35 | "left": "723px", 36 | "top": "215px", 37 | "ico": "el-icon-present", 38 | "state": "running" 39 | } 40 | ], 41 | "lineList": [ 42 | { 43 | "from": "nodeA", 44 | "to": "nodeB", 45 | "label": "条件A" 46 | }, 47 | { 48 | "from": "nodeA", 49 | "to": "nodeC", 50 | "label": "条件B" 51 | }, 52 | { 53 | "from": "nodeB", 54 | "to": "nodeD" 55 | }, 56 | { 57 | "from": "nodeC", 58 | "to": "nodeD" 59 | } 60 | ] 61 | } 62 | -------------------------------------------------------------------------------- /src/data/data_B.yaml: -------------------------------------------------------------------------------- 1 | name: 流程B 2 | nodeList: 3 | - id: nodeA 4 | name: 流程BBB-节点AAAA 5 | type: task 6 | left: 128px 7 | top: 223px 8 | ico: el-icon-user-solid 9 | state: success 10 | - id: nodeB 11 | type: task 12 | name: 流程B-节点B 13 | left: 351px 14 | top: 96px 15 | ico: el-icon-goods 16 | state: error 17 | - id: nodeC 18 | name: 流程B-节点C 19 | type: task 20 | left: 354px 21 | top: 351px 22 | ico: el-icon-present 23 | state: warning 24 | - id: nodeD 25 | name: 流程B-节点D 26 | type: task 27 | left: 723px 28 | top: 215px 29 | ico: el-icon-present 30 | state: running 31 | lineList: 32 | - from: nodeA 33 | to: nodeB 34 | label: 条件A 35 | - from: nodeA 36 | to: nodeC 37 | label: 条件B 38 | - from: nodeB 39 | to: nodeD 40 | - from: nodeC 41 | to: nodeD 42 | -------------------------------------------------------------------------------- /src/data/data_C.js: -------------------------------------------------------------------------------- 1 | export var data_C = { 2 | "name": "流程C", 3 | "nodeList": [ 4 | { 5 | "id": "nodeA", 6 | "name": "流程C-节点A", 7 | "type": "task", 8 | "left": "400px", 9 | "top": "15px", 10 | "ico": "el-icon-user-solid", 11 | "state": "warning" 12 | }, 13 | { 14 | "id": "nodeB", 15 | "name": "流程C-节点B", 16 | "type": "task", 17 | "left": "400px", 18 | "top": "200px", 19 | "ico": "el-icon-goods", 20 | "state": "warning" 21 | }, 22 | { 23 | "id": "nodeC", 24 | "name": "流程C-节点C", 25 | "type": "task", 26 | "left": "400px", 27 | "top": "378px", 28 | "ico": "el-icon-present", 29 | "state": "warning" 30 | } 31 | ], 32 | "lineList": [ 33 | { 34 | "from": "nodeA", 35 | "to": "nodeB" 36 | }, { 37 | "from": "nodeB", 38 | "to": "nodeC" 39 | } 40 | ] 41 | } 42 | 43 | -------------------------------------------------------------------------------- /src/data/data_C.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "流程C", 3 | "nodeList": [ 4 | { 5 | "id": "nodeA", 6 | "name": "流程C-节点A", 7 | "type": "task", 8 | "left": "400px", 9 | "top": "15px", 10 | "ico": "el-icon-user-solid" 11 | }, 12 | { 13 | "id": "nodeB", 14 | "name": "流程C-节点B", 15 | "type": "task", 16 | "left": "400px", 17 | "top": "200px", 18 | "ico": "el-icon-goods" 19 | }, 20 | { 21 | "id": "nodeC", 22 | "name": "流程C-节点C", 23 | "type": "task", 24 | "left": "400px", 25 | "top": "378px", 26 | "ico": "el-icon-present" 27 | } 28 | ], 29 | "lineList": [ 30 | { 31 | "from": "nodeA", 32 | "to": "nodeB" 33 | }, 34 | { 35 | "from": "nodeB", 36 | "to": "nodeC" 37 | } 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /src/data/data_D.js: -------------------------------------------------------------------------------- 1 | export var data_D = { 2 | "name": "流程D", 3 | "nodeList": [ 4 | { 5 | "id": "nodeA", 6 | "name": "流程D-节点A", 7 | "type": "task", 8 | "left": "18px", 9 | "top": "223px", 10 | "ico": "el-icon-user-solid", 11 | "state": "success" 12 | }, 13 | { 14 | "id": "nodeB", 15 | "type": "task", 16 | "name": "流程D-节点B", 17 | "left": "351px", 18 | "top": "96px", 19 | "ico": "el-icon-goods", 20 | "state": "error" 21 | }, 22 | { 23 | "id": "nodeC", 24 | "name": "流程D-节点C", 25 | "type": "task", 26 | "left": "354px", 27 | "top": "351px", 28 | "ico": "el-icon-present", 29 | "state": "warning" 30 | }, { 31 | "id": "nodeD", 32 | "name": "流程D-节点D", 33 | "type": "task", 34 | "left": "723px", 35 | "top": "215px", 36 | "ico": "el-icon-present", 37 | "state": "running" 38 | } 39 | ], 40 | "lineList": [{ 41 | "from": "nodeA", 42 | "to": "nodeB", 43 | "label": "直线,自定义线样式,固定锚点", 44 | "connector": "Straight", 45 | "anchors": ["Top", "Bottom"], 46 | "paintStyle": { "strokeWidth": 2, "stroke": "#1879FF" } 47 | }, { 48 | "from": "nodeA", 49 | "to": "nodeC", 50 | "label": "贝塞尔曲线,固定锚点", 51 | "connector": "Bezier", 52 | "anchors": ["Bottom", "Left"] 53 | }, { 54 | "from": "nodeB", 55 | "to": "nodeD", 56 | "label": "默认连线样式,动态锚点" 57 | }, { 58 | "from": "nodeC", 59 | "to": "nodeD", 60 | "label": "默认连线样式,动态锚点" 61 | } 62 | ] 63 | } 64 | -------------------------------------------------------------------------------- /src/data/data_D.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "流程D", 3 | "nodeList": [ 4 | { 5 | "id": "nodeA", 6 | "name": "流程D-节点A", 7 | "type": "task", 8 | "left": "18px", 9 | "top": "223px", 10 | "ico": "el-icon-user-solid", 11 | "state": "success" 12 | }, 13 | { 14 | "id": "nodeB", 15 | "type": "task", 16 | "name": "流程D-节点B", 17 | "left": "351px", 18 | "top": "96px", 19 | "ico": "el-icon-goods", 20 | "state": "error" 21 | }, 22 | { 23 | "id": "nodeC", 24 | "name": "流程D-节点C", 25 | "type": "task", 26 | "left": "354px", 27 | "top": "351px", 28 | "ico": "el-icon-present", 29 | "state": "warning" 30 | }, 31 | { 32 | "id": "nodeD", 33 | "name": "流程D-节点D", 34 | "type": "task", 35 | "left": "723px", 36 | "top": "215px", 37 | "ico": "el-icon-present", 38 | "state": "running" 39 | } 40 | ], 41 | "lineList": [ 42 | { 43 | "from": "nodeA", 44 | "to": "nodeB", 45 | "label": "直线,自定义线样式,固定锚点", 46 | "connector": "Straight", 47 | "anchors": ["Top", "Bottom"], 48 | "paintStyle": { "strokeWidth": 2, "stroke": "#1879FF" } 49 | }, 50 | { 51 | "from": "nodeA", 52 | "to": "nodeC", 53 | "label": "贝塞尔曲线,固定锚点", 54 | "connector": "Bezier", 55 | "anchors": ["Bottom", "Left"] 56 | }, 57 | { 58 | "from": "nodeB", 59 | "to": "nodeD", 60 | "label": "默认连线样式,动态锚点" 61 | }, 62 | { 63 | "from": "nodeC", 64 | "to": "nodeD", 65 | "label": "默认连线样式,动态锚点" 66 | } 67 | ] 68 | } 69 | -------------------------------------------------------------------------------- /src/data/detail_data.js: -------------------------------------------------------------------------------- 1 | 2 | export var node_data = { 3 | name: '某节点内部详情', 4 | nodeList: [ 5 | { 6 | id: 'node_detailA', 7 | name: '实例A', 8 | type: 'task', 9 | left: '26px', 10 | top: '10px', 11 | ico: 'icon-daqilitiguancex iconfont' 12 | }, 13 | { 14 | id: 'node_detailB', 15 | name: '实例B', 16 | type: 'task', 17 | left: '100px', 18 | top: '10px', 19 | ico: 'icon-VE iconfont' 20 | }, 21 | { 22 | id: 'node_detailC', 23 | name: '实例C', 24 | type: 'task', 25 | left: '170px', 26 | top: '10px', 27 | ico: 'icon-lifangtilitiduomiantifangkuai iconfont' 28 | }, 29 | { 30 | id: 'node_detailC', 31 | name: '实例C', 32 | type: 'task', 33 | left: '270px', 34 | top: '10px', 35 | ico: 'icon-lifangtilitiduomiantifangkuai iconfont' 36 | }, { 37 | id: 'node_detailC', 38 | name: '实例C', 39 | type: 'task', 40 | left: '380px', 41 | top: '10px', 42 | ico: 'icon-lifangtilitiduomiantifangkuai iconfont' 43 | }, { 44 | id: 'node_detailC', 45 | name: '实例C', 46 | type: 'task', 47 | left: '450px', 48 | top: '10px', 49 | ico: 'icon-lifangtilitiduomiantifangkuai iconfont' 50 | }, { 51 | id: 'node_detailC', 52 | name: '实例C', 53 | type: 'task', 54 | left: '580px', 55 | top: '10px', 56 | ico: 'icon-lifangtilitiduomiantifangkuai iconfont' 57 | }, { 58 | id: 'node_detailC', 59 | name: '实例C', 60 | type: 'task', 61 | left: '640px', 62 | top: '10px', 63 | ico: 'icon-lifangtilitiduomiantifangkuai iconfont' 64 | } 65 | ] 66 | } 67 | 68 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import ElementUI from 'element-ui' 4 | import 'element-ui/lib/theme-chalk/index.css' 5 | import "./style/iconfont.css" 6 | import './style/index.css' 7 | Vue.config.productionTip = false 8 | Vue.use(ElementUI, { size: 'small' }) 9 | 10 | new Vue({ 11 | render: h => h(App), 12 | }).$mount('#app') 13 | -------------------------------------------------------------------------------- /src/style/iconfont.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "iconfont"; 3 | src: url("//at.alicdn.com/t/font_1870567_ftka9e8z3st.eot?t=1592409460850"); /* IE9 */ 4 | src: url("//at.alicdn.com/t/font_1870567_ftka9e8z3st.eot?t=1592409460850#iefix") format("embedded-opentype"), 5 | /* IE6-IE8 */ 6 | url("data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAABgkAAsAAAAALBwAABfVAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCEegrHLLdOATYCJANACyIABCAFhG0HgksbUSMzo8LGAQBJvCTZ/yWBkzF4OX7NDIMkYK1pzcRg2/n0Uc1sIdQ5k1iPgXbEOtd4p6stHocFmCjHMtX9U0VUl2WGUkI87dfm7e7fb3Z3DRHpYpkk2j2TLlQIiUS6TiZUOl0t6fD83P7PvXd3rLmXBSkMevRGlOBYsQEOtsFGtESqDGs8/WImtImVZL2QVxg5eUY+fB+sxCAA5nun2YxhQVKwA7GDfXEcwF0OtMekGQUKTlyCvwOUfqV3fwMJFwKGJQgslEHQAAECd5fZKlHjrFwtrxWvzv87FgKTscyEsJbmD/A9ACDwH4q5tWyodkGmsLLNbDZFe/2/D0UVwQ3GeKiQf69TV0OIp14n5r3rqC+TnsDNt0OkoOWQ7KCdAtKIIw2L5BBJQZpgy9iOiGOm0rR0nDssLeQ0kYNW2n6xIWkfm8HYzMNV6LAKEWOKxfzKniFAQDNP0Pzi+9cECYNBCyrt73g9QYrZMZxowbNaRpvGQ05C8dSmjQE4dp+/PIDxPIDC0cDo1VL+g50QTky8DlW9ijRkXVXNJQOb9kADgwAGpMFMPQOID4MuE7A8CRwBQAHT+6euwfX0hPN1Ni9XP/xL652uPpCRKRSmnjU4QEJEjIPFxcMnRWMICFHaXzwBsQBMpPtfFmXA9QRdhwSupzER2BtgYrAaGAesA8aC9cC4YHNgPLA11sGH13odUnhljAYbgDFgBZgAbAQmBNsHRoEdwBCyQ5iWF5PZbbQCfE+AsA5IzjO4TbcwJGeyBGpaRs3CQ1qMchGWNCKSyUTizWE1mtaJp042nDQoUwaXb24eyRDiRCFqPf6JjGUZKANx2mgeMY2Tu+7jppVpaWnIZU6kjUwFROKNLDKN7Akvx0Kokbrnsp1Zy2puLa6xwU5qplmZecRqtqWFENOaaDW7rBOmaTRortb444+YLRZRZbSYhd7GE9ZJ3NTS0Gw0nGxtsLqd2QqtriU9gk4knzdbm3tCmLbosI8R6/m7CdyMz94KOzcipjEX5Pm9q5uHty5tHLyy6nR09+rritgSv8IFYvrVDIZHp2VJYkeRZyrhaDVKkrFa/PyV+Ox+2Hk5unCULIBFZ7S0BF8OqsBdRkBKzPSeeflyKwXDlisu+pVeefg1CH8tDL8FG1gmvjzKhaHIL10JON5e3Qwk/o2nMhkj3tWdnKM1hWrVqz/pC1fu6FXlWKg7LQTY0WqBpeyxP6T5Mzk1Au2pJl8se1aeCrDohbvK4gZN58WUvYyYWblPv5jTpukoBbmYZyO8BIz0q6UCGtmyfsxqc+r/1XjrXkdm4/65prsPu7ObD54Qwmj0Fcl2dPcmKbFtAAPSSGBGmjACGnSJTe5MqUn9V+OdB13ZrYcXmm7f78ys3/urL0DGlWZToGHWU8a/QtnNMTyJY+pJkZlhKY6y8IRhoQS0sH64BM7/FT52/PHkd6LXLi2VS6nF9GyxOP+7Oed3TqqcfmbeATZwHrWZA8Qcfw8SR7nd/lTp5UIoDK6FA5V9RBhDgimW5ozyF6ayk3CqPAkzpeyTxWwfLJb7QrocX5NnGeRldj8DDrQpcJtjsf1c9QsAdYE21A2JorTfxdhFCHYU2vOzJCO5A/KKKMPgDJ1ATaFJPagUIj5CYnkZYyoxRggggTocX1pgDDpQF6Y0h6gw6Y6rQ4hAijANAAI5lD/jStxGMlC1wVKtKTZ78hSSvNQUCYGQIqgTozyknsFvZsI1keNhiYEiRLbhJJpqkNhcICAEUQSrtkGukAfIh92aUkebWEvsAmTIjaFbop+IqLU1yjQEj0OMAG7rGskhe6orzAMGOYuWJ4UvdG0dTfzxfHb4crrExlYolXGJUZhVBsylhVkMCSP8rJRAmtoU1DnpKZeVs0WFF1iWPxmmzuJ0kYMV455qjHuycXihUTIEGzBX5kDg5ovu17Fv+zUXXRQ+mVIQuHhSBnRaw65UHnTzUgRdPrcBHpRoQJAhRYc1frVy1isehNbTJYsEeRDjpYhTuNpzOEGEgEGWlUzsQQ3oLiqXpKu8sotsYYCAOhpyn/A2nUyaCzKTTIB3/rYDbMvL7vbuFW+PSe2t7gp3pfco5SiEoN657CIa8/8KE0StEk0FcFd2HLdS2fXqezu2XvPU9rIrf6LNS0djDNV2xcVEeXVbUr0GPSJzYnnbkSTVg+TGQi/KxjgZOfZgztXlyUC6nRmwcbb545VlXXx0slj4/NNgeygqir+/x/Bs6Q/16LH70Y8i/3b7JR/tv94FTR9JvsdU7fAJv1iLe9+O6skPvs6XUc8b4XKZ+ea689t9z7Vn/c2Dz6ePctx7t94qqln/RVP0/4iFmgc63gcHkqR7M/7Xw/EkcWxvF2J+/oFsgc7HCnG//FioH903X2En/2cfx9G079MejL/P/N0LweBK+MNLM7UhRfLx2JsVSJE7Q0fTw2/8+d7Fw6ndYqby1Xavuz58NH0wudM3KMEKcDsqJUUklu+Dyf2Lm9zFj9eHl0GtsJNoVqCtRYkVIYdTR9MbzBOassHKwBp8LokZROyT/bO5qO33eJj86lxb2PZnHszWEqc6KHFuMJpFtYXdmH9eD37VJ8qVkBfbk+PhDyI/M2A1YfMffy/Og7GYJGHnNE1S31D2aOIotC/NRP7hPTsuRKBQHEc2g742SnHfp0swfjXmhI6PGyIx529tixFRpDhKgEvh0ctnG7sjyH9eKe6CHaPacOSNFyWHv/7k/KhIJEB69AN6DzxSuZP83V6PeeVi2Er+0BURHlcHB3uDGkPqUTFYTZx45Idqi4TsThF6NN0llW3rHQLxnT6s6VZ3oWKTza4uLM1u4eokRvsX+Ubn3eHaEFFEMjIT7vlV6HVDukadIs+euZU2twOgykDRFnHfTt/B5NF0fXgLruU98gajdrd4OLV/sTKwDlwgcbkdejCPZXUtVxlwgIs0JaokAkM1YmorUR5jiaFHRZnUhoaWgzehe/13f/HhVF0iFD89Gbw6/n6uhGdFIeol8mDsPd5XoSdA+zP88mh9ethlz3+mS9GrRP1kTz0o3ujM8YPBZlEPXbbt9q3u9mVCQnbAWe/orw/vFgkjD4WNUHVqIheMPlm5nHjh8y3GV9EcmLvzXdfW9xduf9u5/g33K241qHu1f5W2L4HUykF/ee9qe3r1sLS0u9+Wci/3Le4ctae9K+W9/FpxadcvlLZzyxl80P+8VTMkiiA/Z3DlTzQcp8ey0Iye2w0q7g8ipJPccliUoR3z/JJCfqWNbGkG9W1ds1yRNJOgrJA8fNUM6FYDofaUKmenNXW4JAWG50Fpsvq9wJzsH/uEv+45mS3+9ZZUzh4jY77ZSb7XzL6wt4LYCwNDvQY82iIBXGKhgLU/Vt1K5BJ/xyfr4vb1SefKHK8n8NMXmpyawefDTEqtl7gME2zKbyMNfhsa6RseGfbwcVgkw/tR5vv7wYOUkeaWZ//KXb5mn3ed1B/+fV3MLZep8mFOw92WGtuC5mpqT3GgVVFhQMjb5MXl512m9eddUwNSoguXJimSRiIUoc0hoe4RV18iqpZXKlgYCqtbXqqQ9x+tlE5DO52VUxTt/3fQSQl2QimLjVMbliHVh98sPkzEE3H6219lq+8H/2cT6knHEx0SAKo15u7EHT1POSY4JNon4pS0pRhp9a4+AwNIHRJxRtH2vhyTN8c9YTaMJ9gvcpDipAl/T4ITwprSGWFcai/Fd9b9ZxPysln26zubBNNr5Ofsi/EX0bFdV0KcIX51j56Rs6sPY7E/vdo0oRUYnrT8s2LsJfk5Z8z0eTeTchcdY9/l3F0hTiI/YWwzBtsJSILaHzqPAOrSWpD34l8be6PWiJIEdT9a64Ca2Ok+SbaQJ2xcHR0LwzbGeS2+OTOWv8lrNHw+2eZqJ00QZyyHvIv8Imfi7gE/jegwd2aHkZmet31nHIZnjn2gzliHaa+oh6kvWw63/KCesA4uX0YaszB4IUF8yMLAEEUrE7AqSARO7KiTGMQFwN9pJmg0T4DMTLgPZM20GUtAmwZ5C0eQDe0dG2DDIeT2beSQiE3MBIWF6O9u3gq1I9+NlseXsKrPVraxVgw1b4AKwYl8D92r1Xq4vh4OSg+BYoMK0heZqAiqzEoVQ00DQqiKMM7ljgdFAMES8i0cxZCZNZwwZsjfxcpt9OHh9KXXZ1uEX22TIJWKYYP5N9CaWBt4Pld4NINwLAMoOwsCG/oOfa8qiZVZLsXs2VszI/ePpf2Ztjkmdc7sDRzILSSuTs2pqMnLAmOjemcVDJate0SMsHHmOGjpA/8AJnM/09ahjFkGwr6/LBpr1bDFB5gViaURTAMA7F+TmQ5DEMkgqwvoyXpTZO8DjMUS+pFJ0nUD+fp1qMrXSt0jncS0kCLZtqIKxgHsKIwDgHEIFFsEF9kKLQ9QCQg3WxIt5zV4otlchADFY4CUREMhdEmQ9QCD+Zg4C4kJwykiorMO2ltI5PqofBkQBgAOH7X3hTAzwiysgmstwHAkEHNohd/BBAQz4UZQU4wiWC4GzEqdcIxmWUw+rCcwEbxOkOtEZLKSLrjMYM1vLDjzEACmcQiMua4F/gIM5WISUKbzJ0gUZUQg4WK0JMgpVyCiEPx1ZSw5o8Y9epYARuyJhXtpGj6MAT1ZUhkIE/gDqEwhwdfDyxK7lOII4SooZSIY0eAWHSnbY2LIci12Dt+aMVPVRpMmRvUTF/Tal/VhdoX5RsS+/AtBAxTr+ISKvhLFi/yyrzue2GNRFm+up0lDK9EXOhw/Yt4c4845eMTxROa8zMA9ODKvOh7f+6dEyM55PY/Roj6hgT0iFSh5LT95FGzUY8+wuXNkAw6y/hIfLd/1VDn21xWHO9QYijNl/Y6yAaVBE6JhtGpOqel/ay5oaMsFydWU5mC3cSdrSf+FkPYE36D2C7IBprt0YIy4Eu9GHAeEJeFjfAslZGn/RelA9HnNVjWDpWGo4cQaVne+Iu3vDO64zY5O6UBfq/1BQuyn7Sn8rhcJgx2m+RT7aQfYLQVENgnST3XKzWUQJ2iSL+r3EzwUqQ1i+6rpWOWDBX52U+UvYl5OAKgB4J8jlBkLEMT3XA3/ZhHtKK374O9kmsBYGHIa/yyUj5KAeILvWf+DaoEpgKLJx+q1o9ggNlqfeJw8rMS6GrRd5EFyd0NiF9Ye2mWWR3Mzksy66seTO7p53Mjlul+mqzLmHv1sPbn8ItNDyYnGIz/X8UHNMNdusaDangsJs2u6JukUySGMMb3tRQDuM+Ju73OZxxV1TVp/LpvmJH9i8Gjcs1oBWHvZx24xv8beBxIuXNs1TacmNAPa5H7WpXm0ZZVcwaqwUmgVGX7KMiMwGLiPGlwQGSt9kwe66FblP2WibOq5MoiJeBp/je92xkpIBYALwZuWRkPsJwUUwawY5iCIP0m7TjsiPIo4fGHj/zv44KwMUsQ4K8zAfDAP5+bq/sEsnw1mVhofOOq2krl2Roe4DKEEl1595QKBZEIYLSLzL6CjKJlMxJEtgvdsjsiJWRIwMfSLyuzdiC6nNGZxwLNBz/hMWi3ZqV+5PN7QVC618KdthVydtqP5CZZp5fkLFt/X6WdQGnTZP8Px+Fo8rq/LzxC3TJsz8hDN9C3crk5VLOKX7977E3ow+huTpqiQXEFe1zy060kcGovGFDh4UTEmsdW2M+qhLomVdW9SD9XC3VIe758BBM0ri757ilhFfGkJLZbjH2ShUxbHYzEZFnEhlstj2SU0voRd5Cn6nqxMEO9zoiiiYamVuVZZLORGZ1goebzADiGkmA4Q7z1Seu+1n/kHttr/L+eNdSdPzCJKTcWBwR+sLKtrGK+DgieEniN/3hkK94mn001IbqzuT0NTf12O8FbRGSaWv9Pwh0kEY9aJHr5fiLTuUGPYqCljiYMYYQr/tbII/g7LeNNTEdb4LMbJ7kWh0u5VJ0MvMD6z1Mj3E8EsQRBHGjJ3Fjdcx4nrraJ+cHO/PezPVlMTCCN7JQw5QZEpcJZplIEr5XFLj588YSPTUOfalIDLOEcaHHvl9WwdR9lbNYUGyxE780wg5QT6VZhb5VhUfOD/Npn6qXJs0kUWckhJ5wY1JWa6TnmJWfP9FAvoSo4lm2iTFJeaq55nnc5+EsdZQPeTM+d7SyaDtJlBTfa0uUAIX/+NTbQuMCN/XOdYpcVmeXsotFZqHo+TE9DxMGr0eXB1QppEqnvhIWTleQvzqTEsQkEOxyo1NvtKi1zoiQ+x5OhzypcoWAUUbyEr3134Lck/ICEtpPrbaJQckljtO8qdk2yu4qh6sgSCSdRNRQyxNJfPjttymi0PVgcFxrAjw290WEfMs2mtbkhhRBEUCJ7pIJXKVSFr9O6dbtdF7PQPHoEGoWLGJiunyx4HBcVkB6+VxydKltYt9kFH6mlE1ZGWdpBQEWjwIObCURYMISqy5C9a+mvHhwHJ0Vqd2+TUOKbcZs6Z63S/uANlZcup/96LMm9KSRvv6cFwhw+ba48eO0ROS8ylv35/c5HYD91gz/92LtxnjS3JwtEKsTdODN8ROHw9H+5dbWdCcrREzFIDql4EbL3DV/zVt+9mlwWXRKRaIfj6Jd5e+/r+2hYzynKysCRToulkV1MG6O91rJdIJXxExKFQTp666LdZ/nf9xpMSiagfRDLoCWO4wIxNpZx8SJJsrFtk16OhijiqQqeXYGGoCVur+ytAHu27KPHtMZytHE8HY08D+ze4yyVSl3EdS8tNQt/+SKVHoXLEbIHZnORjb2cGM5M0Sd5WO1WIka2EvMd7u3N5smNH69oqLBpTwrNlzu25YrG1dPHLD0WjMlvzBwbER+tkIbew7Fwp7ea7/ac7DHS+zQ03Fdudx1HMjhMDYYq5ClX3rCwT5eS0W4cvZUcFa9TmS+Scs/vKaRub01dGbIdnPeuUm5pvcj0NAsp/MHbwxBwOkR1M94jTBAftqGZsD0aJ5hwxj46W3ZJm2VV3ALmbbXXzcjPb4rGV3sLz4oEfVYOEgenpgaEI9zmEgTDpvG3IApzimGBLF5vwL+bvk6ajMIlSptGFXNRvi0kIKiWq5UU6/hI+/2yz6UE4qx7UHrRuXFuF5SOeFomh6ygyVlDdXMuTfFo3j2YyE7CYapyoWmvdGKqzcEcKMPIa6yb3PAtPJN81kZ7zaT1KnxdNMXeFwXAYty7EHABgrnhxKBJVUBuaBSAoK/QCSf3yp5fL1bg6lb/6SQSCV7+8907dDtrAe/U96Ch0/72qDfAW71T3oaNdqb3QJx0h8l+G1L+EyI+68kNkAqHUTnJXYC/I1z+Ngdoh/6fuKFKKoOTrsbg+qB5CL9knbS/UB33Utt6rWUzRQTG5ubFDQTcCCgkgFkNbmDLxjD/0+fPUlk1l5VusxM6QZsF8DaSGFsyHNJoyNeTQsbpML3l4inHkayRxyv+7SYls24QYMfeTYtnlc8D/twt9DVnnC036jHzX5SOfCIPXh+pl3FlldbqKLDRA1+36ZyyesB118a8GRRTOcGXztP8a/7Oui9OZkanMZn955l/b+Vcb2+KidslmEXLwUHlpAv9H70U89W8Bu7I1G5BdMEZmo2uk59hGeFgwNFaS7cP3AwUmMM+B/6UzC/fb3Fn9XzJZ8GLGzXKFSxNoln8nY/6JNGK5Q8ik1vpPLQ8YENV+SEkPEMSQAfRbpy8XMueXKxIuQMP/Ihj431vuUPOCsoSnlwcsQ0yFId3dApfuGLSAVb2RQkOlc4IseZU/wMdcMzGvGvoBDkil6jTb15InKIGbaCb0fVfEKcdUqEetCchzUhVTCkaaCcXVbavlds02DRUTS8QMWuzVrdIbbY2GSndjWUo9+w/wMdfMOeBp6x/ggI+udDS1BbRPTCl0QFk8Q993CUl2igpMhc896smQm4WkVOzaUjDSlFQQqlstciInyjTb54pHnuHhO6jRetaUkEobpvV/4sRtx/X8Nq2eOHM5DRqGqtFRAO6jgQJC4uJAhbr0HrJ32bEoMQdM2uu4xYcu1uoQSz8AHEZdjhMqPVNm3eoacxT0O3UGhlM/D6smBqECuIGlo3nlBtnYworFIIy9KEjlpnBQitasiZQLGzf2IcYOatFLPI+KYo0wx2WcNZ7mKBMjbfM2UlEbI8khZFHjduMTNJvkXovu6QCPuZaJCQAA") 7 | format("woff2"), 8 | url("//at.alicdn.com/t/font_1870567_ftka9e8z3st.woff?t=1592409460850") format("woff"), 9 | url("//at.alicdn.com/t/font_1870567_ftka9e8z3st.ttf?t=1592409460850") format("truetype"), 10 | /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ 11 | url("//at.alicdn.com/t/font_1870567_ftka9e8z3st.svg?t=1592409460850#iconfont") format("svg"); /* iOS 4.1- */ 12 | } 13 | 14 | .iconfont { 15 | font-family: "iconfont" !important; 16 | font-size: 16px; 17 | font-style: normal; 18 | -webkit-font-smoothing: antialiased; 19 | -moz-osx-font-smoothing: grayscale; 20 | } 21 | 22 | .icon-workflow-copy:before { 23 | content: "\f078"; 24 | color: #409eff; 25 | font-size: 20px; 26 | } 27 | 28 | .icon-servicemeshfuwuwangge-copy:before { 29 | content: "\f076"; 30 | } 31 | 32 | .icon-servicemeshfu-copy-copy:before { 33 | content: "\f077"; 34 | } 35 | 36 | .icon-dituleiwanggequ-copy:before { 37 | content: "\f072"; 38 | } 39 | 40 | .icon-fangxingweixuanzhong-copy:before { 41 | content: "\f073"; 42 | } 43 | 44 | .icon-daqilitiguancex:before { 45 | content: "\e661"; 46 | } 47 | 48 | .icon-VE:before { 49 | content: "\e666"; 50 | } 51 | 52 | .icon-customer-info:before { 53 | content: "\e667"; 54 | } 55 | 56 | .icon-product:before { 57 | content: "\e66c"; 58 | } 59 | 60 | .icon-distribution:before { 61 | content: "\e671"; 62 | } 63 | 64 | .icon-litijiankong-copy:before { 65 | content: "\f074"; 66 | } 67 | 68 | .icon-dulitixi-copy-copy-copy-copy-copy:before { 69 | content: "\f075"; 70 | } 71 | 72 | .icon-litipouqie:before { 73 | content: "\e603"; 74 | } 75 | 76 | .icon-rongqi:before { 77 | content: "\e625"; 78 | } 79 | 80 | .icon-lifangtilitiduomiantifangkuai:before { 81 | content: "\e600"; 82 | } 83 | 84 | .icon--SearchDatabaseFlat:before { 85 | content: "\f071"; 86 | } 87 | -------------------------------------------------------------------------------- /src/style/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | padding: 0; 3 | margin: 0; 4 | } 5 | 6 | /*节点菜单*/ 7 | .ee-node-pmenu { 8 | cursor: pointer; 9 | height: 32px; 10 | line-height: 32px; 11 | width: 225px; 12 | display: block; 13 | font-weight: bold; 14 | color: #4a4a4a; 15 | padding-left: 5px; 16 | } 17 | 18 | .ee-node-pmenu:hover { 19 | background-color: #e0e0e0; 20 | } 21 | 22 | .ee-node-menu-li { 23 | color: #565758; 24 | width: 150px; 25 | border: 1px dashed #e0e3e7; 26 | margin: 5px 0 5px 0; 27 | padding: 5px; 28 | border-radius: 5px; 29 | padding-left: 8px; 30 | } 31 | 32 | .ee-node-menu-li:hover { 33 | /* 设置移动样式*/ 34 | cursor: move; 35 | background-color: #f0f7ff; 36 | border: 1px dashed #1879ff; 37 | border-left: 4px solid #1879ff; 38 | padding-left: 5px; 39 | } 40 | 41 | .ee-node-menu-ul { 42 | list-style: none; 43 | padding-left: 20px; 44 | } 45 | 46 | /*节点的最外层容器的样式*/ 47 | .ee-node-container { 48 | position: absolute; 49 | display: flex; 50 | width: 170px; 51 | height: 32px; 52 | border: 1px solid #e0e3e7; 53 | border-radius: 5px; 54 | background-color: #fff; 55 | } 56 | 57 | .ee-node-container:hover { 58 | /* 设置移动样式*/ 59 | cursor: move; 60 | background-color: #f0f7ff; 61 | box-shadow: #1879ff 0px 0px 12px 0px; 62 | background-color: #f0f7ff; 63 | border: 1px dashed #1879ff; 64 | } 65 | 66 | /*节点激活样式(被点击的节点)*/ 67 | .ee-node-active { 68 | background-color: #f0f7ff; 69 | box-shadow: #6f93b6 0px 0px 12px 0px; 70 | background-color: #f0f7ff; 71 | border: 1px solid #1879ff; 72 | } 73 | 74 | /*节点左侧的竖线*/ 75 | .ee-node-left { 76 | width: 4px; 77 | background-color: #1879ff; 78 | border-radius: 4px 0 0 4px; 79 | } 80 | 81 | /*节点左侧的图标*/ 82 | .ee-node-left-ico { 83 | line-height: 32px; 84 | margin-left: 8px; 85 | color: #409eff; 86 | } 87 | .ee-node-left-ico i, 88 | .ee-node-left-ico .iconfont { 89 | font-size: 23px; 90 | } 91 | 92 | .ee-node-left-ico:hover { 93 | /* 设置拖拽的样式 */ 94 | cursor: crosshair; 95 | } 96 | 97 | /*节点显示的文字*/ 98 | .ee-node-text { 99 | color: #565758; 100 | font-size: 12px; 101 | line-height: 32px; 102 | margin-left: 8px; 103 | width: 100px; 104 | /* 设置超出宽度文本显示方式*/ 105 | white-space: nowrap; 106 | overflow: hidden; 107 | text-overflow: ellipsis; 108 | text-align: center; 109 | } 110 | 111 | /*节点右侧的图标*/ 112 | .ee-node-right-ico { 113 | line-height: 32px; 114 | position: absolute; 115 | right: 5px; 116 | color: #84cf65; 117 | cursor: default; 118 | } 119 | 120 | /*节点的几种状态样式*/ 121 | .el-node-state-success { 122 | line-height: 32px; 123 | position: absolute; 124 | right: 5px; 125 | color: #84cf65; 126 | cursor: default; 127 | } 128 | 129 | .el-node-state-error { 130 | line-height: 32px; 131 | position: absolute; 132 | right: 5px; 133 | color: #f56c6c; 134 | cursor: default; 135 | } 136 | 137 | .el-node-state-warning { 138 | line-height: 32px; 139 | position: absolute; 140 | right: 5px; 141 | color: #e6a23c; 142 | cursor: default; 143 | } 144 | 145 | .el-node-state-running { 146 | line-height: 32px; 147 | position: absolute; 148 | right: 5px; 149 | color: #84cf65; 150 | cursor: default; 151 | } 152 | 153 | /*node-form*/ 154 | .ee-node-form-header { 155 | height: 42px; 156 | border-top: 1px solid #dce3e8; 157 | border-bottom: 1px solid #dce3e8; 158 | background: #f1f3f4; 159 | color: #000; 160 | line-height: 42px; 161 | padding-left: 12px; 162 | font-size: 14px; 163 | } 164 | 165 | .ee-node-form-body { 166 | margin-top: 10px; 167 | padding-right: 10px; 168 | padding-bottom: 20px; 169 | } 170 | 171 | /* 连线中的label 样式*/ 172 | .jtk-overlay.flowLabel:not(.aLabel), 173 | .jtk-overlay:not(.aLabel) { 174 | padding: 4px 10px; 175 | background-color: white; 176 | color: #565758 !important; 177 | border: 1px solid #e0e3e7; 178 | border-radius: 5px; 179 | } 180 | 181 | /* label 为空的样式 */ 182 | .emptyFlowLabel.jtk-overlay { 183 | display: none; 184 | } 185 | /* 新增 */ 186 | .ee-dot { 187 | background-color: #1879ff; 188 | border-radius: 10px; 189 | } 190 | 191 | .ee-dot-hover { 192 | background-color: red; 193 | } 194 | 195 | .ee-rectangle { 196 | background-color: #1879ff; 197 | } 198 | 199 | .ee-rectangle-hover { 200 | background-color: red; 201 | } 202 | 203 | .ee-img { 204 | } 205 | 206 | .ee-img-hover { 207 | } 208 | 209 | .ee-drop-hover { 210 | border: 1px dashed #1879ff; 211 | } 212 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | publicPath:'./' 3 | } 4 | --------------------------------------------------------------------------------