web-dev-qa-db-ja.com

リアルタイムデータを含むNVD3折れ線グラフ

NVD3.jsを使用して作成された非常に単純な折れ線グラフがあります。タイマーに基づいて、これまでに見た例から抜粋した簡単な再描画を作成しましたが、エラーが発生します

Uncaught TypeError:未定義のプロパティ 'y'を読み取れません

JSは

    var data = [{
        "key": "Long",
        "values": getData()
    }];
    var chart;

    nv.addGraph(function () {
          chart = nv.models.cumulativeLineChart()
                      .x(function (d) { return d[0] })
                      .y(function (d) { return d[1] / 100 })
                      .color(d3.scale.category10().range());

        chart.xAxis
            .tickFormat(function (d) {
                return d3.time.format('%x')(new Date(d))
            });

        chart.yAxis
            .tickFormat(d3.format(',.1%'));

        d3.select('#chart svg')
            .datum(data)
            .transition().duration(500)
            .call(chart);

        nv.utils.windowResize(chart.update);

        return chart;
    });


    function redraw() {
        d3.select('#chart svg')
            .datum(data)
          .transition().duration(500)
            .call(chart);
    }

    function getData() {
        var arr = [];
        var theDate = new Date(2012, 01, 01, 0, 0, 0, 0);
        for (var x = 0; x < 30; x++) {
            arr.Push([theDate.getTime(), Math.random() * 10]);
            theDate.setDate(theDate.getDate() + 1);
        }
        return arr;
    }

    setInterval(function () {
        var long = data[0].values;
        var next = new Date(long[long.length - 1][0]);
        next.setMonth(next.getMonth() + 1)
        long.shift();
        long.Push([next.getTime(), Math.random() * 100]);
        redraw();
    }, 1500);
10
Jaimal Chohan

2番目の回答(コメント後)

cumulativeLineChartのソース を見ました。チャートの作成中にdisplay.yプロパティが作成されるのを確認できます。これは、プライベートメソッド「indexify」に依存しています。そのメソッドの派生物が公開された場合は、再描画する前にchart.reindexify()のようなことを行うことができます。

一時的な回避策として、更新のたびにグラフを最初から再作成できます。トランジションを削除すると、問題なく機能するようです。 jsfiddleの例: http://jsfiddle.net/kaliatech/PGyKF/

最初の回答

累積ラインチャートにバグがあると思います。累積LineChartは、シリーズのデータ​​値に「display.y」プロパティを動的に追加するようです。ただし、再描画のために新しい値がシリーズに追加された場合、このプロパティは再生成されません。私はNVD3に不慣れですが、とにかくこれを行う方法がわかりません。

本当にCumulativeLineChartが必要ですか、それとも通常の折れ線グラフで十分ですか?もしそうなら、私はあなたのコードに次の変更を加える必要がありました:

  • cumulativeLineChartからlineChartに変更します
  • データの2次元配列の使用から、データのオブジェクト(x、yプロパティを持つ)の使用に変更します。
    • (私はNVD3に精通していないため、どのデータ形式が期待されるかを説明できません。2D配列は明らかに初期ロードでは機能しますが、その後の再描画では機能しないと思います。これは、cumulativeLineChartで発生しているのと同じ問題に関連している可能性があります。 。オブジェクトに変更すると、cumulativeLineChartも修正されると思いましたが、そうではなかったようです。)

それほど重要ではありませんが、以下も変更しました。

  • GetData関数をDateの新しいインスタンスを作成するように変更して、日付が増加するときに参照を共有するという予期しない結果を回避しました。

  • GetData関数と同じ範囲のy値で、日単位(月単位ではない)で新しいデータを生成するように更新間隔関数を変更しました。

これらの変更を加えた動作中のjsfiddleは次のとおりです。

11
kaliatech

私が思うものがより良い解決策であることがわかりました。この問題は、累積チャートが処理中にy関数を設定するために発生します。チャートを更新するときはいつでも、最初に正しい元のyを返すデフォルトに戻します。再描画関数で、更新する前にこれを実行します。

chart.y(function (d) { return d.y; });

累積チャートがそれ自体でこれを実行できる場合はさらに良いでしょう(新しいアクセス関数を設定する前に元のアクセス関数を保存し、インデックスを再作成する前に元に戻します)。機会があれば、修正をプッシュしようとします。

1
Rupert Curwen

私は同じ問題に遭遇しました。次の行のy()関数を変更しました

.y(function(d) { return d.display.y })

.y(function(d) { return d.display ? d.display.y : d.y })

これにより、エラーが解消されます。明らかに、エラーの場合は(存在しない)インデックス値は表示されませんが、私の経験では、グラフは表示が定義された状態で再度更新され、正しく表示されます。

0
Backslider