18

私は d3.js を使用しており、この例を変更してブラシ付き面グラフに取り組んでいます。ブラシに基づいて x 軸が変化することに加えて、ブラシ内にあるデータの y 値に基づいてグラフの y 軸を再描画したいと思います ( Google Finance グラフの動作に似ています) 。 .

機能が動作するようになりましたが、ブラシを x 空間と y 空間の両方で描画できるようにする方法でのみです。brushこれを行うには、まず変数に y スケールを追加します。

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

これによりbrush.extent()、次の多次元配列が返されます: [ [x0, y0], [x1, y1] ]. 次に、このデータをbrush()関数で使用して、フォーカス チャートの x ドメインと 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 スケールを定義することにより、ユーザーは、元のチャートのように西から東にドラッグできるだけでなく、フォーカス チャートで「ボックス」をドラッグできるようになりました。

基本的に、私の質問は次のとおりです。ブラシの領域自体の範囲ではなく、ブラシの領域内にある値の範囲を取得するにはどうすればよいですか? これは可能ですか?

d3 のブラシ ドキュメントはこちらです。

4

2 に答える 2

14

私は解決策を思いつきました。

ブラシ フィルター処理された 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);
于 2012-12-21T00:06:26.727 に答える
0

より短い可能性はd3.scale.invert()、あなたのbrush.extent()ように使用することです:

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 が取得されておりd3.brushX()、設計上、東/西方向のブラッシングのみが可能です。

于 2017-08-11T12:35:34.037 に答える