首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与角nvd3 3一起使用的nvd3是slooooowwwww

与角nvd3 3一起使用的nvd3是slooooowwwww
EN

Stack Overflow用户
提问于 2015-09-25 15:02:31
回答 2查看 1.7K关注 0票数 2

我相信我有一个问题,可能很容易通过我错过的东西来解决,但我似乎看不出实际的问题是什么。我有一个应用程序,它每秒钟返回5000点(1000x,y点的5个数组元素),我想使用NVD3在客户端更新。这是一个AngularJS应用程序,所以我使用krispos angular-nvd3指令。然而,它使整个应用程序陷入困境,而且根据Chrome开发工具捕捉到的时间线,该应用程序似乎在等待d3_timer_step返回5-6秒。

我认为这个问题是由于我们如何更新数据,但整个问题似乎与实际的d3部分有关。客户端的代码是

代码语言:javascript
复制
<nvd3 options="optionsRingdown" data="ringdownAvg" config="{refreshDataOnly:true}"></nvd3>

在控制器中,选项定义如下

代码语言:javascript
复制
$scope.options = {
    chart: {
      type: 'lineChart',
      height: 300,
      margin: {
        top: 20,
        right: 40,
        bottom: 60,
        left: 75
      },
      x: function(d) {
        return d.x;
      },
      y: function(d) {
        return d.y;
      },
      useInteractiveGuideline: false,
      yAxis: {
        tickFormat: function(d) {
          return d3.format('0.01f')(d);
        },
        axisLabel: 'Testing'
      },
      xAxis: {
        tickFormat: function(d) {
          return d3.time.format('%X')(new Date(d));
        },
        rotateLabels: -45
      },
      transitionDuration: 0,
      showXAxis: true,
      showYAxis: true
    }
  };

数据在下面的模板中定义

代码语言:javascript
复制
var ringdownT = [{
   values: [],
   key: 'Cell 0'
 }, {
   values: [],
   key: 'Cell 1'
 }, {
   values: [],
   key: 'Cell 2'
 }, {
   values: [],
   key: 'Cell 3'
 }, {
   values: [],
   key: 'Cell 4'
 }];

通过从服务广播的函数调用,使用以下方法更新数据

代码语言:javascript
复制
function updateCRD(d){
   var dataOut = {
     "tauData": [],
     "rdFit": ringdownT,
     "rdAvg":ringdownT
   }
   for (k = 0; k < d.cell.length; k++) {
     dataOut.rdAvg[k].values = d.cell[k].avg_rd;
     dataOut.rdFit[k].values = d.cell[k].fit_rd;
   }

   return dataOut;
}

该函数在广播中使用以下方式调用(每隔1秒广播一次)

代码语言:javascript
复制
$scope.$on('dataAvailable', function() {

    $scope.data = Data.crd;

    var data = updateCRD(Data.crd);

    $scope.tauData = data.tauData;
    $scope.ringdownAvg = data.rdAvg;
    $scope.ringdownFit = data.rdFit;
});

有没有人在这里看到明显不对劲的东西,或者我应该采取不同的做法?我错过了什么选择吗?任何帮助都会很好。

干杯,马特

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-09-25 22:45:05

尝试在配置中添加deepWatchData: false标志(这意味着该指令不会监视更新的数据)并通过api更新图表

代码语言:javascript
复制
<nvd3 options="optionsRingdown" data="ringdownAvg" api="apiRingdown" config="{refreshDataOnly:true, deepWatchData: false}"></nvd3>

该指令监视选项和复杂数据对象,以便使用$watch(watchExpression, listener, [objectEquality])方法进行任何更新。在我们的示例中,deepWatchDataobjectEquality标志,同时监视图表数据以进行更新。

根据角文档,根据angular.equals函数确定watchExpression的不等式。为了保存对象的值以便以后进行比较,使用了angular.copy函数。因此,这意味着观察复杂的对象会对内存和性能产生不利影响。

仅在版本(1.0.2,1.0.3)中,默认情况下此标志为false

然后,要更新图表,我们可以在控制器中使用apiRingdown.update方法:

代码语言:javascript
复制
$scope.$on('dataAvailable', function() {

    $scope.data = Data.crd;

    var data = updateCRD(Data.crd);

    $scope.tauData = data.tauData;
    $scope.ringdownAvg = data.rdAvg;
    $scope.ringdownFit = data.rdFit;

    //this line updates the chart
    $scope.apiRingdown.update();
});

已更新

在最新版本的1.0.4+中添加了一些更新。现在,标记deepWatchData意味着使用或不使用数据监视(它不像以前那样是objectEquality )。默认情况下,deepWatchDatatrue。但是现在我们可以使用一个新的标志$watch来管理deepWatchDataDepth: 2深度,从而调节性能。使用此标志,我们可以为数据指定一个更改检测策略(范围$watch深度):

代码语言:javascript
复制
0 - By Reference (the least powerful, but the most efficient)
1 - By Collection Items
2 - By Value (the most powerful, but also the most expensive; default value)

此外,默认情况下,标志refreshDataOnlytrue

因此,更新后的标记元素可能如下所示:

代码语言:javascript
复制
<nvd3 options="optionsRingdown" data="ringdownAvg" api="apiRingdown" config="{deepWatchDataDepth: 0}"></nvd3>

演示

票数 7
EN

Stack Overflow用户

发布于 2015-09-25 15:34:42

你在用SVG吗?nvd3.lineChartSVG,所以可能是的。如果是这样的话,@mbostock为您提供了答案:http://bl.ocks.org/mbostock/1276463。使用canvas而不是SVG来获得更快的速度。

大多数关于https://www.safaribooksonline.com/blog/2014/02/20/speeding-d3-js-checklist/的建议都是非常可靠的。

你每秒钟要重画5000点吗?如果是这样的话,这是webGL的工作,而不是nvd3。canvas可能足够快,如果画布不够快,那么我将坚持以前的答案。

花在d3_timer_step上的时间是多少?这是没有道理的,该功能将是缓慢的,它可能只是被称为很多次。实际上,d3_timer_frame是由d3_timer_step调用的,这可能是实际的呈现代码,肯定会占用您所有的时间。试着做canvas

可能的nvd3性能改进:

  1. 如果您还没有禁用useInteractiveGuideline,那么一定要禁用它。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32785163

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档