How to add a click event on nvd3.js graph
Asked Answered
A

11

23

I am using nvd3.js and trying to add a click event

d3.selectAll(".nv-bar").on('click', function () {console.log("test");});

JSFiddle

How can I do that ?

Antemortem answered 11/7, 2013 at 16:25 Comment(1)
My previous answer has a fault so had to delete it, did not notice that, will get an answer as soon as I can, or someone else will post an answer before that, sorry about it.Costanzo
B
31

I was running into the same issue and was about to dump NVD3 all together because of the lack of documentation... What you need to do is add a callback function to addGraph(). Also note the d3.selectAll() instead of d3.select().

Good Luck.

nv.addGraph(function() {
     var chart = nv.models.multiBarHorizontalChart()
         .x(function(d) { return d.label })
         .y(function(d) { return d.value })
         .margin({top: 5, right: 5, bottom: 5, left: 5})
         .showValues(false)
         .tooltips(true)
         .showControls(false);

     chart.yAxis
         .tickFormat(d3.format('d'));

     d3.select('#social-graph svg')
         .datum([data])
       .transition().duration(500)
         .call(chart);

       nv.utils.windowResize(chart.update);

       return chart;
     },function(){
          d3.selectAll(".nv-bar").on('click',
               function(){
                     console.log("test");
           });
      });
Bradwell answered 17/7, 2013 at 22:26 Comment(4)
unfortunately i had no luck applying this approach to a nv3d line chart. my goal was to get the data of the clicked line point (x,y), but d3.selectAll("nv-point-paths")on('click') gave me the data of the whole chart instead of the individual point. I hoped to fix this with d3.selectAll("nv-point-paths path").on('click'), but this handler never triggered. Any idea?Naquin
Actually if you take a look at the examles, you will see that the best way to handle events is what wexman suggested.Robbirobbia
on stacked bar chart , once you change legends , the click events disappear. Its not the case with Wexman's answer though.Hepburn
On the function add the param e, and then console.log(e), you'll find data for the selected bar.Dressler
E
43

Just found out that this works as well (at least for multibar charts):

chart.multibar.dispatch.on("elementClick", function(e) {
    console.log(e);
});

I had to look at the source in src/multibar.js to find out; since it's there, I guess this is the way it was intended to be done. However, I second what Alex said in his answer: the lack of documentation for NVD3 is a really big disadvantage. Which is sad because the general idea of the project is great: giving us the power of D3 without going into all the details...

Eyecup answered 13/12, 2013 at 13:38 Comment(4)
This works well. You just have to match the object to your chart type: chart.pie, chart.bars, chart.lines.Anywhere
Very frustrating that the most recent release (1.8.1) no longer returns the event or the series of data, only the bar (or circle), which is a huge pain point if you were using the d3.event to grab the element and style it, e.g change the bar's color. See github.com/novus/nvd3/blob/v1.8.1/build/nv.d3.js#L4946 vs. github.com/novus/nvd3/blob/v1.7.1/build/nv.d3.js#L3745Close
Looking at the source for each model is really useful. Generally, if there's a clickable/interactable element in the chart, the source will show the way to get access to that event with a function, even if there isn't specifically a callback in the documentation. In my case, I was trying to change the textContent of another DOM node according to what data streams were selected.Esthete
I've only tried with line chart's lines, but it seems like e contains all data for the entire chart, instead of only the one series of line that I click on, which loses the entire point of this click event; I want to know which line I've clicked on. After some more testing I've figured out that this is probably a bug on nvd3's side, which, whenever useInteractiveGuideline is also turned on for the graph, we are unable to retrieve which specific line is clicked.Cilo
B
31

I was running into the same issue and was about to dump NVD3 all together because of the lack of documentation... What you need to do is add a callback function to addGraph(). Also note the d3.selectAll() instead of d3.select().

Good Luck.

nv.addGraph(function() {
     var chart = nv.models.multiBarHorizontalChart()
         .x(function(d) { return d.label })
         .y(function(d) { return d.value })
         .margin({top: 5, right: 5, bottom: 5, left: 5})
         .showValues(false)
         .tooltips(true)
         .showControls(false);

     chart.yAxis
         .tickFormat(d3.format('d'));

     d3.select('#social-graph svg')
         .datum([data])
       .transition().duration(500)
         .call(chart);

       nv.utils.windowResize(chart.update);

       return chart;
     },function(){
          d3.selectAll(".nv-bar").on('click',
               function(){
                     console.log("test");
           });
      });
