程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

了解AntV/x6

发布于2023-05-20 19:42     阅读(840)     评论(0)     点赞(7)     收藏(5)


先放官网和图片,最好的学习地方仍然是官网。

官网:https://x6.antv.antgroup.com/

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

这个流程图其实是Echarts没有的,相信很多和我一样的人。做项目要用到Echarts没有,然后就搜索到了这个。你如果会用Echarts,其实你已经会了一半,虽然Echarts是基于Canvas画图的,但是两者的用法和API调用基本相同,实际用起来去官网看API即可。

一、了解antv/x6

刚才上面提到了它是基于 HTMLSVG 的图编辑引擎,我们可以简单的理解成,我创建了一个SVG标签,给这的SVG标签设置各种的规则,然后特定的API/标签在里面画图,最后用事件触发把他们联系在一起。

步骤:

  1. 创建一个标签,成为容器container

  1. 声明一些需要的节点/边的数据

  1. new一个实例对象,使用antv/x6的API在里面设置画布的规则

  1. 把数据放入这个实例中,在画布中渲染出来

这里示范的是vue2+antv/x6

  1. <template>
  2. <div id="home">
  3. <div>
  4. <button class="btn" @click="this.toSVG">导出</button>
  5. </div>
  6. <div id="container"></div>
  7. </div>
  8. </template>
  9. <script>
  10. // 引入antv/x6
  11. import { Graph, DataUri } from "@antv/x6";
  12. export default {
  13. name: "APP",
  14. data() {
  15. return {
  16. graph: null, // 画布实例对象
  17. data: {
  18. nodes: [
  19. {
  20. id: "node1",
  21. shape: "rect",
  22. x: 100,
  23. y: 100,
  24. width: 80,
  25. height: 40,
  26. label: "hello",
  27. },
  28. {
  29. id: "node2",
  30. shape: "ellipse",
  31. x: 240,
  32. y: 300,
  33. width: 80,
  34. height: 40,
  35. label: "world",
  36. },
  37. ],
  38. edges: [
  39. {
  40. source: "node1",
  41. target: "node2",
  42. shape: "double-edge",
  43. },
  44. ],
  45. },
  46. };
  47. },
  48. created() {},
  49. mounted() {
  50. this.initGraph();
  51. },
  52. methods: {
  53. /** 初始化流程图画布 */
  54. initGraph() {
  55. /** 使用Graph API创造出实例对象,开始在SVG上画图/事件处理 */
  56. this.graph = new Graph({
  57. container: document.getElementById("container"), // 画布容器
  58. width: 800, // 画布宽
  59. height: 600, // 画布高
  60. background: {
  61. color: "#ffffff",
  62. }, // 背景颜色设置
  63. snapline: true, // 对齐线
  64. // 配置连线规则
  65. connecting: {
  66. snap: true, // 自动吸附
  67. allowBlank: true, //是否允许连接到画布空白位置的点
  68. allowMulti: false, //是否允许在相同的起始节点和终止之间创建多条边
  69. allowLoop: false, //是否允许创建循环连线,即边的起始节点和终止节点为同一节点
  70. highlight: true, //拖动边时,是否高亮显示所有可用的节点
  71. validateEdge({ edge, type, previous }) {
  72. // 连线时设置折线
  73. edge.setRouter({
  74. name: "er",
  75. });
  76. // 设置连线样式
  77. edge.setAttrs({
  78. line: {
  79. stroke: "#275da3",
  80. strokeWidth: 4,
  81. },
  82. });
  83. return true;
  84. },
  85. },
  86. panning: {
  87. enabled: false, // 支持画布拖拽平移
  88. },
  89. mousewheel: {
  90. enabled: true, // 支持滚动放大缩小
  91. },
  92. // 网格设置
  93. grid: {
  94. type: "mesh",
  95. size: 20, // 网格大小 10px
  96. visible: true, // 渲染网格背景
  97. args: {
  98. color: "#000000", // 网格线/点颜色
  99. thickness: 2, // 网格线宽度/网格点大小
  100. },
  101. },
  102. translating: {
  103. restrict: true,
  104. },
  105. });
  106. this.graph.fromJSON(this.data);
  107. },
  108. /** 点击导出SVG */
  109. toSVG() {
  110. this.graph.toSVG((dataUri) => {
  111. // 下载
  112. DataUri.downloadDataUri(DataUri.svgToDataUrl(dataUri), "chart.svg");
  113. });
  114. },
  115. },
  116. };
  117. </script>
  118. <style lang="scss" scoped>
  119. .btn {
  120. width: 10vw;
  121. height: 5vh;
  122. background: #bbffff;
  123. margin: 10px;
  124. border: 1px solid #000000;
  125. }
  126. </style>

