Почему d3 сохраняет некоторые из моих элементов, когда я хочу, чтобы он удалил все элементы?

#javascript #d3.js

Вопрос:

Я пытаюсь создать очень простой визуализатор дробей, в основном пользователь может ввести числитель и знаменатель, и d3 покажет им поля, синие для числителя, а остальные белые (пустые/пустые), когда они нажимают кнопку.
Функция, которую я использую, приведена ниже:

 const redraw = function() {
  d3.select("frac")
    .selectAll("div")
    .data(window.dataset)
    .exit()
    .remove()
  d3.select("frac")
    .append("div")
    .selectAll("div").data(window.dataset)
    .enter()
    .append("div")
    .attr("class", "bar")
    /* .text((d)=>d) */
    .style("width", width / window.dataset.length   "vw")
    .style("background-color", (d) => {
      if (d == 0) {
        return "white"
      } else if (d == 1) {
        return "blue"
      } else if (d == 2) {
        return "red"
      } else if (d == 3) {
        return "yellow"
      }
    })
}
 

смотрите полный код здесь: https://jsfiddle.net/sbrevolution5/gpueyrtf/53/

По какой-то причине, когда я обновляю число и перерисовываю элемент d3, он сохраняет 2 синих поля, но затем создает новый элемент ниже.

Ответ №1:

Вам нужно поменять местами строки .remove() и .exit() . Итак, из:

     .exit()
    .remove()
 

изменить на

     .remove()
    .exit()
 

Комментарии:

1. Вам не нужно selection.exit() , если вы используете такой подход: элементы уже были удалены из DOM by selection.remove() . exit просто возвращает новый выбор, он не изменяет DOM. Подход этого ответа работает, но ограничивает некоторые параметры, поскольку он позволяет избежать использования канонического цикла ввода/обновления/выхода, вместо этого предпочитая удалять все и вводить все каждое обновление (что может быть или не быть желательным). Если подход предпочтителен, то .data() метод также не нужен: d3.selectAll("selector").remove() достаточно удалить существующие элементы.