2016-10-12 8 views
2

The docs d3のスタッキング関数d3.stackは、オブジェクトの配列を持つ例を示しています(各jsonオブジェクトは、x軸が何を測定していてもポイントのアンサンブルを表します)。例:d3のマトリックスをjsonに再マッピングせずにスタックする

var data = [ 
    {month: new Date(2015, 0, 1), apples: 3840, bananas: 1920, cherries: 960}, 
    {month: new Date(2015, 1, 1), apples: 1600, bananas: 1440, cherries: 720} 
] 

私は、データ系列([ [], [], [], etc ])の行列で積み重ねられたヒストグラムを生成しようとしています。

for(let i=0; i<data.length; i++){ 
    bins[i] = d3.histogram() 
      .domain(x.domain()) 
      .thresholds(x.ticks(10)) 
      (data[i]); 
    } 

そして、別のループ内の各データ系列のグループを作成します:

let bars = this.svg.selectAll(".series" + i) 
    .data(this.bins[i]) 
    .enter().append("g") 
    .classed("series" + i, true) 
これは、行を反復処理し、(Xスケールや他の場所でドメインを事前に定義された)ヒストグラムのビンのシリーズを取得するのに十分に簡単です

もちろん、私はここにこだわっているようにそれをやっている。どのように私はbars.append("rect")に、特定のシリーズの正しいx、y座標でどうするのですか? JSONのキー、値のペアにすべてのデータをいじることなく、stackを起動する方法はあり

[ 
    [[1,2,3,3], [5,8,9], [10], ... etc], //series0 grouping by bins of 5 
    [[1,3], [7,7,9,9], [11], ... etc], //series1 
    [[2,3,3], [8,9], [10,12], ... etc], //series2 
    ...etc 
] 

:別の言い方をすれば、私のようなものを探して、現時点でbinsの本当に便利な配列を持っていますか?

答えて

1

私はthe sourceを一瞥しましたが、コメントはありません+単一のchar変数=私はそれが狂っていないと起こらないことを理解しています。

/* 
* Static helper method to transform an array of histogram bins into an array of objects 
* suitable for feeding into the d3.stack() function. 
* Args: 
* bins (array): an array of d3 histogram bins 
*/ 
static processBins(bins){ 
    let temp = {}; // the keys for temp will be the bin name (i.e. the bin delimiter value) 
    // now create an object with a key for each bin, and an empty object as a placeholder for the data 
    bins[0].map((bin) => { temp[bin.x0] = {}}); 
    for(let i=0; i<bins.length; i++){ 
     //traverse each series 
     bins[i].map(bin => { 
      temp[bin.x0]["series"+i] = bin.length; //push the frequency counts for each series 
     }); 
    } 
    /* now we have an object whose top-level keys are the bins: 
    { 
     binName0: { series0: freqCount0, series1: freqCount1, ...}, 
     binName1: {...}, 
     ... 
    } 
    now, finally we're going to make an arrays of objects containing all the series' freqencies for that bin 
    */ 
    let result = []; 
    for(let binName in temp){      // iterate through the bin objects 
     let resultRow = {}; 
     if(temp.hasOwnProperty(binName)){ 
      resultRow["bin"] = binName;    //put the bin name key/value pair into the result row 
      for(let seriesName in temp[binName]){ //iterate through the series keys 
       if(temp[binName].hasOwnProperty([seriesName])){ 
        resultRow[seriesName] = temp[binName][seriesName]; 
       } 
      } 
     } 
     result.push(resultRow); 
    } 
    return result; 
} 

コールのように:私は他の誰かにいくつかの時間を節約するにしたがって、私の見掛け倒しの試みを提示

let stack = d3.stack().keys(bins.map((d,i)=>{return "series"+i})); //stack based on series name keys 
let layers = stack(MyCoolHistogram.processBins(bins)); 
//and now your layers are ready to enter() into a d3 selection. 

編集: 私は無名関数のスタックデータ3番目の引数は配列であると考えられることに注意してください要素。私。もはやスタックレイヤインデックスではありません。例えば、バーをグループ化する際にサイド・バイ・サイド:これは、x位置を計算するために、このインデックス番号に依存している機能のグループ化休憩http://bl.ocks.org/mbostock/3943967

rect.attr("x", (d,i,j) => { return x(d.data.bin) + j*barWidth/numberOfSeries}); 

私はマイクの要旨はまだV3を使用していることを伝えるだと思うが、 v4が出てからずっと更新されているにもかかわらず。

レイヤインデックスを取得するには、layer.index属性を直接使用する必要があります。だからグループ化すると、レイヤー全体が翻訳されます(これはbar-by-barアニメーションをねじ込みます...もちろん)。

let layers = d3.stack(yourData); 
let layer = this.svg.selectAll(".layer") 
      .data(layers) 
layer.transition() 
    .attr("transform", d => { return "translate(" + d.index*barWidth/numberOfSeries + ",0)"; }); 
関連する問題