Search code examples
eventsd3.jsparametersclick

D3 - Unable to get data parameter on click event


I'm trying to add an onClick event to my D3 barChart and perform some actions depending on the clicked bar, but I'm unable to get the event's 'data' parameter (undefined). Am I missing something? Thanks in advance!

    var data = [{
        letter: 'A',
        frequency: 5
    }, {
        letter: 'B',
        frequency: 8
    }];

    var margin = {
            top: 20,
            right: 20,
            bottom: 30,
            left: 40
        },
        width = 960 - margin.left - margin.right,
        height = 500 - margin.top - margin.bottom;

    var x = d3.scale.ordinal()
        .rangeRoundBands([0, width], .1);

    var y = d3.scale.linear()
        .range([height, 0]);

    var xAxis = d3.svg.axis()
        .scale(x)
        .orient("bottom");

    var yAxis = d3.svg.axis()
        .scale(y)
        .orient("left")
        .ticks(10, "%");

    var svg = d3.select("body").append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");


    d3.select("body").on('click', function(d, i) {
            console.log(d);
            console.log(i);
            console.log(d3.event);
        });




    x.domain(data.map(function(d) {
        return d.letter;
    }));
    y.domain([0, d3.max(data, function(d) {
        return d.frequency;
    })]);

    svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);

    svg.append("g")
        .attr("class", "y axis")
        .call(yAxis)
        .append("text")
        .attr("transform", "rotate(-90)")
        .attr("y", 6)
        .attr("dy", ".71em")
        .style("text-anchor", "end")
        .text("Frequency");

    svg.selectAll(".bar")
        .data(data)
        .enter().append("rect")
        .attr("class", "bar")
        .attr("x", function(d) {
            return x(d.letter);
        })
        .attr("width", x.rangeBand())
        .attr("y", function(d) {
            return y(d.frequency);
        })
        .attr("height", function(d) {
            return height - y(d.frequency);
        });

Solution

  • You have to bind the click event to the bars themselves, not the page body. If you add the following to the end of your code and remove the click event from the body things will work properly.

    svg.selectAll(".bar").on('click', function(d, i) {
                console.log(d);
                console.log(i);
                console.log(d3.event);
            });