Accepted answer

You could use the closure to keep a reference to the parent data like this:

bar.each(function(dbar) {            // dbar refers to the data bound to the bar"rect")
      .on("click", function(drect) { // drect refers to the data bound to the rect
        console.log(dbar.key);       // dbar.key will be either 'likes' or 'dislikes'


See below for various ways to access different levels in your DOM structure. Mix and match! See the live version of this and try to click on the .rect divs:

var data =  [
        key: 'likes',
        values: [{ key: 'blue-frog', value: 1 }, { key: 'goodbye', value: 2 }]
        key: 'dislikes',
        values: [{ key: 'blue-frog', value: 3 }, { key: 'goodbye', value: 4 }]

var chartdivs ="body").selectAll("div.chart")
    .data([data]) // if you want to make multiple charts: .data([data1, data2, data3])
    .attr("class", "chart")
    .style("width", "500px")
    .style("height", "400px");; // chartdivs is a d3.selection of one or more chart divs. The function chart is responsible for creating the contents in those divs

function chart(selection) { // selection is one or more chart divs
  selection.each(function(d,i) { // for each chartdiv do the following
    var chartdiv =;
    var bar = chartdiv.selectAll(".bar")
        .attr("class", "bar")
        .style("width", "100px")
        .style("height", "100px")
        .style("background-color", "red");  

    var rect = bar.selectAll(".rect")
        .data(function(d) { return d.values; })
        .attr("class", "rect")
        .text(function(d) { return d.key; })
        .style("background-color", "steelblue");

    bar.each(function(dbar) {
      var bardiv =;
          .on("click", function(drect) { 
  , bardiv);

    function onclickfunc(rect, bar) { // has access to chart, bar, and rect"background-color", bar.datum().key === 'likes' ? "green" : "grey");
      console.log(rect.datum().key); // will print either 'blue-frog' or 'goodbye'


rect.on("click", this.onChartClick.bind(this)); won't work because you're not passing a function, you're passing the return value of the function (by appending (this)).

If you want to pass this and data (d), try this:

// assuming you have this somewhere earlier
var onChartClick = function () {}

// change your parent click to
rect.on("click", function(d) {
    return, d);


Another way could be f.e passing an object/json or in my case a class instance which creates that rectangle to the event to access it inside

var rect = svgContainer.append("rect");
rect.on('click', function(d){
    alert(; // etc.

Related Query

More Query from same tag