Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

d3-drag - rescale y-axis with drag in d3v5

Tags:

d3.js

d3fc

I'm trying to achieve the effect of rescaling the d3fc cartesian chart when the user drags along the axes.

https://codepen.io/parliament718/pen/BaNQPXx

This is in d3v5, and I'm using d3-zoom to re-scale the axes using d3.event.transform. However, in d3-drag there is no d3.event.transform so I don't understand what the equivelant logic would be using just the mouse coordinates that d3-drag provides.

const zoom = d3.zoom()
   .on('zoom', () => {
       const t = d3.event.transform;
       x.domain(t.rescaleX(x2).domain());
       y.domain(t.rescaleY(y2).domain());
       render();
   });

plot.call(zoom);

//What is the equivelant drag action to rescale?
const yAxisDrag = d3.drag()                 
    .on('end', (args) => {
       var t = d3.zoomTransform(plot.node());

       //zoom.translateBy(plot,d3.event.dx/t.k,d3.event.dy/t.k);
       //How can I use zoom.scaleBy() here instead?
    });
like image 384
parliament Avatar asked Nov 06 '22 09:11

parliament


1 Answers

You can create another zoom behavior which only changes the Y domain. Then, in the drag handler, call the new behavior's scaleBy on the plot area with a scale factor based on the drag event's delta Y:

const yAxisZoom = d3.zoom()
  .on('zoom', () => {
    y.domain(d3.event.transform.rescaleY(y2).domain());
    render();
  });

const yAxisDrag = d3.drag()
  .on('drag', () => {
    const factor = Math.pow(2, -d3.event.dy * 0.01);
    d3.select('#zoom-chart .plot-area').call(yAxisZoom.scaleBy, factor);
  });
like image 186
Josh Brobst Avatar answered Dec 06 '22 05:12

Josh Brobst