6

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);
        });
sr.u
  • 155
  • 1
  • 8

2 Answers2

9

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);
        });
JSBob
  • 1,026
  • 8
  • 11
  • 6
    for me data was on the second parameter of the function and the first is the click event. So I would rather use `function(e, d)` (this is for d3 v7) – Isuru Jun 26 '22 at 14:04
0

For me (v6.6 of d3) the code below is what I wanted, e parameter will be the event, d parameter will be the datum.

.on('change',function myEventF(e,d) {
//function body
});