2016-05-27 5 views
0

Я новичок в 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"}); 
} 

Я думал об этом несколько часов, но я не могу найти правильный ответ, я думаю. Спасибо за помощь!

ответ

0

Все становится ясно, когда вы понимаете, где были вызваны все эти функции: внутри функции json, где данные были первоначально связаны.Когда кнопка вызывает функцию sortSheet, создается новый массив объектов и привязан к строкам. Переход просто начинается с первоначального порядка и перемещает строки в соответствии с новым порядком объектов внутри массива.

И что произойдет, когда первоначальный заказ будет восстановлен?

Сейчас идет интересная часть: restoreSheet вызывается внутри функции json и не имеет доступа к переменной dataset. Таким образом, данные restoreSheet используют исходные данные. Затем переход просто перемещает строки в соответствии с порядком объектов внутри исходного массива.

Я только что сделал скрипку тиражирование этого: https://jsfiddle.net/k9012vro/2/

Проверьте код: У меня есть массив с исходными данными. Затем кнопка «сортировка» создает новый массив.

Когда я нажимаю «оригинал», прямоугольники возвращаются в исходное положение. Но нет ничего особенного в этой функции, новые данные не связываясь:

d3.select("#button1").on("click", function(){ 
    rects.transition() 
    .duration(500).attr("x", function(d, i){ return i * 30}) 
}); 

Он перемещает все прямоугольники в исходное положение, так как эта функция использует тот же самый оригинальный data.

Смежные вопросы