added parentLookup
This commit is contained in:
@@ -42,7 +42,7 @@ export function NodeWrapper<NodeType extends Node>({
|
|||||||
nodeOrigin,
|
nodeOrigin,
|
||||||
onError,
|
onError,
|
||||||
}: NodeWrapperProps<NodeType>) {
|
}: NodeWrapperProps<NodeType>) {
|
||||||
const { node, positionAbsoluteX, positionAbsoluteY, zIndex, isParent } = useStore((s) => {
|
const { node, positionAbsoluteX, positionAbsoluteY, internals } = useStore((s) => {
|
||||||
const node = s.nodeLookup.get(id)! as InternalNode<NodeType>;
|
const node = s.nodeLookup.get(id)! as InternalNode<NodeType>;
|
||||||
|
|
||||||
const positionAbsolute = nodeExtent
|
const positionAbsolute = nodeExtent
|
||||||
@@ -55,8 +55,9 @@ export function NodeWrapper<NodeType extends Node>({
|
|||||||
// so we we need to force a re-render when some change
|
// so we we need to force a re-render when some change
|
||||||
positionAbsoluteX: positionAbsolute.x,
|
positionAbsoluteX: positionAbsolute.x,
|
||||||
positionAbsoluteY: positionAbsolute.y,
|
positionAbsoluteY: positionAbsolute.y,
|
||||||
zIndex: node.internals.z,
|
internals: node.internals,
|
||||||
isParent: node.internals.isParent,
|
// zIndex: node.internals.z,
|
||||||
|
// isParent: node.internals.isParent,
|
||||||
};
|
};
|
||||||
}, shallow);
|
}, shallow);
|
||||||
|
|
||||||
@@ -213,14 +214,14 @@ export function NodeWrapper<NodeType extends Node>({
|
|||||||
{
|
{
|
||||||
selected: node.selected,
|
selected: node.selected,
|
||||||
selectable: isSelectable,
|
selectable: isSelectable,
|
||||||
parent: isParent,
|
parent: internals.isParent,
|
||||||
draggable: isDraggable,
|
draggable: isDraggable,
|
||||||
dragging,
|
dragging,
|
||||||
},
|
},
|
||||||
])}
|
])}
|
||||||
ref={nodeRef}
|
ref={nodeRef}
|
||||||
style={{
|
style={{
|
||||||
zIndex,
|
zIndex: internals.z,
|
||||||
transform: `translate(${positionAbsoluteOrigin.x}px,${positionAbsoluteOrigin.y}px)`,
|
transform: `translate(${positionAbsoluteOrigin.x}px,${positionAbsoluteOrigin.y}px)`,
|
||||||
pointerEvents: hasPointerEvents ? 'all' : 'none',
|
pointerEvents: hasPointerEvents ? 'all' : 'none',
|
||||||
visibility: initialized ? 'visible' : 'hidden',
|
visibility: initialized ? 'visible' : 'hidden',
|
||||||
@@ -254,7 +255,7 @@ export function NodeWrapper<NodeType extends Node>({
|
|||||||
targetPosition={node.targetPosition}
|
targetPosition={node.targetPosition}
|
||||||
dragging={dragging}
|
dragging={dragging}
|
||||||
dragHandle={node.dragHandle}
|
dragHandle={node.dragHandle}
|
||||||
zIndex={zIndex}
|
zIndex={internals.z}
|
||||||
{...nodeDimensions}
|
{...nodeDimensions}
|
||||||
/>
|
/>
|
||||||
</Provider>
|
</Provider>
|
||||||
|
|||||||
@@ -38,14 +38,14 @@ const createRFStore = ({
|
|||||||
(set, get) => ({
|
(set, get) => ({
|
||||||
...getInitialState({ nodes, edges, width, height, fitView, defaultNodes, defaultEdges }),
|
...getInitialState({ nodes, edges, width, height, fitView, defaultNodes, defaultEdges }),
|
||||||
setNodes: (nodes: Node[]) => {
|
setNodes: (nodes: Node[]) => {
|
||||||
const { nodeLookup, nodeOrigin, elevateNodesOnSelect } = get();
|
const { nodeLookup, parentLookup, nodeOrigin, elevateNodesOnSelect } = get();
|
||||||
// setNodes() is called exclusively in response to user actions:
|
// setNodes() is called exclusively in response to user actions:
|
||||||
// - either when the `<ReactFlow nodes>` prop is updated in the controlled ReactFlow setup,
|
// - either when the `<ReactFlow nodes>` prop is updated in the controlled ReactFlow setup,
|
||||||
// - or when the user calls something like `reactFlowInstance.setNodes()` in an uncontrolled ReactFlow setup.
|
// - or when the user calls something like `reactFlowInstance.setNodes()` in an uncontrolled ReactFlow setup.
|
||||||
//
|
//
|
||||||
// When this happens, we take the note objects passed by the user and extend them with fields
|
// When this happens, we take the note objects passed by the user and extend them with fields
|
||||||
// relevant for internal React Flow operations.
|
// relevant for internal React Flow operations.
|
||||||
adoptUserNodes(nodes, nodeLookup, { nodeOrigin, elevateNodesOnSelect });
|
adoptUserNodes(nodes, nodeLookup, parentLookup, { nodeOrigin, elevateNodesOnSelect });
|
||||||
|
|
||||||
set({ nodes });
|
set({ nodes });
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -29,13 +29,14 @@ const getInitialState = ({
|
|||||||
fitView?: boolean;
|
fitView?: boolean;
|
||||||
} = {}): ReactFlowStore => {
|
} = {}): ReactFlowStore => {
|
||||||
const nodeLookup = new Map();
|
const nodeLookup = new Map();
|
||||||
|
const parentLookup = new Map();
|
||||||
const connectionLookup = new Map();
|
const connectionLookup = new Map();
|
||||||
const edgeLookup = new Map();
|
const edgeLookup = new Map();
|
||||||
const storeEdges = defaultEdges ?? edges ?? [];
|
const storeEdges = defaultEdges ?? edges ?? [];
|
||||||
const storeNodes = defaultNodes ?? nodes ?? [];
|
const storeNodes = defaultNodes ?? nodes ?? [];
|
||||||
|
|
||||||
updateConnectionLookup(connectionLookup, edgeLookup, storeEdges);
|
updateConnectionLookup(connectionLookup, edgeLookup, storeEdges);
|
||||||
adoptUserNodes(storeNodes, nodeLookup, {
|
adoptUserNodes(storeNodes, nodeLookup, parentLookup, {
|
||||||
nodeOrigin: [0, 0],
|
nodeOrigin: [0, 0],
|
||||||
elevateNodesOnSelect: false,
|
elevateNodesOnSelect: false,
|
||||||
});
|
});
|
||||||
@@ -59,6 +60,7 @@ const getInitialState = ({
|
|||||||
transform,
|
transform,
|
||||||
nodes: storeNodes,
|
nodes: storeNodes,
|
||||||
nodeLookup,
|
nodeLookup,
|
||||||
|
parentLookup,
|
||||||
edges: storeEdges,
|
edges: storeEdges,
|
||||||
edgeLookup,
|
edgeLookup,
|
||||||
connectionLookup,
|
connectionLookup,
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ export type ReactFlowStore<NodeType extends Node = Node, EdgeType extends Edge =
|
|||||||
transform: Transform;
|
transform: Transform;
|
||||||
nodes: NodeType[];
|
nodes: NodeType[];
|
||||||
nodeLookup: NodeLookup<InternalNode<NodeType>>;
|
nodeLookup: NodeLookup<InternalNode<NodeType>>;
|
||||||
|
parentLookup: Map<string, InternalNode<NodeType>[]>;
|
||||||
edges: Edge[];
|
edges: Edge[];
|
||||||
edgeLookup: EdgeLookup<EdgeType>;
|
edgeLookup: EdgeLookup<EdgeType>;
|
||||||
connectionLookup: ConnectionLookup;
|
connectionLookup: ConnectionLookup;
|
||||||
|
|||||||
@@ -81,7 +81,8 @@ export const getInitialStore = ({
|
|||||||
fitView?: boolean;
|
fitView?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const nodeLookup: NodeLookup = new Map();
|
const nodeLookup: NodeLookup = new Map();
|
||||||
adoptUserNodes(nodes, nodeLookup, {
|
const parentLookup = new Map();
|
||||||
|
adoptUserNodes(nodes, nodeLookup, parentLookup, {
|
||||||
nodeOrigin: [0, 0],
|
nodeOrigin: [0, 0],
|
||||||
elevateNodesOnSelect: false,
|
elevateNodesOnSelect: false,
|
||||||
checkEquality: false
|
checkEquality: false
|
||||||
@@ -104,8 +105,9 @@ export const getInitialStore = ({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
flowId: writable<string | null>(null),
|
flowId: writable<string | null>(null),
|
||||||
nodes: createNodesStore(nodes, nodeLookup),
|
nodes: createNodesStore(nodes, nodeLookup, parentLookup),
|
||||||
nodeLookup: readable<NodeLookup<InternalNode>>(nodeLookup),
|
nodeLookup: readable<NodeLookup<InternalNode>>(nodeLookup),
|
||||||
|
parentLookup: readable<Map<string, InternalNode[]>>(parentLookup),
|
||||||
edgeLookup: readable<EdgeLookup<Edge>>(edgeLookup),
|
edgeLookup: readable<EdgeLookup<Edge>>(edgeLookup),
|
||||||
visibleNodes: readable<InternalNode[]>([]),
|
visibleNodes: readable<InternalNode[]>([]),
|
||||||
edges: createEdgesStore(edges, connectionLookup, edgeLookup),
|
edges: createEdgesStore(edges, connectionLookup, edgeLookup),
|
||||||
|
|||||||
@@ -127,7 +127,8 @@ export type NodeStoreOptions = {
|
|||||||
// The user only passes in relative positions, so we need to calculate the absolute positions based on the parent nodes.
|
// The user only passes in relative positions, so we need to calculate the absolute positions based on the parent nodes.
|
||||||
export const createNodesStore = (
|
export const createNodesStore = (
|
||||||
nodes: Node[],
|
nodes: Node[],
|
||||||
nodeLookup: NodeLookup<InternalNode>
|
nodeLookup: NodeLookup<InternalNode>,
|
||||||
|
parentLookup: Map<string, InternalNode[]>
|
||||||
): {
|
): {
|
||||||
subscribe: (this: void, run: Subscriber<Node[]>) => Unsubscriber;
|
subscribe: (this: void, run: Subscriber<Node[]>) => Unsubscriber;
|
||||||
update: (this: void, updater: Updater<Node[]>) => void;
|
update: (this: void, updater: Updater<Node[]>) => void;
|
||||||
@@ -141,7 +142,7 @@ export const createNodesStore = (
|
|||||||
let elevateNodesOnSelect = true;
|
let elevateNodesOnSelect = true;
|
||||||
|
|
||||||
const _set = (nds: Node[]): Node[] => {
|
const _set = (nds: Node[]): Node[] => {
|
||||||
adoptUserNodes(nds, nodeLookup, {
|
adoptUserNodes(nds, nodeLookup, parentLookup, {
|
||||||
elevateNodesOnSelect,
|
elevateNodesOnSelect,
|
||||||
defaults,
|
defaults,
|
||||||
checkEquality: false
|
checkEquality: false
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export function updateAbsolutePositions<NodeType extends NodeBase>(
|
|||||||
elevateNodesOnSelect: true,
|
elevateNodesOnSelect: true,
|
||||||
defaults: {},
|
defaults: {},
|
||||||
},
|
},
|
||||||
parentNodeIds?: Set<string>
|
parentLookup?: Map<string, InternalNodeBase<NodeType>[]>
|
||||||
) {
|
) {
|
||||||
const selectedNodeZ: number = options?.elevateNodesOnSelect ? 1000 : 0;
|
const selectedNodeZ: number = options?.elevateNodesOnSelect ? 1000 : 0;
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ export function updateAbsolutePositions<NodeType extends NodeBase>(
|
|||||||
throw new Error(`Parent node ${parentId} not found`);
|
throw new Error(`Parent node ${parentId} not found`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parentId || node.internals.isParent || parentNodeIds?.has(id)) {
|
if (parentId || node.internals.isParent || parentLookup?.has(id)) {
|
||||||
const parentNode = parentId ? nodeLookup.get(parentId) : null;
|
const parentNode = parentId ? nodeLookup.get(parentId) : null;
|
||||||
const { x, y, z } = calculateXYZPosition(
|
const { x, y, z } = calculateXYZPosition(
|
||||||
node,
|
node,
|
||||||
@@ -47,20 +47,21 @@ export function updateAbsolutePositions<NodeType extends NodeBase>(
|
|||||||
...node.position,
|
...node.position,
|
||||||
z: (isNumeric(node.zIndex) ? node.zIndex : 0) + (node.selected ? selectedNodeZ : 0),
|
z: (isNumeric(node.zIndex) ? node.zIndex : 0) + (node.selected ? selectedNodeZ : 0),
|
||||||
},
|
},
|
||||||
parentNode?.origin || options.nodeOrigin
|
parentNode?.origin ?? options.nodeOrigin
|
||||||
);
|
);
|
||||||
|
|
||||||
const currPosition = node.internals.positionAbsolute;
|
const currPosition = node.internals.positionAbsolute;
|
||||||
const positionChanged = x !== currPosition.x || y !== currPosition.y;
|
const positionChanged = x !== currPosition.x || y !== currPosition.y;
|
||||||
|
|
||||||
node.internals.positionAbsolute = positionChanged ? { x, y } : currPosition;
|
node.internals = {
|
||||||
node.internals.z = z;
|
...node.internals,
|
||||||
|
positionAbsolute: positionChanged ? { x, y } : currPosition,
|
||||||
|
z,
|
||||||
|
};
|
||||||
|
|
||||||
if (parentNodeIds !== undefined) {
|
if (parentLookup !== undefined) {
|
||||||
node.internals.isParent = !!parentNodeIds?.has(id);
|
node.internals.isParent = !!parentLookup.has(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeLookup.set(id, node);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,6 +76,7 @@ type UpdateNodesOptions<NodeType extends NodeBase> = {
|
|||||||
export function adoptUserNodes<NodeType extends NodeBase>(
|
export function adoptUserNodes<NodeType extends NodeBase>(
|
||||||
nodes: NodeType[],
|
nodes: NodeType[],
|
||||||
nodeLookup: Map<string, InternalNodeBase<NodeType>>,
|
nodeLookup: Map<string, InternalNodeBase<NodeType>>,
|
||||||
|
parentLookup: Map<string, InternalNodeBase<NodeType>[]>,
|
||||||
options: UpdateNodesOptions<NodeType> = {
|
options: UpdateNodesOptions<NodeType> = {
|
||||||
nodeOrigin: [0, 0] as NodeOrigin,
|
nodeOrigin: [0, 0] as NodeOrigin,
|
||||||
elevateNodesOnSelect: true,
|
elevateNodesOnSelect: true,
|
||||||
@@ -84,20 +86,19 @@ export function adoptUserNodes<NodeType extends NodeBase>(
|
|||||||
) {
|
) {
|
||||||
const tmpLookup = new Map(nodeLookup);
|
const tmpLookup = new Map(nodeLookup);
|
||||||
nodeLookup.clear();
|
nodeLookup.clear();
|
||||||
|
parentLookup.clear();
|
||||||
|
|
||||||
const selectedNodeZ: number = options?.elevateNodesOnSelect ? 1000 : 0;
|
const selectedNodeZ: number = options?.elevateNodesOnSelect ? 1000 : 0;
|
||||||
const parentNodeIds = new Set<string>();
|
// const parentNodeIds = new Set<string>();
|
||||||
|
|
||||||
nodes.forEach((userNode) => {
|
nodes.forEach((userNode) => {
|
||||||
const currentStoreNode = tmpLookup.get(userNode.id);
|
const currentStoreNode = tmpLookup.get(userNode.id);
|
||||||
|
|
||||||
if (userNode.parentId) {
|
let internalNode = currentStoreNode!;
|
||||||
parentNodeIds.add(userNode.parentId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.checkEquality && userNode === currentStoreNode?.internals.userNode) {
|
if (options.checkEquality && userNode === currentStoreNode?.internals.userNode) {
|
||||||
nodeLookup.set(userNode.id, currentStoreNode);
|
nodeLookup.set(userNode.id, currentStoreNode);
|
||||||
} else {
|
} else {
|
||||||
nodeLookup.set(userNode.id, {
|
internalNode = {
|
||||||
...options.defaults,
|
...options.defaults,
|
||||||
...userNode,
|
...userNode,
|
||||||
measured: {
|
measured: {
|
||||||
@@ -111,12 +112,22 @@ export function adoptUserNodes<NodeType extends NodeBase>(
|
|||||||
userNode,
|
userNode,
|
||||||
isParent: false,
|
isParent: false,
|
||||||
},
|
},
|
||||||
});
|
};
|
||||||
|
nodeLookup.set(userNode.id, internalNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userNode.parentId) {
|
||||||
|
const childNodes = parentLookup.get(userNode.parentId);
|
||||||
|
if (childNodes) {
|
||||||
|
childNodes.push(internalNode);
|
||||||
|
} else {
|
||||||
|
parentLookup.set(userNode.parentId, [internalNode]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (parentNodeIds.size > 0) {
|
if (parentLookup.size > 0) {
|
||||||
updateAbsolutePositions(nodeLookup, options, parentNodeIds);
|
updateAbsolutePositions(nodeLookup, options, parentLookup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user