3

Humble Financeを使用して一連のデータを一度に 1 点ずつプロットし、タイムラプス効果を実現しています。私のコードは以下のとおりですが、最初に説明したいと思います。

HF に慣れていない方のために説明すると、その初期化関数は 3 つの JavaScript 配列 (priceData、volumeData、および summaryData) を受け取り、3 つのグラフにプロットします。これらの配列にはそれぞれ、XY ペアの複数の配列が含まれています。

私のプログラムでは、3 つの空の「グラフ」配列 (priceData、volumeData、および summaryData) を宣言し、データベースから値を取得して、それらを priceDataOrig、volumeDataOrig、および summaryDataOrig という配列の「マスター」JavaScript 配列に入れます。これらの配列を HF に渡して一度にすべてのデータをプロットするのではなく、40 ミリ秒ごとに自分自身を呼び出す関数 UpdateGraph() を呼び出します。UpdateGraph() は、一度に 1 つの値 (実際には、XY ペアを含む配列) をマスター配列から対応するグラフ配列にプッシュし、HF 初期化関数を呼び出して (グラフ配列を渡します)、3 つのグラフを描画します。グラフ配列に 50 個のポイントが追加されたら、新しいポイントをプッシュする前に最も古いポイントをシフト アウトして、グラフごとに一度にプロットされるポイントが 50 個を超えないようにします。

また、jQuery の load() を使用してグラフをロードしているため、ユーザーが [Go] ボタンをクリックすると、graph.php (上記のすべてを処理する) がページの div にロードされ、ポイントごとにグラフ化が開始されます。 . アイデアは、ユーザーがグラフをリロードして時間の経過をもう一度見たいときはいつでも [Go] をクリックできるようにすることです。

だから今私の問題に:私のテストプログラムでは、合計で約500の値をプロットしているので、これは決して大きなデータセットではありません. Go を初めてクリックすると、すべての値がうまくプロットされます。ただし、ブラウザーのメモリ使用量が急増し (Firefox と Chrome の両方で試しました)、ユーザーがもう一度 [Go] をクリックすると、プロットの途中でブラウザーが完全にクラッシュします。なぜこれが起こっているのか、私は完全に途方に暮れています.プロットが終了した後、すべての配列をnullにしようとしました.

誰にもアイデアはありますか?これが私のgraph.phpコードです。わかりやすくするためにわずかに変更されています。

<?php
    #Queries the DB and constructs the data strings assigned to JavaScript arrays below,
    #An example might be: $priceData = '[[0,100.34],[1,108.31],[2,109.40],[3,104.87]]';
?>

<script>
//Global variables used in UpdateGraph():

//The "master" arrays -- I'm just using the same data for all of
//them for now (an array containing around 500 arrays of XY pairs)
var priceDataOrig = <?php echo $priceData; ?>;
var volumeDataOrig = <?php echo $priceData; ?>;
var summaryDataOrig = <?php echo $priceData; ?>;

var priceData = [],
    volumeData = [],
    jsonData = [];
    i = 0,
    pointsToShowAtOnce = 50,
    totalPoints = priceDataOrig.length,
    updateRate = 40;    //milliseconds

UpdateGraph();

//Periodically updates the graph to show time lapse, adding one new point at a time
function UpdateGraph() {
    //Only add a new point if all the points haven't already been added
    if (i != totalPoints) {
        //Add a new point to each array
        priceData.push(priceDataOrig[i]);
        volumeData.push(volumeDataOrig[i]);
        summaryData.push(jsonDataOrig[i]);

        if (i >= pointsToShowAtOnce) {
            //We're showing the amount of points we want to show, so remove the oldest point
            priceData.shift();
            volumeData.shift();
            jsonData.shift();

            //Sets the new X values for these points -- not really pertinent to
            //my question, it works the same if this block is commented out.
            var pLen = priceData.length;
            var j, c = 0;
            for (j = 0; j < pLen; j++) {
                priceData[j][0] = c;
                volumeData[j][0] = c;
                c++;
            }
        }

        //Load the graph itself. 'humblefinance' is just a div on the page.
        HumbleFinance.init('humblefinance', priceData, volumeData, summaryData);

        i++;

        //This function calls itself at the interval in
        //updateRate until all the points have been drawn
        setTimeout('UpdateGraph()', updateRate);
    } else {
        //I null these out here even though it doesn't seem necessary.
        //It doesn't help though.
        priceDataOrig = null;
        volumeDataOrig = null;
        summaryData = null;
        jsonDataOrig = null;
        priceData = null;
        volumeData = null;
        jsonData = null;
    }
}
</script>

<div id="humblefinance"></div>
4

2 に答える 2

2

HumbleFinance に小さな変更を加えてみてください。init メソッドでは、次の関数が呼び出されます。

this.buildDOM();
this.attachEventObservers();

これらは、グラフを最初に更新するときにのみ実行する必要があるワンタイム構成関数のようです。多くの要素が作成され、イベントがバインドされているように見えますが、それらは解放されないため、何度も何度も実行され、毎回より多くのメモリを消費します。

最も簡単な方法は、パラメーターを追加して、init条件付きでこの部分を除外するか、別の方法として実際にグラフを描画するコードを分離することです。最後に、これらのセットアップ手順を一度だけ呼び出したいと思います。

于 2011-06-22T21:47:26.023 に答える
1

2つのアイデア。

1 - デバッガーによってメモリ リークが発生することがあります。これは、firebug / devtools がオフになっている場合に発生しますか?

2 - HumbleFinance.js のコードをざっと見てみると、そこにあるものを置き換えるのではなく、グラフがコンテナーに追加されているように見えます。init を呼び出す前に、次のようなものが役立つ場合があります。

$('#humbledata')[0].innerHTML = ''

または、jQuery は、これらのことを行うことを好みます。

于 2011-06-22T21:27:16.423 に答える