Mike有一篇关于在D3中编写reusable components的优秀文章。本文介绍了如何使组件可配置以及如何将组件应用于选择的模式。如何使用操纵组件的每个实例的API在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),并提供当前索引作为事件中的参数,但我还没有弄清楚如何根据其索引调用组件的特定实例。
这听起来好像做的方式是只选择需要更新的元素,然后调用组件。其他任何东西都会违反通过此组件模式实现的封装。 – 2014-05-07 18:36:28
我最近完成了基于Mikes文章的关于开源可重用组件的工作。 https://timebandit.github.io/graphSub – timebandit 2015-08-12 12:06:11