2012-05-02 14 views
9

ズームとパンが可能な単純なD3.js折れ線グラフを実装しました。これはStephen Bannaschの優れた例であるhereに基づいています。D3.jsでズームまたはパンするときのドメインを制限する

私のデータのドメインは、xディメンションで[0、n]です。

組み込みのズーム動作(マウスホイールイベントを使用)を使用して、このドメインにズームとパンを制限するにはどうすればよいですか?

ユーザーが下端の0または上端のnを超えてパンするのを防止したいとします。たとえば、x軸の負の値を見ることができず、同じウィンドウにズームを制限したい。

エクステンション([...]、[...]、[...])を使用しているJason Daviesの作業に基づいている例は、バージョン2.9.1では機能しなくなったようです。残念ながら、ズームの動作は現在、それ以外の未解決のAPIドキュメントには記載されていない少数の機能の1つです。

すべてのポインタを歓迎します。

PS。 同じ質問をD3.jsメーリングリストに投稿しましたが、回答が得られませんでした:https://groups.google.com/d/topic/d3-js/w6LrHLF2CYc/discussion。クロスポストの謝罪。

答えて

0

再描画時にドメインを制限するだけで済みます。次のコードは、(http://bl.ocks.org/1182434で使用されているように)初期ドメインを超えてグラフがズームアウトされないようにします。

SimpleGraph.prototype.redraw = function() { 
    var self = this; 
    return function() { 

    self.x.domain([Math.max(self.x.domain()[0], self.options.xmin), Math.min(self.x.domain()[1], self.options.xmax)]); 

    self.y.domain([Math.max(self.y.domain()[0], self.options.ymin), Math.min(self.y.domain()[1], self.options.ymax)]); 

    .... 
+1

この投稿は古いですが、FYI:あなたが参照するリンクはズームアウトして自分の心のコンテンツにパンさせることができます。 (Chrome 29.0) – SgtPooki

+0

あなたのコードは自分のグラフで動作します。乾杯。 – SgtPooki

+1

この例を使用して、パンニング中にグラフがズームします。 –

6

悲しいことに、ビルによって掲示ソリューションは、半分だけのトリックをした:それは確かにパンを阻害しないが、それはズームが適用された場合に歪ませるグラフの原因となります。それでは、通常、適切に均等に配置されたグラフに戻ることは不可能です。

次のバージョンでは、スクロールしても軸の比率は維持されます。

スケーリングが100%に達すると、スケールのドメインは元の位置にリセットされます。これにより、中間ステップが軸の不正なパラメータを返す場合でも、正確な位置決めが保証されます。

完全ではありませんが、私はこのスクリプトがd3(再)がこの機能を実装するまで誰かを助けてくれることを願っています。

# x and y are the scales 
# xAxis and yAxis are the axes 
# graph is the graph you want attach the zoom to 

x0 = x.copy() 
y0 = y.copy() 

successfulTranslate = [0, 0] 

zoomer = d3.behavior.zoom() 
    .scaleExtent([1,2]) 

onZoom = -> 
    ev = d3.event # contains: .translate[x,y], .scale 
    if ev.scale == 1.0 
    x.domain x0.domain() 
    y.domain y0.domain() 
    successfulTranslate = [0, 0] 
    else 
    xTrans = x0.range().map((xVal) -> (xVal-ev.translate[0])/ev.scale).map(x0.invert) 
    yTrans = y0.range().map((yVal) -> (yVal-ev.translate[1])/ev.scale).map(y0.invert) 
    xTransOk = xTrans[0] >= x0.domain()[0] and xTrans[1] <= x0.domain()[1] 
    yTransOk = yTrans[0] >= y0.domain()[0] and yTrans[1] <= y0.domain()[1] 
    if xTransOk 
     x.domain xTrans 
     successfulTranslate[0] = ev.translate[0] 
    if yTransOk 
     y.domain yTrans 
     successfulTranslate[1] = ev.translate[1] 
    zoomer.translate successfulTranslate 

graph.select('g.x.axis').call(xAxis) 
graph.select('g.y.axis').call(yAxis) 
drawBars() 

zoomer.on('zoom', onZoom) 

# ... 
graph.call(zoomer) 
+1

ほぼ完璧です。私がこれを持っていた問題は、ズーム動作中は効果がないということです。 右端付近でズームインする場合は、カーソルを可視領域の左端に置き、ズームアウトします。可視領域の右端が予想限界を超えます。 翻訳の変更を単純に承認/却下するのではなく、別の方向に進む必要があると私は思います。ドメインの制限から、翻訳の有効範囲を計算し、変換値を制限します。 – mdaoust

関連する問題