【问题标题】:Using D3 data().enter()使用 D3 data().enter()
【发布时间】:2014-07-20 19:37:15
【问题描述】:

以下玩具问题说明了我的问题。我有一系列“位置”,比如藏宝图。数组中的每个项目(例如怪物或宝藏)都可能存在于地图上的多个位置。例如

locations = [
  {name:'treasure', color: 'blue', coords:[[100,100], [200,300]]},
  {name:'monsters', color: 'red', coords:[[100,150], [220,420], [50,50]]}
]

现在我想使用 D3 绘制这些图。糟糕/幼稚的方法(有效 - see here for fiddle)看起来像这样:

for location in locations
  for coords in location.coords
    svg.append('circle')
      .attr('cx', coords[0])
      .attr('cy', coords[1])
      .attr('r', 8)
      .style('fill', location.color)
      .datum(location)

但是,当我修改数据的内容时,我不想每次都运行这个幼稚的代码。似乎使用 data() 和 enter() 是“正确”的方法,但我无法弄清楚它如何与子坐标一起工作。例如

svg.selectAll('circle').data(locations).enter().append('circle')
  .attr('cx', (d) -> d.coords[0][0])
  .attr('cy', (d) -> d.coords[0][1])
  .attr('r', 8)
  .style('fill', (d) -> d.color)

这很好用,但正如您所见,我只打印每个位置的 FIRST 坐标,我想将它们全部打印出来。我怀疑这样做的唯一方法是展平我的数据数组,因此总共有 5 个条目 - 3 个怪物和 2 个宝物。

只是想知道是否有办法使用 D3 更好地处理这个问题。

【问题讨论】:

    标签: javascript svg d3.js coffeescript


    【解决方案1】:

    为此,您需要nested selections。这个想法是,不是为每个数据项附加一个元素,而是附加几个。在代码中,它看起来像这样:

    // append a `g` element for each data item to hold the circles
    var groups = svg.selectAll("g.circle").data(locations)
       .enter().append("g").attr("class", "circle");
    
    // now select all the circles in each group and append the new ones
    groups.selectAll("circle")
       // the d in this function references a single data item in locations
       .data(function(d) { return d.coords; })
       .enter().append("circle")
       .attr("cx", function(d) { return d[0]; })
       .attr("cy", function(d) { return d[1]; });
    

    更新和退出选择的工作方式相同。

    【讨论】:

      猜你喜欢
      • 2012-05-04
      • 2017-06-10
      • 2012-11-19
      • 2014-12-12
      • 2017-01-25
      • 1970-01-01
      • 2014-08-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多