Понимание того, как 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 ответа:
когда вы пишете:
….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 и возможность повторного связывания подмножеств данных на нижних элементах:
ключ к пониманию того, что этот код делает-это признать, что выбор массивы массивов элементов 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]...