У Майка есть отличная статья о написании многократно используемых компонентов в D3. В статье описывается шаблон того, как сделать компоненты настраиваемыми и как применить компонент к выделению.
Шаблон позволяет повторно использовать один компонентный объект с множественным выбором путем присоединения его к данным; например.
var chart = myChart();
d3.select("div.chart")
.data(data)
.call(chart);
Реализация моего компонента выглядит следующим образом:
function myChart() {
function my(selection) {
selection.each(function(d, i) {
// generate chart here
// `d` is the data, `i` is the index, `this` is the element
var state = false;
var circle = d3.select(this).append("circle")
.attr("r", "10")
.style("fill", "#000")
.on("click", toggleState);
function toggleState() {
// this function updates the current instance trapped by this closure
(state = !state)
? circle.style("fill", "#fff")
: circle.style("fill", "#000");
}
});
}
my.toggleState(i) {
// How do I access the `i`th instance of the component here?
}
return my;
}
Чего я хотел бы добиться, так это позволить вызывающей стороне манипулировать экземпляром этого компонента с учетом его индекса. Например, если селектор div.chart
выше возвращает выборку, состоящую из двух элементов, я бы хотел вызвать chart.toggleState(1)
и обновить второй элемент div в выборке.
Просто чтобы никого не смущать, почему я пытаюсь это сделать, вызывающая сторона должна синхронизировать два типа компонентов вместе. Представьте, что у меня есть компонент, представленный кружком, и другой компонент, представленный прямоугольником. Два компонента должны быть независимы и не связаны друг с другом. Мне нужно иметь возможность создать 4 круга и 4 прямоугольника, и когда я щелкаю прямоугольник, я хотел бы иметь возможность обновлять соответствующий круг на основе порядка индекса. Я уже разобрался, как вызвать события (d3.dispatch )из компонента и указать текущий индекс в качестве параметра в событии, но не понял, как вызвать конкретный экземпляр компонента учитывая его индекс.