Skip to content

Brushing inside transformed container#145

Description

@lgrkvst

First off, hat 馃憭 off for this breath of fresh air! I've gone through at least five chart libraries of which none gets what svelteplot gets: You definitely want declarative charts in a reactive environment.

As for me, I'm putting charts into svelte-flow nodes, but it might as well be inside three.js planes: a grandfather container might have transformations. Drawing the charts goes spotless 鈥撀爐he issue comes when its time for brushing.

Problem
When is used inside transformed containers (CSS transforms, SvelteFlow zoom/pan, Three.js planes), the brush rectangle draws at incorrect screen coordinates while the data selection remains accurate.

Root Cause
The clientToLayerCoordinates() function converts event.clientX/clientY using:

return [event.clientX - plotBodyRect.left, event.clientY - plotBodyRect.top];

This doesn't account for ancestor CSS transforms, causing coordinate misalignment proportional to the transform scale.

Proposed Solution
Add an optional coordinateTransform prop to the <Brush> component:

<Plot>
  <Brush 
    x="date" 
    coordinateTransform={myTransformFn}
    onbrush={handleBrush} 
  />
</Plot>

<script>
function myTransformFn(clientX, clientY, plotBody) {
  // Apply container-specific coordinate correction
  const corrected = containerToLocal(clientX, clientY);
  return [corrected.x, corrected.y];
}
</script>

** Implementation**
Modify clientToLayerCoordinates() to accept and use the transform function:

export function clientToLayerCoordinates(event, plotBody, transformFn = null) {
    if (!plotBody) return [0, 0];
    
    const plotBodyRect = plotBody.getBoundingClientRect();
    
    if (transformFn) {
        const [transformedX, transformedY] = transformFn(event.clientX, event.clientY, plotBody);
        return [transformedX - plotBodyRect.left, transformedY - plotBodyRect.top];
    }
    
    return [event.clientX - plotBodyRect.left, event.clientY - plotBodyRect.top];
}

Hmm... at this point I realise the clientToLayerCoordinates runs as soon as I move the mouse. It might make sense to make the incision in the Brush component...

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions