javascript - D3 - 如何使用分区布局进行可视化,使其具有均等划分的扇区?

标签 javascript d3.js

我正在使用 D3 来实现分区布局的可视化。我需要的是划分的部分具有相同的宽度,如下所示:

Desired outcome

但我目前拥有的是:

Current version

您可以找到当前正在运行的版本here在 Codepen 上,但我也将代码复制到此处:

var w = 960,
    h = 500,
    x = d3.scale.linear().range([0, w]),
    y = d3.scale.linear().range([0, h]),
    color = d3.scale.ordinal().range(["rgb(255,247,236)","rgb(254,232,200)","rgb(253,212,158)","rgb(253,187,132)","rgb(252,141,89)","rgb(239,101,72)","rgb(215,48,31)","rgb(179,0,0)","rgb(127,0,0)"]);

var vis = d3.select("#chart").append("svg:svg")
    .attr("width", w)
    .attr("height", h);

var partition = d3.layout.partition()
    .children(function(d) { return isNaN(d.value) ? d3.entries(d.value) : null; })
    .value(function(d) { return d.value; });

var data = {
  'root': {

    'asdf': {
      'a': {
        'kdjfklsfj': 1,
        'kdjfklsfsj': 1
      },
      'b': 1
    },

    'bnm': {
      'c': 1,
      'd': {
        'lsdkjfdkljsf': {
          'lsdkfj': 1,
          'kldsjfdlk': 1
        },
        'kdjfkjsdfk': 1
      }
    }

  }
};

var rect = vis.selectAll("rect")
    .data(partition(d3.entries(data)[0]))
    .enter().append("svg:rect")
    .attr("x", function(d) { return x(d.x); })
    .attr("y", function(d) { return y(d.y); })
    .attr("width", function(d) { return x(d.dx); })
    .attr("height", function(d) { return y(d.dy); })
    .attr("fill", function(d) { return color((d.children ? d : d.parent).data.key); })
    .on("click", click);

function click(d) {
  x.domain([d.x, d.x + d.dx]);
  y.domain([d.y, 1]).range([d.y ? 20 : 0, h]);

  rect.transition()
    .duration(750)
    .attr("x", function(d) { return x(d.x); })
    .attr("y", function(d) { return y(d.y); })
    .attr("width", function(d) { return x(d.x + d.dx) - x(d.x); })
    .attr("height", function(d) { return y(d.y + d.dy) - y(d.y); });
}

我发现改变数据值(当前所有项目的值为“1”),自然会增加元素的宽度,但如何才能使其具有均等划分的框?

最佳答案

您告诉分区函数将每个 block 的宽度计算为值(如果有)或其子值的总和。听起来您想使用 child 的数量作为后一种情况的权重,以便例如顶部节点被分为 1/2 和 1/2,而不是 4/7 和 3/7。

编辑: d3的partition()对象旨在根据其子元素的大小总和确定父元素的大小,而(如果我理解你的用例)你想要根据其 sibling 的数量,从其 parent 的大小中分配 child 的大小。

要使其正常工作,您必须管理叶节点对象值以“欺骗”d3 执行您想要的操作。这是一个 data 对象,它使第一个级别具有偶数长度:

var data = {
  'root': {

    'asdf': {
      'a': {
        'kdjfklsfj': 1/6,
        'kdjfklsfsj': 1/6
      },
      'b': 1/6
     },

    'bnm': {
      'c': 1/8,
      'd': {
        'lsdkjfdkljsf': {
          'lsdkfj': 1/8,
          'kldsjfdlk': 1/8
        },
        'kdjfkjsdfk': 1/8
      }
    }
  }
};

换句话说,您必须管理数据以满足 d3 的期望。执行此操作的不是 d3 操作,而是您的数据生成器。

关于javascript - D3 - 如何使用分区布局进行可视化,使其具有均等划分的扇区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12100914/

相关文章:

javascript - d3 堆积面积图不适用于对数刻度

javascript - 移动到 SVG 路径 (d3.js) 中的鼠标单击

javascript - 更新时缺少模板 Rails

javascript - 在不使用 border 属性的情况下显示元素的边框

javascript - 使用 Electron 将 Angular 项目(进行 REST API 调用)转换为桌面应用程序

javascript - nvd3 - 如果 xAxis 可见,则无法显示 XAxis(false)

javascript - Jquery计算旋转矩形的边界框

JavaScript 文本范围错误

javascript - D3 - 平滑的径向图表过渡动画

javascript - 如何复制 SVG 的内容并将其附加到另一个 SVG 框架?