antv-x6 学习记录(1)

192 阅读3分钟

前言: 我是在vue里开发的, 根据文档: 在vue里面使用除了安装'@antv/x6', 需要额外安装'@antv/x6-vue-shape'。

image.png

这是用x6 画的简易关系图。 原型图还有蓝色tag 和灰色tag 首尾相连。

直接上代码:

<template>
  <div class="custom-node" :style="node.data.style">
    {{ node.data.label }}
  </div>
</template>

<script setup>
import { computed } from "vue";

const props = defineProps({
  node: {
    type: Object,
    required: true
  }
});
const node = computed(() => {
  return props.node;
});
// console.log(node.value);
</script>

<style lang="less" scoped>
.custom-node {
  width: fit-content;
  text-align: center;
  padding: 5px 18px;
  z-index: 12999;
  position: relative;
}
</style>


<template>
  <div ref="container" class="x6-container"></div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import { Graph } from "@antv/x6";
import { register } from "@antv/x6-vue-shape";
import NodeComponent from "./node.vue";
import { cloneDeep } from "lodash";

// 注册节点类型
register({
  shape: "vue-node",
  // shape 表示节点的类型,在创建addNode节点的时候,shape 属性对应就表示使用改类型节点
  component: NodeComponent
  // component 表示使用自定义节点
  // propHooks: (metadata) => ({
  //   t: console.log(metadata),
  //   data: metadata.data || {} // 确保传递 data 字段
  // })
});

const container = ref(null);
const graph = ref(null);

onMounted(() => {
    // 表示创建画布
  graph.value = new Graph({
    container: container.value,
    width: 1100,
    height: 400,
    grid: false,
    connecting: {
      router: "orth",
      connector: "rounded"
    }
  });

  const arr1 = [1, 1, 1];
  const arr2 = [2, 2];
  // 发出dash line
  const fromConfig = {
    shape: "vue-node", // 自定义节点type
    x: 50, // 在画布中的位置
    y: 130,
    width: 185,
    // 宽度
    
    //  最重要的点: 往自定义节点组件中传数据一定需要放到data中!!! 传入style 可以到时候动态绑定style
    data: {
      label: "http://swodjee.kn/c...",
      style: {
        minWidth: "185px",
        backgroundColor: "#4080FF",
        border: "1px solid #edd",
        borderRadius: "15px",
        color: "#fff"
      }
    },
    // ports 表示在节点上添加连接桩
    // 所谓的连接桩就是 两个节点连接线的首尾点。
    ports: {
      groups: {
        group1: {
          attrs: {
            circle: {
              r: 1, // 连接点的半径
              magnet: true,
              stroke: "#4080FF",
              strokeWidth: 2,
              fill: "#4080FF"
            }
          },
          position: { // 表示绝对定位
            name: "absolute"
          }
        }
      },
      
      // 所有连接点的集合
      items: [
        {
          id: "port1",
          group: "group1",
          // 通过 args 指定绝对位置
          // 待补充args
          args: { // 表示连接点相对于节点的位置
            x: 170,
            y: 20
          },
          attrs: {
            text: { text: "" }
          }
        }
      ]
    }
  };
  //接收dash line
  const toConfig = {
    shape: "vue-node",
    x: 285,
    y: 130,
    width: 85,
    data: {
      label: "关系",
      style: {
        minWidth: "85px",
        border: "1px solid #edd",
        backgroundColor: "rgb(0,0,0,.05)",
        borderRadius: "15px"
      }
    },
    ports: {
      groups: {
        group1: {
          attrs: {
            circle: {
              r: 1,
              magnet: true,
              stroke: "#f2f2f2",
              strokeWidth: 2,
              fill: "#f2f2f2"
            }
          },
          position: {
            name: "absolute"
          }
        }
      },
      items: [
        {
          id: "port2",
          group: "group1",
          // 通过 args 指定绝对位置
          args: {
            x: "-1",
            y: "20"
          },
          // 这里是连接点的文字!
          attrs: {
            text: { text: "" }
          }
        }
      ]
    }
  };
  const step = 365;

  function handleAddNode(config, index, Y = false) {
    const temp = cloneDeep(config);
    const nodeConfig = { ...temp };
    nodeConfig.x = nodeConfig.x + index * step;
    if (Y) {
      nodeConfig.y = 230;
    }
    // 创建节点
    graph.value.addNode(nodeConfig);
  }

  arr1.forEach((_, index) => {
    handleAddNode(fromConfig, index);
    handleAddNode(fromConfig, index, true);
  });

  arr2.forEach((_, index) => {
    handleAddNode(toConfig, index);
    handleAddNode(toConfig, index, true);
  });

  // 公共边节点
  const node4_4 = graph.value.addNode({
    shape: "vue-node",
    x: 980,
    y: 180,
    width: 85,
    data: {
      label: "关系",
      style: {
        border: "1px solid #edd",
        backgroundColor: "rgb(0,0,0,.05)",
        borderRadius: "15px"
      }
    },
    ports: {
      groups: {
        group1: {
          attrs: {
            circle: {
              r: 1,
              magnet: true,
              stroke: "#f2f2f2",
              strokeWidth: 2,
              fill: "#f2f2f2"
            }
          },
          position: {
            name: "absolute"
          }
        }
      },
      items: [
        {
          id: "port11",
          group: "group1",
          // 通过 args 指定绝对位置
          // 待补充args
          args: {
            x: 40,
            y: 0
          },
          attrs: {
            text: { text: "" }
          }
        },
        {
          id: "port22",
          group: "group1",
          // 通过 args 指定绝对位置
          // 待补充args
          args: {
            x: 40,
            y: 40
          },
          attrs: {
            text: { text: "" }
          }
        }
      ]
    }
  });

  // 这里到时候需要给出各个节点之前的关系 每个节点需要有唯一的nodeName。然后给出各个节点之间的关联关系 通过nodeName 关联!!

  // // 创建边(关键配置)
  // const edge1 = graph.value.addEdge({
  //   source: {
  //     port: "port1",
  //     cell: node1
  //   },
  //   target: {
  //     port: "port2",
  //     cell: node2
  //   },
  //   router: "orth", // 正交路由
  //   connector: "rounded", // 圆角连接器
  //   attrs: {
  //     line: {
  //       stroke: "#4080FF",
  //       strokeDasharray: 5,
  //       // 隐藏箭头必须设置null 删除这个属性不行!
  //       targetMarker: null
  //     }
  //   }
  // });
  // console.log(graph.value.toJSON());

   // 导出数据
  // const test = graph.value.toJSON();
  // test.cells.map((item) => {
  //   item.ports.items[0].id = item.id;
  // });
  // console.log(test);
  // graph.value.fromJSON(test);
  // 导入节点数据 
  // console.log(graph.value.toJSON());
});
</script>

<style>
.x6-container {
  border: 1px solid #eaeaea;
  margin: 20px;
}

.custom-node {
  border-radius: 200px;
  border: 2px solid #fff;
  box-shadow: 0px 4px 16px 0px rgba(0, 0, 0, 0.16);

  .test {
    background-color: #4080ff;
    color: #fff;
  }
  .test1 {
    background-color: #fff;
    color: var(---1, #242933);
  }
}
</style>