2016-12-11 12 views
1

D3.js v4のヒートマップがあり、ズームとパン機能を追加しようとしています。ズームはx軸でのみ機能し、y軸は変更しません。ズームに関連する部分は以下の通りです:D3.js/v4のズームイン時のヒートマップの再描画

var x = d3.scaleTime().range([0, width]).domain([minDate, maxDate]); 
var xAxis = d3.axisBottom().scale(x); 
var zoom = d3.zoom().scaleExtent([1, 2]) 
      .translateExtent([[80, 20], [width, height]]) 
      .on("zoom", zoomed); 

svg.call(zoom); 

function zoomed() { 
    xAxis.scale(d3.event.transform.rescaleX(x)); 
    svg.select(".x.axis").call(xAxis); 
    update(); 
} 

function update() { 
    svg.selectAll(".cell") 
     .attr('clip-path', 'url(#plotAreaClip)') 
     .attr("x", function (d) { return x(d.timestamp); }) 
     .attr("y", function (d) { return y(d.hour); }) 
     .attr("width", function (d) { return x(d3.timeWeek.offset(d.timestamp, 1)) - x(d.timestamp); }) 
     .attr("height", function (d) { return y(d.hour + 1) - y(d.hour); }) 
     .attr("fill", function (d) { return colorScale(d.value); }); 
} 

私は実際にzoomed()機能でupdate()をコメントアウトすると、私はその軸だけで罰金/アウトで拡大します見ることができます。しかし、update()が関数内にある場合は、グラフ内のすべての四角形が削除されます。

JSフィドルリンクはhttps://jsfiddle.net/7z1f4c5p/(私はJSFiddleにcsvファイルをアップロードする方法がわからないので、JSパーツ全体にデータを書き込む必要がありました。残念ですが、コードは下にあります。第97行、ズームは動作しません。

+0

フィドルにコードがありません –

答えて

1

をあなたのupdate()に新しいスケール値を適用する必要があります。

function update() { 
    // update: cache rescaleX value 
    var rescaleX = d3.event.transform.rescaleX(x); 
    svg.selectAll(".cell").attr('clip-path', 'url(#plotAreaClip)') 
     // update: apply rescaleX value 
     .attr("x", function(d) { 
      return rescaleX(d.timestamp); 
     }).attr("y", function(d) { 
      return y(d.hour); 
     }) 
     // update: apply rescaleX value 
     .attr("width", function(d) { 
      return rescaleX(d3.timeWeek.offset(d.timestamp, 1)) - rescaleX(d.timestamp); 
     }).attr("height", function(d) { 
      return y(d.hour + 1) - y(d.hour); 
     }).attr("fill", function(d) { 
      return colorScale(d.value); 
     }); 
} 

clipPathrectwidthheightを持っていません。

0123のようになります。
// update: set widht and height of clippath rect 
plotArea.append("clipPath") 
    .attr("id", "plotAreaClip") 
    .append("rect") 
    .attr('width', width) 
    .attr('height', height); 
    //.attr({width: width, height: height}); 

ここで働いているフィドル - https://jsfiddle.net/7z1f4c5p/2/

あなたは、グラフの左右のスペースを調整する必要があります。ズームすると少し外れているように見えます。

+0

ありがとうございます。 'clipPath'の代わりに' var rescaleX = d3.event.transform.rescaleX(x).clamp(true); 'を使うこともできますか?それは私のために働いたが、私は確信したかった。 – nope

+0

視覚的には同じように見えるかもしれません。違いは 'clamp(true)'で、スケールの出力は '[0、width]'の範囲内に強制されます。 clipPathを使用すると、出力はそのまま縮尺になります。 clipPathの外にあるものは表示されません。これを見る簡単な方法は、グラフの最初の矩形の要素を調べることです。 'clamp(true)'では、長方形xは '0'です。 'clipPath'では、' clamp(true) 'を適用しないので、x位置は負の値になります。これは、' clipPath'領域の外にあり、ズーム範囲の限界を超えているために表示されません。 – phoa

関連する問題