【问题标题】:ngClick causes D3 chart to redrawngClick 导致 D3 图表重绘
【发布时间】:2015-11-14 16:55:10
【问题描述】:

每当我单击其中一个点时,都会导致图表更新。只有当我在 <nvd3> 元素上有一个 ngClick 指令时才会发生这种情况(即使侦听器函数什么都不做)。如果我删除ngClick,一切都很好。

我正在使用一个非常基本的nvd3 散点图和angular-nvd3

是什么导致了这种奇怪的互动?

(这段录像的帧率很低,所以很难看,但是每次点击都会重新绘制图表,包括最上面的那个)

这是一个重现问题的 plunker:

http://plnkr.co/edit/F0ZslBaisoHWIp0VcI8o

谢谢!

更新我已将其范围缩小到 angular-nvd3 中的手表。 ngClick 的存在以某种方式导致“数据”发生变化。 此行正在触发刷新:https://github.com/krispo/angular-nvd3/blob/master/dist/angular-nvd3.js#L328 我的代码中没有任何内容可以更改“数据”(还验证了该对象是指令之外的同一个实例),并且我在 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>

【问题讨论】:

  • 你在 ng-click 上叫什么?
  • 您的数据构建是否与 plunkr 中的完全相同?如果问题在示例中没有重现,那么您的代码中肯定有一些不同的地方。你能发布你的实际代码吗?
  • @StaceyBurns,我更新了我的问题和 plunker,请看一下。现在它重现了这个问题,并且它还有一些我在生产代码中使用的数据。其他区别是:我在 plunker 中更新了 d3、nvd3 和 angular-nvd3 的版本(plunker 使用的是旧版本,我没有注意到),并且我还将它剥离到最低代码。
  • @Tera 用于空的点击处理程序。查看更新后的问题。
  • 这是有线的。我想解决方法是制作一个绝对定位的元素并使用 ng-click...

标签: angularjs d3.js nvd3.js angular-nvd3


【解决方案1】:

您是正确的,以下手表导致了该问题:

// 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}] 

每次点击一个新的点,都会给对象添加颜色属性,所以watch函数实际上是正确运行的。

我建议在https://github.com/krispo/angular-nvd3 上打开一个问题

**编辑 - 澄清一下,添加 ng-click 时发生这种情况的原因是因为这会强制 Angular 摘要循环运行,从而触发监视。

【讨论】:

  • 好的,谢谢。看起来我忽略了关于scope._config.deepWatchData 的部分。将其设置为 false 可以解决问题……尽管这样做仍然感觉不太理想。
  • 是的,这似乎不是最理想的,只有在您的数据没有改变的情况下才有效。例如,如果您将 DeepWatch 设置为 false 并将其添加到您的 ng-click : $scope.data[0].values[0].y = 300 ,它不会更新图表。 (它设置为 true 时更新图表)。
【解决方案2】:

看起来(目前)唯一的解决方法是使用配置设置deepWatchData: false。这可以防止 $watch 被过于频繁地触发。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-20
    • 1970-01-01
    • 2016-06-17
    • 1970-01-01
    • 1970-01-01
    • 2012-04-06
    • 1970-01-01
    相关资源
    最近更新 更多