D3.js的V5版本-Vue框架中使用-树状图

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了D3.js的V5版本-Vue框架中使用-树状图相关的知识,希望对你有一定的参考价值。

参考技术A 一. api简介

d3.tree(),创建一个树状图生成器
d3.tree().size(),定义树的大小
d3.hierarchy(),层级布局,需要和tree生成器一起使用,来得到绘制树所需要的节点数据和边数据
node.descendants()得到所有的节点,已经经过转换的数据
node.links(),得到所有的边,已经经过转换的数据

二.Vue中使用

*点击节点可展开收缩

JavaScript:基于任意JSON动态生成树状图(动态生成vue-giant-tree所需idpid)

最近我的工作项目遇到了一个问题。一个内部有无限个children套娃的JSON,且其id和name是一样的,十分混乱。在这样的条件下需要生成对应的树状图。

我们所使用的框架为vue,使用的树状图为vue-giant-tree。vue-giant-tree如何使用大家可以上网搜索教程,这个不是本文重点。

该插件所需的格式如下:


各位可以看到id与pid有一定规律,pid即parent id,父级id。

那么要如何给一个JSON动态生成树状图所需id、pid?

各位很容易就想到使用递归函数,没错,我一开始偷懒想在网上找找有没有直接可用的类似的递归函数,然而没有。于是只好自己写,现在分享到网上方便有需要的人士下次用一用看看。这里就不废话了,直接贴上代码。

findtree递归函数:

let layer = 1;
let parentId = 1;
let before = 0;
// findtree递归函数
let findTree = function (array) 
    for (let i = 0; i < array.length; i++) 
         // nowId结合上一层的nowId,在尾部加上i+1数字
         let nowId = parseInt(parentId + "" + (i + 1))
         array[i]["myId"] = nowId
         array[i]["myPid"] = before;
            
         // 如果有children则进入递归,进入下一层,将本层的nowId保存好,增加层数layer
         if (array[i].hasOwnProperty("children")) 
           before = nowId
           parentId = nowId
           layer++
           findTree(array[i].children)
         
         // 如果循环到底则减少层数layer,将before和parentId还原回上一层的样子
         if (i === array.length - 1) 
           layer--
           before = parseInt(before.toString().substring(0, layer))
           if (before.toString().length === 1) 
             before = 0
           
           parentId = parseInt(parentId.toString().substring(0, layer))
         
       

// 运行findTree递归函数
findTree(myTree)

本人水平有限,代码应该是有更好的优化手段,刷leetcode的同学可以挑战一下。不过这段代码算是解决了我的问题。无论JSON是怎样,略作改动(如children)都可以生成树结构。

对于我而言的完整的解决代码:

		var that = this;
		let layer = 1;
        let parentId = 1;
        let before = 0;
        // findtree递归函数
        let findTree = function (array) 
          for (let i = 0; i < array.length; i++) 
            // nowId结合上一层的nowId,在尾部加上i+1数字
            let nowId = parseInt(parentId + "" + (i + 1))
            let oneItem = ;
            oneItem["id"] = nowId;
            oneItem["pid"] = before;
            oneItem["name"] = array[i].name;
            oneItem["open"] = false;
            oneItem["checked"] = true;
            that.nodes.push(oneItem)

            // 如果有children则进入递归,进入下一层,将本层的nowId保存好,增加层数layer
            if (array[i].hasOwnProperty("children")) 
              before = nowId
              parentId = nowId
              layer++
              findTree(array[i].children)
            
            // 如果循环到底则减少层数layer,将before和parentId还原回上一层的样子
            if (i === array.length - 1) 
              layer--
              before = parseInt(before.toString().substring(0, layer))
              if (before.toString().length === 1) 
                before = 0
              
              parentId = parseInt(parentId.toString().substring(0, layer))
            
          
        
        // 运行findTree递归函数
        findTree(myTree)

目前的函数还有局限性,算法还需改进。欢迎大家学习与提出建议,也可以帮忙优化一下这段代码噢。

以上是关于D3.js的V5版本-Vue框架中使用-树状图的主要内容,如果未能解决你的问题,请参考以下文章

D3.js的v5版本入门教程(第九章)——完整的柱状图

D3.js的v5版本入门教程(第十三章)—— 饼状图

D3.js的v5版本入门教程(第十二章)—— D3.js中各种精美的图形

d3js树状图tree

d3.js 实现企业图谱(基于vue)

D3.js的v5版本入门教程(第七章)—— 比例尺的使用