If you want to do something when you click a state, for example, change the frame style or the opacity of a figure, you can use the fact that each county is state owned and simply groups the counties in states, capturing the 'click' event in the county, select the appropriate state item and change its visual attributes. The layout of this strategy:
// Setup the visualization, assuming that you have a div with id 'chart' var width = 300, height = 300, div = d3.select('#chart'), svg = div.append('svg') .attr('width', width) .attr('height', height); // Array of states, each one containing one or more counties. In this example, // the states are rectangles, but you get the idea var states = [ { width: 300, height: 300, name: 'Fake State', counties: [ {x: 5, y: 5, width: 95, height: 290, fill: '#b4a0a0'}, {x: 100, y: 5, width: 150, height: 290, fill: '#b4c0a0'}, {x: 250, y: 5, width: 45, height: 290, fill: '#a4a0c0'} ] }]; // Create a group for each state, with class state var gstates = svg.selectAll('g.state') .data(states) .enter() .append('g') .classed('state', true); // Add the state background, in this case, a transparent rectangle gstates .append('rect') .classed('state', true) .attr('width', function(d) { return d.width; }) .attr('height', function(d) { return d.height; }) .attr('fill', '#444') .attr('fill-opacity', 0.0); // For each group, add rectangles for each county, binding them to the // county array of each state. gstates.selectAll('rect.county') .data(function(d) { return d.counties; }) .enter() .append('rect') .classed('county', true) .attr('x', function(d) { return dx; }) .attr('y', function(d) { return dy; }) .attr('width', function(d) { return d.width; }) .attr('height', function(d) { return d.height; }) .attr('fill', function(d) { return d.fill; }) .on('mouseover', function() { d3.select(this).attr('fill-opacity', 0.5); }) .on('mouseout', function() { d3.select(this).attr('fill-opacity', 0.9); }) .on('click', function() { // Retrive the parent group of each county, and then select // the shape corresponding to the state and alter its properties // you can also access the state data var parent = d3.select(d3.select(this).node().parentNode), state = parent.select('rect.state'); // Output 'Fake State' console.log(parent[0][0].__data__.name); state.attr('fill-opacity', 1.0); });
There is a working fiddle here: http://jsfiddle.net/pnavarrc/PGTCM/5/ . Yours faithfully,