3

d3.js ライブラリを使用してヒストグラムを作成する必要があります。ヒストグラムは次のようになります。このヒストグラムの主な目的は、2 つの結果セットを比較することです。下の図に示されている結果は、月の同じ日に収集されたデータを表していますが、2 つの異なる月 (たとえば、1 月 (緑) と 2 月 (青) の 1 日から 6 日) に収集されたデータです。

私が現在持っているヒストグラムは、基本的に正しいデータを示していますが、それらをオーバーレイしていない (または並べて表示していない) だけです。代わりに、1 月を表す結果が 1 番目 (左) に、2 月を表す結果が 2 番目 (右) に、日付順に並べられて表示されます。それらを並べて表示するにはどうすればよいですか?

編集:私はAngular環境で作業しており、グラフを表示するために事前構築されたディレクティブを使用しています。ディレクティブのコードは、https: //github.com/fullscale/dangle/blob/master/dist/dangle.datehisto.js でコーティングされています。

望ましい結果:

希望のチャート

現在の結果:

現在のチャート

4

1 に答える 1

2

ここでの問題は、やろうとしていることに対して実際には線形である必要があるときに、時間スケールを使用していることです。実際の日付/時刻に基づいて x オフセットを増やすのではなく、日付の date.getDate() 部分だけを増やす必要があります。d.time が と同じものを表していると仮定するとnew Date().getTime()、スケールを線形に変更し、日と月のオフセットだけを使用して x 値を決定できます。ただし、これには、月を示すために何らかの形式の凡例を作成する必要があります。

まず、使用しているスケールを変更します。

// create x,y scales (x is inferred as time)
// var x = d3.time.scale()
//    .range([0, width]);
//
// Use linear scale since we really care about the day portion of the date/time
var x = d3.scale.linear()
      .range([0, width]);

次に、月と日の範囲を計算します。

// Get the range of months so we can use the month
// to offset the x value for overlay
var monthExtent = d3.extent(data,function(d) { 
            var date = new Date(); 
            date.setTime(d.time.getTime()); 
            return date.getMonth(); 
        });

// Get the range of days for the graph
// If you always want to display the whole month
// var dateExtent = [0,31]
//
// Otherwise calculate the range
var dateExtent = d3.extent(data,function(d) {  
            var date = new Date(); 
            date.setTime(d.time.getTime()); 
            return date.getDate(); 
        });

次に、x ドメインを日の範囲に設定します。

// recalculate the x and y domains based on the new data.
 // we have to add our "interval" to the max otherwise 
 // we don't have enough room to draw the last bar.
 //
 //x.domain([
 //    d3.min(data, function(d) { 
 //        return d.time;
 //    }), 
 //    d3.max(data, function(d) { 
 //        return d.time;
 //    })
 //]);


 // Our x domain is just the range of days 
 x.domain(dateExtent);

月を区別するためにカラー スケールを追加します。

// Set up a color scale to separate months
 var color = d3.scale.category10();

ここで、x 属性を変更して、日の値と月のオフセットを使用してオーバーレイを作成します。ここでは 20 ピクセルを使用しましたが、代わりにバー幅のパーセンテージに簡単に変更できます。次に、月とカラー スケールを使用して塗りつぶし属性を追加し、各月が独自の色になるようにします。

bars.enter()
    .append('rect')
        .attr('class', 'histo rect ')
        .attr('cursor', 'pointer')
        .attr('x', function(d) {
            // Extract the day portion of the date/time
            // and then offset the rect by it's month value
            var date = new Date();
            date.setTime(d.time.getTime());
            return x(date.getDate()) + (date.getMonth() - monthExtent[0]) * 20; 
        })
        .attr("fill",function(d) { 
            var date = new Date();
            date.setTime(d.time);
            return color(date.getMonth()); 
        })
        .attr("y", function(d) { return height })
        .attr('width', barWidth)
        .transition()
            .delay(function (d,i){ return i * 0; })
            .duration(500)
                .attr('height', function(d) { return height - y(d.count); })
                .attr('y', function(d) { return y(d.count); });

最後に、各日の間に適切な量のスペースがあることを確認するために、おそらく barWidth の計算方法を変更する必要があります。うまくいけば、これが役に立ちます!

于 2013-11-14T18:23:26.337 に答える