2015-09-24 6 views
13

私はthis plnkrで作業しています。私は角度30,45、および60に3本の線を持っています。これらの線にブラシを適用して、チャートがブラシされたときにブラシ付きの矩形と適切な軸の値を交わるところで線が再描画されるようにします。この問題を解決するための助けやヒントがあれば幸いです。d3を使用して回転した線にブラシを付けると、ズーム効果が得られます

編集:回転した線やブラシを上に描画するさまざまなソリューションがある場合は、それも歓迎されます。助けてください。

var ga = d3.select("svg") 
    .append("g") 
    .attr("class", "a axis") 
    .attr("transform", "translate(" + margin.left + "," + (height + margin.top) + ")") 
    .selectAll("g") 
    .data([30, 45, 60]) 
    .enter() 
    .append("g") 
    .attr("class", "rotatedlines") 
    .attr("transform", function(d) { return "rotate(" + -d + ")"; }) 
    .attr("stroke-width", 1) 
    .attr("stroke", "black") 
    .attr("stroke-dasharray", "5,5"); 

Example result

+0

[SEレピュテーショングラフ](http://stackexchange.com/users/4536689/d3-gxt-java?tab=reputation)と同様に、既存のグラフを新しい拡大ビューで上書きしますか? – approxiblue

+0

はい - 例のように上書きしたいと思います。 – somename

+0

あなたの例では、回転30,45,60を使って線を作っています...これは実際のデータセットですか、ここでは実際のx(日付)とy(点)の値がありますかhttp://stackexchange.com/users/4536689/d3-gxt-java?tab = reputation – Cyril

答えて

5

を:

次のように取るべき基本的な手順は以下のとおりです。

  • はのドメインを更新xとyはブラシの大きさに合わせて調整する
  • 軸を再描画する
  • スケール係数を計算し、変換するライン
  • 規模についてエーションし、それに応じて
  • あなたはすべてを描画するスケールを使用していないので、3と4は唯一の必要なステップブラシ

注リセットラインコンテナを翻訳 - より良いをアプローチは、各行に2つのポイントを要素にバインドされたデータとして定義し、スケールを使用して再描画することです。これにより、コードが簡単になります。

あなたのアプローチでは、まだ可能です。これを容易にするために、私はいくつかのコードを修正しました。特に、さまざまな入れ子になったさまざまな入れ子になった要素を整理して、x1x2y1y2属性ではなく、コンテナの翻訳を通して。これらの両方の変更により、1つの変換だけが複数の他の変換を考慮する必要のない場所で行われるので、実装しやすい機能が実現します。また、複数のg要素の行を入れ子にして、より簡単にスケーリングして変換できるようにしました。

ブラシハンドラ関数は次のようになります。

// update scales, redraw axes 
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] ]); 
xAxisG.call(xAxis); 
yAxisG.call(yAxis); 

このコードはかなり自己説明する必要があります - スケールのドメインは、ブラシの現在のエクステントに応じて更新され、軸が再描画されています。

// compute and apply scaling and transformation of the g elements containing the lines 
var sx = (x2.domain()[1] - x2.domain()[0])/(x.domain()[1] - x.domain()[0]), 
    sy = (y2.domain()[1] - y2.domain()[0])/(y.domain()[1] - y.domain()[0]), 
    dx = -x2(x.domain()[0]) - x2.range()[0], 
    dy = -y2(y.domain()[1]) - y2.range()[1]; 
d3.selectAll("g.container") 
    .attr("transform", "translate(" + [sx * dx, sy * dy] + ")scale(" + [sx, sy] + ")"); 

これはトリッキーな部分です - スケールの新しいドメインに基づいて、我々は、ラインのスケールと翻訳を計算する必要があります。スケーリング係数は、古いエクステントと新しいエクステントの比率です(変更されていないスケールのコピーを作成したことに注意してください)。つまり、1より大きい数値です。変換によって、(0,0)元のスケールにもとづいて古い(0,0)座標(これを元のスケールの範囲から得る)と新しいドメイン原点の位置との差によって計算される。

翻訳とスケールを同時に適用する場合は、オフセットに倍率を掛ける必要があります。

// reset brush 
brush.clear(); 
d3.select(".brush").call(brush); 

最後に、ブラシをクリアしてリセットして、灰色の矩形を取り除きます。

完全デモhere

+0

多くのラースに感謝 - これは素晴らしいです! – somename

2

あなたはd3.event.target.extent()経由ブラシ範囲にアクセスすることができます。

  • セット規模
  • セット軸
  • 描画ブラシが行われているとすぐに、あなたはスケールを変更する必要があり、その後、再

軸:目盛りを描画するためのフローはこれです - 現在のxとyのドメインに従って軸を描きます。それはあなたが意味することですか?

私は、コードを少しクリーンアップし、少しデモンストレーション行わ:私の解決策を説明するためにhttp://plnkr.co/edit/epKbXbcBR2MiwUOMlU5A?p=preview

+0

あなたの答えをありがとう。私は回転した線も再描画する必要があります - それはブラシ領域を交差したところです。ブラシ領域が回転した線と交差しない場合は、再描画されたグラフには表示されません。あなたはそれをどのように達成するか考えていますか? – somename

+0

これは単純な部分ですが、私はあなたが既にそれを解決したかもしれないと思いました:-)このバージョンを参照してください:http://plnkr.co/edit/Aw6Gc1PNGtiVSWXNaJU2?p=previewオンライン116.私はキャンバスとラインを分割し、 'transform =" translate(-50,470)scale(2) "'のようなもので 'g'要素を拡大/縮小できます。 – Rudolf

+0

Btw、d3には、数学を借りることができるズームライブラリもあります。 – Rudolf

関連する問題