使用vue.js+d3生成树以及遇到的坑

本文介绍了如何使用vue.js和d3库构建树图,包括安装步骤、代码实现、处理SVG文本溢出以及点击显示完整标题的技巧。在过程中遇到了SVG text的overflow问题,通过foreignObject解决了这个问题,同时分享了使用element-ui提示框的体验和避免scoped影响CSS样式的解决方案。
摘要由CSDN通过智能技术生成

1. vue.js

安装vue.js

最新稳定版本
$ npm install vue
最新稳定 CSP 兼容版本
$ npm install vue@csp

2. d3

安装d3

$ npm i d3 --save

vue中引入

import * as d3 from 'd3'

3. 代码部分

(1)生成树实现

参考:https://www.jianshu.com/p/4e517d4c3885
参考文章里实现了点击节点会收起子节点功能,由于我的需求里没有用到就删除了那部分,如果有需要的去原文章里看哦~
(在实现中根据需求我将树的圆形结点改为了矩形结点,需要圆形结点可将)

nodeEnter.append("rect")

改为

nodeEnter.append("circle")

生成树部分代码

<script>
const dataset = {
   
    name:"标题1",
    children:[
    			{
   
    				name:"标题2标题2标题2标",
    				children:[
    					{
   
    						name:"标题3",
    						children:[
    							{
   name:"标题4",value:100},
    						]
    					},
    					{
   name:"标题3",value:100},
            			{
   name:"标题3",value:100},
    				]
    			},
    			{
   
    				name:"标题2标题2标",
    				children:[
    					{
   name:"标题3" ,value:100},
    					{
   name:"标题3",value:100},
            			{
   name:"标题3",value:100},
    				]
    			}
    		]
}
import * as d3 from 'd3'
export default {
   
	name: 'Scale',
	data() {
   
			return {
   
				id: '',
				zoom: null,
				index: 0,
				duration: 750,
				root: null,
				nodes: [],
				links: [],
				dTreeData: null,
				transform: null,
				margin: {
    top: 0, right: 90, bottom: 30, left: 180 }
				
			}
	},
	methods: {
   
		uuid () {
   
            function s4 () {
   
                return Math.floor((1 + Math.random()) * 0x10000)
                    .toString(16)
                    .substring(1)
            }
            return (
                s4() + s4() + '-' + s4() + '-' + s4() +  '-' + s4() + '-' + s4() + s4() + s4()
            )
        },
        /**
         * @description 获取构造根节点
         */
        getRoot () {
   
            let root = d3.hierarchy(dataset, d => {
    
                return d.children
            })
            root.x0 = this.height / 2
            root.y0 = 0
            return root
        },
        clicktext (d) {
   
            this.$alert(d.data.name, '标题名称', {
   
            confirmButtonText: '确定',
          });
        },
        diagonal (s, d) {
   
            return `M ${
     s.y} ${
     s.x}
                    C ${
     (s.y + d.y) / 2} ${
     s.x},
                    ${
     (s.y + d.y) / 2} ${
     d.x},
                    ${
     d.y} ${
     d.x}`
        },

        /**
         * @description 获取构造的node数据和link数据
         */
        getNodesAndLinks () {
   
            // 树状图根据根节点生成新的x、y坐标, 
            // 所以不能使用vue的计算螺旋桨
            this.dTreeData = this.treemap(this.root)
            this.nodes = this.dTreeData.descendants()
            this.links = this.dTreeData.descendants().slice(1)
		},
		/** 
         * @description 数据与Dom进行绑定
         */
        update (source) {
   
            this.getNodesAndLinks()
            this.nodes.forEach(d => {
    
                d.y = d.depth * 140
            })
            // *************************** Nodes section *************************** //
            // 更新节点
            const svg = d3.select(this.$el).select('svg.d3-tree')
            const container = svg.select('g.container')
            let node = container.selectAll('g.node')
                .data(this.nodes, d => {
   
                    return d.id || (d.id = ++this.index)
                }) 
            // 在父级之前的位置输入任何新源
            let nodeEnter = node.enter().append('g')
                .attr('class', 'node')
                //.on('click', this.clickNode)
                .attr('transform', d => {
   
                    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值