ngClick 导致 D3 图表重绘
ngClick causes D3 chart to redraw
每当我单击其中一个点时,它都会导致图表更新。只有当我在 <nvd3>
元素上有一个 ngClick
指令时才会发生这种情况(即使侦听器函数什么也不做)。如果我删除 ngClick
,一切都很好。
我正在使用一个非常基本的 nvd3
散点图 angular-nvd3
。
是什么导致了这种奇怪的交互?
(这段录音帧率低,所以很难看清,但是每次点击都会重新绘制图表,包括最上面的)
这是一个重现问题的 plunker:
http://plnkr.co/edit/F0ZslBaisoHWIp0VcI8o
谢谢!
UPDATE 我已经将范围缩小到 angular-nvd3 内的手表。 ngClick 的存在以某种方式导致 'data' 发生变化。
此行触发刷新:https://github.com/krispo/angular-nvd3/blob/master/dist/angular-nvd3.js#L328
我的代码中没有任何内容可以更改 'data'(还验证了对象是指令外的同一实例),并且我在 angular-nvd3.js 中看不到任何可以更改数据的内容所有...嗯...
更新
这是我的点击事件监听器(它是空的):
controller.handleChartClick = function(event) {
};
和html:
<div class="col-sm-10">
<nvd3 ng-click="observationsCharts.handleChartClick($event)"
options="observationsCharts.scatterPlotChartOptions"
data="observationsCharts.scatterPlotChartData"></nvd3>
</div>
您是正确的,以下手表导致了问题:
// 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);
问题是,如果你在这个函数中添加一个日志来查看旧数据和新数据是什么,数据实际上是在变化的。
当您点击其中一个点时,nvd3 正在为数据添加颜色属性。
旧数据:
[{"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}]}]
新数据:
[{"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}]
每次单击新点时,颜色属性都会添加到对象中,因此监视功能实际上 运行ning 是正确的。
我建议在 https://github.com/krispo/angular-nvd3
打开一个问题
**编辑 - 澄清一下,添加 ng-click 时发生的原因是因为这会强制 Angular 摘要周期到 运行,这将触发手表。
看起来(目前)唯一的解决方法是使用配置设置 deepWatchData: false
。这可以防止 $watch 过于频繁地被触发。
<nvd3 config="{deepWatchData: false}" options="..." data="..."/>
每当我单击其中一个点时,它都会导致图表更新。只有当我在 <nvd3>
元素上有一个 ngClick
指令时才会发生这种情况(即使侦听器函数什么也不做)。如果我删除 ngClick
,一切都很好。
我正在使用一个非常基本的 nvd3
散点图 angular-nvd3
。
是什么导致了这种奇怪的交互?
(这段录音帧率低,所以很难看清,但是每次点击都会重新绘制图表,包括最上面的)
这是一个重现问题的 plunker:
http://plnkr.co/edit/F0ZslBaisoHWIp0VcI8o
谢谢!
UPDATE 我已经将范围缩小到 angular-nvd3 内的手表。 ngClick 的存在以某种方式导致 'data' 发生变化。 此行触发刷新:https://github.com/krispo/angular-nvd3/blob/master/dist/angular-nvd3.js#L328 我的代码中没有任何内容可以更改 'data'(还验证了对象是指令外的同一实例),并且我在 angular-nvd3.js 中看不到任何可以更改数据的内容所有...嗯...
更新 这是我的点击事件监听器(它是空的):
controller.handleChartClick = function(event) {
};
和html:
<div class="col-sm-10">
<nvd3 ng-click="observationsCharts.handleChartClick($event)"
options="observationsCharts.scatterPlotChartOptions"
data="observationsCharts.scatterPlotChartData"></nvd3>
</div>
您是正确的,以下手表导致了问题:
// 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);
问题是,如果你在这个函数中添加一个日志来查看旧数据和新数据是什么,数据实际上是在变化的。
当您点击其中一个点时,nvd3 正在为数据添加颜色属性。
旧数据:
[{"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}]}]
新数据:
[{"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}]
每次单击新点时,颜色属性都会添加到对象中,因此监视功能实际上 运行ning 是正确的。
我建议在 https://github.com/krispo/angular-nvd3
打开一个问题**编辑 - 澄清一下,添加 ng-click 时发生的原因是因为这会强制 Angular 摘要周期到 运行,这将触发手表。
看起来(目前)唯一的解决方法是使用配置设置 deepWatchData: false
。这可以防止 $watch 过于频繁地被触发。
<nvd3 config="{deepWatchData: false}" options="..." data="..."/>