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);
2番目の回答(コメント後)
cumulativeLineChartのソース を見ました。チャートの作成中にdisplay.yプロパティが作成されるのを確認できます。これは、プライベートメソッド「indexify」に依存しています。そのメソッドの派生物が公開された場合は、再描画する前にchart.reindexify()
のようなことを行うことができます。
一時的な回避策として、更新のたびにグラフを最初から再作成できます。トランジションを削除すると、問題なく機能するようです。 jsfiddleの例: http://jsfiddle.net/kaliatech/PGyKF/ 。
最初の回答
累積ラインチャートにバグがあると思います。累積LineChartは、シリーズのデータ値に「display.y」プロパティを動的に追加するようです。ただし、再描画のために新しい値がシリーズに追加された場合、このプロパティは再生成されません。私はNVD3に不慣れですが、とにかくこれを行う方法がわかりません。
本当にCumulativeLineChartが必要ですか、それとも通常の折れ線グラフで十分ですか?もしそうなら、私はあなたのコードに次の変更を加える必要がありました:
それほど重要ではありませんが、以下も変更しました。
GetData関数をDateの新しいインスタンスを作成するように変更して、日付が増加するときに参照を共有するという予期しない結果を回避しました。
GetData関数と同じ範囲のy値で、日単位(月単位ではない)で新しいデータを生成するように更新間隔関数を変更しました。
これらの変更を加えた動作中のjsfiddleは次のとおりです。
私が思うものがより良い解決策であることがわかりました。この問題は、累積チャートが処理中にy関数を設定するために発生します。チャートを更新するときはいつでも、最初に正しい元のyを返すデフォルトに戻します。再描画関数で、更新する前にこれを実行します。
chart.y(function (d) { return d.y; });
累積チャートがそれ自体でこれを実行できる場合はさらに良いでしょう(新しいアクセス関数を設定する前に元のアクセス関数を保存し、インデックスを再作成する前に元に戻します)。機会があれば、修正をプッシュしようとします。
私は同じ問題に遭遇しました。次の行のy()関数を変更しました
.y(function(d) { return d.display.y })
に
.y(function(d) { return d.display ? d.display.y : d.y })
これにより、エラーが解消されます。明らかに、エラーの場合は(存在しない)インデックス値は表示されませんが、私の経験では、グラフは表示が定義された状態で再度更新され、正しく表示されます。