d3.js 根据选择输入值更改树图

9wbgstp7  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(176)

我试图使我的树图根据输入中选择的值做出响应。我让它对第一个选择起作用,但当我再次将选择放回“全部”时,什么也没有发生。

我在控制台中收到以下错误:

我猜这是因为当去选择的一些孩子被删除,因此没有找到了,当把它放在完整的选择,但我不知道我如何可以解决这个问题。
请参阅codepen
图形的代码:

//Load data
const data = [
  {
    "name": "Top Level",
    "parent": "null",
    "value": 10,
    "type": "black",
    "level": "red",
    "children": [
      {
        "name": "Level 2A",
        "parent": "Top Level",
        "value": 15,
        "type": "grey",
        "level": "red",
        "children": [
          {
            "name": "Son of A",
            "parent": "Level 2: A",
            "value": 5,
            "type": "steelblue",
            "level": "orange"
          },
          {
            "name": "Daughter of A",
            "parent": "Level 2: A",
            "value": 8,
            "type": "steelblue",
            "level": "red"
          }
        ]
      },
      {
        "name": "Level 2B",
        "parent": "Top Level",
        "value": 10,
        "type": "grey",
        "level": "green"
      }
    ]
  }
];

var margin = {top: 10, right: 10, bottom: 10, left: 50},
width = 500 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;

var tree = d3.cluster()
    .size([height, width])
    .size([height-margin.top-margin.bottom,width-margin.left-margin.right]); 

//Create root 
var root = d3.hierarchy(data[0], function(d) { return d.children;});

//Attach canvas element
var svg = d3.select("body")
            .append("svg")
            .attr("width", 1000)
            .attr("height", 1000);  

var g = svg
        .append("g")
        .attr('transform','translate('+ margin.left +','+ margin.right +')');

var link = g.selectAll(".link")
        .data(tree(root).links())
        .enter()
        .append("path")
        .attr("class", "link")
        .attr("d", d3.linkHorizontal()
                .x(function(d) {return d.y;})
                .y(function(d) {return d.x;}));      

var node = g.selectAll(".node")
        .data(root.descendants())
        .enter()
        .append("g") 
        .attr("class", "link") 
        .attr("class", d => 
        { return "node" + (d.children ? " node--internal" : " node--leaf")})
        .attr("transform", d => 
        { return "translate(" + d.y + ","+ d.x + ")" ; })

var text = g.selectAll("text")
        .data(root.descendants())
        .enter().append("text")
        .text(d => d.data.name)
        .attr("class", "label glow") 
        .attr('text-anchor', "start")
        .attr("x", d => d.y)
        .attr("y", d => d.x);

circle = node.append("circle")
    .attr("r", 2.5)

//Select
    var selections = ["All", "Level 2A", "Level 2B"]

    d3.select("#selectButton")
      .selectAll('myOptions')
      .data(selections)
      .enter()
      .append('option')
      .text(function (d) { return d; }) // 
      .attr("value", function (d) { return d; })  

  // SelectInput
  d3.select("#selectButton").on("change", function(d){
    selectedGroup = this.value
    updateChart(selectedGroup, data)
  })

//Update chart function
function updateChart(selection, data){

  //Filter data
  if(selection != "All"){
    var selData = data[0].children.filter(d => d.name == selection);
  } else {
    var selData = data
  }
  console.log(selData)
  var root = d3.hierarchy(selData[0], function(d) { return d.children;}); 
  console.log(root)

  //update chart
  link
    .data(tree(root).links())
    .join()
    .transition()
    .duration(1000)
    .attr("class", "link")
    .attr("d", d3.linkHorizontal()
          .x(function(d) {return d.y;})
          .y(function(d) {return d.x;})
         );
   text
    .data(root.descendants())
    .join()
    .transition()
    .duration(1000)
        .attr('text-anchor', "start")
        .attr("x", d => d.y)
        .attr("y", d => d.x);
   node
    .data(root.descendants())
    .join()
    .transition()
    .duration(1000)
        .attr("class", "link") 
        .attr("class", d => 
        { return "node" + (d.children ? " node--internal" : " node--leaf")})
        .attr("transform", d => 
        { return "translate(" + d.y + ","+ d.x + ")" ; })
  circle
     .data(root.descendants())
     .join()
     .transition()
     .duration(1000)
     .attr("r", 2.5)
};
bybem2ql

bybem2ql1#

为了回答我自己的问题,我必须设置在enter()update()exit()上到底需要发生什么。
我从刚刚加入:

link
    .data(tree(root).links())
    .join()
    .transition()
    .duration(1000)
    .attr("class", "link")
    .attr("d", d3.linkHorizontal()
          .x(function(d) {return d.y;})
          .y(function(d) {return d.x;})
         );

收件人:

var link = g
    .selectAll(".link")
    .data(tree(root).links())
    .join(
      (enter) =>
        enter
          .append("path")
          .attr("class", "link")
          .attr(
            "d",
            d3
              .linkHorizontal()
              .x(function (d) {
                return d.y;
              })
              .y(function (d) {
                return d.x;
              })
          ),
      (update) =>
        update
          .transition()
          .duration(1000)
          .attr("class", "link")
          .attr(
            "d",
            d3
              .linkHorizontal()
              .x(function (d) {
                return d.y;
              })
              .y(function (d) {
                return d.x;
              })
          ),
      (exit) => exit.remove()
    );

有关完整的工作树,请参阅:
https://codepen.io/nvelden/pen/jOxgoVj

相关问题