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

 swa乄ycat曼颜 发布于 2023-02-13 19:53

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

因此,我尝试使用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);       
    }

以下是FeedDataToChart()参数名称:

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

我用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);
            }
        }

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

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

谢谢!

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

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

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

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

1 个回答
  • 与简单地调用的问题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);
    

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

    2023-02-13 19:55 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有