首页 > 解决方案 > 在d3.js中如何改变树形图的节点大小

问题描述

我正在制作一个树形图,其中节点是一个矩形而不是一个圆形,并且需要矩形以不同的大小显示在正确的位置 - 显示一个 80x60 矩形,其中类型是数据中的“高框”,以及 80x20 矩形对于所有其他节点。这是代码

var treeData = {
  "name": "Top Level",
  "children": [{
      "name": "Level 2: A",
       "type": "tall box",
      "children": [{
          "name": "long txt next line long txt",
          "type": "tall box",
        },
        {
          "name": "short txt"
        }
      ]
    },
    {
      "name": "Level 2: B"
    }
  ]
};

// set the dimensions and margins of the diagram
var margin = {
    top: 20,
    right: 90,
    bottom: 30,
    left: 90
  },
  width = 860 - margin.left - margin.right,
  height = 500 - margin.top - margin.bottom;

// declares a tree layout and assigns the size
var treemap = d3.tree()
  .size([height, width]);

//  assigns the data to a hierarchy using parent-child relationships
var nodes = d3.hierarchy(treeData, function(d) {
  return d.children;
});

// maps the node data to the tree layout
nodes = treemap(nodes);

// append the svg object to the body of the page
// appends a 'group' element to 'svg'
// moves the 'group' element to the top left margin
var svg = d3.select("body").append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom),
  g = svg.append("g")
  .attr("transform",
    "translate(" + margin.left + "," + margin.top + ")");

// adds the links between the nodes
var link = g.selectAll(".link")
  .data(nodes.descendants().slice(1))
  .enter().append("path")
  .attr("class", "link")
  .attr("d", function(d) {
    return "M" + d.y + "," + d.x +
      "C" + (d.y + d.parent.y) / 2 + "," + d.x +
      " " + (d.y + d.parent.y) / 2 + "," + d.parent.x +
      " " + d.parent.y + "," + d.parent.x;
  });

// adds each node as a group
var node = g.selectAll(".node")
  .data(nodes.descendants())
  .enter().append("g")
  .attr("class", function(d) {
    return "node" +
      (d.children ? " node--internal" : " node--leaf");
  })
  .attr("transform", function(d) {
    return "translate(" + d.y  + "," + d.x + ")";
  });

// adds the circle to the node
node.append("rect")
        .attr("class", "node")
        .attr("width", 80)
        .attr("height", 20)
        .attr("rx", 10)
        .attr("ry", 10)
        .style("fill", "lightgrey");

// adds the text to the node
node.append("text")
  .attr("dy", ".35em")
  .attr("x", function(d) {
    return d.children ? -13 : 13;
  })
  .style("text-anchor", "start")
  .text(function(d) {
    return d.data.name;
  });

如果我使用条件逻辑来改变大小,则矩形不是从正确的位置开始的。如何移动矩形的起始位置,以使所有矩形与原始圆形节点具有相同的中心,或者让矩形的高度适应不同的文本长度?谢谢。

标签: javascriptd3.js

解决方案


如果您确切知道宽度,例如 80 * 20 和 80 * 60。您可以这样做

// adds the circle to the node
node.append("rect")
    .attr("class", "node")
    .attr("width", 80 )
    .attr("height", d => d.data.type === 'tall box' ? 60 : 20)
    .attr("rx", 10)
    .attr("ry", 10)
    .style('transform', d => d.data.type === 'tall box' ? 'translateY(-30px)' : 
           'translateY(-10px)')
    .style("fill", "lightgrey");

或者你想得到一个合适的尺寸,你需要得到textby的宽度和高度getBBox()

对不起,我的英语很差,我希望它对你有帮助


推荐阅读