d3 v5 在树图上插值颜色

d3 v5 interpolate color on treemap

我正在基于此示例在 d3 v5 中构建树状图:https://www.d3indepth.com/layouts/

我可以将 score 数据点用于最低级别 children 的色标,但我希望上面方框的 parents 的平均值为下面的children。

我的数据样本在这里:

{
 "name": "Unit",
 "children": [
  {
    "name": "SBU",
    "children": [
      {
        "name": "App",
        "value": 3000,
        "score": 0.5
      },
      {
        "name": "App",
        "value": 3500,
        "score": 0.1
      },
      {
        "name": "App",
        "value": 2000,
        "score": 0.9
      }
    ]
  }

代码如下:

d3.json("health.json").then(function(data) {
  console.log(data)

var treemapLayout = d3.treemap()
  .size([1700, 1500])
  .paddingOuter(16);

var rootNode = d3.hierarchy(data)

// Determine the size and placement of the boxes
rootNode
  .sum(function(d) { return d.value; })
  .sort(function(a,b) { return b.value - a.value; });

treemapLayout(rootNode);

var nodes = d3.select('svg g')
  .selectAll('g')
  .data(rootNode.descendants())
  .enter()
  .append('g')
  .attr('transform', function(d) {return 'translate(' + [d.x0, d.y0] + ')'})

nodes
  .append('rect')
  .attr('width', function(d) { return d.x1 - d.x0; })
  .attr('height', function(d) { return d.y1 - d.y0; })
  .attr('style', function(d) {
      return ('fill:' + d3.interpolateRdYlGn(d.data.health))
  })

nodes
  .append('text')
  .attr('dx', 4)
  .attr('dy', 14)
  .text(function(d) {
    return d.data.name;
  })
});

您可以这样做的一种方法是预处理数据以包括父节点的平均子分数以及每个节点的颜色:

  1. 计算每个父节点的平均子分数,并将结果添加到您的数据结构中。

    {
      "name": "SBU",
      "avgScore": 0.5,
      "children: [
    
  2. 使用顺序比例将这些平均结果映射到特定颜色,例如d3.interpolateRdYlGn,并将结果添加到数据中:

    const colorScale = d3.scaleSequential(d3.interpolateRdYlGn)
      .domain([0, 1]); // depending on your data
    
    const nodeColor = colorScale(data.parent.avgScore);
    
    {
      "name": "SBU",
      "avgScore": 0.5,
      "nodeColor": nodeColor
    }
    
  3. 然后您可以为根节点和子节点的数据分配特定颜色:

    const childNodeColor = rgb(100, 200, 100);
    {
      // Child node
      ...,
      nodeColor: childNodeColor
    }
    
  4. 然后简单地渲染树中每个节点的颜色:

    ...
    .attr('style', function(d) {
      return colorScale(d.nodeColor);
    });