2015-10-06 157 views
0

我想在簡單的d3圖中使用縮放行爲。問題在於,無論何時放大,「主」組元素佔據整個svg空間,導致其他現有元素(如軸和文本)重疊。我已經讀過剪輯可以用來解決這個問題,但我沒有設法讓它正常工作。縮放D3裁剪問題

下面的圖像(在應用縮放)顯示問題:與我有什麼到目前爲止已經試過可以發現here

Clipping issues

相關的例子。

回答

0

我終於能夠解決這個問題。要點是:

  • 使用適當的svg元素進行剪輯,通常rect做相應的寬度/高度(與「繪圖」區域相同)的作業。
  • 轉換在剪輯路徑(區域)內繪製的所有元素,而不是父組。

在代碼(省略不相關部分),其結果是:

// Scales, axis, etc. 
... 

// Zoom behaviour & event handler 
let zoomed = function() { 
    let e = d3.event; 
    let tx = Math.min(0, Math.max(e.translate[0], width - width*e.scale)); 
    let ty = Math.min(0, Math.max(e.translate[1], height - height*e.scale)); 
    zoom.translate([tx,ty]); 
    main.selectAll('.circle').attr('transform', 'translate(' + [tx,ty] + ')scale(' + e.scale + ')'); 
    svg.select('.x.axis').call(xAxis); 
    svg.select('.y.axis').call(yAxis); 
} 

let zoom = d3.behavior.zoom() 
    .x(x) 
    .y(y) 
    .scaleExtent([1,8]) 
    .on('zoom', zoomed); 

const svg = d3.select('body').append('svg') 
    .attr('width', width + margin.left + margin.right) 
    .attr('height', height + margin.top + margin.bottom) 
    .attr('pointer-events', 'all') 
    .call(zoom); 

const g = svg.append('g') 
    .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); 

// Set clip region, rect with same width/height as "drawing" area, where we will be able to zoom in 
g.append('defs') 
    .append('clipPath') 
    .attr('id', 'clip') 
    .append('rect') 
    .attr('x', 0) 
    .attr('y', 0) 
    .attr('width', width) 
    .attr('height', height); 

const main = g.append('g') 
    .attr('class', 'main') 
    .attr('clip-path', 'url(#clip)'); 

let circles = main.selectAll('.circle').data(data).enter();