为了账号安全,请及时绑定邮箱和手机立即绑定

D3.js v5 构建树“矩阵”

D3.js v5 构建树“矩阵”

HUWWW 2023-11-02 20:06:03
目标是以矩阵的形式优雅地附加多个小树图。我已经准备了预期输出的简单版本;矩形和文本显示了图案应该是什么样子。接下来需要做的是在矩形下方添加一个简单的两级树图。我正在使用一种数据结构,其中树数据存储在对象数组的每个项目内的对象中:  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 不是函数我以前从未见过这种错误,我担心会出现大问题。问题基于我的矩阵框架(查看如何在片段中附加矩形和文本),如何以类似的方式附加小“迷你树”?
查看完整描述

1 回答

?
DIEA

TA贡献1820条经验 获得超2个赞

您在制作树时遇到错误:

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

应该:

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

你不想要 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+")");


  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"},

          ]

    }},

    {name:"donnie yen", tree: {

      "name": "Top Level",

      "children": [

            { "name": "Fund 1" },

            { "name": "Fund 2" },

          ]

    }},

    {name:"chow yun fat", tree: {

      "name": "Top Level",

      "children": [

            { "name": "Fund 1" },

            { "name": "Fund 2" },

            { "name": "Fund 3"},

            { "name": "Fund 4"},

            { "name": "Fund 5"},

          ]

    }},

  ];


  //var formatComma = d3.format(",");


  var columns = 3;

  var spacing = 150;

  var vSpacing = 180;


  var pmG = graphGroup.selectAll('.pm')

    .data(data)

    .enter()

    .append('g')

    .attr('class', 'pm')

    .attr('id', (d, i) => 'pm' + i)

    .attr('transform', (d, k) => {

      var horSpace = (k % columns) * spacing;

      var vertSpace = ~~((k / columns)) * vSpacing;

      return "translate(" + horSpace + "," + vertSpace + ")";

    });


var miniTree = d3.tree()

    .size([150, 75]);


pmG.append('rect')

    .attr('x',0)

    .attr('y',0)

    .attr('width',100)

    .attr('height',25)

    .style('fill',"#003366");


pmG.append('text')

    .attr('x',50)

    .attr('y',-10)

    .attr('text-anchor','middle')

    .text(function(d) {return d.name});



pmG.selectAll(null)

    .data( function(d) { 

        return miniTree(d3.hierarchy(d.tree)).descendants().slice(1) 

        

        })

  .enter().append("path")

    .attr("transform", "translate(-25,20)") // extra positioning.

    .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;

       });


pmG.selectAll(null)

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

  .enter().append("g")

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

      return "node" +

        (d.children ? " node--internal" : " node--leaf"); })

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

      return "translate(" + (d.x - 25) + "," + (d.y+20) + ")"; }) // with extra positioning.

      .append("circle")

path {

  stroke-width: 1px;

  fill: none;

  stroke: #003366;

}


circle {

  r: 5px;

  fill: #003366;

}

<script src="https://d3js.org/d3.v5.min.js"></script>


查看完整回答
反对 回复 2023-11-02
  • 1 回答
  • 0 关注
  • 100 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信