Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

selection.join() enter and update duplication #260

Closed
xy2i opened this issue Sep 5, 2020 · 1 comment
Closed

selection.join() enter and update duplication #260

xy2i opened this issue Sep 5, 2020 · 1 comment

Comments

@xy2i
Copy link

xy2i commented Sep 5, 2020

In What Makes Software Good, it's mentionned that doing things both on enter and update introduces duplication, like in this code:

var text = g
  .selectAll("text")
  .data(data, key); // JOIN

text.exit() // EXIT
  .remove();

text // UPDATE
  .attr("x", function(d, i) { return i * 32; });
  
text.enter() // ENTER
  .append("text")
    .attr("x", function(d, i) { return i * 32; }) // 🌶
    .text(function(d) { return d; });

In D3 v4, there's the selection.merge() API which works around this problem by merging both enter and update:

var text = g
  .selectAll("text")
  .data(data, key); // JOIN

text.exit() // EXIT
  .remove();

text.enter() // ENTER
  .append("text")
    .text(function(d) { return d; })
  .merge(text) // ENTER + UPDATE
    .attr("x", function(d, i) { return i * 32; });

But, with the selection.join() API, it seems the same problem is present again:

var text = g
  .selectAll("text")
  .data(data, key)
  .join(
    enter => enter.append("text")
      .attr("x", (d, i) => i * 32)
      .text(d => d),
    update => update
      .attr("x", (d, i) => i * 32), // 🌶
    exit => exit.remove()
  )

Is there a way to do this with join() without the duplication?

@Fil
Copy link
Member

Fil commented Sep 5, 2020

var text = g
  .selectAll("text")
  .data(data, key)
  .join(
    enter => enter.append("text")
      .text(d => d),
    update => update,
    exit => exit.remove()
  ).attr("x", (d, i) => i * 32)

or simply

var text = g
  .selectAll("text")
  .data(data, key)
  .join("text").text(d => d).attr("x", (d, i) => i * 32)

see https://observablehq.com/@d3/selection-join

selection.join appends entering elements and removes exiting elements to match the data! Entering and updating elements are merged (and ordered), allowing chained operations on the result.

@Fil Fil closed this as completed Sep 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants