10

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

キャッチされていない 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);
4

3 に答える 3

11

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

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

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

最初の答え

累積線グラフにバグがあると思います。CumulativeLineChart は、一連のデータ値に「display.y」プロパティを動的に追加するようです。ただし、再描画のためにシリーズに新しい値が追加された場合、このプロパティは再生成されません。私はNVD3を初めて使用しますが、とにかくこれを行う方法を知りません。

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

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

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

  • getData 関数を変更してDate の新しいインスタンスを作成し、日付がインクリメントされるときに参照を共有することによる予期しない結果を回避しました。

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

これらの変更を加えた動作中の jsfiddle を次に示します。

于 2012-10-02T15:12:19.643 に答える
1

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

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

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

于 2013-11-18T12:51:10.267 に答える