5

継続的に受信するリアルタイム (動的) データとチャートへのフィードがある状況をシミュレートしたい

したがって、データ配列を 1 秒ごとに継続的に更新する必要がある一方で、d3 を使用してアニメーション化された折れ線グラフのデモを試みます。

原作はベンクリステンセンにインスパイアされている

そして、これが私の変更されたhtmlソースです:私のソースコード

buffer[100]関数をrandom number for every 1 second呼び出してにデータを入力しようとしましたstartGenerator()

    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新しいデータを再描画するたびに、再描画データ インデックスを確認するためにcounteraを使用し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にかなり慣れていません。Every からデータを取得し、単一の折れ線グラフを継続的に更新する方法を特定できる人はbufferいますか?1 second

ありがとうございました!

編集ソースを更新すると、問題は最小限に抑えられました: My New Source

.remove()に行を追加してstopTimer()、sgv に保持されたデータを削除し、リセットしてglobal buffer to null、関数を再度呼び出して、startGenerator()タイマーが停止したときに新しいデータを取得します。

今私が抱えている唯一の問題は、新しいグラフが作成されるたびに、前のものの下に新しいsgvパスが作成されることです。新しいグラフは、作成されるたびに下に移動しています。今日更新した新しいソースを確認してください。コードを実行すると、私の説明が表示されます。

sgv パスを更新するたびに同じ場所に固定するにはどうすればよいですか?

4

1 に答える 1

5

単純に再度呼び出す場合の問題は、既存の要素を再利用するのではなく、FeedDataToChartまったく新しい要素svgと要素を作成することです。path使用している内側の再描画方法は、標準の D3 更新パターンに従っているため、更新を再処理する方法の例として取り上げてください。

初期化を描画から分離することから始めます。更新のたびにスケールとライン ジェネレーターを変更する必要があるわけではありません。また、できるだけ早く svg 要素を作成し、本当に必要でない限り変更しないでください。パス要素も同様です。

D3 ビジュアライゼーションの一般的な構造は、次の 3 つの異なるフェーズで構成されます。

初期化-スクリプトのロード後、できるだけ早く実行する

  • スケールおよび SVG ジェネレーター関数を作成する ( scaleaxislineなどarea)
  • データのクリーンアップと集計関数 ( nest、カスタム フィルターなど)を作成する

作成- DOM の準備ができたらできるだけ早く実行する

  • svg 要素を作成します (.append("svg")チャートごとに 1 回だけ呼び出します)
  • グラフと軸のグループを作成します (余白の規則を参照してください) 。

draw - データが利用可能な場合に実行

  • 選択の入力/更新/削除による最初のセグメント
    • 既存のデータ要素を見つける (.selectAll()データ要素の CSS クラスで)
    • データをチャートに再バインドする
  • enter選択 時に実行
    • チャート データ要素を作成します ( の.append(el)後にのみ呼び出します.enter())
    • チャート データ要素の CSS クラスを設定します (これを正規のハンドルにします)
    • 静的プロパティを設定します (ただし、これらを CSS に入れることができればなおさらです)
  • 実行enterupdate選択
    • 動的プロパティを設定します (これは への呼び出しです.attr("d", line))
  • 部分を削除することもできます (exit選択用) 。

詳細については、D3 での選択に関する Mike Bostock のチュートリアルをご覧ください。

作成、更新、削除のプロセスは、慣れると実際には非常に簡単です。プロトタイプの例を次に示します。

// 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 に答える