这样一个最简单的数据指向图就做好了,但是我们做的肯定没有那么简单,一般情况下需要可以进行链接,拖拽进入可以生成新的模块,连接的点那些可以连接/不可以连接等。这里就需要设置连接桩/交互/事件等,接着往下看,切记一定要沉下心来,这里出错了有的是不会显示的,需要配合Console和console.log一起来找。

二、Graph的配置

官网上是以画布/节点/边/连接桩/交互/事件/数据的顺序介绍的,我也以此开始讲解,官网更加清晰,可以直接移步官网查看。

  1. 画布

这个画布在上面的代码中已经写过了,就是设置画布的背景颜色/大小/缩放/网格等,这个比较简单,需要什么直接放进去就可以实现了。

  1. 节点

上面的代码我是把数据放在data里面(官网是放在initGraph()里面),最后通过数据的导入,实现画布的渲染。如果是十个以内的数据还好,一旦多起来,可以发现里面有很多的相同的属性/数据,这里的节点相当于是毛胚房,你想要什么样的房子自己装修就好。

官方解释:节点和边都有共同的基类 Cell,除了从 Cell 继承属性外,其他的可以在graph.addNode( )设置,可以实现定制节点/修改节点。

这里有一个坑一定要注意: graph.fromJSON()和graph.addNode()的顺序,graph.fromJSON()在前,不然会看不见添加的节点。

明白了这一个,那么我们就知道了,添加所有的这种相似的都可以使用此方法。如果我们要拖拽一个模板进来,就相当于在其中添加了一个定制的节点,其位置就是鼠标放开的位置。

步骤:

  1. 注册节点 Graph.registerNode()

  1. 使用注册的节点

  1. 添加这两个节点边(箭头)

  1. //和官网一样直接添加在initGraph()里面就可以了
  2. //这里有一个坑一定要注意: graph.fromJSON()和graph.addNode()的顺序,graph.fromJSON()在前,不然会看不见添加的节点
  3. Graph.registerNode(
  4. "custom-node",
  5. {
  6. inherit: "rect", // 继承于 rect 节点
  7. width: 100,
  8. height: 40,
  9. markup: [
  10. {
  11. tagName: "rect", // 标签名称
  12. selector: "body", // 选择器
  13. },
  14. {
  15. tagName: "image",
  16. selector: "img",
  17. },
  18. {
  19. tagName: "text",
  20. selector: "label",
  21. },
  22. ],
  23. attrs: {
  24. body: {
  25. stroke: "#8f8f8f",
  26. strokeWidth: 1,
  27. fill: "#fff",
  28. rx: 6,
  29. ry: 6,
  30. },
  31. img: {
  32. "xlink:href":
  33. "https://gw.alipayobjects.com/zos/antfincdn/FLrTNDvlna/antv.png",
  34. width: 16,
  35. height: 16,
  36. x: 12,
  37. y: 12,
  38. },
  39. },
  40. },
  41. true
  42. );
  43. const source = graph.addNode({
  44. shape: 'custom-node', // 可以直接使用上面注册过的 shape
  45. x: 40,
  46. y: 40,
  47. label: 'hello',
  48. })
  49. const target = graph.addNode({
  50. shape: 'custom-node',
  51. x: 160,
  52. y: 180,
  53. label: 'world',
  54. })
  55. //修改节点的数据
  56. source.prop("size", { width: 120, height: 50 }); // 修改 x 坐标
  57. source.attr("rect/fill", "#ccc"); // 修改填充色,等价于 source.prop('attrs/rect/fill', '#ccc')
  58. graph.addEdge({
  59. source,
  60. target,
  61. attrs: {
  62. line: {
  63. stroke: '#8f8f8f',
  64. strokeWidth: 1,
  65. },
  66. },
  67. })
  1. 边(箭头)

