This commit is contained in:
1ilit 2023-09-19 15:48:04 +03:00
parent 8929639d6d
commit df89b1047d
4 changed files with 134 additions and 16 deletions

47
src/components/area.jsx Normal file
View File

@ -0,0 +1,47 @@
import { React, useState } from "react";
export default function Area(props) {
const [size, setSize] = useState({
width: props.areaData.width,
height: props.areaData.height,
});
return (
<g>
<foreignObject
key={props.areaData.id}
x={props.areaData.x}
y={props.areaData.y}
width={size.width}
height={size.height}
style={{ cursor: "move" }}
onMouseDown={props.onMouseDown}
>
<div className="border-2 border-dashed border-blue-600 opacity-70 bg-slate-400 w-fill h-full">
{props.areaData.name}
</div>
</foreignObject>
<circle cx={props.areaData.x} cy={props.areaData.y} r={5} fill="blue" />
<circle
cx={props.areaData.x + props.areaData.width}
cy={props.areaData.y}
r={5}
fill="blue"
/>
<circle
cx={props.areaData.x}
cy={props.areaData.y + props.areaData.height}
r={5}
fill="blue"
/>
<circle
cx={props.areaData.x + size.width}
cy={props.areaData.y + size.height}
r={5}
fill="blue"
cursor="pointer"
onMouseDown={(e) => {}}
/>
</g>
);
}

View File

@ -2,9 +2,15 @@ import React, { useRef, useState } from "react";
import { useDrop } from "react-dnd";
import Table from "./table";
import { defaultTableTheme, Cardinality, Constraint } from "../data/data";
import Area from "./area";
export default function Canvas(props) {
const [dragging, setDragging] = useState(-1);
const ObjectType = {
NONE: 0,
TABLE: 1,
AREA: 2,
};
const [dragging, setDragging] = useState([ObjectType.NONE, -1]);
const [linking, setLinking] = useState(false);
const [line, setLine] = useState({
startTableId: -1,
@ -32,14 +38,23 @@ export default function Canvas(props) {
const canvas = useRef(null);
const handleMouseDownRect = (e, id) => {
const handleMouseDownRect = (e, id, type) => {
const { clientX, clientY } = e;
const table = props.tables.find((t) => t.id === id);
setOffset({
x: clientX - table.x,
y: clientY - table.y,
});
setDragging(id);
if (type === ObjectType.TABLE) {
const table = props.tables.find((t) => t.id === id);
setOffset({
x: clientX - table.x,
y: clientY - table.y,
});
setDragging([ObjectType.TABLE, id]);
} else if (type === ObjectType.AREA) {
const area = props.areas.find((t) => t.id === id);
setOffset({
x: clientX - area.x,
y: clientY - area.y,
});
setDragging([ObjectType.AREA, id]);
}
};
const handleMouseMove = (e) => {
@ -77,9 +92,17 @@ export default function Canvas(props) {
endY: r.endY + dy,
}))
);
} else if (dragging >= 0) {
props.setAreas(
props.areas.map((t) => ({
...t,
x: t.x + dx,
y: t.y + dy,
}))
);
} else if (dragging[0] === ObjectType.TABLE && dragging[1] >= 0) {
const updatedTables = props.tables.map((t) => {
if (t.id === dragging) {
if (t.id === dragging[1]) {
const updatedTable = {
...t,
x: e.clientX - offset.x,
@ -91,14 +114,14 @@ export default function Canvas(props) {
});
props.setTables(updatedTables);
const updatedRelationShips = props.relationships.map((r) => {
if (r.startTableId === dragging) {
if (r.startTableId === dragging[1]) {
return {
...r,
startX: props.tables[r.startTableId].x + 15,
startY:
props.tables[r.startTableId].y + r.startFieldId * 36 + 40 + 19,
};
} else if (r.endTableId === dragging) {
} else if (r.endTableId === dragging[1]) {
return {
...r,
endX: props.tables[r.endTableId].x + 15,
@ -108,11 +131,25 @@ export default function Canvas(props) {
return r;
});
props.setRelationships(updatedRelationShips);
} else if (dragging[0] === ObjectType.AREA && dragging[1] >= 0) {
console.log("hi");
const updatedAreas = props.areas.map((t) => {
if (t.id === dragging[1]) {
const updatedArea = {
...t,
x: e.clientX - offset.x,
y: e.clientY - offset.y,
};
return updatedArea;
}
return t;
});
props.setAreas(updatedAreas);
}
};
const handleMouseDown = (e) => {
if (dragging < 0) {
if (dragging[0] === ObjectType.TABLE && dragging[1] < 0) {
if (onRect.tableId < 0) {
setPanning(true);
setPanOffset({ x: e.clientX, y: e.clientY });
@ -122,7 +159,7 @@ export default function Canvas(props) {
};
const handleMouseUp = () => {
setDragging(-1);
setDragging([ObjectType.NONE, -1]);
setPanning(false);
setCursor("default");
if (linking) handleLinking();
@ -137,7 +174,7 @@ export default function Canvas(props) {
const handleGripField = (id) => {
setPanning(false);
setDragging(-1);
setDragging([ObjectType.NONE, -1]);
setLinking(true);
};
@ -248,6 +285,13 @@ export default function Canvas(props) {
</defs>
<rect width="100%" height="100%" fill="url(#grid)" />
{props.areas.map((a) => (
<Area
key={a.id}
areaData={a}
onMouseDown={(e) => handleMouseDownRect(e, a.id, ObjectType.AREA)}
></Area>
))}
{props.tables.map((table, i) => (
<Table
key={table.id}
@ -258,7 +302,9 @@ export default function Canvas(props) {
setOnRect={setOnRect}
handleGripField={handleGripField}
setLine={setLine}
onMouseDown={(e) => handleMouseDownRect(e, table.id)}
onMouseDown={(e) =>
handleMouseDownRect(e, table.id, ObjectType.TABLE)
}
onDelete={deleteTable}
/>
))}

View File

@ -85,6 +85,26 @@ export default function EditorPanel(props) {
{contentList[parseInt(tab) - 1]}
</Tabs>
<button
onClick={() => {
const newArea = {
id: props.areas.length,
name: `area_${props.areas.length}`,
x: 0,
y: 0,
width: 200,
height: 200,
color: defaultTableTheme,
};
props.setAreas((prev) => {
const updatedTables = [...prev, newArea];
return updatedTables;
});
}}
>
add area
</button>
<br />
<button
onClick={() => {
const newTable = {

View File

@ -11,6 +11,7 @@ export default function Editor(props) {
const [code, setCode] = useState("");
const [tables, setTables] = useState([]);
const [relationships, setRelationships] = useState([]);
const [areas, setAreas] = useState([]);
return (
<>
@ -25,6 +26,8 @@ export default function Editor(props) {
setCode={setCode}
relationships={relationships}
setRelationships={setRelationships}
areas={areas}
setAreas={setAreas}
/>
<Canvas
tables={tables}
@ -33,6 +36,8 @@ export default function Editor(props) {
setCode={setCode}
relationships={relationships}
setRelationships={setRelationships}
areas={areas}
setAreas={setAreas}
/>
</DndProvider>
<Sidebar />