Skip to content

Commit 3aff262

Browse files
committed
refactor(minimap)!: use xy minimap instance (#1560)
* refactor(minimap)!: use xy minimap instance Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com> * chore(minimap): cleanup Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com> * chore(minimap): cleanup deps Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com> * chore(changeset): add Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com> * refactor(node-toolbar): replace `ViewportTransform` type Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com> * chore(node-toolbar): cleanup deps Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com> * chore(core): re-export Viewport type Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com> * chore(core): update system Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com> * chore(docs): cleanup dead links Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com> * chore(core): cleanup exports Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com> --------- Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com>
1 parent e5a3055 commit 3aff262

File tree

9 files changed

+84
-100
lines changed

9 files changed

+84
-100
lines changed

.changeset/seven-ads-wait.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@vue-flow/minimap": minor
3+
---
4+
5+
Replace d3 with xyflow minimap instance

docs/src/guide/vue-flow/config.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ const edges = ref([
498498

499499
### default-viewport (optional)
500500

501-
- Type: [`ViewportTransform`](/typedocs/interfaces/ViewportTransform)
501+
- Type: `Viewport`
502502

503503
- Default: `{ zoom: 1, position: { x: 0, y: 0 } }`
504504

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
"@vueuse/core": "^10.5.0",
7474
"d3-drag": "^3.0.0",
7575
"d3-selection": "^3.0.0",
76-
"@xyflow/system": "^0.0.36"
76+
"@xyflow/system": "^0.0.37"
7777
},
7878
"devDependencies": {
7979
"@rollup/plugin-replace": "^5.0.3",

packages/core/src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,6 @@ export { useKeyPress } from './composables/useKeyPress'
6767
export { VueFlowError, ErrorCode, isErrorOfType } from './utils/errors'
6868

6969
export * from './types'
70+
71+
// todo: add more re-exports
72+
export { type Viewport } from '@xyflow/system'

packages/minimap/package.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,12 @@
6161
"vue": "^3.3.0"
6262
},
6363
"dependencies": {
64-
"d3-selection": "^3.0.0",
65-
"d3-zoom": "^3.0.0"
64+
"@xyflow/system": "^0.0.37"
6665
},
6766
"devDependencies": {
6867
"@tooling/eslint-config": "workspace:*",
6968
"@tooling/tsconfig": "workspace:*",
7069
"@tooling/vite-config": "workspace:*",
71-
"@types/d3-selection": "^3.0.7",
72-
"@types/d3-zoom": "^3.0.5",
7370
"@vue-flow/core": "workspace:*",
7471
"vue-tsc": "^1.8.16"
7572
},

packages/minimap/src/MiniMap.vue

Lines changed: 51 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
<script lang="ts" setup>
2-
import type { CoordinateExtent, GraphNode, PanelPosition } from '@vue-flow/core'
2+
import type { GraphNode, PanelPosition } from '@vue-flow/core'
33
import { Panel, getBoundsOfRects, getConnectedEdges, getRectOfNodes, useVueFlow } from '@vue-flow/core'
4-
import { zoom, zoomIdentity } from 'd3-zoom'
5-
import type { D3ZoomEvent } from 'd3-zoom'
6-
import { pointer, select } from 'd3-selection'
7-
import { computed, provide, ref, toRef, useAttrs, watchEffect } from 'vue'
4+
import { computed, onMounted, onUnmounted, provide, ref, toRef, useAttrs, watch } from 'vue'
5+
import type { XYMinimapInstance } from '@xyflow/system'
6+
import { XYMinimap } from '@xyflow/system'
87
import type { MiniMapEmits, MiniMapNodeFunc, MiniMapProps, MiniMapSlots, ShapeRendering } from './types'
98
import MiniMapNode from './MiniMapNode.vue'
109
import { Slots } from './types'
@@ -39,10 +38,12 @@ const attrs: Record<string, any> = useAttrs()
3938
const defaultWidth = 200
4039
const defaultHeight = 150
4140
42-
const { id, edges, viewport, translateExtent, dimensions, emits, d3Selection, d3Zoom, getNodesInitialized } = useVueFlow()
41+
const { id, edges, viewport, translateExtent, dimensions, emits, panZoom, getNodesInitialized } = useVueFlow()
4342
4443
const el = ref<SVGElement>()
4544
45+
let minimapInstance: XYMinimapInstance | null = null
46+
4647
provide(Slots, slots)
4748
4849
const elementWidth = toRef(() => width ?? attrs.style?.width ?? defaultWidth)
@@ -116,64 +117,54 @@ const d = computed(() => {
116117
a${maskBorderRadius},${maskBorderRadius} 0 0 1 ${maskBorderRadius},-${maskBorderRadius}z`
117118
})
118119
119-
watchEffect(
120-
(onCleanup) => {
121-
if (el.value) {
122-
const selection = select(el.value as Element)
123-
124-
const zoomHandler = (event: D3ZoomEvent<SVGSVGElement, any>) => {
125-
if (event.sourceEvent.type !== 'wheel' || !d3Selection.value || !d3Zoom.value) {
126-
return
127-
}
128-
129-
const pinchDelta =
130-
-event.sourceEvent.deltaY *
131-
(event.sourceEvent.deltaMode === 1 ? 0.05 : event.sourceEvent.deltaMode ? 1 : 0.002) *
132-
zoomStep
133-
const zoom = viewport.value.zoom * 2 ** pinchDelta
134-
135-
d3Zoom.value.scaleTo(d3Selection.value, zoom)
120+
onMounted(() => {
121+
watch(
122+
panZoom,
123+
(panZoomInstance) => {
124+
if (el.value && panZoomInstance) {
125+
minimapInstance = XYMinimap({
126+
domNode: el.value,
127+
panZoom: panZoomInstance,
128+
getTransform: () => [viewport.value.x, viewport.value.y, viewport.value.zoom],
129+
getViewScale: () => viewScale.value,
130+
})
136131
}
137-
138-
const panHandler = (event: D3ZoomEvent<HTMLDivElement, any>) => {
139-
if (event.sourceEvent.type !== 'mousemove' || !d3Selection.value || !d3Zoom.value) {
140-
return
141-
}
142-
143-
const moveScale = viewScale.value * Math.max(1, viewport.value.zoom) * (inversePan ? -1 : 1)
144-
145-
const position = {
146-
x: viewport.value.x - event.sourceEvent.movementX * moveScale,
147-
y: viewport.value.y - event.sourceEvent.movementY * moveScale,
148-
}
149-
150-
const extent: CoordinateExtent = [
151-
[0, 0],
152-
[dimensions.value.width, dimensions.value.height],
153-
]
154-
155-
const nextTransform = zoomIdentity.translate(position.x, position.y).scale(viewport.value.zoom)
156-
const constrainedTransform = d3Zoom.value.constrain()(nextTransform, extent, translateExtent.value)
157-
158-
d3Zoom.value.transform(d3Selection.value, constrainedTransform)
159-
}
160-
161-
const zoomAndPanHandler = zoom()
162-
.on('zoom', pannable ? panHandler : () => {})
163-
.on('zoom.wheel', zoomable ? zoomHandler : () => {})
164-
165-
selection.call(zoomAndPanHandler)
166-
167-
onCleanup(() => {
168-
selection.on('zoom', null)
132+
},
133+
{ immediate: true },
134+
)
135+
136+
onUnmounted(() => {
137+
minimapInstance?.destroy()
138+
})
139+
140+
watch(
141+
[
142+
() => pannable,
143+
() => zoomable,
144+
() => inversePan,
145+
() => zoomStep,
146+
translateExtent,
147+
() => dimensions.value.height,
148+
() => dimensions.value.width,
149+
],
150+
() => {
151+
minimapInstance?.update({
152+
translateExtent: translateExtent.value,
153+
width: dimensions.value.width,
154+
height: dimensions.value.height,
155+
inversePan,
156+
pannable,
157+
zoomStep,
158+
zoomable,
169159
})
170-
}
171-
},
172-
{ flush: 'post' },
173-
)
160+
},
161+
{ immediate: true },
162+
)
163+
})
174164
175165
function onSvgClick(event: MouseEvent) {
176-
const [x, y] = pointer(event)
166+
const [x, y] = minimapInstance?.pointer(event) || [0, 0]
167+
177168
emit('click', { event, position: { x, y } })
178169
}
179170

packages/node-toolbar/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
"@tooling/tsconfig": "workspace:*",
4949
"@tooling/vite-config": "workspace:*",
5050
"@vue-flow/core": "workspace:*",
51+
"@xyflow/system": "^0.0.37",
5152
"vue-tsc": "^1.8.16"
5253
},
5354
"publishConfig": {

packages/node-toolbar/src/NodeToolbar.vue

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script lang="ts" setup>
22
import { computed, inject, toRef } from 'vue'
3-
import type { GraphNode, Rect, ViewportTransform } from '@vue-flow/core'
3+
import type { Viewport } from '@xyflow/system'
4+
import type { GraphNode, Rect } from '@vue-flow/core'
45
import { NodeIdInjection, Position, getRectOfNodes, useVueFlow } from '@vue-flow/core'
56
67
import type { CSSProperties } from 'vue'
@@ -46,7 +47,7 @@ const wrapperStyle = computed<CSSProperties>(() => ({
4647
zIndex: zIndex.value,
4748
}))
4849
49-
function getTransform(nodeRect: Rect, transform: ViewportTransform, position: Position, offset: number, align: Align): string {
50+
function getTransform(nodeRect: Rect, viewport: Viewport, position: Position, offset: number, align: Align): string {
5051
let alignmentOffset = 0.5
5152
5253
if (align === 'start') {
@@ -58,28 +59,28 @@ function getTransform(nodeRect: Rect, transform: ViewportTransform, position: Po
5859
// position === Position.Top
5960
// we set the x any y position of the toolbar based on the nodes position
6061
let pos = [
61-
(nodeRect.x + nodeRect.width * alignmentOffset) * transform.zoom + transform.x,
62-
nodeRect.y * transform.zoom + transform.y - offset,
62+
(nodeRect.x + nodeRect.width * alignmentOffset) * viewport.zoom + viewport.x,
63+
nodeRect.y * viewport.zoom + viewport.y - offset,
6364
]
6465
// and then shift it based on the alignment. The shift values are in %.
6566
let shift = [-100 * alignmentOffset, -100]
6667
6768
switch (position) {
6869
case Position.Right:
6970
pos = [
70-
(nodeRect.x + nodeRect.width) * transform.zoom + transform.x + offset,
71-
(nodeRect.y + nodeRect.height * alignmentOffset) * transform.zoom + transform.y,
71+
(nodeRect.x + nodeRect.width) * viewport.zoom + viewport.x + offset,
72+
(nodeRect.y + nodeRect.height * alignmentOffset) * viewport.zoom + viewport.y,
7273
]
7374
shift = [0, -100 * alignmentOffset]
7475
break
7576
case Position.Bottom:
76-
pos[1] = (nodeRect.y + nodeRect.height) * transform.zoom + transform.y + offset
77+
pos[1] = (nodeRect.y + nodeRect.height) * viewport.zoom + viewport.y + offset
7778
shift[1] = 0
7879
break
7980
case Position.Left:
8081
pos = [
81-
nodeRect.x * transform.zoom + transform.x - offset,
82-
(nodeRect.y + nodeRect.height * alignmentOffset) * transform.zoom + transform.y,
82+
nodeRect.x * viewport.zoom + viewport.x - offset,
83+
(nodeRect.y + nodeRect.height * alignmentOffset) * viewport.zoom + viewport.y,
8384
]
8485
shift = [-100, -100 * alignmentOffset]
8586
break

pnpm-lock.yaml

Lines changed: 11 additions & 25 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)