Понимание того, как D3.js связывает данные с узлами


Я читаю через D3.JS документация, и мне трудно понять the selection.data метод из документации.

это пример кода, приведенный в документации:

var matrix = [
  [11975,  5871, 8916, 2868],
  [ 1951, 10048, 2060, 6171],
  [ 8010, 16145, 8090, 8045],
  [ 1013,   990,  940, 6907]
];

var tr = d3.select("body").append("table").selectAll("tr")
    .data(matrix)
  .enter().append("tr");

var td = tr.selectAll("td")
    .data(function(d) { return d; })
  .enter().append("td")
    .text(function(d) { return d; });

Я понимаю, но что происходит с на var td заявление?

мое лучшее предположение заключается в следующем:

  • The var tr заявление связал четыре элемента массива для каждого тр узел
  • The var td оператор затем использует этот четырехэлементный массив в качестве своих данных, так или иначе

, а как .data(function(d) { return d; }) на самом деле получить эти данные, и как это вернуть?

3 64

3 ответа:

когда вы пишете:

….data(someArray).enter().append('foo');

D3 создает кучу <foo> элементы, для каждой записи в массиве. Что еще более важно, он также связывает данные для каждой записи в массиве с этим элементом DOM, как __data__ собственность.

попробуйте это:

var data = [ {msg:"Hello",cats:42}, {msg:"World",cats:17} ]; 
d3.select("body").selectAll("q").data(data).enter().append("q");
console.log( document.querySelector('q').__data__ );

то, что вы увидите (в консоли) - это объект {msg:"Hello",cats:42}, так как это было связано с первым созданным q элемент.

если вы позже делать:

d3.selectAll('q').data(function(d){
  // stuff
});

значение d получается, что __data__ собственность. (На данный момент это до вас, чтобы убедиться, что вы заменить // stuff С кодом, который возвращает новый массив значений.)

вот еще один пример отображение данных, привязанных к элементу HTML и возможность повторного связывания подмножеств данных на нижних элементах:

no description

ключ к пониманию того, что этот код делает-это признать, что выбор массивы массивов элементов DOM. Самый внешний массив называется "выборкой", внутренние массивы называются "группами", и эти группы содержат элементы DOM. Вы можете проверить это, зайдя в консоль по адресу d3js.org и сделать выбор, как d3.selectAll ('p'), вы увидите массив, содержащий массив, содержащий элементы' p'.

в вашем примере при первом вызове selectAll ('tr') вы получаете выборку с одной группой, которая содержит все элементы' tr'. Тогда каждый элемент matrix соответствует каждому элементу 'tr'.

но когда вы вызываете selectAll ('td') на этом выборе, выбор уже содержит группу элементов' tr'. На этот раз каждый из этих элементов будет каждый группы элементов 'td'. Группа-это просто массив, но она также имеет свойство parentNode, которое ссылается на старый выбор, в этом случае 'tr' элементы.

Теперь, когда вы называете data(function(d) { return d; }) на этом новом выборе элементов 'td',d - это данные, привязанные к родительскому узлу каждой группы. Таким образом, в Примере ' td в первой группе будут связаны с массивом [11975, 5871, 8916, 2868]. Вторая группа ' td связаны с [ 1951, 10048, 2060, 6171].

вы можете прочитать собственное превосходное объяснение Майка Бостока выбора и привязки данных здесь: http://bost.ocks.org/mike/selection/

использовать Я для отображения индекса используемых данных.

var tr = d3.select("body").append("table").selectAll("tr")
.data(matrix)
.enter().append("tr") //create a row for each data entry, first index
.text(function(d, i) { return i}); // show the index i.e. d[0][] then d[1][] etc.

var td = tr.selectAll("td")
.data(function(d) { return d; })
.enter().append("td")
.style("background-color", "yellow") //show each cell
.text(function(d,i) { return i + " " + d; }); // i.e d[from the tr][0] then d[from the tr][1]...