NgClick forces a D3 chart to redraw

Whenever I click on one of the points, it causes the chart to update. This only happens if I have the ngClick directive for the <nvd3> element (even if the listener function does nothing). If I remove ngClick , everything will be fine.

I am using a pretty basic nvd3 scatter nvd3 with angular-nvd3 .

What could cause this strange interaction?

(The frame rate of this record is low, so it's hard to see, but the chart is redrawn on every click, including the top one)

Clicking points on a chart

Here is the plunker that reproduces the problem:

http://plnkr.co/edit/F0ZslBaisoHWIp0VcI8o

Thanks!

UPDATE I narrowed it down to hours in angular -nvd3. Somehow, the presence of ngClick causes the data to change. This line starts the update: https://github.com/krispo/angular-nvd3/blob/master/dist/angular-nvd3.js#L328 There is nothing in my code that changes the "data" (it also checks that the object is the same instance outside the directive), and I see nothing in angular -nvd3.js, which could even change the data ... hmmm ...

UPDATE Here is my click event listener (it is empty):

 controller.handleChartClick = function(event) { }; 

and html:

 <div class="col-sm-10"> <nvd3 ng-click="observationsCharts.handleChartClick($event)" options="observationsCharts.scatterPlotChartOptions" data="observationsCharts.scatterPlotChartData"></nvd3> </div> 
+5
source share
2 answers

You are correct that the following hours cause the problem:

 // Watching on data changing scope.$watch('data', function (newData, oldData) { if (newData !== oldData && scope.chart) { if (!scope._config.disabled && scope._config.autorefresh) { scope._config.refreshDataOnly && scope.chart.update ? scope.chart.update() : scope.api.refresh(); // if wanted to refresh data only, use chart.update method, otherwise use full refresh. } } }, scope._config.deepWatchData); 

The fact is that if you add a log of this function to find out what old and new data is, the data actually changes.

When you click on one of the dots, nvd3 adds a color attribute to the data.

old data:

 [{"key":"Battery Voltage","values":[{"x":1439419440000,"y":90,"series":0},{"x":1439419440000,"y":43,"series":0},{"x":1439419440000,"y":345,"series":0},{"x":1439167620000,"y":73,"series":0},{"x":1439167620000,"y":42,"series":0},{"x":1439167620000,"y":36,"series":0},{"x":1440010740000,"y":32,"series":0},{"x":1439419440000,"y":62,"series":0},{"x":1439167620000,"y":73,"series":0},{"x":1439167620000,"y":42,"series":0},{"x":1439167620000,"y":36,"series":0}]}] 

new data:

 [{"key":"Battery Voltage","values":[{"x":1439419440000,"y":90,"series":0,"color":"#1f77b4"},{"x":1439419440000,"y":43,"series":0,"color":"#1f77b4"},{"x":1439419440000,"y":345,"series":0},{"x":1439167620000,"y":73,"series":0},{"x":1439167620000,"y":42,"series":0},{"x":1439167620000,"y":36,"series":0},{"x":1440010740000,"y":32,"series":0},{"x":1439419440000,"y":62,"series":0,"color":"#1f77b4"},{"x":1439167620000,"y":73,"series":0},{"x":1439167620000,"y":42,"series":0},{"x":1439167620000,"y":36,"series":0}],"color":"#1f77b4","value":90}] 

Each time you click a new point, a color attribute is added to the object, so the clock function works correctly.

I would suggest opening a question at https://github.com/krispo/angular-nvd3

** Edit. Just to clarify, the reason this happens when ng-click is added is because it causes the Angular digest loop to start, which will start the clock.

+2
source

It seems like the only workaround for this (for now) is to use the deepWatchData: false configuration deepWatchData: false . This prevents the $ watch from being triggered too often.

 <nvd3 config="{deepWatchData: false}" options="..." data="..."/> 
+2
source

All Articles