d3 / d3-zoom

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

Listen for zoom events with without d3-selection? #254

Closed Nate-Wessel closed 1 year ago

Nate-Wessel commented 1 year ago

The docs on the zoom function say that

The returned behavior, zoom, is both an object and a function, and is typically applied to selected elements via selection.call.

I'm interested in that "typically" part. I'm using this in React, and I already have a reference to the element I want to listen for zoom events on. It seems largely redundant to have to wrap this element in a select before calling the zoom function. This is the only place I'm explicitly depending on d3-selection since all my other DOM manipulation is handled by React. Is there another way?

A tiny bit of sample code:

import { createRef, Component } from 'react';
import { select } from 'd3-selection'
import { zoom } from 'd3-zoom'
...
export default class GeoMap extends Component{
   #zoom
   constructor(props){
      super(props) 
      this.SVGref = createRef()
   }
   componentDidMount(){
      this.#zoom = zoom().on('zoom',this.transformProjection)
      select(this.SVGref.current).call(this.#zoom)
   }
...

Is it possible to refactor this to remove the d3-selection dependency?

Fil commented 1 year ago

Not really—you'd have to implement a compatible interface with D3's selection and the many properties we use: https://github.com/d3/d3-zoom/blob/main/src/zoom.js#L72

(We also use d3-selection's pointer method.)

Nate-Wessel commented 1 year ago

Got it. Thanks for the quick reply!