Я новичок в d3.js, и я прохожу через книгу «D3.js в действии». До сих пор мне удалось выяснить все вопросы, которые у меня были, но я не могу полностью ответить сам по себе.D3 привязка данных [D3js в действии]
Я размещаю исходный код из книги здесь, так как он доступен на веб-сайте книг и на главной странице авторов. Это bl.ocks: http://bl.ocks.org/emeeks/raw/186d62271bb3069446b5/
Основная идея кода - создать таблицу, подобную таблице, из элементов div, заполненных фиктивными данными Twitter. Также реализована функция сортировки для сортировки данных по метке времени и изменения порядка листа. Также как функция для восстановления первоначального заказа.
Вот код (я оставил ту часть, где создается структура таблицы, за исключением той части, где привязанный данные):
<html>
<...>
<body>
<div id="traditional">
</div>
</body>
<footer>
<script>
d3.json("tweets.json",function(error,data) { createSpreadsheet(data.tweets)});
function createSpreadsheet(incData) {
var keyValues = d3.keys(incData[0])
d3.select("div.table")
.selectAll("div.datarow")
.data(incData, function(d) {return d.content})
.enter()
.append("div")
.attr("class", "datarow")
.style("top", function(d,i) {return (40 + (i * 40)) + "px"});
d3.selectAll("div.datarow")
.selectAll("div.data")
.data(function(d) {return d3.entries(d)})
.enter()
.append("div")
.attr("class", "data")
.html(function (d) {return d.value})
.style("left", function(d,i,j) {return (i * 100) + "px"});
d3.select("#traditional").insert("button", ".table")
.on("click", sortSheet).html("sort")
d3.select("#traditional").insert("button", ".table")
.on("click", restoreSheet).html("restore")
function sortSheet() {
var dataset = d3.selectAll("div.datarow").data();
dataset.sort(function(a,b) {
var a = new Date(a.timestamp);
var b = new Date(b.timestamp);
return a>=b ? 1 : (a<b ? -1 : 0);
})
d3.selectAll("div.datarow")
.data(dataset, function(d) {return d.content})
.transition()
.duration(2000)
.style("top", function(d,i) {return (40 + (i * 40)) + "px"});
}
function restoreSheet() {
d3.selectAll("div.datarow")
.transition()
.duration(2000)
.style("top", function(d,i) {return (40 + (i * 40)) + "px"});
}
}
</script>
</footer>
</html>
То, что я не в полной мере понять, как sortSheet и restoreSheet Работа.
Эта часть sortSheet выглядит так, что она восстанавливает данные, но после ведения журнала консоли, я думаю, что на самом деле она не переустанавливает данные в DOM. Вместо этого он просто перерисовывает элементы div.tablerow на основе индекса массива отсортированного массива.
Но тогда какая цель имеет ключевая функция? И почему работает переход? Как он знает, какой старый элемент должен вставить новую позицию?
EDIT: --- После некоторого чтения я теперь знаю, что selectAll().data()
действительно возвращает выбор обновления. По-видимому, уже привязанные данные, идентифицированные ключевой функцией, повторно сортируются в соответствии с порядком ключей в новом наборе данных? Это верно? Таким образом, выбор обновления содержит существующие div.datarow
s, но в новом порядке. Функция transition()
работает над новым порядком, рисуя только что упорядоченные div.datarow
s, начиная с индекса 0, чтобы первый элемент определял его положение на странице, чтобы индексировать n для последнего элемента. Графический переход затем как-то (как? Путем выбора выбора?) Знает, где перерисованный div.datarow
был раньше и создает эффект перехода. Это верно до сих пор? ---
d3.selectAll("div.datarow")
.data(dataset, function(d) {return d.content}) //why the key function?
.transition()
.duration(2000)
.style("top", function(d,i) {return (40 + (i * 40)) + "px"});
А что происходит, когда восстанавливается первоначальный заказ? По-видимому, во время обеих операций не происходит реального восстановления данных, а порядок div.datarow
s в DOM не изменяется. Таким образом, функция восстановления также перерисовывает макет на основе индекса массива. Но на какой выбор работает функция .transition()? Это обновление? Это обновление. И почему рисунок с использованием индекса приводит к старой компоновке? Не должен ли индекс элементов DOM всегда быть 0,1, ..., n? думаю. По-видимому, старый макет страницы перерисовывается, и DOM никогда не менялся. Но как может функция перехода() создать соответствующий графический эффект?
function restoreSheet() {
d3.selectAll("div.datarow")
.transition()
.duration(2000)
.style("top", function(d,i) {return (40 + (i * 40)) + "px"});
}
Я думал об этом несколько часов, но я не могу найти правильный ответ, я думаю. Спасибо за помощь!