Bradwell answered 17/7, 2013 at 22:26 Comment(4)
unfortunately i had no luck applying this approach to a nv3d line chart. my goal was to get the data of the clicked line point (x,y), but d3.selectAll("nv-point-paths")on('click') gave me the data of the whole chart instead of the individual point. I hoped to fix this with d3.selectAll("nv-point-paths path").on('click'), but this handler never triggered. Any idea?Naquin
Actually if you take a look at the examles, you will see that the best way to handle events is what wexman suggested.Robbirobbia
on stacked bar chart , once you change legends , the click events disappear. Its not the case with Wexman's answer though.Hepburn
On the function add the param e, and then console.log(e), you'll find data for the selected bar.Dressler
N
4

There are three key points here.

1) No documentation means you have to go through the source code.

2) All graphs have a tooltip, which means events are already firing in the source code.

3) Use the configuration object (in the Documentation) as a road map of the source code.

ie.

var config = {chart: {type: 'multiChart',xAxis:{},yAxis{}}

Open the nvd3/nv.d3.js file

CTRL+F+ the chart type. In this case it is 'multiChart'.

You will see nv.models.multiChart.

Scroll down to find the tooltip events and you will find the needed documentation.

lines1.dispatch.on('elementMouseout.tooltip', function(evt) {tooltip.hidden(true) });
stack1.dispatch.on('elementMouseout.tooltip', function(evt) {tooltip.hidden(true) });
bars1.dispatch.on('elementMouseout.tooltip', function(evt) {tooltip.hidden(true) });

Therefore, to write your own event...

var config = {chart: {type: 'multiChart',
               bars1: {
                dispatch:{
                    elementClick:function(e){//do Stuff}
                },
               xAxis:{},yAxis{}
              }
Nascent answered 27/4, 2016 at 20:10 Comment(0)
W
2

This worked for me: (e.target.data outputs the data attributes attached to that element, like x, y)

$(document).on("click", "#chart svg", function(e) {
     console.log (e);
     console.log (e.target.__data__);
    });
Windup answered 28/11, 2013 at 22:58 Comment(0)
O
2

If using AngularJS, use this code in your app.js.

$scope.$on('elementClick.directive', function(angularEvent, event){
    console.log(event);
});
Ostiary answered 18/9, 2015 at 6:57 Comment(0)
M
2

This coderwall blog heads us the right direction.

chr.scatter.dispatch.on('elementClick', function(event) { console.log(event); });

Massey answered 1/4, 2016 at 5:18 Comment(0)
I
2

This worked for me. https://bridge360blog.com/2016/03/07/adding-and-handling-click-events-for-nvd3-graph-elements-in-angular-applications/

Just use console.log(e) instead of console.log(e.data) to avoid undefined error.

Intestine answered 18/4, 2016 at 13:9 Comment(0)
T
0

jQuery makes this easy:

$( ".nv-bar" ).click(function() {
  console.log("test");
});

Fiddle @ http://jsfiddle.net/eTT5y/1/

Tyrant answered 14/1, 2014 at 0:19 Comment(0)
A
0
$('.nv-pie .nv-pie .nv-slice').click(function(){
   temp = $(this).text();
   alert(temp);
})

This would work fine for the Pie Chart ,Similarly u can go ahead for other charts too....

Ainsley answered 21/2, 2014 at 8:41 Comment(0)
I
0

For stacked area chart, you should disable interactiveGuideline and use elementClick.area:

chart.useInteractiveGuideline(false);

chart.stacked.scatter.dispatch.on("elementClick.area", function(e) {
  console.log(e);
});
Isodynamic answered 21/12, 2015 at 13:42 Comment(0)
F
0

Just add callback to you options in controller If using BarChart then replace multibar to discretebar

$scope.options = {
chart: {
    type: 'multiBarHorizontalChart',
    height: 450,
    x: function(d){return d.label;},
    y: function(d){return d.value;},
    showControls: true,
    showValues: true,
    duration: 500,
    xAxis: {
        showMaxMin: false
    },
    yAxis: {
        axisLabel: 'Values',
        tickFormat: function(d) {
            return d3.format(',.2f')(d);
        }
    },
    callback: function(chart) {
        chart.multibar.dispatch.on('elementClick', function(e){
            console.log('elementClick in callback', e.data);                             
        });
    }
}
};
Floweret answered 25/10, 2019 at 4:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.