D3.js v6.2 — получить индекс данных в функции прослушивателя — selection.on(‘click’, прослушиватель)

#d3.js

#d3.js

Вопрос:

В предыдущих версиях можно было получить индекс i с помощью: selection.on("click", function(d,i){...}

Однако, похоже, это больше не работает в последней версии, поскольку первым параметром всегда является объект события. Как я могу получить индекс базы данных в функции прослушивателя?

 let data = [2,5,8,9]

d3.select("body").selectAll("p")
  .data(data)
  .enter()
  .append("p")
  .text(d=>d)
  .on("mouseover", function(e,d,i){
    //console.log(e); --> event
    console.log(d); 
    console.log(i);
    // i should be the index of the hovered element
  }) 
 <script src="https://d3js.org/d3.v6.min.js"></script> 

Когда указанное событие отправляется для выбранного элемента, указанный прослушиватель будет оценен для элемента, которому будет передано текущее событие (event) и текущая дата (d), причем это будет текущий элемент DOM (event.currentTarget).

Официальная документация: https://github.com/d3/d3-selection/blob/v2.0.0/README.md#selection_on

Ответ №1:

Наблюдаемый блокнот о новых функциях в d3-selection 2.0 предлагает использовать локальную переменную для сохранения индекса:

Слушателям больше не передается индекс выбранного элемента (i) или его дочерние элементы (узлы). Они использовались редко, приводили к путанице, если элементы выбирались повторно, и могли вызвать утечки памяти. Если они вам нужны, вставьте их в данные элемента или используйте вместо этого локальную переменную.


Это можно сделать без особых усилий в следующих строках:

Обратите внимание, что, хотя в приведенном выше примере .each() для наглядности используется отдельный вызов, это также можно сделать в существующем вызове .text() для краткости и производительности.

Ответ №2:

Боюсь, что индекс был удален в этом обновлении. Если вы ищете один, самый простой способ получить его — добавить его к данным в качестве свойства ( .data(data.map((d,i) => ({ value: d, i: i }))) например) или посмотреть индекс в выборе узлов, которые у вас есть:

 let data = [2,5,8,9]

const p = d3.select("body").selectAll("p")
  .data(data)
  .enter()
  .append("p")
  .text(d=>d)
  .on("mouseover", function(e,d){
    console.log(d); 
    console.log(p.nodes().indexOf(this));
  }) 
 <script src="https://d3js.org/d3.v6.min.js"></script>