前言
最近接手的项目中有个功能,需要实现股权穿透图的效果。由于自己是第一次实现该功能,通过上网查找相关资料学习和研究,最终实现了需求。谨以此篇记录自己的成长过程。同时也希望能够帮助到遇到相关需求的同学。
企查查效果图:
查看企查查中的股权穿透图效果我们发现人家这个东西做的还是比较细节和完整的,而我们只需要实现核心功能就行了。
最终实现的效果图
实现功能
- 包含子节点时支持展开、收起
- 支持股权图的拖拽、大小缩放
- 支持图片下载、重置
- 鼠标移入展示详情弹窗
遇到问题
设置zoom缩放时不生效
js
this.svg = d3.select('#app')
.append('svg')
.attr('width', svgW)
.attr('height', svgH)
.attr('id', 'treesvg')
.call(d3.zoom().scaleExtent([0, 5])
.on('zoom',
() => {
this.svg.attr('transform',
d3.event.transform.translate(svgW / 2, svgH / 2));
})
)
直接使用网上相关资料的这代码是会报错,需要在绑定zoom事件时的函数中拿到event参数
正确写法:
js
.on("zoom", (e) => {
this.svg.attr('transform',e.transform.translate(0, 0));
})
)
点击+-按钮子节点没反应
直接使用资料中的这段代码,发现绑定的click事件不生效,也不报错。
经过排查后来发现是这个回调函数参数的问题 ,第一个参数是event
对象,第二个参数d
才是svg的对象
正确写法:
js
// ...
.on("click", (e, d) => {
// ...
});
详情弹窗频繁触发问题
在实现鼠标移入节点展示弹窗详情的效果时,最先开始的思路是拿到dom的event参数中x、y坐标点,设置弹窗盒子的定位top、left。 虽然能实现鼠标移入展示弹框,但是当鼠标频繁在dom上移动而不移出时,此时的弹框也会频繁的显隐。
-
解决方案1 使用函数防抖,限制一下
mouseenter
事件 -
解决方案2 借鉴了网上资料后使用
getBoundingClientRect()
方法获取svg边界,可以拿到对应边界坐标
js
rectMouseenterHandler(e,d){
const svg = document.querySelector(`rect[id="${d.id}"]`);
const rect = svg.getBoundingClientRect();
const {top,right,bottom} = rect
}
相关知识点
- d3.tree -- 创建一个新的整齐(同深度节点对齐)的树布局.
- d3.zoom -- 创建一个缩放交互.
- d3.select -- 从文档中选取一个元素.
- d3.hierarchy -- 从给定的层次结构数据构造一个根节点并为各个节点指定深度等属性.
- zoom.scaleExtent -- 设置可缩放系数大小.
- transform.translate -- 根据指定的值平移当前坐标变换.
- transition.remove -- 在过渡结束后移除选中的元素.
- tree.nodeSize -- 设置节点尺寸.
- tree.separation -- 设置两个相邻的节点之间的间距.
- node.descendants -- 从当前节点开始返回其后代节点数组.
- selection.selectAll -从每个被选中的元素中选择多个后代元素.
- selection.data -- 将元素与数据绑定.
- selection.enter -- 获取需要插入的选择集(数据个数大于元素个数)的占位符.
- selection.exit -- 获取多余的元素的选择集(数据个数小于元素个数).
- selection.on -- 添加或移除事件监听器.
- selection.attr -- 设置或获取属性.
- selection.style -- 获取或设置样式属性.
- selection.text -- 设置或获取文本内容.
- selection.append -- 创建、添加并返回一个新的元素.
- selection.insert -- 创建、插入并返回一个新的元素.
- selection.remove -- 从文档中移除元素.
- transition.duration -- 指定每个过渡元素的过渡时间(毫秒).
相关资料
实现的过程中主要参考了这篇文章,收获颇多,感谢作者! d3.js开发股权穿透图分享 - 掘金 (juejin.cn)
完整代码
完整代码请移步github:vue2+d3实现的股权穿透图 (github.com)
总结
虽然开发中有的需求,网上有已经实现好的类似的轮子,有时候想节省成本拿来直接用,但未必拿来就能用!可能因为开发环境报错、依赖版本问题报错、或者代码就有问题。
不管是拿来改造用还是参考用,我们都要弄清楚代码逻辑和思路。最重要的是还需要加入自己的思考,虽然刚开始很难搞,一头雾水,但当我们彻底理解实现后发现会有不少的收获。
如果文章对你有帮助,可以点赞、评论、收藏、转发互动支持哈 😀😀😀
点击链接 学习交流群(前端微信群) 加vx拉你进 前端学习交流群 让我们一起 好好学习(🐟🐟🐟)吧😎😎😎