Ho zoom e pan che funzionano per l'asse x ma mi piacerebbe aggiungere il panning per l'asse y. Ho provato a usare d3.behavior.zoom
e d3.event.translate[1]
per ottenere il valore di traduzione y e usarlo, ma il valore di traduzione cambia quando si verifica lo zoom, quindi mentre si trascina il mouse sull'asse y, lo zoom esegue anche panoramiche sull'asse y (in modo non intuitivo).D3: è possibile eseguire lo zoom + eseguire il pan di un asse e eseguire il pan solo sull'altro?
Ho anche provato a utilizzare due istanze d3.behavior.zoom
, una per l'asse xe una per l'asse y, ma solo l'ultimo aggiunto viene chiamato sugli eventi di zoom.
Ecco un esempio che funziona per lo zoom e pan nella direzione x che mi piacerebbe anche aggiungere y panning troppo (ma non y zoom):
var x = d3.scale.linear()
.domain([0, 800])
.range([0, 800]);
var y = d3.scale.linear()
.domain([0, 800])
.range([0, 800]);
var rectangleSelector = d3.select('svg')
.append('g')
.selectAll('rect')
.data([[0, 0], [50, 50], [100, 100]])
.enter()
.append('rect')
.attr('fill', 'black')
.attr('x', d => x(d[0]))
.attr('y', d => y(d[1]))
.attr('width', d => x(d[0] + 40) - x(d[0]))
.attr('height', d => y(40));
d3.select('svg')
.call(d3.behavior.zoom().x(x).on('zoom',() => {
rectangleSelector
.attr('x', d => x(d[0]))
.attr('y', d => y(d[1]))
.attr('width', d => x(d[0] + 40) - x(d[0]))
.attr('height', d => y(40));
}));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg width="800" height="800"></svg>
In questo esempio, tento di usare il valore y da d3.event.translate[1]
e funziona per il trascinamento, ma il comportamento indesiderato è che, a seconda di dove il mouse dell'utente sta facendo lo zoom, cambia anche il valore di traduzione per l'asse y.
var x = d3.scale.linear()
.domain([0, 800])
.range([0, 800]);
var y = d3.scale.linear()
.domain([0, 800])
.range([0, 800]);
var rectangleSelector = d3.select('svg')
.append('g')
.selectAll('rect')
.data([[0, 0], [50, 50], [100, 100]])
.enter()
.append('rect')
.attr('fill', 'black')
.attr('x', d => x(d[0]))
.attr('y', d => y(d[1]))
.attr('width', d => x(d[0] + 40) - x(d[0]))
.attr('height', d => y(40));
d3.select('svg')
.call(d3.behavior.zoom().x(x).on('zoom',() => {
var translateY = d3.event.translate[1];
rectangleSelector
.attr('x', d => x(d[0]))
.attr('y', d => y(d[1] + translateY))
.attr('width', d => x(d[0] + 40) - x(d[0]))
.attr('height', d => y(40));
}));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg width="800" height="800"></svg>
'd3.behavior.zoom()' è chainable con 'x()' e 'y()'; Sto solo specificando 'x()' e quindi il comportamento dello zoom cambia solo l'asse x. Ma riporta ancora i valori tradotti per l'asse y, che mi piacerebbe usare per tradurre quell'asse - il problema è che sono influenzati dallo zoom, non solo dal panning. – Beau
Sono in procinto di creare un JSFiddle. – Beau
Forse questo: http://bl.ocks.org/jgbos/9752277 – altocumulus