likes
comments
collection
share

记一期@antv/x6的踩坑使用

作者站长头像
站长
· 阅读数 13

概述

X6 是 AntV 旗下的图编辑引擎,提供了一系列开箱即用的交互组件和简单易用的节点定制能力,方便我们快速搭建流程图、DAG 图、ER 图等图应用,下面记录几个使用过程中遇到的几个坑.

坑1

使用X6的时候一定要和官网示例所给的版本号保持一致,如果直接无脑下载最新版使用,会发现最后很多接口没有提供或者已经在高版本弃用,而官方文档所给示例还是以前旧版本的,详情见使用 HTML/React/Vue/Angular 渲染中提供的vue结合使用的demon

坑2

流程图中除了官网所给的基础的节点和边,在实际项目中必然涉及到非常高的自定义扩展,特别是ui方面,因此需要使用对应x6所提供的扩展节点和自定义节点的相关方法,详情见:使用 HTML/React/Vue/Angular 渲染

示例

文章以vue2版本为例

  • APP.vue
<template>
  <div>
    <el-button @click="addHTMLNode">追加HTML节点</el-button>
    <el-button @click="addElButtonNode">追加ElButton节点</el-button>
    <el-button @click="addELDatePickerNode">追加DatePicker节点</el-button>
    <el-button @click="download">下载</el-button>
    <div class="container"></div>
    <div class="container-mini-map" ref="containerMiniMap"></div>
  </div>
</template>

<script>
import { Graph, DataUri } from "@antv/x6";
import "@antv/x6-vue-shape";
import Button from "./components/Button.vue";
import DatePicker from "./components/DatePicker.vue";
Graph.registerNode("el-button", {
  inherit: "vue-shape",
  x: 200,
  y: 150,
  width: 150,
  height: 100,
  component: {
    render: (h) => h(Button),
  },
});
Graph.registerNode("el-date-picker", {
  inherit: "vue-shape",
  x: 200,
  y: 150,
  width: 150,
  height: 100,
  component: {
    render: (h) => h(DatePicker),
  },
});
export default {
  data() {
    return {
      graph: null,
    };
  },
  mounted() {
    this.init();
  },
  methods: {
    addElButtonNode() {
      this.graph.addNode({
        x: 40,
        y: 40,
        width: 100,
        height: 40,
        shape: "el-button",
      });
    },
    addELDatePickerNode() {
      this.graph.addNode({
        x: 40,
        y: 40,
        width: 100,
        height: 40,
        shape: "el-date-picker",
      });
    },
    addHTMLNode() {
      const source = this.graph.addNode({
        x: 40,
        y: 40,
        width: 100,
        height: 40,
        shape: "html",
        html() {
          const wrap = document.createElement("div");
          wrap.style.width = "100%";
          wrap.style.height = "100%";
          wrap.style.background = "#008c8c";
          wrap.style.display = "flex";
          wrap.style.justifyContent = "center";
          wrap.style.alignItems = "center";
          wrap.innerText = "html节点";
          return wrap;
        },
      });
    },
    download() {
      this.graph.toSVG((dataUri) => {
        DataUri.downloadDataUri(DataUri.svgToDataUrl(dataUri), "chart.svg");
      });
    },
    init() {
      const data = {
        // 节点
        nodes: [
          {
            id: "node1", // String,可选,节点的唯一标识
            x: 40, // Number,必选,节点位置的 x 值
            y: 40, // Number,必选,节点位置的 y 值
            width: 80, // Number,可选,节点大小的 width 值
            height: 40, // Number,可选,节点大小的 height 值
            label: "hello", // String,节点标签
          },
          {
            id: "node2", // String,节点的唯一标识
            x: 160, // Number,必选,节点位置的 x 值
            y: 180, // Number,必选,节点位置的 y 值
            width: 80, // Number,可选,节点大小的 width 值
            height: 40, // Number,可选,节点大小的 height 值
            label: "world", // String,节点标签
          },
        ],
        // 边
        edges: [
          {
            source: "node1", // String,必须,起始节点 id
            target: "node2", // String,必须,目标节点 id
          },
        ],
      };
      this.graph = new Graph({
        container: document.querySelector(".container"),
        history: true,
        selecting: {
          enabled: true,
          rubberband: true, // 启用框选
          className: "my-selecting",
        },
        panning: {
          // enabled: true,
        },
        scroller: {
          enabled: true,
        },
        minimap: {
          enabled: true,
          container: this.$refs.containerMiniMap,
        },
        background: {
          color: "#fffbe6", // 设置画布背景颜色
        },
        grid: {
          size: 10, // 网格大小 10px
          visible: true, // 渲染网格背景
        },
      });
      this.graph.fromJSON(data);
    },
  },
};
</script>

<style >
.container {
  width: 80% !important;
  min-height: 500px !important;
}
.container-mini-map {
  width: 300px;
  height: 300px;
  border: 1px solid red;
}
.my-selecting {
  border: 1px solid red;
}
</style>
  • ./component/Button.vue
<template>
  <div>
    <el-button type="primary" @click="handlePrimaryClick">按钮</el-button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      value: "",
    };
  },
  components: {},
  methods: {
    handlePrimaryClick() {
      console.log("primary-click");
    },
  },
};
</script>

<style lang='less'>
</style>

  • ./component/DatePicker.vue
<template>
  <div>
    <el-date-picker
      type="date"
      v-model="value"
      placeholder="请输入"
    ></el-date-picker>
  </div>
</template>

<script>
export default {
  data() {
    return {
      value: "",
    };
  },
  components: {},
  methods: {
    handlePrimaryClick() {
      console.log("primary-click");
    },
  },
};
</script>

<style lang='less'>
</style>

  • main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.config.productionTip = false
Vue.use(ElementUI)
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

  • package.json 注意对应包的版本要保持一致
{
  "name": "vue2-project-test",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build"
  },
  "dependencies": {
    "@antv/x6": "1.12.14",
    "@antv/x6-vue-shape": "1.1.4",
    "element-ui": "2.15.0",
    "core-js": "^3.8.3",
    "vue": "^2.6.14",
    "vue-grid-layout": "^2.4.0",
    "vue-router": "^3.5.1",
    "vuex": "^3.6.2"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~5.0.0",
    "@vue/cli-plugin-router": "~5.0.0",
    "@vue/cli-plugin-vuex": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "less": "^4.0.0",
    "less-loader": "^8.0.0",
    "vue-template-compiler": "^2.6.14"
  }
}

最终效果

记一期@antv/x6的踩坑使用

转载自:https://juejin.cn/post/7246657502842863677
评论
请登录