pops
pops

Reputation: 53

How to store zoom state and update incrementally in d3?

d3 stores the transform state of an element and updates it when there is a zoom event.

I want to use my own object to store the transform state, and only use the d3 zoom event to update it.

Here's an example of what I've tried to do:

// My transform state object
myTransState = {x:0, y:0, k:1}

onZoomEvent(e){

// Update my transform state object with change
myTransState.x += e.transform.x
myTransState.y += e.transform.y
myTransState.k *= e.transform.k

// Reset d3 transform state
e.transform.x = 0
e.transform.y = 0
e.transform.k = 1

}

This isn't working. The increment in x and y grows large and the plot moves far away from the mouse pointer.

I know I can use the d3 state transform directly, however I need to track the state myself for some situations (for example, separate x and y scale factors kx and ky).

Why isn't this working as expected? Is there something else that is modifying the d3 transform state after I reset it?

Upvotes: 0

Views: 631

Answers (1)

Rodrigo Divino
Rodrigo Divino

Reputation: 1931

Modifying the event is not enough to reset the zoom transform, because d3 does not store the current zoom coordinates in the event.

To reset the transform, you need to call the zoom.transform

selection.call(zoom.transform, zoomIdentity)

Where the selection is the same selection that called selection.call(zoom), and zoomIdentity is the identity transform {x: 0, y:0, z:1}

Be aware that calling zoom.transform will also trigger the onZoomEvent callback. To avoid a infinite loop, you can check if the transform of the event is {x: 0, y: 0, z: 1}, and if it is the callback is cancelled.

  onZoomEvent(e){
    if(e.transform.toString() === zoomIdentity.toString()) {
       return
    }


    // Update my transform state object with change
    myTransState.x += e.transform.x
    myTransState.y += e.transform.y
    myTransState.k *= e.transform.k

    // Reset d3 transform state
    selection.call(zoom.transform, zoomIdentity)
}

Upvotes: 1

Related Questions