2012-12-20 7 views
17

私はd3.jsを使用していますが、this exampleを変更してブラシ付き領域グラフを作成しています。ブラシに基づいて変化するx軸に加えて、ブラシ内に収まるデータのy値に基づいて、グラフのy軸を再描画したいと考えています(振る舞いはa Google Finance chartと同様です)。ブラシ付き領域グラフのy軸を更新します

私は、ブラシをx空間とy空間の両方で描くことができるように機能しています。 [ [x0, y0], [x1, y1] ]

var brush = d3.svg.brush() 
    .x(x2) 
    .y(y2) 
    .on("brush", brush); 

これはbrush.extent()は、次の多次元配列を返すことができる:私は最初brush変数にYスケールを追加することによって、これを行いました。この作品

function brush() { 
    var extent = brush.extent(); 
    x.domain(brush.empty() ? x2.domain() : [ extent[0][0], extent[1][0] ]); 
    y.domain(brush.empty() ? y2.domain() : [ extent[0][1], extent[1][1] ]); 
    focus.select("path").attr("d", area); 
    focus.select(".x.axis").call(xAxis); 
    focus.select(".y.axis").call(yAxis); 
} 

が、ブラシの変数にYスケールを定義することにより、ユーザーは現在、 "ドラッグすることができます:私は、フォーカスチャートのx軸とy軸ドメインを再定義するbrush()機能でこのデータを使用し元のチャートのように、西から東にドラッグできるだけでなく、フォーカスチャートの「ボックス」を使用します。

私の質問は:ブラシの領域自体の範囲ではなく、ブラシの領域内にある値の範囲を取得するにはどうすればよいですか?これも可能ですか?

d3のブラシのマニュアルはhereです。

答えて

13

私は解決策を思いついた。

ブラシフィルタリングされたx.domainを使用して元のデータセットをフィルタリングしました。この新たなフィルタリングされたデータセットは、ブラシ内に入る値だけを有する:

// Use x.domain to filter the data, then find the max and min duration of this new set, then set y.domain to that 
    x.domain(brush.empty() ? x2.domain() : brush.extent()); 
    var dataFiltered = data.filter(function(d, i) { 
    if ((d.date >= x.domain()[0]) && (d.date <= x.domain()[1])) { 
     return d.duration; 
    } 
    }) 
    y.domain([0, d3.max(dataFiltered.map(function(d) { return d.duration; }))]); 

最後に、y軸ならびにx軸を再描画してください:

focus.select("path").attr("d", area); 
focus.select(".x.axis").call(xAxis); 
focus.select(".y.axis").call(yAxis); 
+3

完璧な回答!私のチャートのコードにうまくドロップできました。 – fundead

0

短い可能性そのようなあなたのbrush.extent()d3.scale.invert()を使用することです。しかし

var domainExtent = brush.extent().map(function(d){return scale.invert(d);}); 
var filteredData = data.filter(function(d){return ((d <= domainExtent[1]) && (d >= domainExtent[0]));}); 

、今d3はを獲得したことにより、は、東/西方向のブラッシングのみを設計で可能にします。

関連する問題