import { FC, useState, useEffect } from "react"; import { values } from "lodash"; import { v4 as uuidv4 } from "uuid"; import eventBus from "../../events/eventBus"; import { Popover } from "./Popover"; import { IGraphData } from "../../types"; import { useJsPlumb } from "../useJsPlumb"; const CANVAS_ID: string = "canvas-container-" + uuidv4(); interface ICanvasProps { nodes: any; connections: any; canvasPosition: any; onNodeUpdate: any; onGraphUpdate: any; onCanvasUpdate: any; onConnectionAttached: any; onConnectionDetached: any; setNodeForEdit: any; setNodeForDelete: any; } export const Canvas: FC = (props) => { const { nodes, connections, canvasPosition, onNodeUpdate, onGraphUpdate, onCanvasUpdate, onConnectionAttached, onConnectionDetached, setNodeForEdit, setNodeForDelete } = props; const [nodeDragging, setNodeDragging] = useState(); const [nodeHovering, setNodeHovering] = useState(); const [dragging, setDragging] = useState(false); const [scale, setScale] = useState(1); const [_scale, _setScale] = useState(1); const [_left, _setLeft] = useState(0); const [_top, _setTop] = useState(0); const [_initX, _setInitX] = useState(0); const [_initY, _setInitY] = useState(0); let translateWidth = (document.documentElement.clientWidth * (1 - _scale)) / 2; let translateHeight = ((document.documentElement.clientHeight - 64) * (1 - _scale)) / 2; const [containerCallbackRef, setZoom, setStyle, removeEndpoint] = useJsPlumb( nodes, connections, ((graphData: IGraphData) => onGraphUpdate(graphData)), ((positionData: any) => onNodeUpdate(positionData)), ((connectionData: any) => onConnectionAttached(connectionData)), ((connectionData: any) => onConnectionDetached(connectionData)) ); const onCanvasMousewheel = (e: any) => { if (e.deltaY < 0) { _setScale(_scale + _scale * 0.25); setScale(_scale + _scale * 0.25); } if (e.deltaY > 0) { _setScale(_scale - _scale * 0.25); setScale(_scale - _scale * 0.25); } } const onCanvasMouseUpLeave = (e: any) => { if (dragging) { let left = _left + e.pageX - _initX; let top = _top + e.pageY - _initY; _setLeft(left); _setTop(top); setDragging(false); onCanvasUpdate({ left: left, top: top }); } } const onCanvasMouseMove = (e: any) => { if (!dragging) { return; } const styles = { "left": _left + e.pageX - _initX + 'px', "top": _top + e.pageY - _initY + 'px' } setStyle(styles); } const onCanvasMouseDown = (e: any) => { _setInitX(e.pageX); _setInitY(e.pageY); setDragging(true); } useEffect(() => { setZoom(_scale); }, [_scale]); useEffect(() => { onCanvasUpdate({ scale: scale }); }, [scale]); useEffect(() => { const styles = { "left": _left + 'px', "top": _top + 'px' } setStyle(styles); }, [_left, _top, setStyle]); useEffect(() => { _setTop(canvasPosition.top); _setLeft(canvasPosition.left); _setScale(canvasPosition.scale); }, [canvasPosition]); useEffect(() => { eventBus.on("EVENT_DRAG_START", (data: any) => { setNodeDragging(data.detail.message.id); }); eventBus.on("EVENT_DRAG_STOP", (data: any) => { setNodeDragging(null); }); eventBus.on("NODE_DELETED", (data: any) => { removeEndpoint(data.detail.message.node); }); return () => { eventBus.remove("NODE_DELETED", () => { }); eventBus.remove("EVENT_DRAG_START", () => {}); eventBus.remove("EVENT_DRAG_STOP", () => { }); }; }, []); return ( <> {nodes &&
{ event.stopPropagation(); event.preventDefault(); }} >
{values(nodes).map((x) => (
setNodeHovering(x.key)} onMouseLeave={() => { if (nodeHovering === x.key) { setNodeHovering(null); } }} > {((nodeHovering === x.key) && (nodeDragging !== x.key)) && { setNodeForEdit(x); }} onDeleteClick={() => { setNodeForDelete(x); }} > }
{x.configuration.prettyName}
{x.configuration.prettyName}
))}
} ); };