2013-07-23 3 views
4

В ответ Майк опубликовал here, он рассматривает три разных способа применения изменения к согласованному элементу на основе индекса или настраиваемого фильтра. Я пытаюсь разъяснить, надеюсь, для большего количества людей, чем только я, фактический выбор в этих решениях.Выборы в D3, JQuery

Так выдан документ с 6 SVG прямоугольников с классом .bar, у нас есть эти различные выборы и то, что они возвращаются:

d3.select ("бар."):

[Array[1] 
0: rect.[object SVGAnimatedString] 
length: 1 
parentNode: html 
__proto__: Array[0] 

d3.selectAll ("бар"):

[Array[6] 
0: rect.[object SVGAnimatedString] 
1: rect.[object SVGAnimatedString] 
2: rect.[object SVGAnimatedString] 
3: rect.[object SVGAnimatedString] 
4: rect.[object SVGAnimatedString] 
5: rect.[object SVGAnimatedString] 
length: 6 
parentNode: html 
__proto__: Array[0] 

$ («бар»):

[ 
<rect class=​"dataBars" x=​"53.191489361702125" width=​"212.7659574468085" y="4.761904761904762" height=​"11.11111111111111">​</rect>​, 
<rect class=​"dataBars" x=​"74.46808510638297" width=​"372.3404255319149" y=​"20.634920634920636" height=​"11.11111111111111">​</rect>​, 
<rect class=​"dataBars" x=​"127.6595744680851" width=​"212.7659574468085" y=​"36.507936507936506" height=​"11.11111111111111">​</rect>,​ 
<rect class=​"dataBars" x=​"31.914893617021274" width=​"212.7659574468085" y=​"52.38095238095238" height=​"11.11111111111111">​</rect>​, 
<rect class=​"dataBars" x=​"159.5744680851064" width=​"265.9574468085106" y=​"68.25396825396825" height=​"11.11111111111111">​</rect>​, 
<rect class=​"dataBars" x=​"234.04255319148936" width=​"138.29787234042553" y=​"84.12698412698413" height=​"11.11111111111111">​</rect>​, 
] 

Теперь вот где получить-х сложнее (для меня по крайней мере), сказать, что я хочу, чтобы применить style к 3-му прямоугольника, этот прямоугольник можно найти с помощью

d3.selectAll(".bar")[0][2] 

Но если мы хотим, чтобы затем использовать d3.selection.attr(), что возвращает

TypeError: Property 'style' of object #<SVGRectElement> is not a function 

Но мы можем обернуть этот выбор

d3.select(d3.selectAll(".bars rect")[0][2]).style("fill", "red") 

и это будет работать должным образом.

Тогда, если мы хотим, чтобы применить фильтр, такой, как

filter(function (d) { return d === 5 || d === 15;} 

d3.selectAll(".bar") должны быть использованы, и d3.select(d3.selectAll(".bar")) не будет работать правильно.

Я прочитал превосходные учебники и документацию Майка по выборам, но когда я думаю, что я понял, что-то всплывает и меня удивляет. Так в чем разница между этими выборами и как я могу узнать, какой из них использовать? Большое спасибо, и извините за длинный пост!

+0

Ну, 'd3.selectAll (". Bar ") [0] [2]' возвращает "необработанный" элемент DOM, а элементы DOM не имеют функции 'style'. 'd3.select (d3.selectAll (". bar "))' не работает, потому что '.select' ожидает либо элемент DOM, либо селектор (строка), но не выбор D3. –

ответ

3

В общем, вы не должны обращаться к элементам возвращаемого выбора по их индексам, а скорее фильтровать или использовать подсегмент. Таким образом, вы можете применить .attr() и .atyle() без проблем. Причиной этого является то, что D3 не возвращает «чистый» массив элементов DOM (например, jquery), а элементы в оболочке, поддерживающей операции D3. Он по-прежнему ведет себя как массив, но если вы указали в него, вы получите «чистый» элемент DOM. Вы также можете присвоить элемент DOM d3.select(), и он сгенерирует обертку вокруг этого элемента, которая позволит использовать все материалы D3.

Если вы посмотрите на documentation for filter(), вы найдете примеры использования и подвыборки. Вы можете использовать эти методы для получения третьего элемента выбора, например. Использование функции .filter() имеет смысл только в том случае, если вы привязали данные к объектам, которые вы фильтруете, в противном случае подсегмент должен делать то, что вы хотите.

+0

спасибо за объяснение! – user4815162342

+0

jQuery не возвращает массив элементов. Он возвращает объект jQuery, который является * array-like * и позволяет вам обращаться к выбранным элементам через их индекс. –

+0

Какая разница с обычным массивом? Возвращаемое значение выглядит как простой массив для меня. –

5

Я пытался сделать это в прошлом и сталкивался с подобными ошибками.Тогда я понял, что я действительно не придерживался предполагаемого API. Во-вторых, вы начинаете получать доступ к элементам выбора по индексу, вы выходите из проторенного пути.

См nested selections

Так что, если вы хотите, чтобы стиль вашего третьего бара, вы могли бы сделать

d3.selectAll(".bar").style("color", function(d,i) { return i === 2 ? "red" : null; }) 

И если ваш выбор один уровень более вложенная чем, сделать его function(d,i,j) и аналогичным образом перейти от там. И т. Д.

+1

Как и Ларс, вы также можете выбрать, прежде чем обновлять стиль, чтобы не устанавливать ничего в null: d3.selectAll («. Bar rect»). Filter (function (d, i) {return i == 2;}). стиль («fill», «red») –

+0

@AdamPearce очень хороший момент, я как бы замалчивал это. – roippi

+0

@roippi Спасибо за пример на фильтрах, будет повышать, но у меня нет репутации! – user4815162342

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