antv x6 踩坑日记+屏幕适配方案

坑点

基于官方模版封装的 vue 组件节点

  • 坑一: 在点击拓扑图中触发 router.push() 事件 无法通过this 去调用 , 通过引入router 来实现导航跳转,这个时候可能会无法携带参数,这个时候重启一下项目就好。
  • 坑二: vue组件封装的节点 data 属性 和 节点传参数 的效果不一样 ,动态的属性,可以不用传过去,通过监听动态数值的改变 来进行API的调用,修改相应节点的数值。
  • 坑三: 节点事件参数中的 坐标 和 node.position 中的坐标不对应 这导致获取序列化 回显的时候,无法回显到固定的位置
// 伪代码
graph.on("node:moved", ({ x,y node}) => {
  // 两处的 x y  都代表 节点坐标  但是值不同
    const { x,y} = node.position()
    
    const xNewRem = x / this.currentFontSize;
    const yNewRem = y / this.currentFontSize;
    const data = node.getData()
    console.log('data',x,y,this.currentFontSize,node.position());
    node.setData({
      xRem: xNewRem,
      yRem: yNewRem,
    });
  });

大屏适配方案

基于大佬的帖子完成了 项目可视化适配 但是找遍了社区 找不到 antv x6 的屏幕适配方案,我基于rem 的思想,完成antv X6 适配大屏(16:9)的适配方案。宽窄屏幕未设置
项目 rem 适配 参考 1rem = 1vw 的比例 做
https://juejin.cn/post/6931708519976534029
https://www.njleonzhang.com/2018/08/15/flexible-pc-full-screen.html

  • 处于边学习边开发阶段 未进行封装处理
  mounted() {
    // 注册 vue component
    // 如果需要序列化/反序列化数据,必须使用该方式
    Graph.registerVueComponent(
      "count",
      {
        template: ``,
        components: {
          Count,
        },
      },
      true
    );
    const graph = new Graph({
      container: document.getElementById("graphBox"),
      width: 1800,
      height: 500,
      grid: true,
    });

    this.graph = graph;
    // 移动节点时  将坐标转化 rem     这里的参数中的 xy 与 node.positon 中的不一样 ???
    graph.on("node:moved", ({ node}) => {
      const { x,y} = node.position()
      
      const xNewRem = x / this.currentFontSize;
      const yNewRem = y / this.currentFontSize;
      const data = node.getData()
      console.log('data',x,y,this.currentFontSize,node.position());
      node.setData({
        xRem: xNewRem,
        yRem: yNewRem,
      });
    });
    // antv x6 屏幕适配
    window.addEventListener("resize", () => {
      
      // 所有的信息都是基于 1920 屏幕的比例   如果改变了比例要转换为1920比例进行转化
      const currentFontSize = +(
        document.documentElement.clientWidth / 10
      ).toFixed(1); // 获取当前 1rem 对比的 单位
      this.currentFontSize = currentFontSize;

      // 画布适配
      this.graph.resizeGraph(
        (1800 / 192) * currentFontSize,
        (600 / 192) * currentFontSize
      );
      // 所有节点 适配
      this.devs.forEach((item) => {
        // 注册时就是用的 设备id
        const node = this.graph.getCellById(item._id);
        if (node) {
          // 拿到 当前节点等 宽高 坐标 的Rem 信息
          const { widthRem, heightRem, xRem, yRem } = node.getData();
          // 设置节点的宽高
          node.resize(widthRem * currentFontSize, heightRem * currentFontSize);
          // 设置节点的位置
          node.position(xRem * currentFontSize, yRem * currentFontSize);
        }
      });
    });
  },
  • 以上代码 只做了屏幕宽度变化的画布 节点 适配,至于如何去实现保存起来的序列化布局数据也能实现适配,结合以下代码
  created() {
    // 屏幕初始值
    this.currentFontSize = +(document.documentElement.clientWidth / 10).toFixed(
      1
    );
  },
  methods:{
      // 获取系列化数据  保存数据  发送接口
    saveData() {
      const data = this.graph.toJSON();
      console.log("存储的布局信息", data);
      localStorage.setItem("layout", JSON.stringify(data));
    },
    // 测试 回显数据  回显示信息之前要获取屏幕宽度  根据rem 设置宽高和坐标的 绝对位置
    change() {
      const data = JSON.parse(localStorage.getItem("layout"));
      // 处理节点回显
      const nodeData =  data.cells.map(item=>{
        const {widthRem, heightRem, xRem, yRem} = item.data
        item.size.width = widthRem * this.currentFontSize
        item.size.height = heightRem * this.currentFontSize
        item.position.x = xRem * this.currentFontSize
        item.position.y = yRem * this.currentFontSize
        return item
      });
      this.graph.fromJSON(nodeData);
      console.log("回显的布局信息", nodeData);
    },
  }
  • 这里新增节点还有bug 下面代码处理一下
    addNode(obj) {
      const nodeTemplate = {
        id: obj._id,
        shape: "vue-shape",
        // 1920 设计稿下的 rem 
        x: this.pxToRem(200)*this.currentFontSize,
        y: this.pxToRem(150)*this.currentFontSize,
        width: this.pxToRem(150)*this.currentFontSize,
        height: this.pxToRem(100)*this.currentFontSize,
        data: {
          // 节点可以保存的值   这里存储的是 
          widthRem: this.pxToRem(150),
          heightRem: this.pxToRem(100),
          xRem: this.pxToRem(200),
          yRem: this.pxToRem(150),
        },
        component: "count",
      };
      this.graph.addNode(nodeTemplate);
    },
    pxToRem(px,rem = 192) {
      // 转化为1920 屏幕下的rem
      return px / rem;
    },

你可能感兴趣的:(antvX6,vue,vue.js,javascript,前端)