猿问

D3.js v5 构建树“矩阵”

目标是以矩阵的形式优雅地附加多个小树图。我已经准备了预期输出的简单版本;矩形和文本显示了图案应该是什么样子。接下来需要做的是在矩形下方添加一个简单的两级树图。


我正在使用一种数据结构,其中树数据存储在对象数组的每个项目内的对象中:


  var data = [

    {name:"jackie chan", tree: {

      "name": "Top Level",

      "children": [

            { "name": "Fund 1" },

            { "name": "Fund 2" },

            { "name": "Fund 3"}

          ]

    }},

    {name:"jet li", tree: {

      "name": "Top Level",

      "children": [

            { "name": "Fund 1" },

            { "name": "Fund 2" },

            { "name": "Fund 3"},

            { "name": "Fund 4"},

          ]

    }},

...

我认为我可以通过将所有树方法封装到一个大数据调用中来实现所需的结果,然后使用与代码片段结果中所示相同的方法来附加矩形和文本:


pmG.selectAll(null)

    .data( function(d) {return miniTree(d3.hierarchy(d.tree).descendants().slice(1))})

  .enter().append("path")

    .attr("class", "link")

    .attr("d", function(d) {

       return "M" + d.x + "," + d.y

         + "C" + d.x + "," + (d.y + d.parent.y) / 2

         + " " + d.parent.x + "," +  (d.y + d.parent.y) / 2

         + " " + d.parent.x + "," + d.parent.y;

       });

但是我得到了错误:


未捕获的类型错误:i.eachBefore 不是函数


我以前从未见过这种错误,我担心会出现大问题。


问题

基于我的矩阵框架(查看如何在片段中附加矩形和文本),如何以类似的方式附加小“迷你树”?


HUWWW
浏览 101回答 1
1回答

DIEA

您在制作树时遇到错误:&nbsp;.data(&nbsp;function(d)&nbsp;{return&nbsp;miniTree(d3.hierarchy(d.tree).descendants().slice(1))&nbsp;})应该:&nbsp;.data(&nbsp;function(d)&nbsp;{return&nbsp;miniTree(d3.hierarchy(d.tree)).descendants().slice(1)&nbsp;&nbsp;})你不想要 d3.hierarchy 的后代,但是 miniTree - 我第一次查看它时错过了它。var margins = {top:100, bottom:300, left:100, right:100};var height = 600;var width = 900;var totalWidth = width+margins.left+margins.right;var totalHeight = height+margins.top+margins.bottom;var svg = d3.select('body').append('svg').attr('width', totalWidth).attr('height', totalHeight);var graphGroup = svg.append('g').attr('transform', "translate("+margins.left+","+margins.top+")");&nbsp; var data = [&nbsp; &nbsp; {name:"jackie chan", tree: {&nbsp; &nbsp; &nbsp; "name": "Top Level",&nbsp; &nbsp; &nbsp; "children": [&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { "name": "Fund 1" },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { "name": "Fund 2" },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { "name": "Fund 3"}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ]&nbsp; &nbsp; }},&nbsp; &nbsp; {name:"jet li", tree: {&nbsp; &nbsp; &nbsp; "name": "Top Level",&nbsp; &nbsp; &nbsp; "children": [&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { "name": "Fund 1" },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { "name": "Fund 2" },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { "name": "Fund 3"},&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { "name": "Fund 4"},&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ]&nbsp; &nbsp; }},&nbsp; &nbsp; {name:"donnie yen", tree: {&nbsp; &nbsp; &nbsp; "name": "Top Level",&nbsp; &nbsp; &nbsp; "children": [&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { "name": "Fund 1" },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { "name": "Fund 2" },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ]&nbsp; &nbsp; }},&nbsp; &nbsp; {name:"chow yun fat", tree: {&nbsp; &nbsp; &nbsp; "name": "Top Level",&nbsp; &nbsp; &nbsp; "children": [&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { "name": "Fund 1" },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { "name": "Fund 2" },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { "name": "Fund 3"},&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { "name": "Fund 4"},&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { "name": "Fund 5"},&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ]&nbsp; &nbsp; }},&nbsp; ];&nbsp; //var formatComma = d3.format(",");&nbsp; var columns = 3;&nbsp; var spacing = 150;&nbsp; var vSpacing = 180;&nbsp; var pmG = graphGroup.selectAll('.pm')&nbsp; &nbsp; .data(data)&nbsp; &nbsp; .enter()&nbsp; &nbsp; .append('g')&nbsp; &nbsp; .attr('class', 'pm')&nbsp; &nbsp; .attr('id', (d, i) => 'pm' + i)&nbsp; &nbsp; .attr('transform', (d, k) => {&nbsp; &nbsp; &nbsp; var horSpace = (k % columns) * spacing;&nbsp; &nbsp; &nbsp; var vertSpace = ~~((k / columns)) * vSpacing;&nbsp; &nbsp; &nbsp; return "translate(" + horSpace + "," + vertSpace + ")";&nbsp; &nbsp; });var miniTree = d3.tree()&nbsp; &nbsp; .size([150, 75]);pmG.append('rect')&nbsp; &nbsp; .attr('x',0)&nbsp; &nbsp; .attr('y',0)&nbsp; &nbsp; .attr('width',100)&nbsp; &nbsp; .attr('height',25)&nbsp; &nbsp; .style('fill',"#003366");pmG.append('text')&nbsp; &nbsp; .attr('x',50)&nbsp; &nbsp; .attr('y',-10)&nbsp; &nbsp; .attr('text-anchor','middle')&nbsp; &nbsp; .text(function(d) {return d.name});pmG.selectAll(null)&nbsp; &nbsp; .data( function(d) {&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; return miniTree(d3.hierarchy(d.tree)).descendants().slice(1)&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; .enter().append("path")&nbsp; &nbsp; .attr("transform", "translate(-25,20)") // extra positioning.&nbsp; &nbsp; .attr("class", "link")&nbsp; &nbsp; .attr("d", function(d) {&nbsp; &nbsp; &nbsp; &nbsp;return "M" + d.x + "," + d.y&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;+ "C" + d.x + "," + (d.y + d.parent.y) / 2&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;+ " " + d.parent.x + "," +&nbsp; (d.y + d.parent.y) / 2&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;+ " " + d.parent.x + "," + d.parent.y;&nbsp; &nbsp; &nbsp; &nbsp;});pmG.selectAll(null)&nbsp; &nbsp; .data( function(d) {return miniTree(d3.hierarchy(d.tree)).descendants() })&nbsp; .enter().append("g")&nbsp; &nbsp; .attr("class", function(d) {&nbsp; &nbsp; &nbsp; return "node" +&nbsp; &nbsp; &nbsp; &nbsp; (d.children ? " node--internal" : " node--leaf"); })&nbsp; &nbsp; .attr("transform", function(d) {&nbsp; &nbsp; &nbsp; return "translate(" + (d.x - 25) + "," + (d.y+20) + ")"; }) // with extra positioning.&nbsp; &nbsp; &nbsp; .append("circle")path {&nbsp; stroke-width: 1px;&nbsp; fill: none;&nbsp; stroke: #003366;}circle {&nbsp; r: 5px;&nbsp; fill: #003366;}<script src="https://d3js.org/d3.v5.min.js"></script>
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答