d3嵌套变量数据绑定

时间:2017-10-23 23:38:23

标签: javascript d3.js

我是D3的新手,试图解决一个不那么容易的问题(至少对我来说!)这是我的样本数据集。

var data = [
    {"x":1000, "y": {"10":100, "10.2":200, "10.3":300, "10.4":600}},
    {"x":1001, "y": {"9.2":60, "9.6":400, "10.1":20, "10.8":320, "11":20, "8.8":722}},
    {"x":1002, "y": {"9.8":80, "9.9":600, "9.2":40}},
    {"x":1003, "y": {"10.1":60, "10.3":400, "10.8":360, "9.6":88}},
    {"x":1004, "y": {"9.8":20, "10.4":450}}
];

如何使用d3绑定它以创建具有x的属性x=的值的矩形,y对象的y=个键,y对象的width=值和{{1任何给定的常数?

基本上,根据height=对象中元素的数量,每个x都有一个可变数量的矩形。

1 个答案:

答案 0 :(得分:1)

这确实有点复杂,主要是因为你的y属性只包含一个对象,而不是一个对象数组。

我的解决方案使用d3.entries,根据API

  

返回包含指定对象(关联数组)的属性键和值的数组。每个条目都是一个具有键和值属性的对象,例如{key:" foo",value:42}。返回的数组的顺序是未定义的。 (强调我的)

有一个数组是很重要的,所以我们可以绑定数据(因为data()方法只接受三个东西:数组,函数或什么都没有。)

所以,在这个解决方案中,我使用外部对象来附加组...

var groups = svg.selectAll(null)
  .data(data)
  .enter()
  .append("g");

...和每个外部对象的y对象附加矩形......

var rects = groups.selectAll(null)
  .data(function(d) {
    return d3.entries(d.y)
  })
  .enter()
  .append("rect");

...并使用d3.entries()将对象转换为对象数组,可以与data()一起使用。

这是一个演示(我改变了你的实际值,所以我们可以更好地看到矩形):



var data = [{
  "x": 100,
  "y": {
    "10": 100,
    "20": 200,
    "26": 300,
    "35": 400
  }
}, {
  "x": 20,
  "y": {
    "50": 60,
    "59.6": 400,
    "70.1": 20,
    "80.8": 320,
    "88": 20,
    "98.8": 722
  }
}, {
  "x": 30,
  "y": {
    "109.8": 80,
    "119.9": 600,
    "139.2": 40
  }
}, {
  "x": 10,
  "y": {
    "150.1": 60,
    "170.3": 400,
    "190.8": 360,
    "209.6": 88
  }
}, {
  "x": 50,
  "y": {
    "259.8": 20,
    "280.4": 450
  }
}];

var colours = d3.scaleOrdinal(d3.schemeCategory10);

var constant = 5;

var svg = d3.select("svg");

var groups = svg.selectAll(null)
  .data(data)
  .enter()
  .append("g")
  .style("fill", function(d, i) {
    return colours(i)
  })

var rects = groups.selectAll(null)
  .data(function(d) {
    return d3.entries(d.y)
  })
  .enter()
  .append("rect");

rects.attr("y", function(d) {
    return +d.key
  })
  .attr("width", function(d) {
    return d.value
  })
  .attr("height", constant)
  .attr("x", function(d) {
    return d3.select(this.parentNode).datum().x;
  })

<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="600" height="300"></svg>
&#13;
&#13;
&#13;

注意我如何获得ywidth值,特别是x值(访问父级的数据)。