¡Finalmente casi lo conseguí! Los ejes X e Y en mi gráfico de dispersión tienen cada uno un comportamiento d3.drag() separado que ajusta la escala y el gráfico en sí mismo llama a d3.zoom() para paneo/zoom. Puedo desplazarme perfectamente, pero el zoom todavía no es correcto.
Ver aquí: codepen
Por lo general, el zoom se realiza configurando el dominio de la escala en una versión modificada de algunos dominios predeterminados de escalas x e y (x2, y2) que se configuran inicialmente.
x.domain(d3.event.transform.rescaleX(x2).domain()); y.domain(d3.event.transform.rescaleY(y2).domain());Esto funciona bien por sí solo, pero en combinación con otros comportamientos de zoom y arrastre, el cambio de escala hace que el estado de zoom de la trama no esté sincronizado, lo que hace que la trama salte al desplazarse o hacer zoom.
Para eludir esto, cada instancia de zoom/arrastre modifica directamente los dominios de las escalas. Todo funciona bien, sin embargo, acercar y alejar no configura los dominios correctamente. Creo que necesito implementar el valor d3.event.transform.k para calcular el delta de alguna manera. Es posible hacer zoom, pero luego sale mal.
// ZOOMING if (d3.event.sourceEvent && d3.event.sourceEvent.type == "wheel") { let domainX = x.domain(); let linearX = d3.scaleLinear().domain(x.range()).range([0, domainX[0] - domainX[1]]); let deltaX = linearX(tx - lastX); let domainY = y.domain(); let linearY = d3.scaleLinear().domain(y.range()).range([domainY[1] - domainY[0], 0]); let deltaY = linearY(ty - lastY) if (tk > lastK) { // ZOOM IN x.domain([domainX[0] - deltaX, domainX[1] + deltaX]); y.domain([domainY[0] + deltaY, domainY[1] - deltaY]); } else { // ZOOM OUT x.domain([domainX[0] + deltaX, domainX[1] - deltaX]); y.domain([domainY[0] - deltaY, domainY[1] + deltaY]); } }¡Por favor ayuda! Gracias.
D3fc se usa aquí pero no es importante.