如何在d3中嵌套选择?

时间:2012-06-28 20:55:46

标签: d3.js

我想用不同颜色绘制三个连续的正方形(这没有问题,它在“比例”变量中)并在每个大颜色下面放置可变数量的较小正方形(我不能这样做,“点” “变量”。我究竟做错了什么?这是我的代码和要点https://gist.github.com/3013836

var data = [-1,0,1]

var rect_size = 25; //px

var x = d3.scale.ordinal().domain(d3.range(data.length)).rangeBands([0, rect_size*data.length]);
var color = d3.scale.linear().domain([-1.5, 0, 1.5]).range(["#278DD6","#ffffff","#d62728"]).clamp(false);

var svg = d3.select("body").append("svg")
    .attr("width", 800)
    .attr("height", 200)

scale = svg.selectAll("rect")
    .data(data)
  .enter().append("rect")
    .attr("x", function(d,i) { return x(i); })
    .attr("y",0)
    .attr("width", rect_size)
    .attr("height", rect_size)
    .style("fill", function(d) { return color(d); });

dots = [[1,2,3],[1,2],[1,2,3,4]]
var y = d3.scale.ordinal().domain(d3.range(dots.length)).rangeBands([0, (rect_size/2)*dots.length]);
scale.selectAll("g")
    .data(dots, function(d){return d;})
  .enter().append("rect")
    .attr("x", function(d,i) {return x(i);})
    .attr("y", function(d,i) {return y(i);})
    .attr("width", rect_size/2)
    .attr("height", rect_size/2)
    .style("fill", "black");

1 个答案:

答案 0 :(得分:1)

您已将选择scale定义为三个rect元素。然后,您在每个元素中添加了三个rect元素。如果使用浏览器的元素检查器,生成的结构将如下所示:

<rect class="outer">
  <rect class="inner"></rect>
  <rect class="inner"></rect>
  <rect class="inner"></rect>
</rect>

这只显示三个rects,因为SVG中的rects不是container elements;内部的行为被忽略了。

如果要对元素进行分组,则需要g (group) element。你想要一个像这样的结构:

<g>
  <rect class="outer"></rect>
  <rect class="inner"></rect>
  <rect class="inner"></rect>
  <rect class="inner"></rect>
</g>

您可以首先使用data-join创建g元素的选择。然后append一个外部矩形到g元素。最后使用nested join创建内部rects。类似的东西:

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

var outerRect = g.append("rect")
    .attr("class", "outer");

var innerRect = g.selectAll(".inner")
    .data(innerData)
  .enter().append("rect")
    .attr("class", "inner");

其他一些事情:

  • 您可以对g元素使用变换,这样就不必单独定位外部和内部rects。这样,内部rects可以相对于外部rects定位,代码更简单。

  • 您的上一次加入已被破坏,因为您选择“g”并附加“rect”;无论你追加什么都应该与你的选择器相匹配。

  • 除非您还处理更新并退出,否则您通常不需要key function来加入数据。由于您只处理输入加入,并且您知道选择为空,因此不需要关键功能。