【问题标题】:How to plot animated line chart using d3 while the data table is required to be updated every 1 second?如何使用 d3 绘制动画折线图,而数据表需要每 1 秒更新一次?
【发布时间】:2013-11-29 09:25:37
【问题描述】:

我想模拟有连续传入的实时(动态)数据并馈送到图表的情况

因此,我尝试用d3来演示一个动画折线图,同时要求数据数组每1秒持续更新一次。

原作灵感来自benjchristensen

这是我修改后的 html 源代码:my source code

我尝试通过调用函数startGenerator()random number for every 1 second 填充buffer[100]

    function startGenerator()
    {
        //signalGenerator();    
        setInterval("signalGenerator()", 1000); //
    }

    function signalGenerator()
    {
        var buffer = new Array(100);

        var i;
        for (i = 0; i < buffer.length; i++)
        {
            buffer[i] = Math.random() * 10;
        }

        FeedDataToChart("#graph1", 300, 300, "basis", true, 100, 100, buffer, 0);       
    }

下面是FeedDataToChart()参数名称:

function FeedDataToChart(id, width, height, interpolation, animate, updateDelay, transitionDelay, data, startIndex)

我使用counter检查重绘数据索引,每次重绘新数据时,counter增加1。在counter &lt; data.length-1 之前,re-draw timer 应该停止并再次从buffer[100] 获取新数据。

        function stopTimer()
        {
            clearInterval(myTimer);
            alert("The redraw timer stop here, get new data from buffer");
        }

        function startTimer()
        {
            if (myTimer == null)
            {
                myTimer = setInterval(function() {
                if (counter < data.length - 1)
                {
                    var v = data.shift(); // remove the first element of the array
                    data.push(v); // add a new element to the array (we're just taking the number we just shifted off the front and appending to the end)
                    if(animate) 
                    {
                        redrawWithAnimation();
                    } 
                    else 
                    {
                        redrawWithoutAnimation();
                    }
                    counter++;
                }
                else
                {
                    alert("no more data in buffer");
                    stopTimer();
                    counter = startIndex;
                }
            }, updateDelay);
            }
        }

我的问题出现,当我尝试重复 startGenerator() 函数时,结果显示如下:

我对 javascript 很陌生。谁能指出我如何从buffer1 second 中提取数据并不断更新单线图表?

谢谢!

EDIT我更新了源,问题已经最小化:My New Source

我在stopTimer() 处添加.remove() 行以删除sgv 持有的数据并重置global buffer to null 并再次调用startGenerator() 函数以在计时器停止时提取新数据。

现在我遇到的唯一问题是,每次创建新图时,它都会在前一个图的下方创建一个新的 sgv 路径。每次创建新图表时,它都会向下移动。检查我今天更新的新来源。运行代码后,您将看到我的描述。

如何在每次更新时将 sgv 路径固定在同一位置?

【问题讨论】:

  • 对我来说很好——jsfiddle.net/7RfVG
  • 你试图取消注释 setInterval("signalGenerator()", 1000);并再次运行代码。
  • 我明白你的意思,但我不清楚你想做什么。您只是想为同一行生成更多数据吗?
  • 是的,你是对的。我想为同一行生成更多数据并连续为其设置动画。
  • 你能用同样的函数生成更多的数据吗?是否需要多次调用该函数?

标签: javascript animation charts d3.js svg-animate


【解决方案1】:

再次调用FeedDataToChart 的问题在于,它会创建全新的svgpath 元素,而不是重复使用现有元素。您使用的内部重绘方法遵循标准的 D3 更新模式,因此请以此为例说明如何重做更新。

首先将初始化与绘图分开。没有理由在每次更新时都需要更改比例和线路生成器,因此请尽早解决。还要尽快创建 svg 元素,除非确实需要,否则不要更改它。路径元素也是如此。

任何 D3 可视化的一般结构都包含三个不同的阶段:

初始化 - 脚本加载后尽快执行

  • 创建比例和 svg 生成器函数(scaleaxislinearea 等)
  • 创建数据清理和聚合函数(nest、自定义过滤器等)

创建 - DOM 准备好后尽快执行

  • 创建 svg 元素(每个图表只调用一次 .append("svg")
  • 创建图表和轴组(参见margin conventions

draw - 在数据可用时执行

  • 通过输入/更新/删除选择的第一段
    • 查找现有数据元素(数据元素 CSS 类上的.selectAll()
    • 将数据重新绑定到图表
  • 执行enter 选择
    • 创建图表数据元素(仅在.enter() 之后调用.append(el)
    • 设置图表数据元素 CSS 类(使其成为规范句柄)
    • 设置静态属性(但如果你能把它们放在 CSS 中就更好了)
  • 执行enterupdate 选择
    • 设置动态属性(这里是对.attr("d", line)的调用)
  • 您可能还有一个删除部分(用于exit 选择)

有关更多信息,请查看 Mike Bostock 在selections in D3 上的教程。

一旦您习惯了,创建、更新、删除过程实际上非常简单。这是一个典型的例子:

// select existing data elements and rebind data
var dots = d3.selectAll(".dot")
    .data(data);

// append a circle for new dots
dots.enter().append("circle")
    .attr("class", "dot")
    .attr("r", 4);

// remove old dots
dots.exit().remove();

// update all new and existing dots
dots.attr("cx", x)
    .attr("cy", y);

编写简单而高性能的 D3 的关键是尽量减少对 DOM 所做的更改,因为 DOM 操作往往是主要的性能瓶颈。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-18
    • 2015-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多