如何使用d3绘制动画折线图,而数据表需要每1秒更新一次?

jhy*_*yap 5 javascript charts animation d3.js svg-animate

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

因此,我尝试使用d3演示动画折线图,而数据阵列需要每1秒连续更新一次.

最初的作品灵感来自benjchristensen

这是我修改过的html源码:我的源代码

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

    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);       
    }
Run Code Online (Sandbox Code Playgroud)

以下是FeedDataToChart()参数名称:

function FeedDataToChart(id, width, height, interpolation, animate, updateDelay, transitionDelay, data, startIndex)
Run Code Online (Sandbox Code Playgroud)

我用a counter来检查重绘数据索引,每次重新绘制新数据时,都会counter增加1.直到counter < 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);
            }
        }
Run Code Online (Sandbox Code Playgroud)

尝试重复该startGenerator()功能时出现问题,结果显示如下: 折线图

我是javascript的新手.任何人都可以指出如何从buffer每个数据中提取数据1 second并连续更新单线图表吗?

谢谢!

编辑我更新源和问题已被最小化:我的新来源

我在该处添加.remove()stopTimer()以删除sgv-holded数据并重置global buffer to nullstartGenerator()再次调用该函数以在计时器停止时提取新数据.

现在唯一的问题是,每次创建新图形时,它都会创建一个新的sgv路径,其位于前一个之下.每次创建时,新图形都会向下移动.检查我今天更新的新来源.运行代码后,您将捕获我的描述.

每次更新时,如何在同一位置修复sgv路径?

cou*_*and 5

与简单地调用的问题FeedDataToChart再次是,它创造全新svgpath元素,而不是重用现有的.您正在使用的内部重绘方法遵循标准的D3更新模式,因此请将其作为如何重新更新更新的示例.

首先将初始化与绘图分开.规模和线生成器没有理由需要在每次更新时进行更改,因此请尽早解决.还可以尽快创建svg元素,除非确实需要,否则不要更改它.与path元素一样.

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

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

  • 创建规模和SVG发生器函数(scale,axis,line,area等等)
  • 创建数据清理和聚合功能(nest,自定义过滤器等)

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

  • 创建svg元素(.append("svg")每个图表只调用一次)
  • 创建图表和轴组(请参阅边距约定)

draw - 在数据可用时执行

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

有关更多信息,请参阅Mike Bostock关于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);
Run Code Online (Sandbox Code Playgroud)

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