@antv/x6 再vue中 ,自定义图形,画流程图、数据建模、er图等图形 ...

打印 上一主题 下一主题

主题 830|帖子 830|积分 2492

X6 是基于 HTML 和 SVG 的图编辑引擎,提供低成本的定制能力和开箱即用的内置扩展,方便我们快速搭建 DAG 图、ER 图、流程图、血缘图等应用。
最终效果图


1.安装

npm install @antv/x6 --save  //x6主要包
  1. npm install  @antv/x6-vue-shape  //使用vue组件画图插件
复制代码
  1. npm install @antv/x6-plugin-dnd //拖拽 添加元素图形插件
复制代码

2.直接上代码
dom元素 form.vue
  1. <template>
  2.     <!-- 新增、编辑弹窗-->
  3.     <el-dialog width="1200px" class="flow-dialog" top="5vh" title="实体编辑" :visible.sync="show" :append-to-body="true" :close-on-click-modal = "false" v-el-drag-dialog>
  4.       <div class="content">
  5.         <!--左侧工具栏-->
  6.         <div class="stencil" >
  7.           <p>流程编辑器</p>
  8.           <span @mousedown="startDragToGraph(item, $event)" v-for="item in list" :key="item" @click="test(item)" class="percentage-value">
  9.             <i style="margin-right: 5px;cursor: pointer;"  class="el-icon-setting"/>
  10.             <span class="percentage-content">{{ item }}</span>
  11.           </span>
  12.         </div>
  13.         <div class="panel">
  14.           <!--流程图工具栏-->
  15.           <div class="toolbar">
  16.             <el-button class="float-btn" icon="el-icon-s-claim" type="primary" @click="save()">保存</el-button>
  17.             <el-button class="float-btn" icon="el-icon-s-home" type="danger" @click="show=false">退出</el-button>
  18.             <el-button style="margin-left: 100px;" class="float-btn" icon="el-icon-s-tools" type="success" @click="">设置预览参数</el-button>
  19.             <el-button class="float-btn" icon="el-icon-notebook-2" type="info" @click="">预览节点数据</el-button>
  20.             <el-button class="float-btn" icon="el-icon-refresh" type="success" @click="">重算预览数据</el-button>
  21.           </div>
  22.           <!--流程图画板-->
  23.           <div id="containerShape" />
  24.         </div>
  25.       </div>
  26.     </el-dialog>
  27. </template>
复制代码
js部门
  1. <script>
  2. import elDragDialog from '@/directive/el-drag-dialog'
  3.   import { register } from '@antv/x6-vue-shape'
  4.   import { Graph,Shape} from "@antv/x6";
  5.   import CustomNode from './CustomNode.vue'
  6.   import { Dnd } from '@antv/x6-plugin-dnd'
  7.   export default {
  8.     directives: { elDragDialog },
  9.     data() {
  10.       return {
  11.         show:false,
  12.         list: ['数据查询', '横向连接', '追加合并', '分组汇总', '数据过滤','字段设置','输出'],
  13.         graph:{}
  14.       }
  15.     },
  16.     mounted() {
  17.       const attrs = {
  18.         circle: {
  19.           r: 4,
  20.           magnet: true,
  21.           fill: '#fff',
  22.           stroke: '#85A5FF',
  23.           strokeWidth: 1,
  24.         },
  25.       };
  26.       register({
  27.         shape: 'custom-vue-node',
  28.         component: CustomNode,
  29.         width: 180,
  30.         height: 40,
  31.         // port默认不可见
  32.         ports: {
  33.           groups: {
  34.             in: {
  35.               position: {
  36.                 name:'left',
  37.                 args: {
  38.                   dx: -10,
  39.                   y: '50%',
  40.                 },
  41.               },
  42.               attrs: attrs
  43.             },
  44.             out: {
  45.               position: {
  46.                 name:'right',
  47.                 args: {
  48.                   x: '100%',
  49.                   dx: 10,
  50.                   y: '50%',
  51.                 },
  52.               },
  53.               attrs: attrs
  54.             },
  55.           },
  56.         },
  57.       })
  58.     },
  59.     methods: {
  60.       open() {
  61.         this.show = true;
  62.         this.$nextTick(() => {
  63.           this.init("containerShape");
  64.         });
  65.       },
  66.       init(id){
  67.         const graph = new Graph({
  68.           container: document.getElementById(id),
  69.           width: 1000,
  70.           height: 1000,
  71.           connecting: {
  72.             router: 'manhattan',
  73.             anchor: 'center',
  74.             connectionPoint: 'anchor',
  75.             createEdge() {
  76.               return new Shape.Edge({
  77.                 attrs: {
  78.                   line: {
  79.                     stroke: '#52c41a',
  80.                     strokeWidth: 1,
  81.                     strokeDasharray: 5,
  82.                     targetMarker: 'classic',
  83.                     style: {
  84.                       animation: 'ant-line 30s infinite linear',
  85.                     },
  86.                   },
  87.                 },
  88.                 zIndex: 0,
  89.               })
  90.             },
  91.           }
  92.         })
  93.         graph.addNode({
  94.           shape: 'custom-vue-node',
  95.           x: 100,
  96.           y: 100,
  97.           ports: [{group: 'in'},{group: 'out'}],
  98.           data:{
  99.             percentage: 30
  100.           }
  101.         })
  102.         this.graph = graph;
  103.      },
  104.       save() {
  105.        this.graph.addNode({
  106.          shape: 'custom-vue-node',
  107.          x: 200,
  108.          y: 300,
  109.          ports: [{group: 'in'},{group: 'out'}],
  110.          data:{
  111.            percentage: '数据流程飒飒飒飒拉开阿斯兰的卡死了的科目来打开'
  112.          }
  113.        })
  114.       },
  115.       // 自定义一个拖拽方法,也可以单独封装成一个js文件(方便调用)
  116.       // 这里直接写到vue文件的methods方法里了
  117.       // 需求:未置灰的可以拖拽,置灰的无法拖拽即禁用状态
  118.       startDragToGraph(item, e) {
  119.           const node = this.graph.createNode({
  120.             shape: 'custom-vue-node',
  121.             x: 200,
  122.             y: 300,
  123.             ports: [{group: 'in'},{group: 'out'}],
  124.             data:{
  125.               percentage: item
  126.             }
  127.           });
  128.           const dnd = new Dnd({
  129.             target: this.graph,
  130.             // ☆拖拽结束时,验证节点是否可以放置到目标画布中。
  131.             validateNode: () => {
  132.               console.log('成功拖拽至目标画布')
  133.             },
  134.           })
  135.           dnd.start(node, e)
  136.       },
  137.     }
  138.   }
  139. </script>
