d3.js中的进入和退出是什么?

时间:2019-06-22 20:47:24

标签: javascript d3.js

我试图通过这个例子来理解,但是不了解退出功能。实际上,在退出之前,我得到的是Enter,但是即使在将不同的数据绑定到Exit函数之后,在Enter函数之后立即实现exit函数时,也不会附加创建的li项目。

请帮助我了解输入a的任务

enter image description here

<ul id="#example">
  <li></li>
  <li></li>
  <li></li>
</ul>
<script>

var updateSelection;
var veri;

window.onload = function() {
  // Bağlanacak veri sayısı 5
  veri = [5, 10, 15, 20, 25];


  updateSelection = d3
    .select("ul") 
    .selectAll("li") 
    .data(veri)
    .enter() 
    .append("li")
    .text(d => d)
    .style("color","blue");

  console.log(updateSelection);

  updateSelection = d3
    .select("ul") 
    .selectAll("li")
    .data([1,2]) 
    .exit() 
    .append("li")
    .text(d => d)
    .style("color","red");

  console.log(updateSelection);

}
</script>

2 个答案:

答案 0 :(得分:0)

在d3JS v4和5中,如果创建选择并应用.data()函数,则将更改您所拥有的选择对象的性质。如果将其存储在变量中,则可以随后在该对象上调用.enter().exit()函数以分别选择应添加的项目和应删除的项目。然后,您可以使用.merge()函数将新项目与先前存在的项目合并,顾名思义,该函数将这些项目合并到一个选择中,类似于全新d3.select()的结果会是。

关于代码,您不必多次进行选择,而且我认为多次调用.data()弊大于利。我将添加一些代码,在其中向图表绘制图例。我希望它能说明我的观点。

// I select all legend values and apply a new set of data to it
let items = this.legend
    .selectAll(".item")
    .data(values);
// I remove the values that can be removed
items.exit().remove();
// I specifically select the new items and draw a new <g> element for each
const enterItems = items.enter()
    .append("g")
    .classed("item", true);

// Each of those <g> elements gets a <circle> and a <text> node
enterItems.datum(d => d)
    .append("circle")
    .attr("r", 3);
enterItems.datum(d => d)
    .append("text")
    .attr("dx", -7)
    .attr("dy", 3);

// Finally I merge the new <g> elements with the ones that I left over
// from before I called `.data()` - so not the ones I deleted
// It's good practice not to apply any code to this merged selection
// that involves drawing new items, but to only respond to changes in data,
// i.e. calculating and setting dynamic variables.
items = enterItems
    .merge(items)
    // Apply to all because this redraw
    // might have been caused by a resize event
    .attr("transform", (_, i) =>
      `translate(${this.$element[0].clientWidth - this.margin.right},
                      ${this.margin.top + i * 10 + 5})`);

// This also applies to all child elements. I may change the color and the text,
// but I do not recalculate the fixed size of the circles or the positioning of the
// text - because I know those would never change
items.select("circle")
    .style("fill", d => this.colors(d))
    .attr("class", d => `legend item-${d}`);
items.select("text")
    .text(d => d);

答案 1 :(得分:0)

有很多关于D3选择的教程,这本很老的书很不错:https://bost.ocks.org/mike/join/

关于您的问题,目前尚不清楚为什么要将元素附加到退出选择中。但是,值得一提的是,使用出口选择,包括附加元素,都可以做他们想做的任何事情。

简而言之,这就是代码中发生的事情:

  1. 您正在使用此数据...

    [5, 10, 15, 20, 25]
    

    ...进入输入选择。如您所见,数据数组中有5个元素,所以enter选择有5个元素。看看控制台:

var veri = [5, 10, 15, 20, 25];

var updateSelection = d3
  .select("ul")
  .selectAll("li")
  .data(veri)
  .enter()
  .append("li")
  .text(d => d)
  .style("color", "blue");

console.log("size of enter selection: " + updateSelection.size());
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<ul></ul>

  1. 然后,再次选择所有内容,并将选择内容绑定到此数据数组:

    [1, 2]
    

如您所见,您在前一个数据数组中有5个元素,在新数据数组中有2个元素(因为这里没有键函数,因此您要按索引绑定元素)。因此,由于您有3个数据元素而没有相应的DOM元素,因此退出选择大小为3。比较两个数组:

[5, 10, 15, 20, 25]
[1, 2]   |   |   |
         |   |   |
         V   V   V
//these elements belong to the exit selection

再次查看控制台:

var veri = [5, 10, 15, 20, 25];

var updateSelection = d3
  .select("ul")
  .selectAll("li")
  .data(veri)
  .enter()
  .append("li")
  .text(d => d)
  .style("color", "blue");

updateSelection = d3
  .select("ul")
  .selectAll("li")
  .data([1, 2])
  .exit()
  .append("li")
  .text(d => d)
  .style("color", "red");

console.log("size of exit selection: " + updateSelection.size());
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<ul></ul>

最后,我们拥有的视觉效果正是预期的视觉效果:我们有5个蓝色元素(对应于enter选择)和3个红色元素(对应于退出选择)(无论出于何种原因,您都将其追加< / em>或已删除)。