question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Edge not aligned with handle when scale is applied

See original GitHub issue

Hi there. I’ve got an issue similar to #1075 and #1136 where the calculated edge path does not align with handles, and my use case may provide some insight onto why it’s happening.

I use spectacle to create presentations and recently wanted to start using graphs created with react-flow in the slide. However, there is something strange happening when the slide is scaled down. The image below is from the graph rendered on a slide.

image

This one is the graph rendered outside of the Spectrum <Slide> component, but otherwise identical. The edges are correct.

image

I can confirm that it has something to do with the scale transform based on the slide’s height and width. If I change the size of the slide and reduce its dimensions (e.g., 1280x720 instead of 1920x1080) the misalignment is less severe but still present.

If you use the Spectacle print mode, the edges are more accurate, but still slightly off.

image

This may be too complex of a use case for a fix, especially if it is the result of a misconfiguration of Spectacle. But I figured that it at least gives you a reproducible example of the misalignment issue.

Any ideas on how prevent this from happening when you’re working with a graph contained in a non-standard series of DOM elements?

Thanks in advance. Love the library!

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:1
  • Comments:10 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
litewarpcommented, Nov 17, 2021

Codesandbox here

If you just render the <TestFlow /> element, the edges are aligned. If you render it within the Spectacle Components, the edges are misaligned.

image

2reactions
litewarpcommented, Nov 14, 2021

As an FYI, my workaround was just to recalculate the elements myself in a custom edge.

In order to get the correct edgePath, you could do something like the following:

import React from 'react'
import {
  EdgeProps,
  getSmoothStepPath,
  getMarkerEnd,
  useStoreState,
  Position,
  Node,
  XYPosition,
  getBezierPath
} from 'react-flow-renderer'

export type EdgeVariant = 'linear' | 'smoothstep' | 'bezier'

type CustomEdgeProps = EdgeProps<{
  label?: string
  variant: EdgeVariant
}>

type LinearEdgePathProps = {
  sourceX: number
  sourceY: number
  targetX: number
  targetY: number
}

type StepBezierEdgePathProps = LinearEdgePathProps & {
  sourcePosition: Position
  targetPosition: Position
}

type EdgePathCalculationProps = StepBezierEdgePathProps & {
  variant: EdgeVariant
}

// copied from 'rf src/container/EdgeRenderer/utils.ts'
const getHandlePosition = (
  position: Position,
  node: Node,
  handle: any | null = null
): XYPosition => {
  const x = (handle?.x || 0) + node.__rf.position.x
  const y = (handle?.y || 0) + node.__rf.position.y
  const width = handle?.width || node.__rf.width
  const height = handle?.height || node.__rf.height

  switch (position) {
    case Position.Top:
      return {
        x: x + width / 2,
        y
      }
    case Position.Right:
      return {
        x: x + width,
        y: y + height / 2
      }
    case Position.Bottom:
      return {
        x: x + width / 2,
        y: y + height
      }
    case Position.Left:
      return {
        x,
        y: y + height / 2
      }
  }
}

const getCustomEdgePath = ({
  variant,
  sourceX,
  sourceY,
  targetX,
  targetY,
  sourcePosition,
  targetPosition
}: EdgePathCalculationProps): string => {
  switch (variant) {
    case 'bezier':
      return getBezierPath({
        sourceX,
        sourceY,
        sourcePosition,
        targetX,
        targetY,
        targetPosition
      })
    case 'smoothstep':
      return getSmoothStepPath({
        sourceX,
        sourceY,
        sourcePosition,
        targetX,
        targetY,
        targetPosition
      })
    case 'linear':
      return `M ${sourceX},${sourceY}L ${targetX},${targetY}`
  }
}

const CustomEdge: React.FC<CustomEdgeProps> = ({
  id,
  style = {},
  sourcePosition,
  targetPosition,
  data,
  arrowHeadType,
  markerEndId,
  source,
  target
}) => {
  const nodes = useStoreState((state) => state.nodes)

  const sourceNode = nodes.find((node) => node.id === source)
  const sourceHandle = getHandlePosition(sourcePosition, sourceNode as Node, null)

  const targetNode = nodes.find((node) => node.id === target)
  const targetHandle = getHandlePosition(targetPosition, targetNode as Node, null)

  const markerEnd = getMarkerEnd(arrowHeadType, markerEndId)

  const edgePath = getCustomEdgePath({
    sourceX: sourceHandle.x,
    sourceY: sourceHandle.y,
    sourcePosition,
    targetX: targetHandle.x,
    targetY: targetHandle.y,
    targetPosition,
    variant: data?.variant ?? 'bezier'
  })

  return (
    <>
      <path
        id={id}
        style={style}
        className="react-flow__edge-path"
        d={edgePath}
        markerEnd={markerEnd}
      />
      {data?.label ? (
        <text>
          <textPath
            href={`#${id}`}
            style={{ fontSize: '12px' }}
            startOffset="50%"
            textAnchor="middle"
          >
            {data.label}
          </textPath>
        </text>
      ) : null}
    </>
  )
}

Read more comments on GitHub >

github_iconTop Results From Across the Web

Edge Not Scaling Properly - Microsoft Community
The youtube app, games and home screen are fine but when i launch edge it creates black bars around 2 inches thick all...
Read more >
CSS Transform Skew & Scale not working properly in ...
I'm having an issue with skew and/or scale transform property on Microsoft Edge. The transforms work perfect on IE, Chrome and FF, but...
Read more >
How to solve bevel problems in Blender - Artisticrender.com
The most common issue when beveling is that the bevel is not applied uniformly. In object mode hit "ctrl+a" and choose "scale" to...
Read more >
About aligning features—ArcMap | Documentation
ArcGIS provides several tools to help you align your data. ... so should not be used if you need fine-control over the resulting...
Read more >
Rotary Scales Alignment - MicroE Optical Encoders
Use a lint-free clean room wipe or cotton swab dampened with isopropyl alcohol or acetone only. Handle the scale by the edges. Do...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found