首页 > 解决方案 > D3 图导致“哦 Snap”

问题描述

我正在开发一个每秒更新的 d3 图表。

将选项卡在后台打开一段时间后,在浏览器上出现“Oh Snap”错误。

我已经将问题追踪到图表的轴上,该轴根据我收到的数据的当前限制(最小值和最大值)动态更新。

图表功能:

    function realtimeChart($chartContainer, width, height) {
          // data arrays
          this.dataMin = [];
          this.dataMax = [];

          // chart dimensions
          this.width = width || 500;
          this.height = height || 500;

          //
          this.globalX = 0;
          this.duration = 100;
          this.max = 50;
          this.step = 1;

          //
          this.chart = d3.select($chartContainer.get(0))
            .attr('width', this.width)
            .attr('height', this.height + 25);

          var x = d3.scaleLinear()
            .domain([0, this.width])
            .range([40, this.width]),
            y = d3.scaleLinear()
            .domain([0, 10])
            .range([this.height - 20, 10]);

          this.line = d3.line()
            .x(function(d) {
              return x(d.x);
            })
            .y(function(d) {
              return y(d.y);
            });
          this.smoothLine = d3.line()
            .curve(d3.curveCardinal)
            .x(function(d) {
              return x(d.x);
            })
            .y(function(d) {
              return y(d.y);
            });
          this.lineArea = d3.area()
            .x(function(d) {
              return x(d.x);
            })
            .y0(y(0))
            .y1(function(d) {
              return y(d.y);
            })
            .curve(d3.curveCardinal);

          // Draw the axis
          this.xAxis = d3.axisBottom().scale(x);
          this.yAxis = d3.axisLeft().scale(y);

          this.axisX = this.chart.append('g')
            .attr('class', 'x axis')
            .attr('transform', 'translate(0, ' + (this.height - 20) + ')')
            .call(this.xAxis);

          this.axisY = this.chart.append('g')
            .attr('class', 'y axis')
            .attr('transform', 'translate(40, 0)')
            .call(this.yAxis);

          // Append the holder for line chart and fill area
          this.pathMin = this.chart.append('path');
          this.pathMax = this.chart.append('path');

          this.next = function(min, max) {
            // Generate new data
            var pointMin = {
                x: this.globalX,
                y: min || 0
              },
              pointMax = {
                x: this.globalX,
                y: max || cur
              };

            this.dataMin.push(pointMin);
            this.dataMax.push(pointMax);

            this.globalX += this.step;

            // Shift the chart left
            x.domain([this.globalX - (this.max - this.step) - 1, this.globalX - 1]);
            y.domain([min - 2, max + 2]);

            //THE PROBLEM IS SOLVED WHEN I COMMENT THE AXIS UPDATE
            this.axisX.transition()
              .duration(this.duration)
              .ease(d3.easeLinear, 2)
              .call(this.xAxis);
            this.axisY.transition()
              .duration(this.duration)
              .ease(d3.easeLinear, 2)
              .call(this.yAxis);

            // Draw new line
            this.pathMin.datum(this.dataMin)
              .attr('class', 'smoothline min')
              .attr('d', this.smoothLine);

            this.pathMax.datum(this.dataMax)
              .attr('class', 'smoothline max')
              .attr('d', this.smoothLine);

            // Remote old data (max 49 pointCurs)
            if (this.dataCur.length > 49) {
              this.dataMin.shift();
              this.dataMax.shift();
            }
          }
      }

我如何初始化图表:

    var $chartDiv;
    $chartDiv = $("<div>")
      .addClass("timerRow")
      .addClass("chartRow")
      .append(function() {
        var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
          return $(svg)
            .attr({
              "width": "500",
              "height": "500",
              "class": "chart"
            });
       });

    $chartDiv.data({
      "chart": new realtimeChart(
            $chartDiv.find("svg").first(),
            $("#dataDiv").innerWidth() - 40,
          150)
    })

收到新数据后如何更新图表:

  chart = $chartRow.data("chart")
  chart.next(timeData.min, timeData.max);

有谁知道如何在不移除轴的情况下解决这个问题?

标签: javascriptd3.js

解决方案


推荐阅读