2017-03-03 10 views
0

私は6つのカテゴリの1つであるデータの束を持っており、各データには関連する時間があります。ヒストグラムを使ってこれらのデータを毎月のビンにビンする必要がありますが、これは簡単ですが、各カテゴリをスタックする必要もあります。積み重ねたヒストグラムの例を探していましたが、見つけ出すことができるのはd3 v3からのものだけです。スタッキングAPIでは明らかに違いがあります。今すぐ私はstack()を呼び出した後でそれにこだわっています。無意味なデータが戻ってきます。私は積み重なった棒グラフを生成することができません。d3 v4:スタックにヒストグラムデータを使用していますか?

   var data = this.data; 
       var margin = {top: 20, right: 20, bottom: 30, left: 50}, 
        width = this.width - margin.left - margin.right, 
        height = this.height - margin.top - margin.bottom; 


       data.forEach(function(d) { 
        d.date = d3.isoParse(d.createdDate); 
       }); 

       // set the ranges 
       var x = d3.scaleTime() 
        .domain(d3.extent(data, function(d) { return d.date; })) 
        .rangeRound([0, width]); 
       var y = d3.scaleLinear() 
        .range([height, 0]); 
       var colours = d3.scaleOrdinal(d3.schemeCategory10); 

       var svg = d3.select(this.$.chart); 
       var svg2 = svg.select("#canvas"); 

       var histogram = d3.histogram() 
        .value(function(d) { return d.date; }) 
        .domain(x.domain()) 
        .thresholds(x.ticks(d3.timeMonth)); 

       var dataGroupedByType = d3.nest() 
        .key(function(d) { 
         return d.type; 
        }) 
        .object(data, d3.map); 

       var histDataByType = []; 
       for (var key in dataGroupedByType) { 
        var histData = histogram(dataGroupedByType[key]); 
        histDataByType.push({type: key, values: histData}); 
       } 

       var stack = d3.stack() 
        .keys(["A","B","C","D","E","F"]) 
        .value(function(d, key) { 
         return d.values; 
        }); 

       var stackedHistData = stack(histDataByType); 

dataGroupedByType各データオブジェクトの配列を含む6つのキー付きオブジェクト(FスルーA)を持つオブジェクトです。次に、を作成して、それぞれがtypeというプロパティ(AからF)とvaluesの配列を持つ6個のオブジェクトの配列を作成します。これは常に同じ長さです(私のデータは91ヶ月間で91です)。その配列内にbinデータ(存在する場合)を持つ別の配列と、x0x1の値があります。この時点で、ビニングが完了しました。必要なのはすべてをスタックしてy0y1の値を取得することだけです。

私はstackと呼んでいますが、それは私にゴミを出してくれます。 stackedHistDataは6の配列で、各配列は0のプロパティ、0のプロパティ、 'NaN'に等しい1のプロパティ、および91の長さの配列、インデックス、およびキー(A〜F)を持つdataプロパティを持ちます。スタックコールによって生成されることになっているy0y1の値も表示されません。この種のヒストグラムデータをどのように使用するのですか?

答えて

0

最終的にこのことがわかります。私は基本的にデータ構造found hereをエミュレートしようとしました。

まず、データからキーを取得し、時を解析します。

var keys = []; 
data.forEach(function(d) { 
    d.date = d3.isoParse(d.relevantDate); 
    keys.push(d.type); 
}); 

keys = _.uniq(keys); 

ここでは、キーの配列を一意にするためにlodashライブラリを使用しています。次のステップは、あなたが通常のヒストグラムのために行うようにビンを作ることです。

var histogram = d3.histogram() 
    .value(function(d) { return d.date; }) 
    .domain(x.domain()) 
    .thresholds(x.ticks(d3.timeMonth)); 

var bins = histogram(data); 
y.domain([0, d3.max(bins, function(d) { return d.length; })]); 

ドメインがあまりにもここで宣言することができます。今度は楽しい部分が来ます:

var stackData = []; 
for (var bin in bins) { 
    //console.log(bins[bin].x0, bins[bin].x1) 
    var pushableObject = {}; 
    // add the time boundaries. 
    pushableObject.x0 = bins[bin].x0; 
    pushableObject.x1 = bins[bin].x1; 
    // for each bin, split the data into the different keys. 
    bins[bin].forEach(function(d) { 
     //console.log(d); 
     if (!pushableObject[d.type]) { pushableObject[d.type] = [d]} 
     else pushableObject[d.type].push(d); 
    }) 
    // if any of the keys didn't get represented in this bin, give them empty arrays for the stack function. 
    keys.forEach(function(key) { 
     if (!pushableObject[key]) { 
      pushableObject[key] = []; 
     } 
    }) 

    stackData.push(pushableObject); 
} 

空のstackDataを作成し、ビンをループします。各ビンに対して、x0とx1でオブジェクトを設定します。これは、グラフを描画するために必要となるためです。次に、私はforeachループをビンに入れ、そこに格納された各データ項目をループします。記憶域オブジェクトは、このループで型(別名キー)ごとに1つの配列を取得します。その後、stack関数が正しく機能するように、このビンに表示されなかったタイプを捕まえるためのバックアップループがあります。それについては、ここにあります:

var realStack = d3.stack() 
    .keys(keys) 
    .value(function(d, key) { 
     return d[key].length; 
    }); 

すべてのデータが適切にマッサージされているので、とても簡単です。それは、データそのものではなく、データバケットの長さを取得するだけです。次に、rectを追加するときにそのスタック関数を使用し、stackData変数を渡すと、すべてがうまくいきます。

関連する問題