2016-07-13 11 views
2

こんにちは私の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; 
     }; 

+0

こんにちは@WebFixItMan、forループを実行した後、データオブジェクト "dataSet"を共有できますか トップ。両方のエラーの主な理由は、 'formattedDateTime'関数の出力から来ていると思います。 – Alex

+0

D3のどのバージョン? –

+0

こんにちはアレックスとジェラルド! 私はシリルの返信がアレックスの質問に答えると信じています。 Gerardoの場合、私はCDNリンクを使用しています: \t '' – WebFixItMan

答えて

3

問題はあなたが渡している日付は、この形式になっている:

は、 '2016年7月12日15時58分40秒'

var parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse; 

それが必要:あなたが作ったはparsedata機能(日付にはハイフンがありません注意してください)それは解析します

var parseDate = d3.time.format("%Y/%m/%d %H:%M:%S").parse; 

次のバグは、あなたが範囲を取得するためのデータを渡すが、そのどこにも定義されていない、ですされています:

x.domain(d3.extent(data, function(d) { return d.theTime; })); 
y.domain(d3.extent(data, function(d) { return d.theValue;})); 

それがされている必要があります。

x.domain(d3.extent(dataset, function(d) { 
    return d.theTime; 
})); 
y.domain(d3.extent(dataset, function(d) { 
    return d.theValue; 
})); 

作業コードhere

+0

こんにちはキリル: あなたのアドバイス成功への道をほとんどなくしました。それは私にこれを解決する方向を与えてくれました。私は 'Uncaught TypeError:未定義の長さ 'プロパティを読み込めません。 JSFiddleであなたの例のように変数 'dataset'をハードコーディングすると、私のディスプレイも機能しました。しかし、私のバージョンでは、私は動的な 'dataset'変数を使用することに限定されています。私は 'dataset.forEach '関数の前に' alert(typeof(dataset)) 'を実行し、それを' object'として報告しました。私はこれを克服する方法を研究するつもりですが、あなたが洞察を持っていれば、私はフィードバックを大いに感謝します。 – WebFixItMan

関連する問題