Подтвердить что ты не робот

D3 Ключевые функции

Как читатели могут собраться из следующего... Я новичок в D3.... Я экспериментирую в данный момент с помощью .enter() и .exit().remove(). Я пытаюсь понять, что делает ключевая функция...? Я просматриваю DOM с помощью Chrome > Console и не вижу никаких очевидных различий между .data(dataSet, keyFunction) и без ключевой функции .data(dataSet).

Кто-нибудь может предложить любые эксперименты, чтобы попробовать (или консольные выражения), которые могут помочь мне понять, что делает таинственная ключевая функция....

4b9b3361

Ответ 1

Я также новичок в d3 и боролся с ключевой функцией. Я не нашел ответа Тристана Рида, потому что он действительно мало говорит о ключевой функции.

Пусть работает через пример, сначала без ключевой функции, а затем с помощью.

Вот наш начальный html перед применением javascript. У нас есть два div, и никаких данных не привязано ни к чему.

<body>
    <div>** First div **</div>
    <div>** Second div **</div>
</body>

Вызов данных() без ключевой функции

Добавьте пару строк javascript.

var arr1 = [35, 70, 24, 86, 59];
d3.select("body")
    .selectAll("div")
    .data(arr1)
    .enter()
    .append("div")
    .html(function(d) { return d });

Как выглядит наш html сейчас? Вот html вместе со значениями связанных данных (добавлены комментарии).

<body>
    <div>** First div ** </div>   <!-- data:  35 -->
    <div>** Second div ** </div>  <!-- data:  70 -->
    <div>24</div>                 <!-- data:  24 -->
    <div>86</div>                 <!-- data:  86 -->
    <div>59</div>                 <!-- data:  59 -->
</body>

Вызов data() сопоставил массив div с массивом значений с помощью ключа. Клавишами по умолчанию, используемыми для массивов, являются индексы. Таким образом, это ключи, которые были использованы.

selected divs (by text)  key       data elements  key
-----------------------  ---       -------------  ---
** First div **          0         35             0
** Second div **         1         70             1
                                   24             2
                                   86             3
                                   59             4

Идя по клавишам, два элемента данных имеют совпадения в выбранных divs - те с ключами 0 и 1. Соответствующие divs привязаны к данным, но больше ничего не происходит.

Все элементы данных без соответствующего ключа передаются в enter(). В этом случае нет совпадений для ключей 2, 3 и 4. Таким образом, эти элементы данных передаются в enter(), а для каждого из них добавляется новый div. Добавленные div также привязаны к их соответствующим значениям данных.

Вызов данных() с помощью ключевой функции

Давайте изменим наш javascript, сохранив то, что у нас есть, но добавим еще пару строк. Мы будем выполнять одни и те же выборки с помощью вызова данных (с другим массивом), но на этот раз с помощью ключевой функции. Обратите внимание на частичное перекрытие между arr1 и arr2.

var arr1 = [35, 70, 24, 86, 59];
d3.select("body")
    .selectAll("div")
    .data(arr1)                            // no key function
    .enter()
    .append("div")
    .html(function(d) { return d });

var arr2 = [35, 7, 24, 2];
d3.select("body")
    .selectAll("div")
    .data(arr2, function(d) { return d })  // key function used
    .enter()
    .append("div")
    .html(function(d) { return "new: " + d});

Получающийся html выглядит так (с добавленным комментарием):

<body>
    <div>** First div** </div>    <!-- data:  35 -->
    <div>** Second div ** </div>  <!-- data:  70 -->
    <div>24</div>                 <!-- data:  24 -->
    <div>86</div>                 <!-- data:  86 -->
    <div>59</div>                 <!-- data:  59 -->
    <div>new: 7</div>             <!-- data:  7 -->
    <div>new: 2</div>             <!-- data:  2 -->
</body>

Второй вызов data() использовал значение, возвращаемое функцией для ключей. Для выбранных элементов функция возвращает значение, полученное из данных, которые уже были привязаны к ним при первом вызове data(). То есть их ключ основан на их связанных данных.

Для второго вызова data() ключи, используемые для сопоставления, выглядят следующим образом.

selected divs (by text) key       data elements  key
----------------------- ---       -------------  ---
** First div **         35        35             35
** Second div **        70        7              7
24                      24        24             24
86                      86        2              2
59                      59

Элементы данных без соответствующих ключей - это 7 и 2. Эти элементы данных передаются в enter(). Таким образом, мы получаем два новых divs, присоединенных к телу.

Хорошо, теперь давайте оглянемся на оригинальный пост. ОП сказал, что между вызовом data() не существует никакой разницы между функцией и без нее. Вероятно, потому, что, как предлагает Тристан Рид, ключевая функция использовалась для элементов html, которые не имели связанных данных. Когда нет связанных данных, не будет соответствующих ключей, поэтому все элементы данных будут переданы функции enter().

Работа через этот пример помогла осветить для меня отношения между выборами, ключами и связанными данными. Надеюсь, это будет полезно кому-то другому.

Ответ 2

Ключевая функция объясняет, как присоединить данные к элементам. Ключевая функция по умолчанию, если вы ее не используете, - это использовать индекс.

Чтобы понять все это, рассмотрите, что d3 selectAll/data выполняет две фазы согласования. Первый - селектор, например. d3.selectAll('div'), который будет соответствовать всем div. Второй - это объединение данных, data([1,2,3]), которое ищет элементы со свойствами данных, которые соответствуют данным, которые вы передаете в. Основное внимание уделяется тому, что я считаю, что понимание этого имеет основополагающее значение для получения полной выгоды от d3.

Вот пример (и скрипка), которая демонстрирует разницу.

function id (d) { return d; }

d3.select('.no-key').selectAll('div')
    .data([1,2,3])
    .enter().append('div')
    .text(id);

d3.select('.yes-key').selectAll('div')
    .data([1,2,3], id)
    .enter().append('div')
    .text(id);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div class='no-key'>
    <div class='a'>already here</div>
</div>
<br/>
<div class='yes-key'>
    <div>already here</div>
</div>

Ответ 3

В запросе моего героя SO, позвольте мне попытаться устранить желание @markthekoala для экспериментов с консолью, что наглядно демонстрирует эффект указания ключевой функции в операторе .data().

http://bl.ocks.org/migurski/4601038

Я на самом деле считаю это еще более наглядным примером, чем отличный, с которым я связан в своих комментариях выше! ПРИМЕЧАНИЕ: длинное название блока имеет хорошее объяснение того, что происходит под капотом, поэтому внимательно прочитайте его.

Вы можете играть с блочным кодом в FIDDLE.

Честно говоря, мне очень сложно улучшить объяснения в этих двух примерах, и особенно о экспериментах, которые так умно выполняются на втором.