chore(examples): add overview, cleanup

This commit is contained in:
moklick
2021-12-17 10:43:53 +01:00
parent 3b25086149
commit 3206d49c15
10 changed files with 36 additions and 380 deletions
-98
View File
@@ -1,98 +0,0 @@
import React, { useState, MouseEvent } from 'react';
import ReactFlow, {
removeElements,
addEdge,
isNode,
Background,
Elements,
BackgroundVariant,
FlowElement,
Node,
Edge,
Connection,
OnLoadParams,
} from 'react-flow-renderer';
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
const onElementClick = (_: MouseEvent, element: FlowElement) => console.log('click', element);
const initialNodes: Node[] = [
{ id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 }, className: 'light' },
{ id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 100 }, className: 'light' },
{ id: '3', data: { label: 'Node 3' }, position: { x: 400, y: 100 }, className: 'light' },
{ id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 200 }, className: 'light' },
];
const initialEdges: Edge[] = [
{ id: 'e1-2', source: '1', target: '2', animated: true },
{ id: 'e1-3', source: '1', target: '3' },
];
const BasicFlow = () => {
const [rfInstance, setRfInstance] = useState<OnLoadParams | null>(null);
const [nodes, setNodes] = useState<Node[]>(initialNodes);
const [edges, setEdges] = useState<Edge[]>(initialEdges);
// const onElementsRemove = (elementsToRemove: Elements) => setNodes((els) => removeElements(elementsToRemove, els));
// const onConnect = (params: Edge | Connection) => setNodes((els) => addEdge(params, els));
const onLoad = (reactFlowInstance: OnLoadParams) => setRfInstance(reactFlowInstance);
const updatePos = () => {
setNodes((nds) => {
return nds.map((n) => {
n.position = {
x: Math.random() * 400,
y: Math.random() * 400,
};
return n;
});
});
};
const logToObject = () => console.log(rfInstance?.toObject());
const resetTransform = () => rfInstance?.setTransform({ x: 0, y: 0, zoom: 1 });
const toggleClassnames = () => {
setNodes((nds) => {
return nds.map((n) => {
n.className = n.className === 'light' ? 'dark' : 'light';
return n;
});
});
};
return (
<ReactFlow
nodes={nodes}
edges={edges}
onLoad={onLoad}
onElementClick={onElementClick}
// onElementsRemove={onElementsRemove}
// onConnect={onConnect}
onNodeDragStop={onNodeDragStop}
className="react-flow-basic-example"
defaultZoom={1.5}
minZoom={0.2}
maxZoom={4}
>
<Background variant={BackgroundVariant.Lines} />
<div style={{ position: 'absolute', right: 10, top: 10, zIndex: 4 }}>
<button onClick={resetTransform} style={{ marginRight: 5 }}>
reset transform
</button>
<button onClick={updatePos} style={{ marginRight: 5 }}>
change pos
</button>
<button onClick={toggleClassnames} style={{ marginRight: 5 }}>
toggle classnames
</button>
<button onClick={logToObject}>toObject</button>
</div>
</ReactFlow>
);
};
export default BasicFlow;
@@ -1,25 +0,0 @@
import React, { memo, FC, CSSProperties } from 'react';
import { Handle, Position, NodeProps, Connection, Edge } from 'react-flow-renderer';
const targetHandleStyle: CSSProperties = { background: '#555' };
const sourceHandleStyleA: CSSProperties = { ...targetHandleStyle, top: 10 };
const sourceHandleStyleB: CSSProperties = { ...targetHandleStyle, bottom: 10, top: 'auto' };
const onConnect = (params: Connection | Edge) => console.log('handle onConnect', params);
const ColorSelectorNode: FC<NodeProps> = ({ data, isConnectable }) => {
return (
<>
<Handle type="target" position={Position.Left} style={targetHandleStyle} onConnect={onConnect} />
<div>
Custom Color Picker Node: <strong>{data.color}</strong>
</div>
<input className="nodrag" type="color" onChange={data.onChange} defaultValue={data.color} />
<Handle type="source" position={Position.Right} id="a" style={sourceHandleStyleA} isConnectable={isConnectable} />
<Handle type="source" position={Position.Right} id="b" style={sourceHandleStyleB} isConnectable={isConnectable} />
</>
);
};
export default memo(ColorSelectorNode);
-135
View File
@@ -1,135 +0,0 @@
import React, { useState, useEffect, MouseEvent } from 'react';
import { ChangeEvent } from 'react';
import ReactFlow, {
isEdge,
removeElements,
addEdge,
MiniMap,
Controls,
Node,
FlowElement,
OnLoadParams,
Elements,
Position,
SnapGrid,
Connection,
Edge,
} from 'react-flow-renderer';
import ColorSelectorNode from './ColorSelectorNode';
const onLoad = (reactFlowInstance: OnLoadParams) => console.log('flow loaded:', reactFlowInstance);
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
const onElementClick = (_: MouseEvent, element: FlowElement) => console.log('click', element);
const initBgColor = '#1A192B';
const connectionLineStyle = { stroke: '#fff' };
const snapGrid: SnapGrid = [16, 16];
const nodeTypes = {
selectorNode: ColorSelectorNode,
};
const CustomNodeFlow = () => {
const [elements, setElements] = useState<Elements>([]);
const [bgColor, setBgColor] = useState<string>(initBgColor);
useEffect(() => {
const onChange = (event: ChangeEvent<HTMLInputElement>) => {
setElements((els) =>
els.map((e) => {
if (isEdge(e) || e.id !== '2') {
return e;
}
const color = event.target.value;
setBgColor(color);
return {
...e,
data: {
...e.data,
color,
},
};
})
);
};
setElements([
{
id: '1',
type: 'input',
data: { label: 'An input node' },
position: { x: 0, y: 50 },
sourcePosition: Position.Right,
},
{
id: '2',
type: 'selectorNode',
data: { onChange: onChange, color: initBgColor },
style: { border: '1px solid #777', padding: 10 },
position: { x: 250, y: 50 },
},
{
id: '3',
type: 'output',
data: { label: 'Output A' },
position: { x: 550, y: 25 },
targetPosition: Position.Left,
},
{
id: '4',
type: 'output',
data: { label: 'Output B' },
position: { x: 550, y: 100 },
targetPosition: Position.Left,
},
{ id: 'e1-2', source: '1', target: '2', animated: true, style: { stroke: '#fff' } },
{ id: 'e2a-3', source: '2', sourceHandle: 'a', target: '3', animated: true, style: { stroke: '#fff' } },
{ id: 'e2b-4', source: '2', sourceHandle: 'b', target: '4', animated: true, style: { stroke: '#fff' } },
]);
}, []);
const onElementsRemove = (elementsToRemove: Elements) => setElements((els) => removeElements(elementsToRemove, els));
const onConnect = (params: Connection | Edge) =>
setElements((els) => addEdge({ ...params, animated: true, style: { stroke: '#fff' } }, els));
return (
<ReactFlow
elements={elements}
onElementClick={onElementClick}
onElementsRemove={onElementsRemove}
onConnect={onConnect}
onNodeDragStop={onNodeDragStop}
style={{ background: bgColor }}
onLoad={onLoad}
nodeTypes={nodeTypes}
connectionLineStyle={connectionLineStyle}
snapToGrid={true}
snapGrid={snapGrid}
defaultZoom={1.5}
>
<MiniMap
nodeStrokeColor={(n: Node): string => {
if (n.type === 'input') return '#0041d0';
if (n.type === 'selectorNode') return bgColor;
if (n.type === 'output') return '#ff0072';
return '#eee';
}}
nodeColor={(n: Node): string => {
if (n.type === 'selectorNode') return bgColor;
return '#fff';
}}
/>
<Controls />
</ReactFlow>
);
};
export default CustomNodeFlow;
-201
View File
@@ -1,201 +0,0 @@
import React, { useState, MouseEvent, CSSProperties } from 'react';
import ReactFlow, {
removeElements,
addEdge,
MiniMap,
Controls,
Background,
isNode,
Node,
Elements,
FlowElement,
OnLoadParams,
FlowTransform,
SnapGrid,
Connection,
Edge,
} from 'react-flow-renderer';
const onNodeDragStart = (_: MouseEvent, node: Node) => console.log('drag start', node);
const onNodeDrag = (_: MouseEvent, node: Node) => console.log('drag', node);
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
const onNodeDoubleClick = (_: MouseEvent, node: Node) => console.log('node double click', node);
const onPaneClick = (event: MouseEvent) => console.log('pane click', event);
const onPaneScroll = (event?: MouseEvent) => console.log('pane scroll', event);
const onPaneContextMenu = (event: MouseEvent) => console.log('pane context menu', event);
const onSelectionDrag = (_: MouseEvent, nodes: Node[]) => console.log('selection drag', nodes);
const onSelectionDragStart = (_: MouseEvent, nodes: Node[]) => console.log('selection drag start', nodes);
const onSelectionDragStop = (_: MouseEvent, nodes: Node[]) => console.log('selection drag stop', nodes);
const onSelectionContextMenu = (event: MouseEvent, nodes: Node[]) => {
event.preventDefault();
console.log('selection context menu', nodes);
};
const onElementClick = (_: MouseEvent, element: FlowElement) =>
console.log(`${isNode(element) ? 'node' : 'edge'} click:`, element);
const onSelectionChange = (elements: Elements | null) => console.log('selection change', elements);
const onLoad = (reactFlowInstance: OnLoadParams) => {
console.log('flow loaded:', reactFlowInstance);
reactFlowInstance.fitView();
};
const onMoveStart = (transform?: FlowTransform) => console.log('zoom/move start', transform);
const onMoveEnd = (transform?: FlowTransform) => console.log('zoom/move end', transform);
const onEdgeContextMenu = (_: MouseEvent, edge: Edge) => console.log('edge context menu', edge);
const onEdgeMouseEnter = (_: MouseEvent, edge: Edge) => console.log('edge mouse enter', edge);
const onEdgeMouseMove = (_: MouseEvent, edge: Edge) => console.log('edge mouse move', edge);
const onEdgeMouseLeave = (_: MouseEvent, edge: Edge) => console.log('edge mouse leave', edge);
const onEdgeDoubleClick = (_: MouseEvent, edge: Edge) => console.log('edge double click', edge);
const initialElements: Elements = [
{
id: '1',
type: 'input',
data: {
label: (
<>
Welcome to <strong>React Flow!</strong>
</>
),
},
position: { x: 250, y: 0 },
},
{
id: '2',
data: {
label: (
<>
This is a <strong>default node</strong>
</>
),
},
position: { x: 100, y: 100 },
},
{
id: '3',
data: {
label: (
<>
This one has a <strong>custom style</strong>
</>
),
},
position: { x: 400, y: 100 },
style: { background: '#D6D5E6', color: '#333', border: '1px solid #222138', width: 180 },
},
{
id: '4',
position: { x: 250, y: 200 },
data: {
label: (
<>
You can find the docs on{' '}
<a href="https://github.com/wbkd/react-flow" target="_blank" rel="noopener noreferrer">
Github
</a>
</>
),
},
},
{
id: '5',
data: {
label: (
<>
Or check out the other <strong>examples</strong>
</>
),
},
position: { x: 250, y: 325 },
},
{
id: '6',
type: 'output',
data: {
label: (
<>
An <strong>output node</strong>
</>
),
},
position: { x: 100, y: 480 },
},
{ id: '7', type: 'output', data: { label: 'Another output node' }, position: { x: 400, y: 450 } },
{ id: 'e1-2', source: '1', target: '2', label: 'this is an edge label' },
{ id: 'e1-3', source: '1', target: '3' },
{ id: 'e3-4', source: '3', target: '4', animated: true, label: 'animated edge' },
{ id: 'e4-5', source: '4', target: '5', label: 'edge with arrow head' },
{ id: 'e5-6', source: '5', target: '6', type: 'smoothstep', label: 'smooth step edge' },
{
id: 'e5-7',
source: '5',
target: '7',
type: 'step',
style: { stroke: '#f6ab6c' },
label: 'a step edge',
animated: true,
labelStyle: { fill: '#f6ab6c', fontWeight: 700 },
},
];
const connectionLineStyle: CSSProperties = { stroke: '#ddd' };
const snapGrid: SnapGrid = [16, 16];
const nodeStrokeColor = (n: Node): string => {
if (n.style?.background) return n.style.background as string;
if (n.type === 'input') return '#0041d0';
if (n.type === 'output') return '#ff0072';
if (n.type === 'default') return '#1a192b';
return '#eee';
};
const nodeColor = (n: Node): string => {
if (n.style?.background) return n.style.background as string;
return '#fff';
};
const OverviewFlow = () => {
const [elements, setElements] = useState(initialElements);
const onElementsRemove = (elementsToRemove: Elements) => setElements((els) => removeElements(elementsToRemove, els));
const onConnect = (params: Connection | Edge) => setElements((els) => addEdge(params, els));
return (
<ReactFlow
elements={elements}
onElementClick={onElementClick}
onElementsRemove={onElementsRemove}
onConnect={onConnect}
onPaneClick={onPaneClick}
onPaneScroll={onPaneScroll}
onPaneContextMenu={onPaneContextMenu}
onNodeDragStart={onNodeDragStart}
onNodeDrag={onNodeDrag}
onNodeDragStop={onNodeDragStop}
onNodeDoubleClick={onNodeDoubleClick}
onSelectionDragStart={onSelectionDragStart}
onSelectionDrag={onSelectionDrag}
onSelectionDragStop={onSelectionDragStop}
onSelectionContextMenu={onSelectionContextMenu}
onSelectionChange={onSelectionChange}
onMoveStart={onMoveStart}
onMoveEnd={onMoveEnd}
onLoad={onLoad}
connectionLineStyle={connectionLineStyle}
snapToGrid={true}
snapGrid={snapGrid}
onEdgeContextMenu={onEdgeContextMenu}
onEdgeMouseEnter={onEdgeMouseEnter}
onEdgeMouseMove={onEdgeMouseMove}
onEdgeMouseLeave={onEdgeMouseLeave}
onEdgeDoubleClick={onEdgeDoubleClick}
>
<MiniMap nodeStrokeColor={nodeStrokeColor} nodeColor={nodeColor} nodeBorderRadius={2} />
<Controls />
<Background color="#aaa" gap={20} />
</ReactFlow>
);
};
export default OverviewFlow;
-70
View File
@@ -1,70 +0,0 @@
import React, { useState, CSSProperties } from 'react';
import ReactFlow, {
removeElements,
addEdge,
MiniMap,
isNode,
Controls,
Background,
OnLoadParams,
Elements,
Connection,
Edge,
} from 'react-flow-renderer';
import { getElements } from './utils';
const buttonWrapperStyles: CSSProperties = { position: 'absolute', right: 10, top: 10, zIndex: 4 };
const onLoad = (reactFlowInstance: OnLoadParams) => {
reactFlowInstance.fitView();
console.log(reactFlowInstance.getElements());
};
const initialElements: Elements = getElements(30, 30);
const StressFlow = () => {
const [elements, setElements] = useState<Elements>(initialElements);
const onElementsRemove = (elementsToRemove: Elements) => setElements((els) => removeElements(elementsToRemove, els));
const onConnect = (params: Connection | Edge) => setElements((els) => addEdge(params, els));
const updatePos = () => {
setElements((elms) => {
return elms.map((el) => {
if (isNode(el)) {
return {
...el,
position: {
x: Math.random() * window.innerWidth,
y: Math.random() * window.innerHeight,
},
};
}
return el;
});
});
};
const updateElements = () => {
const grid = Math.ceil(Math.random() * 10);
setElements(getElements(grid, grid));
};
return (
<ReactFlow elements={elements} onLoad={onLoad} onElementsRemove={onElementsRemove} onConnect={onConnect}>
<MiniMap />
<Controls />
<Background />
<div style={buttonWrapperStyles}>
<button onClick={updatePos} style={{ marginRight: 5 }}>
change pos
</button>
<button onClick={updateElements}>update elements</button>
</div>
</ReactFlow>
);
};
export default StressFlow;
-30
View File
@@ -1,30 +0,0 @@
import { Elements } from 'react-flow-renderer';
export function getElements(xElements: number = 10, yElements: number = 10): Elements {
const initialElements = [];
let nodeId = 1;
let recentNodeId = null;
for (let y = 0; y < yElements; y++) {
for (let x = 0; x < xElements; x++) {
const position = { x: x * 100, y: y * 50 };
const data = { label: `Node ${nodeId}` };
const node = {
id: nodeId.toString(),
style: { width: 50, fontSize: 11 },
data,
position,
};
initialElements.push(node);
if (recentNodeId && nodeId <= xElements * yElements) {
initialElements.push({ id: `${x}-${y}`, source: recentNodeId.toString(), target: nodeId.toString() });
}
recentNodeId = nodeId;
nodeId++;
}
}
return initialElements;
}