broke out handleId by itself rather than joined with nodeID, modded necessary functions to give handles not assigned IDs an empty string for backwards compadibility. Also modded handles so that only target-source and source-target connections are allowed, and no repeat connections are allowed.

This commit is contained in:
jasonpul
2020-10-01 15:47:37 -04:00
parent bee2ca5c0c
commit d9ba18d49c
9 changed files with 55 additions and 48 deletions
+2 -2
View File
@@ -15,8 +15,8 @@ export default memo(({ data }) => {
Custom Color Picker Node: <strong>{data.color}</strong>
</div>
<input className="nodrag" type="color" onChange={data.onChange} defaultValue={data.color} />
<Handle type="source" position="right" id="a" style={{ top: 10, background: '#555' }} />
<Handle type="source" position="right" id="b" style={{ bottom: 10, top: 'auto', background: '#555' }} />
<Handle type="source" position="right" id="0" style={{ top: 10, background: '#555' }} />
<Handle type="source" position="right" id="1" style={{ bottom: 10, top: 'auto', background: '#555' }} />
</>
);
});
+2 -2
View File
@@ -56,8 +56,8 @@ const CustomNodeFlow = () => {
{ id: '4', type: 'output', data: { label: 'Output B' }, position: { x: 550, y: 100 }, targetPosition: 'left' },
{ id: 'e1-2', source: '1', target: '2', animated: true, style: { stroke: '#fff' } },
{ id: 'e2a-3', source: '2__a', target: '3', animated: true, style: { stroke: '#fff' } },
{ id: 'e2b-4', source: '2__b', target: '4', animated: true, style: { stroke: '#fff' } },
{ id: 'e2a-3', source: '2', sourceHandle: '0', target: '3', animated: true, style: { stroke: '#fff' } },
{ id: 'e2b-4', source: '2', sourceHandle: '1', target: '4', animated: true, style: { stroke: '#fff' } },
]);
}, []);
+4 -4
View File
@@ -43,7 +43,7 @@ const nodeTypes = {
const HorizontalFlow = () => {
const [elements, setElements] = useState(initialElements);
const onConnect = (params) => {
// console.log('on connect', params);
console.log('on connect', params);
setElements((els) => addEdge(params, els));
};
@@ -55,9 +55,9 @@ const HorizontalFlow = () => {
onLoad={onLoad}
className="validationflow"
nodeTypes={nodeTypes}
// onConnectStart={onConnectStart}
// onConnectStop={onConnectStop}
// onConnectEnd={onConnectEnd}
onConnectStart={onConnectStart}
onConnectStop={onConnectStop}
onConnectEnd={onConnectEnd}
/>
);
};
+9 -14
View File
@@ -117,19 +117,14 @@ const Header = () => {
};
ReactDOM.render(
<Validation />,
<Router forceRefresh={true}>
<Header />
<SourceDisplay />
<Switch>
{routes.map((route) => (
<Route exact path={route.path} render={() => <route.component />} key={route.path} />
))}
</Switch>
</Router>,
document.getElementById('root')
);
// ReactDOM.render(
// <Router forceRefresh={true}>
// <Header />
// <SourceDisplay />
// <Switch>
// {routes.map((route) => (
// <Route exact path={route.path} render={() => <route.component />} key={route.path} />
// ))}
// </Switch>
// </Router>,
// document.getElementById('root')
// );
-4
View File
@@ -85,8 +85,6 @@ function onMouseDown(
// checks if element below mouse is a handle and returns connection in form of an object { source: 123, target: 312 }
function checkElementBelowIsValid(event: MouseEvent) {
const elementBelow = document.elementFromPoint(event.clientX, event.clientY);
// console.log(elementBelow)
// console.log(handleId)
const result: Result = {
elementBelow,
@@ -194,9 +192,7 @@ const BaseHandle = ({
},
]);
// const nodeIdWithHandleId = id ? `${nodeId}__${id}` : nodeId;
const handleId = id ? `${id}`: ''
return (
<div
data-handleid={handleId}
+1 -8
View File
@@ -19,15 +19,8 @@ export const getHandleBounds = (
(handle): HandleElement => {
const bounds = handle.getBoundingClientRect();
const dimensions = getDimensions(handle);
const nodeIdAttr = handle.getAttribute('data-nodeid');
const handleId = handle.getAttribute('data-handleid');
const handlePosition = (handle.getAttribute('data-handlepos') as unknown) as Position;
const nodeIdSplitted = nodeIdAttr ? nodeIdAttr.split('__') : null;
let handleId = null;
if (nodeIdSplitted) {
handleId = (nodeIdSplitted.length ? nodeIdSplitted[1] : nodeIdSplitted) as string;
}
return {
id: handleId,
+4 -2
View File
@@ -132,8 +132,10 @@ function renderEdge(
selectedElements: Elements | null,
elementsSelectable: boolean
) {
const [sourceId, sourceHandleId] = edge.source.split('__');
const [targetId, targetHandleId] = edge.target.split('__');
const sourceId = edge.source
const sourceHandleId = edge.sourceHandle!
const targetId = edge.target
const targetHandleId = edge.targetHandle!
const sourceNode = nodes.find((n) => n.id === sourceId);
const targetNode = nodes.find((n) => n.id === targetId);
+2
View File
@@ -58,6 +58,8 @@ export interface Edge {
type?: string;
source: ElementId;
target: ElementId;
sourceHandle?: ElementId;
targetHandle?: ElementId;
label?: string;
labelStyle?: CSSProperties;
labelShowBg?: boolean;
+31 -12
View File
@@ -40,7 +40,19 @@ export const removeElements = (elementsToRemove: Elements, elements: Elements):
});
};
const getEdgeId = ({ source, target }: Connection): ElementId => `reactflow__edge-${source}-${target}`;
const getEdgeId = ({ source, sourceHandle, target, targetHandle }: Connection): ElementId => `reactflow__edge-${source}${sourceHandle}-${target}${targetHandle}`;
const existingConnection = (edge: Edge, elements: Elements) => {
for (const element of elements) {
if (isEdge(element)) {
if (element.source === edge.source && element.sourceHandle === edge.sourceHandle && element.target === edge.target && element.targetHandle === edge.targetHandle) {
return true
}
}
}
return false
}
export const addEdge = (edgeParams: Edge | Connection, elements: Elements): Elements => {
if (!edgeParams.source || !edgeParams.target) {
@@ -49,22 +61,27 @@ export const addEdge = (edgeParams: Edge | Connection, elements: Elements): Elem
// make sure that there is node with the target and one with the source id
[edgeParams.source, edgeParams.target].forEach((id) => {
const nodeId = id.includes('__') ? id.split('__')[0] : id;
if (!elements.find((e) => isNode(e) && e.id === nodeId)) {
throw new Error(`Can't create edge. Node with id=${nodeId} does not exist.`);
if (!elements.find((e) => isNode(e) && e.id === id)) {
throw new Error(`Can't create edge. Node with id=${id} does not exist.`);
}
});
// need to check if handles exist
//
//
//
let edge: Edge
if (isEdge(edgeParams)) {
return elements.concat({ ...edgeParams });
edge = {...edgeParams}
} else {
edge = {
...edgeParams,
id: getEdgeId(edgeParams),
} as Edge;
}
const edge = {
...edgeParams,
id: getEdgeId(edgeParams),
} as Edge;
return elements.concat(edge);
if (existingConnection(edge, elements)) {return elements}
return elements.concat(edge)
};
export const pointToRendererPoint = (
@@ -112,6 +129,8 @@ export const parseElement = (element: Node | Edge): Node | Edge => {
...element,
source: element.source.toString(),
target: element.target.toString(),
sourceHandle: element.sourceHandle ? element.sourceHandle.toString() : '',
targetHandle: element.targetHandle ? element.targetHandle.toString() : '',
id: element.id.toString(),
type: element.type || 'default',
};