diff --git a/examples/react/src/examples/CustomMiniMapNode/index.tsx b/examples/react/src/examples/CustomMiniMapNode/index.tsx index 21b1d073..1bb0f39b 100644 --- a/examples/react/src/examples/CustomMiniMapNode/index.tsx +++ b/examples/react/src/examples/CustomMiniMapNode/index.tsx @@ -1,4 +1,4 @@ -import { MouseEvent, CSSProperties, useCallback } from 'react'; +import { MouseEvent, CSSProperties, useCallback, useState } from 'react'; import { ReactFlow, @@ -14,19 +14,13 @@ import { ReactFlowInstance, useEdgesState, useNodesState, + Panel, } from '@xyflow/react'; const onInit = (reactFlowInstance: ReactFlowInstance) => console.log('flow loaded:', reactFlowInstance); const onNodeClick = (_: MouseEvent, node: Node) => console.log('click', node); const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node); -const buttonStyle: CSSProperties = { - position: 'absolute', - left: 10, - top: 10, - zIndex: 4, -}; - const CustomMiniMapNode = ({ x, y, width, height }: MiniMapNodeProps) => { return ; }; @@ -34,6 +28,7 @@ const CustomMiniMapNode = ({ x, y, width, height }: MiniMapNodeProps) => { const CustomMiniMapNodeFlow = () => { const [nodes, setNodes, onNodesChange] = useNodesState([]); const [edges, setEdges, onEdgesChange] = useEdgesState([]); + const [hideAllNodes, setHideAllNodes] = useState(false); const onConnect = useCallback((params: Connection | Edge) => setEdges((els) => addEdge(params, els)), [setEdges]); const addRandomNode = () => { @@ -45,10 +40,17 @@ const CustomMiniMapNodeFlow = () => { x: Math.random() * window.innerWidth, y: Math.random() * window.innerHeight, }, + hidden: hideAllNodes, }; setNodes((nds) => nds.concat(newNode)); }; + const toggleHideAllNodes = () => { + setHideAllNodes(!hideAllNodes); + setNodes((nds) => nds.map((n) => ({ ...n, hidden: hideAllNodes }))); + setEdges((eds) => eds.map((e) => ({ ...e, hidden: hideAllNodes }))); + }; + return ( { - + + + + ); }; diff --git a/examples/svelte/src/components/Header/Header.svelte b/examples/svelte/src/components/Header/Header.svelte index 0ebe84e9..c03eef13 100644 --- a/examples/svelte/src/components/Header/Header.svelte +++ b/examples/svelte/src/components/Header/Header.svelte @@ -17,6 +17,7 @@ 'handle-connect', 'interaction', 'intersections', + 'minimap-bug', 'node-toolbar', 'node-resizer', 'overview', diff --git a/examples/svelte/src/routes/examples/custom-minimap/+page.svelte b/examples/svelte/src/routes/examples/custom-minimap/+page.svelte index 1e9c96ca..0a0c734c 100644 --- a/examples/svelte/src/routes/examples/custom-minimap/+page.svelte +++ b/examples/svelte/src/routes/examples/custom-minimap/+page.svelte @@ -4,15 +4,17 @@ Background, Controls, MiniMap, + Panel, type Node, - type Edge, + type Edge } from '@xyflow/svelte'; - + import '@xyflow/svelte/dist/style.css'; import CustomMiniMapNode from './CustomMiniMapNode.svelte'; let nodes = $state.raw([]); let edges = $state.raw([]); + let hideAllNodes = $state(false); function addRandomNode() { const nodeId = (nodes.length + 1).toString(); @@ -21,28 +23,33 @@ data: { label: `Node: ${nodeId}` }, position: { x: Math.random() * (typeof window !== 'undefined' ? window.innerWidth : 800), - y: Math.random() * (typeof window !== 'undefined' ? window.innerHeight : 600), + y: Math.random() * (typeof window !== 'undefined' ? window.innerHeight : 600) }, - type: 'default' + type: 'default', + hidden: hideAllNodes }; nodes = [...nodes, newNode]; } + + function toggleHideAllNodes() { + hideAllNodes = !hideAllNodes; + nodes = nodes.map((node) => ({ + ...node, + hidden: hideAllNodes + })); + } - + - + + + + + diff --git a/packages/svelte/src/lib/plugins/Minimap/Minimap.svelte b/packages/svelte/src/lib/plugins/Minimap/Minimap.svelte index 04bb982a..6748dc47 100644 --- a/packages/svelte/src/lib/plugins/Minimap/Minimap.svelte +++ b/packages/svelte/src/lib/plugins/Minimap/Minimap.svelte @@ -61,16 +61,19 @@ height: store.height / store.viewport.zoom }); - const hasVisibleNodes = $derived(store.nodeLookup.size > 0 && store.nodes.some((n) => !n.hidden)); + // let boundingRect = $derived( + // store.nodeLookup.size > 0 && store.nodes.some((n) => !n.hidden) + // ? getBoundsOfRects( + // getInternalNodesBounds(store.nodeLookup, { filter: (n) => !n.hidden }), + // viewBB + // ) + // : viewBB + // ); let boundingRect = $derived( - hasVisibleNodes - ? getBoundsOfRects( - getInternalNodesBounds(store.nodeLookup, { filter: (n) => !n.hidden }), - viewBB - ) - : viewBB + getBoundsOfRects(getInternalNodesBounds(store.nodeLookup, { filter: (n) => !n.hidden }), viewBB) ); + let scaledWidth = $derived(boundingRect.width / width); let scaledHeight = $derived(boundingRect.height / height); let viewScale = $derived(Math.max(scaledWidth, scaledHeight)); @@ -124,7 +127,7 @@ {#each store.nodes as userNode (userNode.id)} {@const node = store.nodeLookup.get(userNode.id)} - {#if node && nodeHasDimensions(node)} + {#if node && nodeHasDimensions(node) && !node.hidden} {@const nodeDimesions = getNodeDimensions(node)} , params: GetInternalNodesBoundsParams = {} ): Rect => { + const emptyRect = { x: 0, y: 0, width: 0, height: 0 }; + if (nodeLookup.size === 0) { - return { x: 0, y: 0, width: 0, height: 0 }; + return emptyRect; } let box = { x: Infinity, y: Infinity, x2: -Infinity, y2: -Infinity }; + let hasVisibleNodes = false; + nodeLookup.forEach((node) => { if (params.filter === undefined || params.filter(node)) { + hasVisibleNodes = true; const nodeBox = nodeToBox(node as InternalNodeBase); box = getBoundsOfBoxes(box, nodeBox); } }); - return boxToRect(box); + return hasVisibleNodes ? boxToRect(box) : emptyRect; }; export const getNodesInside = (