2013-07-26 2 views
1

Я новичок в d3 и использую «Интерактивную визуализацию данных для Интернета» Скотта Мюррея (что очень кстати), чтобы начать меня. Теперь все, что я видел до сих пор, работает так, как описано, но что-то меня смутило, если посмотреть на процедуру создания нового элемента. Простой пример (из Скотт Мюррей):d3: путаница о selectAll() при создании новых элементов

svg.selectAll("circle") 
    .data(dataset) 
    .enter() 
    .append("circle"); 

Название "circle" используется для selectAll, который возвращает пустой выбор (что нормально, как я узнал). Затем круги добавляются, помещая одно и то же имя в .append. Большой!

Теперь то, что меня смутило, было то, что происходит, когда вы хотите снова сделать то же самое. Таким образом, у вас есть второй набор данных и вы хотите создавать новые круги таким же образом. Использование того же кода, что и замена набора данных, очевидно, не будет работать, поскольку selectAll("circle") больше не будет возвращать пустой выбор. Поэтому я играл и узнал, что могу использовать любое имя в selectAll и даже оставить его пустым: selectAll()

В примерах Скотта Мэрраиса всегда используется один тип (круг, текст и т. Д.) Для каждого набора данных. Наконец-то я нашел в чем-то официальные примеры, как

svg.selectAll("line.left") 
    .data(dataset) 
    .enter() 
    .append("line") 
    .attr ... 

svg.selectAll("line.right") 
    .data(dataset) 
    .enter() 
    .append("line"); 
    .attr ... 

Теперь мой вопрос: Как это запись в selectAll("ENTRY") действительно используется? Может ли он использоваться позже, чтобы снова ссылаться на эти элементы каким-либо образом или это действительно просто фиктивное имя, которое можно выбрать каким-либо образом и просто нужно вернуть пустой выбор? Я больше не мог найти эту запись в результирующей структуре DOM или объекте.

Благодарим вас за недоразумение.

ответ

3

Что вы вкладываете в вызов selectAll() перед вызовом .data() действительно имеет значение только в том случае, если вы меняете или обновляете отображаемое. Представьте, что у вас уже есть несколько кругов, и вы хотите изменить свои позиции. Координаты определяются данными, поэтому сначала вы могли бы сделать что-то вроде

svg.selectAll("circle") 
    .data(data) 
    .enter() 
    .append("circle") 
    .attr("cx", function(d) { return d; }) 
    .attr("cy", function(d) { return d; }); 

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

svg.selectAll("circle") 
    .data(newData) 
    .attr("cx", function(d) { return d; }) 
    .attr("cy", function(d) { return d; }); 

Что происходит, что D3 соответствует элементам newData к существующим кругам (то, что вы выбрали в selectAll). Таким образом, вам не нужно снова добавлять круги (они уже есть), но только обновляют их координаты.

Обратите внимание, что при первом вызове вам не нужно было выбрать circle s. Это хорошая практика, чтобы сделать это, однако, чтобы четко понять, что вы пытаетесь сделать, и избежать проблем с случайным выбором других элементов.

Подробнее об этом шаблоне обновления here.

+0

ОК, но «круг» по-прежнему обращается к элементам svg, не так ли? Что делать, если у меня есть дополнительные круги на моем svg? Или, допустим, у меня есть два набора данных для двух групп кругов. Могу ли я группировать их таким образом, как circle.left и circle.right? – nothing9

+1

Да, селектор ссылается на элементы SVG в этом случае. Если у вас есть дополнительные круги, они будут выбраны и сопоставлены. Вы можете сгруппировать их, например. назначая классы CSS и соответствующим образом определяя ('.left' после' circle' относится к классу CSS). –

+0

Aaaaaahhhh.Спасибо, теперь ты меня смутил! :) – nothing9

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