复制代码
css部门
  1. <style type="text/css">
  2.   @keyframes ant-line {
  3.     to {
  4.     stroke-dashoffset: -1000
  5.     }
  6.   }
  7. </style>
  8. <style type="text/css" scoped>
  9.   .flow-dialog ::v-deep .el-dialog__body{
  10.     max-height: 85vh;
  11.     padding: 0;
  12.   }
  13.   .toolbar ::v-deep .el-button--small{
  14.     padding: 5px 10px;
  15.   }
  16.   .content {
  17.     width: 1180px;
  18.     height: 85vh;
  19.     display: flex;
  20.   }
  21.   .stencil {
  22.     width: 230px;
  23.     height: 100%;
  24.     position: relative;
  25.     margin-right: 10px;
  26.     border-right: 1px solid rgba(0, 0, 0, 0.08);
  27.     box-sizing: border-box;
  28.     text-align: center;
  29.   }
  30.   .stencil p{
  31.      margin: 0;
  32.      line-height: 37px;
  33.      border-bottom: 1px solid #00000008;
  34.      background-color: #f7f9fb;
  35.      font-size: 14px;
  36.      padding-left: 5px;
  37.      text-align: left;
  38.    }
  39.   .panel {
  40.     width: calc(100% - 230px);
  41.     height: 100%;
  42.   }
  43.   .panel .toolbar {
  44.     width: 100%;
  45.     height: 38px;
  46.     display: flex;
  47.     align-items: center;
  48.     background-color: #f7f9fb;
  49.     border-bottom: 1px solid rgba(0, 0, 0, 0.08);
  50.   }
  51.   .panel #containerShape {
  52.     width: 100%;
  53.     height: calc(100% - 10px) !important;
  54.   }
  55.   .percentage-value{
  56.     display: inline-block;
  57.     width: max-content;
  58.     background-color: #fff;
  59.     border: 1px solid #c2c8d5;
  60.     border-left: 4px solid #5F95FF;
  61.     border-radius: 4px;
  62.     box-shadow: 0 2px 5px 1px rgba(0, 0, 0, 0.06);
  63.     padding: 8px;
  64.     font-size: 16px;
  65.     margin-top: 10px;
  66.     text-align: left;
  67.   }
  68.   .percentage-content{
  69.     width: 100px;
  70.     max-width: 150px;
  71.     overflow: hidden;
  72.     font-size: 12px;
  73.     display: inline-block;
  74.   }
  75. </style>
复制代码
CustomNode.vue节点元素dom
  1. <template>
  2.   <span class="percentage-value">
  3.     <i style="margin-right: 5px;cursor: pointer;" @click="save()" class="el-icon-setting"/>
  4.     <span class="percentage-content">{{ percentage }}%</span>
  5.     <i @click="save()" class="el-icon-success data-start"/>
  6.   </span>
  7. </template>
  8. <script>
  9.   export default {
  10.     inject: ['getNode'],
  11.     data() {
  12.       return {
  13.         percentage: 50,
  14.       }
  15.     },
  16.     mounted() {
  17.       const cell = this.getNode();
  18.       this.percentage = cell.data.percentage;
  19.     },
  20.     methods: {
  21.       save(){
  22.         console.log("点击成功")
  23.       }
  24.     }
  25.   }
  26. </script>
  27. <style type="text/css" scoped>
  28. .percentage-value{
  29.    display: inline-block;
  30.    width: max-content;
  31.    background-color: #fff;
  32.    border: 1px solid #c2c8d5;
  33.    border-left: 4px solid #5F95FF;
  34.    border-radius: 4px;
  35.    box-shadow: 0 2px 5px 1px rgba(0, 0, 0, 0.06);
  36.    padding: 10px;
  37.    font-size: 16px;
  38. }
  39. .percentage-content{
  40.    width: 100px;
  41.    max-width: 150px;
  42.    overflow: hidden;
  43.    font-size: 12px;
  44.    display: inline-block;
  45. }
  46.   .data-start{
  47.     margin-right: 5px;
  48.     margin-left: 10px;
  49.     cursor: pointer;
  50.     color: #6bcc00;
  51.   }
  52. </style>
复制代码
相干官方文档x6.antv官网

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

刘俊凯

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表