likes
comments
collection
share

「AntV」如何用AntV X6实现思维导图节点收缩功能?

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

上一篇文章写的是怎么用X6做一个类似于processOn的思维导图,但是是没有做节点的收缩展开功能的,这种功能应该如何实现呢? 「AntV」如何用AntV X6实现思维导图节点收缩功能? 「AntV」如何用AntV X6实现思维导图节点收缩功能?

处理收缩节点按钮生成

上一篇文章中,在注册html节点时,有一个creatHtmlDom的方法,内部存在一个创建子节点的createChildNode的方法(当前只放了当前功能相关的代码)

export const createChildNode = (data, propsData) => {
  // 创建子节点部分
  ...
  ...
  // 核心部分,创建收缩节点时那个圈圈节点
  if (data.children && data.children.length) {
    const collapseNode = document.createElement("span");
    const isCollapsed = !!data.collapsed;
    let originName = "";
    if (isCollapsed) {
      originName = "mindmap__wrap-collapsed";
      if (data.count > 99) {
        const i = document.createElement("i");
        i.classList.add("xq-icon-more");
        collapseNode.appendChild(i);
      } else {
        collapseNode.innerText = data.count;
      }
    } else {
      originName = "mindmap__wrap-open";
    }

    let collapseName = "";
    collapseNode.className = originName;

    if (propsData.direction == "LR") {
      collapseName = originName + "-right";
    } else if (propsData.direction == "RL") {
      collapseName = originName + "-left";
    } else if (propsData.direction == "TB") {
      collapseName = originName + "-bottom";
    } else {
      collapseName = originName + "-top";
    }
    // 这个是处理节点居中还是不居中的模式,不用考虑
    if (!propsData.heightCenter) {
      collapseNode.classList.add("not-center");
    }

    collapseNode.classList.add(collapseName);
    // 绑定收缩展开事件
    collapseNode.setAttribute("event", "node:collapse");
    collapseNode.style.borderColor = data.textLine || propsData.textLine;

    collapseNode.style.background = propsData.backgroundColor;
    collapseNode.style.color = data.textLine || propsData.textLine;
    textNode.appendChild(collapseNode);
  }
  // wrap:子节点最顶级
  // textNode: 文字节点
  wrap.appendChild(textNode);
  
}

// 样式核心部分
// 通过opacity来控制节点的显示与隐藏,如果通过visible之类的控制,会有鼠标悬停到节点没有触发节点展示的bug
.mindmap__wrap-open {
  opacity: 0;
}
.mindmap__wrap-collapsed {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-width: 1px;
  border-style: solid;
  border-radius: 7px;
  position: absolute;
  // visibility: hidden;
  cursor: pointer;

  &:hover {
    opacity: 1;
  }
}
// 其他部分就是处理对圈圈节点的定位了(注意组件上下左右四个方向的布局)

处理收缩展开事件

 this.graph.on("node:collapse", ({ node, e }) => {
        const p = node.getPosition();
        const _nodeData = node.data.nodeData;
        const children = _nodeData.children;
        // 获取当前节点收缩效果,true代表当前节点的子节点都被收缩,false则相反
        const hasCollapsed = _nodeData.collapsed;
        // 计算当前节点下子节点的全部数量
        const count = collapsedNodes(children);
        
        // 找到目标数据并设置切换数据效果
        // 注意:这个字段如何有作用?往下看
        let { node: node2 } = findItem(this.mindData, _nodeData.id);
        // 给数据设置hasCollapsed
        Vue.set(node2, "collapsed", !hasCollapsed);
        // 这个count做节点收缩时,展示的数据
        node2.count = count;
        // 重置编辑节点
        // 目的是,当前操作`node:collapse`事件时,如果当前画布中存在编辑类型的输入框节点,
        // 需要将输入框转成正常节点
        this.resetEditNode();
        if (
          !hasCollapsed &&
          this.originChoosedNode &&
          this.originChoosedNode.dataset.id !== _nodeData.id
        ) {
          this.currentData = {};
        }
        e.stopPropagation();
        // 注意!!!非常重要
        // 当收缩的当前节点子节点数量过大时,会造成画布偏移,
        // 你点击时,圈圈的位置跟你收缩后,节点位置不一致(看下面两张图),此时需要计算画布偏移量进行重新归位
        setTimeout(() => {
          const _node = this.graph.getCellById(node.id);
          const p2 = _node.getPosition();

          const pTranslate = this.graph.translate();
          // 注意!一定要乘以缩放比例,不然纵向布局无法定位到刷新之前的位置
          const zoom = this.graph.zoom();
          const deviationX = pTranslate.tx - (p2.x - p.x) * zoom;
          const deviationY = pTranslate.ty - (p2.y - p.y) * zoom;

          this.graph.translate(deviationX, deviationY);
        });
      });

「AntV」如何用AntV X6实现思维导图节点收缩功能?「AntV」如何用AntV X6实现思维导图节点收缩功能?

如何让收缩事件生效?

getChildren: (d) => { 
    // 此部分是收缩节点时使用 
    const hasCollapsed = !!d.collapsed; 
    return hasCollapsed ? null : d.children; 
},

「AntV」如何用AntV X6实现思维导图节点收缩功能?

好了,让我们看看效果: 我录了视频但是我不会放,谁会的可以教教我。。。

「AntV」如何用AntV X6实现思维导图节点收缩功能?「AntV」如何用AntV X6实现思维导图节点收缩功能?

最后,感谢大家阅读我的小文章,请帮我点亮一下我的小心心吧!!!

「AntV」如何用AntV X6实现思维导图节点收缩功能? 「AntV」如何用AntV X6实现思维导图节点收缩功能? 「AntV」如何用AntV X6实现思维导图节点收缩功能?
转载自:https://juejin.cn/post/7283798844235808803
评论
请登录