d3 / d3-zoom

Pan and zoom SVG, HTML or Canvas using mouse or touch input.
https://d3js.org/d3-zoom
ISC License
502 stars 143 forks source link

Trigger zoom event programaticaly in unit tests #193

Closed Meemaw closed 4 years ago

Meemaw commented 4 years ago

I would like to test the zoom behavior of our application. I'm struggling with invoking the Event that would trigger the zoom.on callback of d3-zoom using mouse wheel.

The code goes something amongst those line (React):

constructor(props: Props) {
    super(props);

    const { width, height } = props;
    this.zoom = d3
      .zoom<HTMLDivElement, unknown>()
      .translateExtent([[0, 0], [width, height]])
      .extent([[0, 0], [width, height]]);
  }

  setupZoom = (ref: HTMLDivElement) => {
    const rectSelection = d3.select(ref);
    rectSelection.call(this.zoom.on('zoom', this.handleZoomEvent));
    rectSelection.on('dblclick.zoom', null);
    rectSelection.on('mousedown.zoom', null);
  };

  handleZoomEvent = () => {
    const { height, width, onResize } = this.props;
    const {
      event: { sourceEvent },
    } = d3;

    if (
      !sourceEvent ||
      sourceEvent.deltaMode === undefined ||
      sourceEvent.deltaY === undefined
    ) {
      return;
    }

    const { deltaMode, deltaY } = sourceEvent;
    const zoomFactor = (deltaY * (deltaMode ? 120 : 1)) / 500;

    onResize({
      width: width + zoomFactor * width,
      height: height + zoomFactor * height,
    });
  };

I've tried firing different events in my test and none of them invoked the handleZoomEvent function. If you need any additional information let me know!

mbostock commented 4 years ago

I expect you’ll need to create fake mouse events and dispatch them with element.dispatchEvent. Or you could invoke your zoom handlers directly using d3.customEvent but that would be more “fake”.

Please use Stack Overflow tag d3.js to ask for help. Stack Overflow provides a better collaborative forum: thousands of D3-related questions have been asked there, and some answers may be relevant to you.

When asking for help, please include a link to demonstrate the issue, preferably as an Observable notebook. It is often impossible to debug from code snippets alone. Isolate the issue and reduce your code as much as possible before asking for help. The less code you post, the easier it is for someone to debug, and the more likely you are to get a helpful response.

If you have a question about D3’s behavior and want to discuss it with other users, also consider the d3-js Google Group or joining the d3-js Slack.

Thank you! 🤗

amers185 commented 5 months ago

I am running into a similar issue. @Meemaw were you able to fix your issue?