D3附加不同的元素,保持共同的索引

时间:2016-07-18 14:13:12

标签: javascript d3.js

我的应用程序应该根据数据类型将不同的元素附加到SVG。我的代码或多或少看起来像这样:

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

var circles = elements.filter(function (d,i) {
    return d.type == "category1"
})
    .append("circle")


var rectangles = smallCircles.filter(function (d,i) {
            return d.type == "category2"
        })
            .append("rect")

所以,如果data.type =" catgory1",程序应该附加一个圆圈,如果它等于" category2",它应该附加一个矩形。我遇到的问题是我根据他们各自的指数(" i"在函数(d,i)中)设置他们在SVG上的位置。但是,为了做到这一点,我需要索引序列在这两种元素类型中保持一致。有没有更好的方法来做到这一点,而不仅仅是使用一个外部变量,每次新元素被追加时都会变成++?

1 个答案:

答案 0 :(得分:2)

你可以通过几种方式做到这一点。

首先,您可以使用.each并封装附加逻辑:

var elements = svg.selectAll(".elements")
  .data([
    {
      type: "category1"
    },{
      type: "category2"
    } 
  ])
  .enter().append("g");

elements.each(function(d,i){

  // i is index on everything

  var self = d3.select(this);
  switch(d.type) {
      case "category1":
          self.append("circle");
          break;
      case "category2":
          self.append("rect");
          break;
      default:
          break;
  }
});

或者,第二,更好的方法是将您的元素作为数据的一部分:

var data = [
    {
      type: "category1"
    },{
      type: "category2"
    } 
  ];

data.forEach(function(d){
  switch(d.type) {
      case "category1":
          d.elem = "circle"
          break;
      case "category2":
          d.elem = "rect"
          break;
      default:
          break;
  }
});

var svg = d3.select('body').append('svg');

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

elements.append(function(d){
  return document.createElement(d.elem);
});