D3习语,用于在enter()上附加分组元素

d3 idiom for appending grouped elements on enter()?

本文关键字:元素 习语 用于 enter D3      更新时间:2023-09-26

是否有更好的成语将<svg:g>分组元素集附加到enter()选择上的容器上,作为通用更新模式的一部分?

var cell = d3.select(this); // parent container
cell = cell
  .selectAll('.plot').data([0]);   // seems kludgy
cell
  .enter().append('g').classed('plot',true);  // append the wrapping <g> element
cell = cell
  .selectAll("circle")
  .data(_.values(slice));
cell
  .enter().append("circle"); // general enter() -- create plot elements
cell.attr() // etc.  general update--style plot elements
cell
  .exit().remove();
当然,

if ( cell.select('g.plot').empty() ) {
  cell = cell.append('g').classed('plot', true);
}

而不是前两个语句也可以做到这一点,但这似乎是一个非常常见的操作,selectAll().data([0])似乎是人为的——是否有一个更优雅的d3习语?

对于必要时创建或选择元素,我通常会使用类似于if块的结构,而不是使用带有无意义数据的数据连接。

不仅是更短的代码,但它意味着你没有携带额外的数据属性在你的元素,当它没有任何意义。其他人也更容易知道你在做什么!

我唯一要改变的是实际保存您用于.empty()测试的选择,因为如果它是不是空,您将使用它。(您可以使用另一个变量来保存this-selection,但是d3.select(this)并不是一个重复的高计算方法调用,即使这样,当您第一次创建组时,您也只会重复一次。)

var plot = d3.select(this) // this is the parent container
             .selectAll('g.plot'); //select the plot group if it exists
if ( plot.empty() ) 
    plot = d3.select(this).append('g').classed('plot',true);
           //create the plot group if necessary
var cell = plot.selectAll("circle") //now select/create data elements as usual
  .data(_.values(slice));
cell
  .enter().append("circle"); // general enter() -- create plot elements
cell.attr() // etc.  general update--style plot elements
cell
  .exit().remove();

只需在需要的每组元素后面加上"g"。

var cell = d3.select(this)
  .append("g")
    .attr("class","plot")
    .selectAll("circle")
    .data(…);
cell.enter().append("circle")
    .attr(…);
cell.exit().remove();

这里什么不行?