这里官网上的意思是Edge边,但是我自己更习惯称为箭头,感觉更贴切吧。

edge里面的配置:

  1. source: rect1, target: rect2, 源 ---> 节点

  1. vertices: [ { x: 100, y: 200 }, { x: 300, y: 120 }, ], 顶点(边经过的顶点)

  1. router: "orth", 路径:默认是直线;

  1. connector: { name: "rounded", args: {}, },简写写 connector: 'rounded'连接器:圆形的

  1. labels: [ { attrs: { label: { text: "edge", }, }, position: 0.4,}, ],设置标签文本、位置、样式等。简化写法:labels: ["edge"],

  1. 设置边上的箭头(这里可以直接设用已经预设好的)

  1. attrs: {
  2. line: {
  3. sourceMarker: "block", // 实心箭头
  4. targetMarker: {
  5. name: "ellipse", // 椭圆
  6. rx: 10, // 椭圆箭头的 x 半径
  7. ry: 6, // 椭圆箭头的 y 半径
  8. },
  9. },
  10. },

7.修改边与修改节点的方式有所不同,节点是不统一的,哪一个修改就是哪一个。边是统一的的,直接使用edge.prop("target", { x: 300, y: 300 }); // 修改终点e

dge.attr("line/stroke", "#ccc"); // 修改边颜色,等价于 edge.prop('attrs/line/stroke', '#ccc')

  1. 连接桩

就是每个节点连接的位置,有几个/在那个位置/应该怎么连接等。

步骤:

  1. 在 Graph.registerNode()注册的节点中配置ports,并通过 groups 选项来设置分组

  1. groups内分上下左右,再对上下的port设置即可

  1. 在添加节点的时候graph.addNode因为加入了ports,也需要在其中配置ports的属性

  1. 交互(连接的配置)

主要记住这个连接的配置是在画布上的,new Graph({})

这个记不住的,直接翻过去照着一个个找,用就对了。

  1. 事件

看代码很容易理解,监听画布的 cell节点/单击、节点/单击、边/单击、空白区域/单击

这里数据太多,演示也多,直接去官网

  1. graph.on("cell:click", ({ e, x, y, cell, view }) => {});
  2. graph.on("node:click", ({ e, x, y, node, view }) => {});
  3. graph.on("edge:click", ({ e, x, y, edge, view }) => {});
  4. graph.on("blank:click", ({ e, x, y }) => {});
  5. graph.on("cell:mouseenter", ({ e, cell, view }) => {});
  6. graph.on("node:mouseenter", ({ e, node, view }) => {});
  7. graph.on("edge:mouseenter", ({ e, edge, view }) => {});
  8. graph.on("graph:mouseenter", ({ e }) => {});
  1. 数据

导出数据

  1. graph.toJSON()导出的是json数据

  1. 导出SVG或者png这里需要引入DataUri,这里导出的大小有问题,需要自己设置

  1. // 引入antv/x6
  2. import { Graph, DataUri } from "@antv/x6";
  3. /** 点击导出SVG */
  4. toSVG() {
  5. graph.toSVG((dataUri) => {
  6. // 下载
  7. DataUri.downloadDataUri(DataUri.svgToDataUrl(dataUri), "chart.svg");
  8. });
  9. },

导入数据

导入就只能是json数据了

graph.fromJSON({ nodes: [], edges: [],});

小结:其实看完这些,做起一些简单的还是ctrl+C / V就行了,但是涉及到逻辑的连接以及对数据的有一些要求时,其中的判断就会很多,慢慢写就好。

接下来,我会自己做一个逻辑的部署图,仅供参考/持续更新

原文链接:https://blog.csdn.net/weixin_73416102/article/details/129779711




所属网站分类: 技术文章 > 博客

作者:西门费雪

链接:http://www.qianduanheidong.com/blog/article/528233/ee2c4e98fea263874445/

来源:前端黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

7 0
收藏该文
已收藏

评论内容:(最多支持255个字符)