2
votes

I'm trying to prevent the default behavior when I click on the angular-nvD3 Stacked Area Chart. I managed to access the onclick function, but I don't know how to prevent the event (modifies the graphic) from happening. I don't want the graphic to change when the user clicks on it.

.js:

$scope.stackedAreaChartOptions = {
  chart: {
    type: 'stackedAreaChart',
    height: 450,
    margin : {
      top: 20,
      right: 20,
      bottom: 30,
      left: 40
    },
    x: function(d){return d[0];},
    y: function(d){return d[1];},
    useVoronoi: false,
    clipEdge: true,
    duration: 100,
    useInteractiveGuideline: true,
    xAxis: {
      showMaxMin: false,
      tickFormat: function(d) {
        return d3.time.format('%H:%M')(new Date(d))
      }
    },
    yAxis: {
      tickFormat: function(d){
        return d3.format(',.2f')(d);
      }
    },
    zoom: {
      enabled: false,
      scaleExtent: [1, 10],
      useFixedDomain: false,
      useNiceScale: false,
      horizontalOff: false,
      verticalOff: true,
      unzoomEventType: 'dblclick.zoom'
    },
    //chart events
    stacked: {
      dispatch: {

        areaClick:
        function (t,u){ null; console.log("areaClick");}
        ,
        areaMouseover:
        function (t,u){ null; console.log("areaMouseover");}
        ,
        areaMouseout:
        function (t,u){null; console.log("areaMouseout");}
        ,
        renderEnd:
        function (t,u){null; console.log("renderEnd");}
        ,
        elementClick:
        function (t,u){null; console.log("elementClick");}
        ,
        elementMouseover:
        function (t,u){null; console.log("elementMouseover");}
        ,
        elementMouseout:
        function (t,u){ null;console.log("elementMouseout");}
      }
    },
    controlLabels: {stacked:"Absoluto", expanded:"Relativo"},
    controlOptions:
    [
      "Stacked",
      false,
      "Expanded"
    ]

  },
  title: {
    enable: true,
    text: '',
    css: {
      'font-weight': 'bold'
    }
  },
  caption: {
    enable: true,
    html: 'Visualización por horas de acceso a noticia',
    css: {
      'text-align': 'center',
      'margin': '2px 13px 0px 7px',
      'font-style': 'italic'
    }
  }
};

HTML:

<nvd3 options="stackedAreaChartOptions" data="stackedAreaChartData" api="api"></nvd3>

When I click on the graphic, the messages (console.log) are being shown, but I need to prevent the click event from happening.

2
CSS pointer-events:none;zer00ne

2 Answers

4
votes

I know this is an old question, but I run into this problem for my project and here is how I solved it.

It seems it's not possible to disabled these events using angular-nvd3. You must disable them using NVD3.

Get the chart api object available on your angular-nvd3 chart and disable the events on the chart object binded to this api:

HTML

<nvd3 options="options" data="data" api="chartAPI"></nvd3>

Javascript

 $timeout( function() {
  if ($scope.chartAPI) {
    var chart = $scope.chartAPI.getScope().chart;
    chart.stacked.dispatch.on('areaClick.toggle', null);
    chart.stacked.dispatch.on('areaClick', null);
  }
}, 1000);

I made a timeout be sure to have the chartAPI when doing the changes.

Note : It seems you have to disable these events again when you update or refresh the chart (chart.refresh()).

Working example here: https://codepen.io/mvidailhet/pen/JNYJwx It seems there is a glitch in the chart update on Codepen, but you get the point :)

Hope it helps!

0
votes

You were close. CSS pointer-events:none; has the disadvantage that it turns off every pointer event (most importantly hover, mouseenter and mouseout).

So IMHO you should avoid to use it.

Actually you were close. You should not pass an it-does-nothing function but null or undefined instead to options.chart.stacked.dispatch.areaClick. Like this:

//chart events
stacked: {
    dispatch: {
        areaClick: void 0
    }
}

I had this very same problem and spent more than an hour to find it out.

EDIT

Turned out that I was wrong. It solved just because it ran into an error that prevented the event. So you can throw an error and everything is fine... :)

Also found a workaround but that causes memory leak, so I'll not share that.

My solution was: accept that it applies click event and hides all other layers. Too small issue to invest more time and effort in it.