feat(noderenderer): convert from flat to nested format internally
This commit is contained in:
@@ -44,14 +44,12 @@ interface NodesProps extends NodeRendererProps {
|
|||||||
parentId?: string;
|
parentId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface NodeProps extends NodesProps {
|
interface NodeProps extends Omit<NodesProps, 'nodes'> {
|
||||||
nodes: Node[];
|
|
||||||
node: Node;
|
node: Node;
|
||||||
nodeType: string;
|
nodeType: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Node({
|
function Node({
|
||||||
nodes,
|
|
||||||
node,
|
node,
|
||||||
nodeType,
|
nodeType,
|
||||||
isDraggable,
|
isDraggable,
|
||||||
@@ -79,7 +77,7 @@ function Node({
|
|||||||
typeof node.width !== 'undefined' &&
|
typeof node.width !== 'undefined' &&
|
||||||
typeof node.height !== 'undefined';
|
typeof node.height !== 'undefined';
|
||||||
|
|
||||||
const childNodes = useMemo(() => nodes.filter((n) => n.parentNode === node.id && !n.isHidden), [nodes, node.id]);
|
const { childNodes = [] } = node;
|
||||||
const childRect = useMemo(() => getRectOfNodes(childNodes), [childNodes]);
|
const childRect = useMemo(() => getRectOfNodes(childNodes), [childNodes]);
|
||||||
const isParentNode = !!childNodes.length;
|
const isParentNode = !!childNodes.length;
|
||||||
|
|
||||||
@@ -147,7 +145,6 @@ function Node({
|
|||||||
|
|
||||||
function Nodes({
|
function Nodes({
|
||||||
nodes,
|
nodes,
|
||||||
parentId,
|
|
||||||
isDraggable,
|
isDraggable,
|
||||||
resizeObserver,
|
resizeObserver,
|
||||||
scale,
|
scale,
|
||||||
@@ -159,12 +156,7 @@ function Nodes({
|
|||||||
recursionDepth,
|
recursionDepth,
|
||||||
...props
|
...props
|
||||||
}: NodesProps): any {
|
}: NodesProps): any {
|
||||||
const rootNodes = useMemo(
|
return nodes.map((node) => {
|
||||||
() => (parentId ? nodes.filter((n) => n.parentNode === parentId) : nodes.filter((n) => !n.parentNode)),
|
|
||||||
[nodes, parentId]
|
|
||||||
);
|
|
||||||
|
|
||||||
return rootNodes.map((node) => {
|
|
||||||
const nodeType = node.type || 'default';
|
const nodeType = node.type || 'default';
|
||||||
|
|
||||||
if (!props.nodeTypes[nodeType]) {
|
if (!props.nodeTypes[nodeType]) {
|
||||||
@@ -175,7 +167,6 @@ function Nodes({
|
|||||||
<Fragment key={node.id}>
|
<Fragment key={node.id}>
|
||||||
<Node
|
<Node
|
||||||
node={node}
|
node={node}
|
||||||
nodes={nodes}
|
|
||||||
nodeType={nodeType}
|
nodeType={nodeType}
|
||||||
parentId={node.id}
|
parentId={node.id}
|
||||||
snapToGrid={snapToGrid}
|
snapToGrid={snapToGrid}
|
||||||
@@ -188,19 +179,21 @@ function Nodes({
|
|||||||
recursionDepth={recursionDepth}
|
recursionDepth={recursionDepth}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
<MemoizedNodes
|
{node.childNodes && node.childNodes.length > 0 && (
|
||||||
nodes={nodes}
|
<MemoizedNodes
|
||||||
parentId={node.id}
|
nodes={node.childNodes}
|
||||||
snapToGrid={snapToGrid}
|
parentId={node.id}
|
||||||
snapGrid={snapGrid}
|
snapToGrid={snapToGrid}
|
||||||
nodesDraggable={nodesDraggable}
|
snapGrid={snapGrid}
|
||||||
nodesConnectable={nodesConnectable}
|
nodesDraggable={nodesDraggable}
|
||||||
resizeObserver={resizeObserver}
|
nodesConnectable={nodesConnectable}
|
||||||
elementsSelectable={elementsSelectable}
|
resizeObserver={resizeObserver}
|
||||||
scale={scale}
|
elementsSelectable={elementsSelectable}
|
||||||
recursionDepth={recursionDepth + 1}
|
scale={scale}
|
||||||
{...props}
|
recursionDepth={recursionDepth + 1}
|
||||||
/>
|
{...props}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,7 +2,26 @@ import { useCallback } from 'react';
|
|||||||
|
|
||||||
import { useStore } from '../store';
|
import { useStore } from '../store';
|
||||||
import { getNodesInside } from '../utils/graph';
|
import { getNodesInside } from '../utils/graph';
|
||||||
import { ReactFlowState } from '../types';
|
import { ReactFlowState, Node } from '../types';
|
||||||
|
|
||||||
|
function getChildNodes(nodes: Node[], parent?: Node): Node[] {
|
||||||
|
const children: Node[] = [];
|
||||||
|
const remaining: Node[] = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < nodes.length; i++) {
|
||||||
|
const n = nodes[i];
|
||||||
|
if ((!parent && !n.parentNode) || n.parentNode === parent?.id) {
|
||||||
|
children.push(n);
|
||||||
|
} else {
|
||||||
|
remaining.push(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return children.map((child) => {
|
||||||
|
child.childNodes = getChildNodes(remaining, child);
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function useVisibleNodes(onlyRenderVisible: boolean) {
|
function useVisibleNodes(onlyRenderVisible: boolean) {
|
||||||
const nodes = useStore(
|
const nodes = useStore(
|
||||||
@@ -16,7 +35,7 @@ function useVisibleNodes(onlyRenderVisible: boolean) {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
return nodes;
|
return getChildNodes(nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default useVisibleNodes;
|
export default useVisibleNodes;
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ export interface Node<T = any> {
|
|||||||
height?: number | null;
|
height?: number | null;
|
||||||
handleBounds?: NodeHandleBounds;
|
handleBounds?: NodeHandleBounds;
|
||||||
parentNode?: ElementId;
|
parentNode?: ElementId;
|
||||||
|
childNodes?: Node[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ArrowHeadType {
|
export enum ArrowHeadType {
|
||||||
|
|||||||
Reference in New Issue
Block a user