Scott Skiles
Scott Skiles

Reputation: 3847

How can I use D3.js "onClick" event with an nvd3 bar when zoomed in on chart data?

Another obscure nvd3 question, this time with onClick.

I was able to use this question to figure out how to add an "onClick" event for bars using nvd3's linePlusBarChart.

The jsfiddle here is working. Please feel free to click on a bar to see what I'm going for (using alert as a test). The relevant code is at the bottom of the JavaScript, also shown here:

d3.select('#chart1 svg')
    .datum(testdata)
    .transition().duration(500).call(chart);
    nv.utils.windowResize(chart.update);
    chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });
    return chart;       
   }, function(){
      d3.selectAll(".nv-bar").on('click', 
          function(e){
            console.log(e);
            alert("You clicked on bar!");
          }
      );   
  });

This is really great! I am really happy with this as a solution. Using function(e) to get data from the NVD3 bar I can then use the bar data (quantity and date) to do other cool things with JavaScript.

Unfortunately, I discovered that if I use the bottom panel to zoom in on a specific date range the 'onClick' event stops working.

What is happening that causes the onClick event to become disassociated with a specific bar?

Is there an additional location that I need to add the onClick logic?

Any help would be greatly appreciated.

Upvotes: 2

Views: 317

Answers (1)

rioV8
rioV8

Reputation: 28663

The brush calls the historicalBar chart with the focus bars as selection.

After rendering the chart dispatches the renderEnd event.

We put the onclick callback in a separate function because we need it more then once

function addOnClick() {
  d3.selectAll(".nv-bar")
    .on('click', function(e) { console.log(e); alert("You clicked on bar!"); } );
}

We need to add a callback for this event

chart.bars.dispatch.on('renderEnd', addOnClick);

The complete code for the chart will be

var chart;
nv.addGraph(function() {
    chart = nv.models.linePlusBarChart()
      .margin({top: 50, right: 80, bottom: 30, left: 80})
      .legendRightAxisHint(' [Using Right Axis]')
      .color(d3.scale.category10().range());
    chart.xAxis.tickFormat(function(d) {
      return d3.time.format('%x')(new Date(d))
    }).showMaxMin(false);
    chart.y2Axis.tickFormat(function(d) { return '$' + d3.format(',f')(d) });
    chart.bars.forceY([-3899468]).padData(false);
    chart.lines.forceY([-600]).padData(false);

    chart.x2Axis.tickFormat(function(d) {
      return d3.time.format('%x')(new Date(d))
    }).showMaxMin(false);
    d3.select('#chart1 svg')
      .datum(testdata)
      .transition().duration(500).call(chart);
    nv.utils.windowResize(chart.update);
    chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });
    chart.bars.dispatch.on('renderEnd', addOnClick);
    return chart;
  }, addOnClick
);
function addOnClick() {
  d3.selectAll(".nv-bar")
    .on('click', function(e) { console.log(e); alert("You clicked on bar!"); } );
}

Upvotes: 1

Related Questions