2016-09-21 8 views
5

私はd3.js v4を使用しています。現在、プログラムによるズームを実装しています。このPanning and Zooming Tutorialはすごく助けになりました。ズームはホイールをスクロールしても機能しますが、ズームするボタンを作成したいと思います。私はズームとパンに必要なものが、翻訳[tx, ty]とスケールファクタkであることを知っています。私はx軸にタイムスケールを使用しています。私は、x軸にp1 (point 1)p2(point 2)のピクセル値を得て、次にそれらの値を使ってk(スケールファクタ)を得ることによって、txとスケールファクタkを得ました。こうした同様:問題(プログラマチックズームv4)

var tx = 0 - k * p1; 

が続いd3.zoomIdentity()にそれを送り、私のxdomainを再スケーリング:

var k = 500/(xScale(p2) - xScale(p1)); //500 is desired pixel diff. between p1 and p2, and xScale is my d3.scaleTime() accessor function. 
// for this zoom i just want the first value and last value to be at scale difference of the entire width. 

その後、私はこれでTXを計算します。ズームアウトするためのボタンを作成しました。問題は、ズームインしてズームアウトするときにボタンを使用しようとするときです。ズームアウトすると、x軸は縮小されます。私はなぜそれがx軸を縮小するのか、正確に戻ってズームするのを見つけることができません。

マイJSFiddle

https://jsfiddle.net/codekhalifah/Lmdfrho7/2/

私が試した何

012にズームの章を読みます

マイコード

ホイールズームが、私はこの機能を実行に適用された後:

function zoomed() { 
     if (d3.event.sourceEvent && d3.event.sourceEvent.type === "brush") return; // ignore zoom-by-brush 
var t = d3.event.transform; 
console.log(t); 
console.log(xScale.domain()); 
xScale.domain(t.rescaleX(x2).domain()); 
usageAreaPath.attr("d", area); 
usageLinePath.attr('d',line); 
weatherAreaPath.attr('d',weatherChart.area); 
focus.select(".axis--x").call(xAxis); 
focus.selectAll('.circle') 
    .attr('cx', function(d) { return xScale(getDate(d)); }) 
    .attr('cy', function(d) { return yScale(d.kWh); }) 
    .attr("transform", "translate(0," + 80 + ")"); 

     ... other non related items 
    } 

ズームが正常に動作しますが、私が欲しい通常の位置にピンを見るにはズームインしようとすると、手動で、その後にズームや後。私が今しながら、少しのためにこれを見てきた、と私はそれを作業のソートを得た

function programmaticZoom(){ 
var currDataSet = usageLinePath.data()[0], //current data set 
     currDataSetLength = currDataSet.length,//current data set length 
     x1 = currDataSet[0].usageTime, //getting first data item 
     x2 = currDataSet[currDataSetLength-1].usageTime, //2nd data item 
     x1px = xScale(moment(x1)), //Get current point 1 
     x2px = xScale(moment(x2)); // Get current point 2 

     // calculate scale factor 
     var k = width/(x2px - x1px); // get scale factor 
     var tx = 0 - k * x1px; // get tx 
     var t = d3.zoomIdentity.translate(tx).scale(k); //create zoom identity 

     xScale.domain(t.rescaleX(window.x2).domain()); 
     usageAreaPath.attr("d", area); 
     usageLinePath.attr('d',line); 
     weatherAreaPath.attr('d',weatherChart.area); 
     focus.select(".axis--x").call(xAxis); 
     focus.selectAll('.circle') 
      .attr('cx', function(d) { return xScale(getDate(d)); }) 
      .attr('cy', function(d) { return yScale(d.kWh); }) 
      .attr("transform", "translate(0," + 80 + ")"); 

} 
+0

ズームボタンを常にデフォルトの初期表示にズームするだけですか? – Hamms

+0

@ハムス私は実際にさまざまなレベルにズームすることができるようにしたい。これは私の最初のテストレベルでした。しかし、タイムスケールでは、月間ビューから週ビュー、1日から1時間、15分まで拡大したいと考えています。私の最初のテストレベルは、数ヶ月を見に戻ったことでした。 – inspired

+0

@ハムどんなアイデア? – inspired

答えて

3

私の手動ズームボタン機能、そこに私は理解できない一つのことだが、あなたはできるかもしれませんあなたが私よりもd3に精通しているからです。 programmaticZoom()関数では、txはグラフの開始位置のオフセットであり、kはスケールです。これを使用して、私がブロックを変更:

var k = width/(x2px - x1px); // get scale var tx = 0 - k * x1px; // get tx var t = d3.zoomIdentity.translate(tx).scale(k);

をまず、k = 1.0

var k = 1; var t = d3.zoomIdentity.scale(k);

に、グラフが完全にウィンドウにフィットします。 kを元の値に設定したのが間違っていたのは、 kの値を k > 1.0に増やすと、それは画面を越えてグラフの幅を広げてしまうからです。グラフ上のコンテンツは、画面上に表示されている範囲内で、可能な限り というグラフ上ののスペースを占めるように再調整する必要があります。 k < 1では、 width/(x2px - x1px);の場合と同じように、グラフは画面のサイズよりも小さくなります。このように再調整すると、グラフの内容がグラフ内の の最大値に収まるようになりますが、グラフが画面より小さいため、縮小されたグラフに合わせて再調整され、画面より小さく表示されます。

グラフはで始まる、それは相殺ので、私は完全にtxを処分しました。グラフが拡大表示されると、その幅は画面を超えて拡大されます。グラフの表示を開始する位置とオフセットを同じにする必要があり、必要のない部分が画面から離れないようにする必要があるため、ここではオフセットするのが理にかなっています。あなたが完全にズームアウトしている場合、グラフは画面のサイズであるです。オフセットすると、画面の始めにグラフが表示されず、グラフの一部が画面。あなたのケースでは、kがすでにグラフを縮小しているので、オフセットは、画面の中央に収縮したグラフを表示します。しかし、グラフが収縮していない場合、オフセットはグラフの一部を画面から押しのけます。

これを変更すると、ズームアウトボタンが表示されますが、まだ問題があります。が表示されます。 zoomed()関数では、var t = d3.event.transform;を設定します。 d3.event.transformには、完全にズームアウトしたときにそれぞれ1, 0, and 0になる必要があるk, x, and yという値が含まれています。しかし、関数でこれらの値を変更することはできません。なぜなら、d3.event.transformは、イベントが発生した後にのみ存在します。具体的には、マウスホイールです。ズームボタンをクリックしたときにのみこれらの値をk = 1, x = 0, y = 0にすることができれば、問題は完全に修正する必要があります。いくつかを助けた

うまくいけば、私はD3に非常に精通していないよ、これはあなたの問題のほとんどを解決し、うまくいけば、あなたに間違って何が起こっていたかのアイデアを与える必要があります。

関連する問題