Mike has an excellent article on writing reusable components in D3. This article describes how to configure components and how to apply a component to a selection.
The template allows you to reuse a single component object with several choices, attaching it to the data; eg.
var chart = myChart(); d3.select("div.chart") .data(data) .call(chart);
My component implementation is as follows:
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; }
What I would like to achieve is to allow the caller to manipulate an instance of this component based on its index. For example, if the div.chart selector above returns a selection that has two elements, I would like to call chart.toggleState(1) and update the 2nd div in the list.
Just because I am not confusing anyone why I am trying to do this, the caller needs to synchronize the two types of components together. Imagine that I have a component that is represented by a circle and another component that is represented by a rectangle. These two components must be independent and not tied to each other. I need to create 4 circles and 4 rectangles, and when I click the rectangle I would like to update the corresponding circle based on the index. I already understood how to raise events (d3.dispatch) from the component and provide the current index as a parameter in the event, but I did not understand how to call a specific instance of the component based on its index.
khaledh
source share