2017-01-18 5 views
0

В настоящее время я работаю над силовым моделированием. Here's the fiddle если вам это нужно. Данный раздел дает мне немного хлопот - я пытаюсь его ссылку и не узлы, где ситуация похожа, так что мы можем увидеть разницу работы и нерабочий:D3.js - что такое selection.call() возвращение?

function linkRender(selection) { 
    selection 
     .data(links) 
     .enter().append("line") 
     .attr("stroke-width",2) 
     .attr("stroke","black") 
} 
let link = svg.selectAll("line").call(linkRender); 

Здесь call() должен возвращать выбор, то есть линии связи. Однако, при визуализации ссылок в selection.on(), если я использую переменную link работать, он не делает должным образом, к своему огорчению:

simulation.on("tick",byFrame); 
function byFrame() { 
    // This doesn't work! 
    link 
     .attr("x1", d => d.source.x) 
     .attr("y1", d => d.source.y) 
     .attr("x2", d => d.target.x) 
     .attr("y2", d => d.target.y) 

    // But this works! 
    svg.selectAll("circle") 
     .attr("cx",d => d.x) 
     .attr("cy",d => d.y) 
} 

И если я назначу переменную link к linkRender() старому, то есть,

let link = linkRender(svg.selectAll("line")) 

до тех пор, как я установил linkRender() вернуть код внутри (return selection.data(links).etc), визуализация работает отлично.

Наконец, вот сравнение link и svg.selectAll("line"):

enter image description here

Так что я хотел бы знать, что происходит. Заранее спасибо!

ответ

2

Ваши утверждения не являются эквивалентными и поэтому не сопоставимы. Документация по selection.call() сообщает нам:

Вызывает указанную функцию ровно один раз, передавая этот выбор вместе с любыми необязательными аргументами. Возвращает этот выбор.

Это следует понимать буквально: возвращение этого выбора означает именно выбор указанной функция вызывается с. Поскольку перед вызовом нет строк, ваш выбор будет пустым при вызове на нем .call(). Хотя вы можете успешно использовать этот пустой выбор в этой функции для привязки данных и добавления строк, это не изменит исходный выбор.

Поскольку

Выбор неизменны.

метод .call() тем не менее вернуть оригинал, то есть пустой, выбор, который затем будет назначен link. Легко видеть, что это отличается от вашего другого решения при выборе вновь добавленных строк или при возврате выбора ввода из вашей измененной функции.

Это фактически работает для узлов, потому что в byFrame() вы не можете получить к ним доступ через node, но вместо этого сделайте svg.selectAll("circle").

Я думаю, что для этого приложения, используя

let link = linkRender(svg.selectAll("line")); 

будет путь. Как вы уже упоминали, для корректного возврата выбора потребуется linkRender().

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