Skip to content

Commit 49bd8c9

Browse files
committed
refactor: GraphVisualizer - code optimization
1 parent 53120ca commit 49bd8c9

File tree

8 files changed

+77
-45
lines changed

8 files changed

+77
-45
lines changed

src/Shared/Components/GraphVisualizer/GraphVisualizer.tsx

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,12 @@ export const GraphVisualizer = ({
6868
if (!graphVisualizerRef.current || !reactFlowInstanceRef.current) return () => {}
6969

7070
const observer = new ResizeObserver((entries) => {
71+
let shouldPanOnScroll = false
7172
entries.forEach((entry) => {
7273
const { width } = entry.contentRect
73-
setPanOnScroll(reactFlowInstanceRef.current.getNodesBounds(nodes).width + PADDING_X * 2 > width)
74+
shouldPanOnScroll = reactFlowInstanceRef.current.getNodesBounds(nodes).width + PADDING_X * 2 > width
7475
})
76+
setPanOnScroll(shouldPanOnScroll)
7577
})
7678

7779
observer.observe(graphVisualizerRef.current)
@@ -84,22 +86,16 @@ export const GraphVisualizer = ({
8486
// METHODS
8587
const onNodesChange: OnNodesChange<GraphVisualizerExtendedNode> = (changes) => {
8688
setNodes((nds) =>
87-
applyNodeChanges(changes, processNodes(nds, edges)).map((node) => {
88-
const _node = node
89-
delete _node.position
90-
return _node
91-
}),
89+
applyNodeChanges(changes, processNodes(nds, edges)).map(
90+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
91+
({ position, ...node }) => node,
92+
),
9293
)
9394
}
9495

9596
const onEdgesChange: OnEdgesChange = (changes) => {
96-
setEdges((eds) =>
97-
applyEdgeChanges(changes, processEdges(eds)).map((edge) => {
98-
const _edge = edge
99-
delete _edge.type
100-
return _edge
101-
}),
102-
)
97+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
98+
setEdges((eds) => applyEdgeChanges(changes, processEdges(eds)).map(({ type, ...edge }) => edge))
10399
}
104100

105101
const onViewportChange = (updatedViewport: Viewport) => {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { useMemo } from 'react'
2+
import { Handle, Position, useEdges } from '@xyflow/react'
3+
4+
import { BaseNodeProps } from './types'
5+
6+
export const BaseNode = ({ id, className, isConnectable, children }: BaseNodeProps) => {
7+
const edges = useEdges()
8+
9+
const { hasSource, hasTarget } = useMemo(
10+
() => ({
11+
hasSource: edges.some(({ source }) => source === id),
12+
hasTarget: edges.some(({ target }) => target === id),
13+
}),
14+
[edges],
15+
)
16+
17+
return (
18+
<div className={className}>
19+
{children}
20+
{hasSource && <Handle type="source" position={Position.Right} isConnectable={isConnectable} />}
21+
{hasTarget && <Handle type="target" position={Position.Left} isConnectable={isConnectable} />}
22+
</div>
23+
)
24+
}
Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
1-
import { Handle, NodeProps, Position, useEdges } from '@xyflow/react'
1+
import { NodeProps } from '@xyflow/react'
22

33
import { ComponentSizeType } from '@Shared/constants'
44

55
import { SelectPicker, SelectPickerVariantType } from '../../SelectPicker'
66
import { DropdownNodeProps } from './types'
7+
import { BaseNode } from './BaseNode'
78

89
export const DropdownNode = ({ id, data, isConnectable }: NodeProps<DropdownNodeProps>) => {
910
const { isError, ...restData } = data
10-
const edges = useEdges()
11-
12-
const hasSource = edges.some(({ source }) => source === id)
13-
const hasTarget = edges.some(({ target }) => target === id)
1411

1512
return (
16-
<div className={`bg__primary border__primary br-6 dc__inline-flex w-180 ${isError ? 'er-5' : ''}`}>
13+
<BaseNode
14+
id={id}
15+
className={`bg__primary border__primary br-6 dc__inline-flex w-180 ${isError ? 'er-5' : ''}`}
16+
isConnectable={isConnectable}
17+
>
1718
<SelectPicker<string | number, false>
1819
{...restData}
1920
classNamePrefix="graph-visualizer-dropdown-node"
@@ -22,8 +23,6 @@ export const DropdownNode = ({ id, data, isConnectable }: NodeProps<DropdownNode
2223
menuSize={ComponentSizeType.xs}
2324
fullWidth
2425
/>
25-
{hasSource && <Handle type="source" position={Position.Right} isConnectable={isConnectable} />}
26-
{hasTarget && <Handle type="target" position={Position.Left} isConnectable={isConnectable} />}
27-
</div>
26+
</BaseNode>
2827
)
2928
}
Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
1-
import { Handle, NodeProps, Position, useEdges } from '@xyflow/react'
1+
import { NodeProps } from '@xyflow/react'
22

33
import { IconNodeProps } from './types'
4+
import { BaseNode } from './BaseNode'
45

56
export const IconNode = ({ data, id, isConnectable }: NodeProps<IconNodeProps>) => {
67
const { icon } = data
7-
const edges = useEdges()
8-
9-
const hasSource = edges.some(({ source }) => source === id)
10-
const hasTarget = edges.some(({ target }) => target === id)
118

129
return (
13-
<div className="bg__primary border__primary br-6 dc__inline-flex p-7">
10+
<BaseNode
11+
id={id}
12+
isConnectable={isConnectable}
13+
className="bg__primary border__primary br-6 dc__inline-flex p-7"
14+
>
1415
<span className="dc__no-shrink flex dc__fill-available-space icon-dim-20">{icon}</span>
15-
{hasSource && <Handle type="source" position={Position.Right} isConnectable={isConnectable} />}
16-
{hasTarget && <Handle type="target" position={Position.Left} isConnectable={isConnectable} />}
17-
</div>
16+
</BaseNode>
1817
)
1918
}
Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,23 @@
1-
import { Handle, NodeProps, Position, useEdges } from '@xyflow/react'
1+
import { NodeProps } from '@xyflow/react'
22

33
import { Tooltip } from '@Common/Tooltip'
44

55
import { TextNodeProps } from './types'
6+
import { BaseNode } from './BaseNode'
67

78
export const TextNode = ({ id, data, isConnectable }: NodeProps<TextNodeProps>) => {
89
const { icon, text } = data
9-
const edges = useEdges()
10-
11-
const hasSource = edges.some(({ source }) => source === id)
12-
const hasTarget = edges.some(({ target }) => target === id)
1310

1411
return (
15-
<div className="bg__primary border__primary br-6 p-7 dc__inline-flex dc__align-items-center dc__gap-8 w-180">
12+
<BaseNode
13+
id={id}
14+
className="bg__primary border__primary br-6 p-7 dc__inline-flex dc__align-items-center dc__gap-8 w-180"
15+
isConnectable={isConnectable}
16+
>
1617
{!!icon && <span className="dc__no-shrink flex dc__fill-available-space icon-dim-20">{icon}</span>}
1718
<Tooltip content={text}>
18-
<p className="m-0 fs-12 lh-20 fw-6 cn-9 dc__ellipsis-right">{text}</p>
19+
<p className="m-0 fs-12 lh-20 fw-6 cn-9 dc__truncate">{text}</p>
1920
</Tooltip>
20-
{hasSource && <Handle type="source" position={Position.Right} isConnectable={isConnectable} />}
21-
{hasTarget && <Handle type="target" position={Position.Left} isConnectable={isConnectable} />}
22-
</div>
21+
</BaseNode>
2322
)
2423
}

src/Shared/Components/GraphVisualizer/components/types.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
1-
import { ReactElement } from 'react'
1+
import { ReactElement, ReactNode } from 'react'
22
import { Node } from '@xyflow/react'
33

44
import { SelectPickerProps } from '../../SelectPicker'
55

6+
export interface BaseNodeProps {
7+
id: string
8+
className?: string
9+
isConnectable: boolean
10+
children: ReactNode
11+
}
12+
613
export type IconNodeProps = Node<
714
{
815
icon: ReactElement

src/Shared/Components/GraphVisualizer/styles.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
// REACT FLOW
2+
.graph-visualizer {
3+
.react-flow {
4+
--xy-edge-stroke-default: var(--N200);
5+
--xy-background-color-default: var(--bg-secondary);
6+
}
7+
}
8+
19
.graph-visualizer-dropdown-node {
210
&__control {
311
gap: 8px !important;

src/Shared/Components/GraphVisualizer/utils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Edge, MarkerType } from '@xyflow/react'
1+
import { Edge, MarkerType, Viewport } from '@xyflow/react'
22

33
import { NODE_GAP_X, NODE_GAP_Y, NODE_HEIGHT_MAP, NODE_WIDTH_MAP } from './constants'
44
import { GraphVisualizerExtendedNode, GraphVisualizerNode, GraphVisualizerProps } from './types'
@@ -53,7 +53,7 @@ const placeNode = (
5353
nodeId: string,
5454
x: number,
5555
y: number,
56-
positions: Record<string, { x: number; y: number }>,
56+
positions: Record<string, Pick<Viewport, 'x' | 'y'>>,
5757
childrenMap: Map<string, string[]>,
5858
nodeMap: Map<string, GraphVisualizerNode>,
5959
) => {
@@ -93,7 +93,7 @@ const placeNode = (
9393

9494
const calculateNodePositions = (nodes: GraphVisualizerProps['nodes'], edges: GraphVisualizerProps['edges']) => {
9595
// Store calculated positions for each node
96-
const positions: Record<string, { x: number; y: number }> = {}
96+
const positions: Record<string, Pick<Viewport, 'x' | 'y'>> = {}
9797

9898
// Map to store parent-child relationships
9999
const childrenMap = new Map<string, string[]>()

0 commit comments

Comments
 (0)