5

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

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

原作的灵感来自benjchristensen

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

我尝试通过调用函数来buffer[100]填充random 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)

我用 acounter检查重绘数据索引,每次重绘新数据时,counter增加1. 直到counter < data.length-1re-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 保存的数据并重置global buffer to null并再次调用该startGenerator()函数以在计时器停止时提取新数据。

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

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

4

1 回答 1

5

简单地再次调用的问题FeedDataToChart在于它创建了全新的svg元素,path而不是重用现有的元素。您使用的内部重绘方法遵循标准的 D3 更新模式,因此以它为例来了解如何重做更新。

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

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

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

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

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

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

绘制- 数据可用时执行

  • 通过输入/更新/删除选择的第一段
    • 查找现有数据元素(.selectAll()在数据元素 CSS 类上)
    • 将数据重新绑定到图表
  • 执行enter选择
    • 创建图表数据元素(仅调用.append(el)after .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 操作往往是主要的性能瓶颈。

于 2013-12-03T00:01:35.930 回答