d3 (за сценой) -area.style.append работает, а area.style + area.append не работает. Почему? - PullRequest
2 голосов
/ 07 апреля 2020

Привет У меня есть вопрос о природе d3, который я думаю очень подробно о d3.

Насколько я понял,

объявление переменной в d3 похоже,

 var svg = d3.select('boby').append('svg')

означает,

«Я собираюсь выбрать« body »и добавить« svg ». И сохранить его как переменную с именем« svg »."

Вместо

"переменная svg is 'для выбора тела и добавления svg"

Причина, по которой я так думаю,
Если вторая - правильная интерпретация,

каждый раз, когда я набираю svg, он будет добавлять svg каждый раз.

Так что я думаю, что мое первое понимание правильно.



Однако,

Если это В этом случае приведенный ниже код должен работать.

var area = svg.append('g')

area.append('path')

area.attr('d').data(somedata)

Потому что я добавил 'g'
, а затем сохранил его как переменную под названием 'area'
, а затем добавил туда 'path'
а затем добавил туда атрибут
, а затем связал некоторые данные для этого.

Но это не сработало.

Тогда я попытался,

удаление другой переменной и добавление дополнительных условий после этой новой переменной, например

var uarea = area.append('path')

uarea.attr('d').data(somedata)

И это сработало идеально.

Почему мой первый подход не сработал, пока работает последний. Я думаю, что этот вопрос больше о том, что произошло за кулисами в d3. Я мог бы sh кто-то мог дать мне некоторый удар просветления в d3.

1 Ответ

2 голосов
/ 07 апреля 2020

Я не уверен, что правильно понял ваш вопрос. Но я постараюсь дать ответ здесь.

Краткий ответ: Нет, предположение, которое вы тестируете, неверно, поскольку предполагает, что .append() изменяет существующий выбор. area остается выбором g независимо от того, что вы добавляете к area.


Я собираюсь начать прямо с самого начала из-за вашего первого предположения о добавлении SVG.

Методы выбора D3 часто цепочечные, потому что они часто используются для возврата выбора. Возвращая выборку, можно использовать другой метод выбора для возвращаемого значения, что позволяет создавать цепочки.

Но выборка, возвращаемая методом выбора, не всегда является выборкой из тех же элементов - то есть она может быть другим выбором.

Если используется метод .style(), .attr(), .each(), .call(), .on(), .raise(), .html(), .text() et c для установки атрибута, стиля и т. Д. c, возвращаемым значением является сам исходный выбор. Методы, которые обычно можно использовать для возврата текущего выбора, это те, которые что-то изменяют в выборе. Если значение не установлено, многие из этих методов могут использоваться для возврата значения вместо выбора .

Если используется метод, например .append(), .enter(), .exit(), .merge(), .filter(), .select(), .selectAll(), et c, тогда возвращаемое значение будет другим выбором.

При использовании цепочки для определения переменная, присвоенное значение является возвращаемым значением последнего элемента в цепочке.

Наконец, выбор D3 не может быть изменен:

Выбор является неизменным. Все методы выбора, которые влияют на то, какие элементы выбраны (или их порядок), возвращают новый выбор, а не изменяют текущий выбор. ( source )

Как только мы определили выбор как состоящий из определенных элементов, мы не можем его изменить. Мы можем только переопределить переменную с другим выбором.

D3v3 немного отличался в этом отношении, но не для целей вашего вопроса


Теперь, глядя на вашу первоначальную оценку в этой строке:

var svg = d3.select('body').append('svg')

И ваше объяснение:

Я собираюсь выбрать [] тело и добавить [a] 'svg ». и сохраните его как переменную с именем svg.

Ваше объяснение верно, давайте разберем цепочку и используем две переменные, чтобы добиться того же, чтобы увидеть два выбранных вами варианта:

var body = d3.select("body") // returns a selection of the body
var svg = body.append("svg") // returns a selection of a newly created svg

body остается выделением тела - добавление вещей к body не меняет того, что body - выделение тела. Затем мы используем svg, чтобы сохранить новый выбор: выбор нового приложения SVG. Добавление любого элемента к svg позже не изменит svg от выбора svg.


Применяя все вышеперечисленное, мы видим, что такой подход, как:

var area = svg.append('g') // returns a selection of a new g element, stored as `area`

area.append('path')        // returns a selection of a new created path element, but you don't store this reference, nothing is done with it.

area.attr('d', somePathData) // attempting to modify a g element instead of a path.

Это не будет работать так, как вы ожидаете, area остается выделением элемента g: вы определили его как таковой и не переопределили area для выбора другого. .append() создает новый выбор - тот, который вы не используете, кроме как для создания пути.

Как вы заметили, если мы сохраним выбор path в новой переменной, код будет работать как положено :

var area = svg.append('g') // returns a selection of a new g element

var path = area.append('path') // returns a selection of a new path element

path.attr('d', somePathData) // modifies a path element

Наконец, если нам больше не нужно изменять путь, нам не нужно использовать переменную для его хранения, мы можем сделать:

var area = svg.append('g') // returns a selection of a new g element

area.append('path') // returns a selection of a new path element
    .attr('d', somePathData) // modifies the selection of the path element
...