こんにちは私のStackOverflowの友人:D3.jsを使用した時系列データの解析
時間がありましたらお問い合わせください。私は数週間D3.jsを勉強していて、その10%を理解しているように感じ始めています(ha、ha、ha)。私は非常に単純な線グラフを生成しようとしています。データは非常にシンプルですが、私の生データソースにはUTCのタイムスタンプがあり、実数/小数は単純なものを超えてクラッシュしています。
生データソースは次のようになります。
機能をフォーマットするjQueryとJavaScriptの時間を使って{ "Links": {}, "Items": [ { "Timestamp": "2016-07-12T22:21:10Z", "Value": 1055.6793212890625, "UnitsAbbreviation": "m3/h", "Good": true, "Questionable": false, "Substituted": false }, { "Timestamp": "2016-07-12T22:39:10Z", "Value": 989.00830078125, "UnitsAbbreviation": "m3/h", "Good": true, "Questionable": false, "Substituted": false } ], "UnitsAbbreviation": "m3/h" }
私は、以下の単純化されたデータセットを組み立てることができる午前:ここ
var dataset = [ {'theTime': '2016/07/12 15:58:40', 'theValue': 1123.07275390625}, {'theTime': '2016/07/12 16:21:10', 'theValue': 1055.6793212890625}, {'theTime': '2016/07/12 16:45:40', 'theValue': 962.4850463867188}, {'theTime': '2016/07/12 17:14:40', 'theValue': 831.2259521484375}, {'theTime': '2016/07/12 17:55:10', 'theValue': 625.3046875} ];
は私のコードです:
//~ Populate the 'dataset': var dataset = []; $.get(url, function(data){ var itemCount = data.Items.length; var commaCount = itemCount - 1; for(i=0; i < itemCount; i++){ if(i == commaCount){ dataset.push("{'theTime': '" + formattedDateTime(data.Items[i].Timestamp) + "', 'theValue': " + data.Items[i].Value + "}"); } else { dataset.push("{'theTime': '" + formattedDateTime(data.Items[i].Timestamp) + "', 'theValue': " + data.Items[i].Value + "},"); } } var margin = {top: 20, right: 20, bottom: 30, left: 50}; var width = 960 - margin.left - margin.right; var height = 500 - margin.top - margin.bottom; var parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse; var x = d3.time.scale() .range([0, width]); var y = d3.scale.linear() .range([height, 0]); var xAxis = d3.svg.axis() .scale(x) .orient("bottom"); var yAxis = d3.svg.axis() .scale(y) .orient("left"); var line = d3.svg.line() .x(function(d) { return x(d.theTime); }) .y(function(d) { return y(d.theValue); }); var svg = d3.select("#myChart").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); dataset.forEach(function(d) { d.theTime = parseDate(d.theTime); d.theValue = +d.theValue; }); x.domain(d3.extent(data, function(d) { return d.theTime; })); y.domain(d3.extent(data, function(d) { return d.theValue;})); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text("return time(ms)"); svg.append("path") .datum(dataset) .attr("class", "line") .attr("d", line); }); //~~~ Format The Date: function formattedDateTime(dateAndTime) { var d = new Date(dateAndTime); var numDate = d.getDate(); var numMonth = d.getMonth() + 1; var numYear = d.getFullYear(); var numHours = d.getHours(); var numMinutes = d.getMinutes(); var numSeconds = d.getSeconds(); numDate = (numDate < 10) ? "0" + numDate : numDate; numMonth = (numMonth < 10) ? "0" + numMonth : numMonth; numHours = (numHours < 10) ? "0" + numHours : numHours; numMinutes = (numMinutes < 10) ? "0" + numMinutes : numMinutes; numSeconds = (numSeconds < 10) ? "0" + numSeconds : numSeconds; return numYear + "/" + numMonth + "/" + numDate + " " + numHours + ":" + numMinutes + ":" + numSeconds; };
最初のエラーは 'dataset.forEach()'関数で発生します.wh ichは "Uncaught TypeError: Cannot read property 'length' of undefined
"です。そのデータを解析する私の努力は、コード内の 'svg.append( "path")'ポイント( "Error: <path> attribute d: Expected number, "MNaN,NaNLNaN,NaNL…
")で発生する別のエラーに起因します。
Uggghhhh! (:-C)。聴衆にD3.jsのメンターがいれば、私が間違ってやっていることとそれを修正する方法を特定するのを手伝ってください。 ¡ミュシャ・グラシアス!
// =============は01 ========================
Iを追加しましたそれは働いた! Yeee Haaaw!
下記の改訂版の作業コードを掲載します。しかし、この記事の後に続く誰のためにも、私が見つけたものを説明したかったのです。
リンク先のポスト(Alternatives for using forEeach() loop while converting data for D3.js)のマークは、dataset.push()を変更してすべての引用符を削除するように提案しました。これは文字列の代わりにオブジェクトを与えました。いくつかのトラブルシューティングの後、それは最終的に期待通りに表示されました(完全に心得!)、そしてMarkに感謝します。あなたの提案はトリックでした。
ここ改訂コードです:
//~ Populate the 'dataset': var dataset = []; $.get(url, function(data){ var itemCount = data.Items.length; var commaCount = itemCount - 1; for(i=0; i<itemCount; i++){ dataset.push({theTime: formattedDateTime(data.Items[i].Timestamp), theValue: data.Items[i].Value}); } var margin = {top: 20, right: 20, bottom: 30, left: 50}; var width = 960 - margin.left - margin.right; var height = 500 - margin.top - margin.bottom; var parseDate = d3.time.format("%Y/%m/%d %H:%M:%S").parse; var x = d3.time.scale() .range([0, width]); var y = d3.scale.linear() .range([height, 0]); var xAxis = d3.svg.axis() .scale(x) .orient("bottom"); var yAxis = d3.svg.axis() .scale(y) .orient("left"); var line = d3.svg.line() .x(function(d) { return x(d.theTime); }) .y(function(d) { return y(d.theValue); }); var svg = d3.select("#myChart").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); dataset.forEach(function(d) { d.theTime = parseDate(d.theTime); d.theValue = parseFloat(d.theValue); }); x.domain(d3.extent(dataset, function(d) { return d.theTime; })); y.domain(d3.extent(dataset, function(d) { return d.theValue;})); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text("M³/hr"); svg.append("path") .datum(dataset) .attr("class", "line") .attr("d", line); }); //~~~ Format The Date: function formattedDateTime(dateAndTime) { var d = new Date(dateAndTime); var numDate = d.getDate(); var numMonth = d.getMonth() + 1; var numYear = d.getFullYear(); var numHours = d.getHours(); var numMinutes = d.getMinutes(); var numSeconds = d.getSeconds(); numDate = (numDate < 10) ? "0" + numDate : numDate; numMonth = (numMonth < 10) ? "0" + numMonth : numMonth; numHours = (numHours < 10) ? "0" + numHours : numHours; numMinutes = (numMinutes < 10) ? "0" + numMinutes : numMinutes; numSeconds = (numSeconds < 10) ? "0" + numSeconds : numSeconds; return numYear + "/" + numMonth + "/" + numDate + " " + numHours + ":" + numMinutes + ":" + numSeconds; };
こんにちは@WebFixItMan、forループを実行した後、データオブジェクト "dataSet"を共有できますか トップ。両方のエラーの主な理由は、 'formattedDateTime'関数の出力から来ていると思います。 – Alex
D3のどのバージョン? –
こんにちはアレックスとジェラルド! 私はシリルの返信がアレックスの質問に答えると信じています。 Gerardoの場合、私はCDNリンクを使用しています: \t '' – WebFixItMan