diff --git a/src/components/draw_area.jsx b/src/components/draw_area.jsx
index cb19e99..5e3e121 100644
--- a/src/components/draw_area.jsx
+++ b/src/components/draw_area.jsx
@@ -1,10 +1,12 @@
import React, { useRef, useState } from "react";
import { useDrop } from "react-dnd";
import Rect from "./rect";
+import Node from "./node";
export default function Canvas(props) {
const [dragging, setDragging] = useState(false);
const [offset, setOffset] = useState({ x: 0, y: 0 });
+ const [links, setLinks] = useState([]);
const canvas = useRef(null);
@@ -23,11 +25,52 @@ export default function Canvas(props) {
const { clientX, clientY } = event;
const updatedRectangles = props.rectangles.map((rect) => {
if (rect.id === dragging) {
- return {
+ const updatedRect = {
...rect,
x: clientX - offset.x,
y: clientY - offset.y,
};
+ const updatedLinks = links.map((link) => {
+ let updatedLink = link;
+ if (link.rect === updatedRect.id) {
+ switch (link.node) {
+ case Node.TOP:
+ updatedLink = {
+ ...link,
+ x: updatedRect.x + updatedRect.width / 2,
+ y: updatedRect.y,
+ };
+ break;
+ case Node.BOTTOM:
+ updatedLink = {
+ ...link,
+ x: updatedRect.x + updatedRect.width / 2,
+ y: updatedRect.y + updatedRect.height,
+ };
+ break;
+ case Node.LEFT:
+ updatedLink = {
+ ...link,
+ x: updatedRect.x,
+ y: updatedRect.y + updatedRect.height / 2,
+ };
+ break;
+ case Node.RIGHT:
+ updatedLink = {
+ ...link,
+ x: updatedRect.x + updatedRect.width,
+ y: updatedRect.y + updatedRect.height / 2,
+ };
+ break;
+ default:
+ break;
+ }
+ }
+ return updatedLink;
+ });
+
+ setLinks(updatedLinks);
+ return updatedRect;
}
return rect;
});
@@ -84,9 +127,27 @@ export default function Canvas(props) {
label={rectangle.label}
width={rectangle.width}
height={rectangle.height}
+ links={links}
+ setLinks={setLinks}
onMouseDown={(event) => handleMouseDown(event, rectangle.id)}
/>
))}
+ {links.map(
+ (link, index) =>
+ links.length >= 2 &&
+ index % 2 === 0 &&
+ index + 1 < links.length && (
+
+ )
+ )}
diff --git a/src/components/node.js b/src/components/node.js
new file mode 100644
index 0000000..6aa33f5
--- /dev/null
+++ b/src/components/node.js
@@ -0,0 +1,9 @@
+const Node = {
+ NONE: "NONE",
+ TOP: "TOP",
+ LEFT: "LEFT",
+ RIGHT: "RIGHT",
+ BOTTOM: "BOTTOM",
+};
+
+export default Node;
diff --git a/src/components/rect.jsx b/src/components/rect.jsx
index ecd87da..96a5b6f 100644
--- a/src/components/rect.jsx
+++ b/src/components/rect.jsx
@@ -1,7 +1,11 @@
-import React from "react";
+import { React, useState } from "react";
+import Node from "./node";
import { Button } from "@arco-design/web-react";
const Rect = (props) => {
+ const [isHovered, setIsHovered] = useState(false);
+ const [node, setNode] = useState(Node.NONE);
+
return (
{
y={props.y}
width={props.width}
height={props.height}
- style={{ fill: "blue", cursor: "move" }}
+ style={{ cursor: "move" }}
onMouseDown={props.onMouseDown}
+ onMouseEnter={() => {
+ setIsHovered(true);
+ }}
+ onMouseLeave={() => {
+ setIsHovered(false);
+ }}
>
-
+
+
{
+ setNode(Node.TOP);
+ props.setLinks([
+ ...props.links,
+ {
+ rect: props.id,
+ node: Node.TOP,
+ x: props.x + props.width / 2,
+ y: props.y,
+ },
+ ]);
+ }}
+ style={{ fill: node === Node.TOP ? "green" : "black" }}
+ />
+ {
+ setNode(Node.LEFT);
+ props.setLinks([
+ ...props.links,
+ {
+ rect: `${props.id}`,
+ node: Node.LEFT,
+ x: props.x,
+ y: props.y + props.height / 2,
+ },
+ ]);
+ }}
+ style={{ fill: node === Node.LEFT ? "green" : "black" }}
+ />
+ {
+ setNode(Node.RIGHT);
+ props.setLinks([
+ ...props.links,
+ {
+ rect: props.id,
+ node: Node.RIGHT,
+ x: props.x + props.width,
+ y: props.y + props.height / 2,
+ },
+ ]);
+ }}
+ style={{ fill: node === Node.RIGHT ? "green" : "black" }}
+ />
+ {
+ setNode(Node.BOTTOM);
+ props.setLinks([
+ ...props.links,
+ {
+ rect: props.id,
+ node: Node.BOTTOM,
+ x: props.x + props.width / 2,
+ y: props.y + props.height,
+ },
+ ]);
+ }}
+ style={{ fill: node === Node.BOTTOM ? "green" : "black" }}
+ />
);
};