28

X 軸にタイム スケールを持つ D3 棒グラフを作成しています。x 軸の範囲はさまざまです。

棒グラフの棒の正しい幅を指定するにはどうすればよいですか? 序数スケールを使用rangeBandsしている人を見たことがありますが、時間スケールでこれを行う方法がわかりません。

これが私のコードです:

var x = d3.time.scale().range([0, width]);
var xAxis = d3.svg.axis().scale(x).orient("bottom");
[...]

// After new data has been fetched, update the domain of x...
x.domain(d3.extent(data, function(d) { return d.date; }));
d3.select(".x.axis").call(xAxis);

// ... and draw bars for chart
var bars = svg.selectAll(".air_used")
    .data(data, function(d) { return d.date; });

bars.attr("y", function(d) { return y(d.air_used); })
.attr("height", function(d) { return height - y(d.air_used); })
.attr("x", function(d) { return x(d.date); })
.attr("width", 20) // ??

20 の代わりに、最後の行に何を入力すればよいですか?

更新: JSFiddle はこちら: http://jsfiddle.net/aWJtJ/2/

4

4 に答える 4

34

幅を取得する関数はありませんが、非常に簡単に計算できます。

.attr("width", width/data.length);

バーを接触させたくない場合は、そこから少量を差し引くことをお勧めします。xそれに応じて位置を調整する必要もあります。

.attr("x", function(d) { return x(d.date) - (width/data.length)/2; })
.attr("width", width/data.length);

最初の目盛りが最初の値に配置されるため、目盛りを適切に配置するには、x 軸スケールの範囲も調整する必要があります。

var x = d3.time.scale().range([width/data.length/2, width-width/data.length/2]);

ここでjsfiddle を完成させてください。

于 2013-09-16T19:24:27.577 に答える
3

時系列ベースの x 軸を使用して棒グラフのズーム レベルを変更すると、この問題が発生し、2 つの解決策が見つかりました。

1) 幅の計算に役立つコンパニオン序数スケールを作成します (面倒)。

2) 時系列の x 軸はあなたの友人です - 幅を計算するために使用します。

ズームレベルに関係なく、バーを常に「月」幅にしたい場合は、次のようにすることができます。d.date がデータで利用可能であると想定しています。

 svg.selectAll(".air_used").attr("width", function(d.date) {
    var next = d3.time.month.offset(d.date, 1);
    return (x(next)- x(d));
  });

これは、すべてのズーム スケールで機能するため、うまく機能します。この関数を「ズーム」ハンドラの最後で呼び出すだけで済みます。つまり、.on("zoom", zoomed); 通常、x 軸はこの時点で調整されています。

于 2016-03-30T13:31:22.307 に答える
2

時間スケールは連続しているため、「正しい」バーの幅について多くのアイデアが考えられます。データ ポイントが非常に細かく、不均一に分布している場合は、固定幅の細いバーを使用して重複を最小限に抑えることができます。予想されるデータ値について事前に何かを知っていて、それらが均一な粒度である場合は、 @LarsKotthoff のようなことを行ってそれらを均等に配置できます。

考慮すべきことの 1 つは、実際に時間スケールが必要かどうかです。棒グラフは通常、連続スケールのポイントではなく、カテゴリ値を表すために使用されます。おそらく、日付範囲から派生したドメインを使用した序数スケールが実際に必要な場合があります。その場合、元の投稿に従って rangeBands を使用できます。

あなたがしていることをするのが間違っていると言っているのではありません。考えるだけの食べ物です。

于 2013-09-16T19:33:12.607 に答える