diff --git a/src/components/ControlPanel.jsx b/src/components/ControlPanel.jsx index fa74c4d..6a45935 100644 --- a/src/components/ControlPanel.jsx +++ b/src/components/ControlPanel.jsx @@ -37,17 +37,12 @@ import todo from "../assets/calendar.png"; import { toPng, toJpeg, toSvg } from "html-to-image"; import { saveAs } from "file-saver"; import { - jsonDiagramIsValid, - enterFullscreen, - exitFullscreen, - ddbDiagramIsValid, - dataURItoBlob, jsonToMySQL, jsonToPostgreSQL, jsonToSQLite, jsonToMariaDB, jsonToSQLServer, -} from "../utils"; +} from "../utils/toSQL"; import { AreaContext, NoteContext, @@ -73,6 +68,9 @@ import useTransform from "../hooks/useTransform"; import useTables from "../hooks/useTables"; import useUndoRedo from "../hooks/useUndoRedo"; import useSelect from "../hooks/useSelect"; +import { enterFullscreen, exitFullscreen } from "../utils/fullscreen"; +import { ddbDiagramIsValid, jsonDiagramIsValid } from "../utils/validateSchema"; +import { dataURItoBlob } from "../utils/utils"; export default function ControlPanel({ diagramId, diff --git a/src/components/Controls.jsx b/src/components/Controls.jsx index ad5c853..06b78f0 100644 --- a/src/components/Controls.jsx +++ b/src/components/Controls.jsx @@ -1,7 +1,7 @@ import { Divider, Tooltip } from "@douyinfe/semi-ui"; -import { exitFullscreen } from "../utils"; import useTransform from "../hooks/useTransform"; import useLayout from "../hooks/useLayout"; +import { exitFullscreen } from "../utils/fullscreen"; export default function Controls() { const { transform, setTransform } = useTransform(); diff --git a/src/components/Issues.jsx b/src/components/Issues.jsx index 99c24db..f7e09a3 100644 --- a/src/components/Issues.jsx +++ b/src/components/Issues.jsx @@ -1,9 +1,10 @@ import { useContext, useState, useEffect } from "react"; import { Collapse, Badge } from "@douyinfe/semi-ui"; import { TypeContext } from "../pages/Editor"; -import { validateDiagram, arrayIsEqual } from "../utils"; +import { validateDiagram } from "../utils/toSQL"; import useSettings from "../hooks/useSettings"; import useTables from "../hooks/useTables"; +import { arrayIsEqual } from "../utils/utils"; export default function Issues() { const { settings } = useSettings(); diff --git a/src/components/Relationship.jsx b/src/components/Relationship.jsx index 77cf012..a90f52b 100644 --- a/src/components/Relationship.jsx +++ b/src/components/Relationship.jsx @@ -1,7 +1,7 @@ import { useRef } from "react"; -import { calcPath } from "../utils"; import { Cardinality } from "../data/data"; import useSettings from "../hooks/useSettings"; +import { calcPath } from "../utils/calcPath"; export default function Relationship({ data }) { const { settings } = useSettings(); @@ -50,14 +50,7 @@ export default function Relationship({ data }) { setIsHovered(false)} >
(
setHoveredField(i)} onMouseLeave={() => setHoveredField(-1)} > @@ -99,9 +101,7 @@ function Relationship({ relationship }) { relationship.startX, relationship.endX, relationship.startY, - relationship.endY, - relationship.startFieldId, - relationship.endFieldId + relationship.endY )} stroke="gray" fill="none" @@ -231,10 +231,12 @@ export default function SimpleCanvas({ diagram, zoom }) { height="100%" fill="url(#pattern-circles)" > - + {relationships.map((r, i) => ( ))} diff --git a/src/components/Table.jsx b/src/components/Table.jsx index 54927a4..960088b 100644 --- a/src/components/Table.jsx +++ b/src/components/Table.jsx @@ -32,7 +32,7 @@ import { Toast, } from "@douyinfe/semi-ui"; import { TabContext, TypeContext } from "../pages/Editor"; -import { getSize, hasCheck, hasPrecision, isSized } from "../utils"; +import { getSize, hasCheck, hasPrecision, isSized } from "../utils/toSQL"; import useLayout from "../hooks/useLayout"; import useSettings from "../hooks/useSettings"; import useUndoRedo from "../hooks/useUndoRedo"; diff --git a/src/components/TableOverview.jsx b/src/components/TableOverview.jsx index 438ead8..eeb282b 100644 --- a/src/components/TableOverview.jsx +++ b/src/components/TableOverview.jsx @@ -36,7 +36,7 @@ import { IllustrationNoContentDark, } from "@douyinfe/semi-illustrations"; import { TypeContext } from "../pages/Editor"; -import { getSize, hasCheck, hasPrecision, isSized } from "../utils"; +import { getSize, hasCheck, hasPrecision, isSized } from "../utils/toSQL"; import useTables from "../hooks/useTables"; import useUndoRedo from "../hooks/useUndoRedo"; import useSelect from "../hooks/useSelect"; diff --git a/src/components/Thumbnail.jsx b/src/components/Thumbnail.jsx index c3fa5ad..7f0e5f8 100644 --- a/src/components/Thumbnail.jsx +++ b/src/components/Thumbnail.jsx @@ -1,4 +1,4 @@ -import { calcPath } from "../utils"; +import { calcPath } from "../utils/calcPath"; export function Thumbnail({ diagram, i, zoom }) { const translateX = 32 * zoom; @@ -119,9 +119,7 @@ export function Thumbnail({ diagram, i, zoom }) { e.startX, e.endX, e.startY - translateY / zoom, - e.endY - (translateY / zoom) * 0.5, - e.startFieldId, - e.endFieldId + e.endY - (translateY / zoom) * 0.5 )} fill="none" strokeWidth={1} diff --git a/src/components/TypesOverview.jsx b/src/components/TypesOverview.jsx index 0c08091..2e35af1 100644 --- a/src/components/TypesOverview.jsx +++ b/src/components/TypesOverview.jsx @@ -28,7 +28,7 @@ import { IllustrationNoContentDark, } from "@douyinfe/semi-illustrations"; import { TypeContext } from "../pages/Editor"; -import { isSized, hasPrecision, getSize } from "../utils"; +import { isSized, hasPrecision, getSize } from "../utils/toSQL"; import useUndoRedo from "../hooks/useUndoRedo"; export default function TableOverview() { diff --git a/src/pages/Templates.jsx b/src/pages/Templates.jsx index 89ff470..d79eaad 100644 --- a/src/pages/Templates.jsx +++ b/src/pages/Templates.jsx @@ -1,12 +1,12 @@ import { useEffect } from "react"; import logo_light from "../assets/logo_light_160.png"; -import template_screenshot from "../assets/template_screenshot.png" +import template_screenshot from "../assets/template_screenshot.png"; import { Link } from "react-router-dom"; import { Tabs, TabPane, Banner, Steps } from "@douyinfe/semi-ui"; import { IconDeleteStroked } from "@douyinfe/semi-icons"; import { db } from "../data/db"; import { useLiveQuery } from "dexie-react-hooks"; -import { calcPath } from "../utils"; +import { calcPath } from "../utils/calcPath"; function Thumbnail({ diagram, i }) { const zoom = 0.3; @@ -82,8 +82,9 @@ function Thumbnail({ diagram, i }) {
{table.fields.map((f, j) => (
@@ -103,15 +104,7 @@ function Thumbnail({ diagram, i }) { {diagram.relationships?.map((e, i) => ( Your templates} itemKey="2" > - { - customTemplates?.length > 0 ? -
- {customTemplates?.map((c, i) => ( -
- -
-
-
- {c.title} -
-
- -
+ {customTemplates?.length > 0 ? ( +
+ {customTemplates?.map((c, i) => ( +
+ +
+
+
+ {c.title}
-
+
-
-
-
- ))} -
: -
- You have no custom templates saved.
} - /> -
- -
-
How to save a template
- - - - - +
+ +
+ +
+ ))} +
+ ) : ( +
+ You have no custom templates saved.
} + /> +
+ +
+
+ How to save a template +
+ + + + + +
- } +
+ )}
diff --git a/src/utils/calcPath.js b/src/utils/calcPath.js new file mode 100644 index 0000000..1c78df4 --- /dev/null +++ b/src/utils/calcPath.js @@ -0,0 +1,112 @@ +const calcPath = (x1, x2, y1, y2, zoom = 1) => { + const tableWidth = 200 * zoom; + if (y1 <= y2) { + if (x1 + tableWidth <= x2) { + x2 -= 14; + } else if (x2 <= x1 + tableWidth && x1 <= x2) { + // x2-=14; + // x1-=14; + } else if (x2 + tableWidth >= x1 && x2 + tableWidth <= x1 + tableWidth) { + x1 -= 14; + x2 -= 14; + } else { + x2 -= 14; + x1 -= 14; + } + } else { + if (x1 + tableWidth <= x2) { + x2 -= 14; + } else if (x1 + tableWidth >= x2 && x1 + tableWidth <= x2 + tableWidth) { + // + x1 -= 14; + x2 -= 14; + } else if (x1 >= x2 && x1 <= x2 + tableWidth) { + // x1-=19; + // x2-=14; + } else { + x1 -= 14; + x2 -= 14; + } + } + x1 *= zoom; + x2 *= zoom; + y1 *= zoom; + y2 *= zoom; + + let r = 10 * zoom; + const offsetX = 8 * zoom; + const midX = (x2 + x1 + tableWidth) / 2; + const endX = x2 + tableWidth < x1 ? x2 + tableWidth : x2; + + if (Math.abs(y1 - y2) <= 36 * zoom) { + r = Math.abs(y2 - y1) / 3; + if (r <= 2) { + if (x1 + tableWidth <= x2) + return `M ${x1 + tableWidth - 2 * offsetX} ${y1} L ${x2} ${y2 + 0.1}`; + else if (x2 + tableWidth < x1) + return `M ${x1} ${y1} L ${x2 + tableWidth} ${y2 + 0.1}`; + } + } + + if (y1 <= y2) { + if (x1 + tableWidth <= x2) { + return `M ${x1 + tableWidth - offsetX * 2} ${y1} L ${ + midX - r + } ${y1} A ${r} ${r} 0 0 1 ${midX} ${y1 + r} L ${midX} ${ + y2 - r + } A ${r} ${r} 0 0 0 ${midX + r} ${y2} L ${endX} ${y2}`; + } else if (x2 <= x1 + tableWidth && x1 <= x2) { + return `M ${x1 + tableWidth - 2 * offsetX} ${y1} L ${ + x2 + tableWidth + } ${y1} A ${r} ${r} 0 0 1 ${x2 + tableWidth + r} ${y1 + r} L ${ + x2 + tableWidth + r + } ${y2 - r} A ${r} ${r} 0 0 1 ${x2 + tableWidth} ${y2} L ${ + x2 + tableWidth - 2 * offsetX + } ${y2}`; + } else if (x2 + tableWidth >= x1 && x2 + tableWidth <= x1 + tableWidth) { + return `M ${x1} ${y1} L ${x2 - r} ${y1} A ${r} ${r} 0 0 0 ${x2 - r - r} ${ + y1 + r + } L ${x2 - r - r} ${y2 - r} A ${r} ${r} 0 0 0 ${ + x2 - r + } ${y2} L ${x2} ${y2}`; + } else { + return `M ${x1} ${y1} L ${midX + r} ${y1} A ${r} ${r} 0 0 0 ${midX} ${ + y1 + r + } L ${midX} ${y2 - r} A ${r} ${r} 0 0 1 ${ + midX - r + } ${y2} L ${endX} ${y2}`; + } + } else { + if (x1 + tableWidth <= x2) { + return `M ${x1 + tableWidth - offsetX * 2} ${y1} L ${ + midX - r + } ${y1} A ${r} ${r} 0 0 0 ${midX} ${y1 - r} L ${midX} ${ + y2 + r + } A ${r} ${r} 0 0 1 ${midX + r} ${y2} L ${endX} ${y2}`; + } else if (x1 + tableWidth >= x2 && x1 + tableWidth <= x2 + tableWidth) { + return `M ${x1} ${y1} L ${x1 - r - r} ${y1} A ${r} ${r} 0 0 1 ${ + x1 - r - r - r + } ${y1 - r} L ${x1 - r - r - r} ${y2 + r} A ${r} ${r} 0 0 1 ${ + x1 - r - r + } ${y2} L ${endX} ${y2}`; + } else if (x1 >= x2 && x1 <= x2 + tableWidth) { + return `M ${x1 + tableWidth - 2 * offsetX} ${y1} L ${ + x1 + tableWidth - 2 * offsetX + r + } ${y1} A ${r} ${r} 0 0 0 ${x1 + tableWidth - 2 * offsetX + r + r} ${ + y1 - r + } L ${x1 + tableWidth - 2 * offsetX + r + r} ${ + y2 + r + } A ${r} ${r} 0 0 0 ${x1 + tableWidth - 2 * offsetX + r} ${y2} L ${ + x2 + tableWidth - 2 * offsetX + } ${y2}`; + } else { + return `M ${x1} ${y1} L ${midX + r} ${y1} A ${r} ${r} 0 0 1 ${midX} ${ + y1 - r + } L ${midX} ${y2 + r} A ${r} ${r} 0 0 0 ${ + midX - r + } ${y2} L ${endX} ${y2}`; + } + } +}; + +export { calcPath }; diff --git a/src/utils/fullscreen.js b/src/utils/fullscreen.js new file mode 100644 index 0000000..72d0b30 --- /dev/null +++ b/src/utils/fullscreen.js @@ -0,0 +1,26 @@ +function enterFullscreen() { + const element = document.documentElement; + if (element.requestFullscreen) { + element.requestFullscreen(); + } else if (element.mozRequestFullScreen) { + element.mozRequestFullScreen(); + } else if (element.webkitRequestFullscreen) { + element.webkitRequestFullscreen(); + } else if (element.msRequestFullscreen) { + element.msRequestFullscreen(); + } +} + +function exitFullscreen() { + if (document.exitFullscreen) { + document.exitFullscreen(); + } else if (document.mozCancelFullScreen) { + document.mozCancelFullScreen(); + } else if (document.webkitExitFullscreen) { + document.webkitExitFullscreen(); + } else if (document.msExitFullscreen) { + document.msExitFullscreen(); + } +} + +export { enterFullscreen, exitFullscreen }; diff --git a/src/utils/index.js b/src/utils/toSQL.js similarity index 82% rename from src/utils/index.js rename to src/utils/toSQL.js index 5740f6a..009e180 100644 --- a/src/utils/index.js +++ b/src/utils/toSQL.js @@ -1,53 +1,5 @@ -import { Validator } from "jsonschema"; -import { ddbSchema, jsonSchema } from "../data/schemas"; import { sqlDataTypes } from "../data/data"; -function enterFullscreen() { - const element = document.documentElement; - if (element.requestFullscreen) { - element.requestFullscreen(); - } else if (element.mozRequestFullScreen) { - element.mozRequestFullScreen(); - } else if (element.webkitRequestFullscreen) { - element.webkitRequestFullscreen(); - } else if (element.msRequestFullscreen) { - element.msRequestFullscreen(); - } -} - -function exitFullscreen() { - if (document.exitFullscreen) { - document.exitFullscreen(); - } else if (document.mozCancelFullScreen) { - document.mozCancelFullScreen(); - } else if (document.webkitExitFullscreen) { - document.webkitExitFullscreen(); - } else if (document.msExitFullscreen) { - document.msExitFullscreen(); - } -} - -function jsonDiagramIsValid(obj) { - return new Validator().validate(obj, jsonSchema).valid; -} - -function ddbDiagramIsValid(obj) { - return new Validator().validate(obj, ddbSchema).valid; -} - -function dataURItoBlob(dataUrl) { - const byteString = atob(dataUrl.split(",")[1]); - const mimeString = dataUrl.split(",")[0].split(":")[1].split(";")[0]; - const arrayBuffer = new ArrayBuffer(byteString.length); - const intArray = new Uint8Array(arrayBuffer); - - for (let i = 0; i < byteString.length; i++) { - intArray[i] = byteString.charCodeAt(i); - } - - return new Blob([intArray], { type: mimeString }); -} - function getJsonType(f) { if (!sqlDataTypes.includes(f.type)) { return '{ "type" : "object", additionalProperties : true }'; @@ -597,10 +549,6 @@ function jsonToSQLServer(obj) { .join("\n")}`; } -function arrayIsEqual(arr1, arr2) { - return JSON.stringify(arr1) === JSON.stringify(arr2); -} - function isSized(type) { return ["CHAR", "VARCHAR", "BINARY", "VARBINARY", "TEXT"].includes(type); } @@ -882,135 +830,15 @@ function validateDiagram(diagram) { return issues; } -const calcPath = (x1, x2, y1, y2, startFieldId, endFieldId, zoom = 1) => { - const tableWidth = 200 * zoom; - if (y1 <= y2) { - if (x1 + tableWidth <= x2) { - x2 -= 14; - } else if (x2 <= x1 + tableWidth && x1 <= x2) { - // x2-=14; - // x1-=14; - } else if (x2 + tableWidth >= x1 && x2 + tableWidth <= x1 + tableWidth) { - x1 -= 14; - x2 -= 14; - } else { - x2 -= 14; - x1 -= 14; - } - } else { - if (x1 + tableWidth <= x2) { - x2 -= 14; - } else if (x1 + tableWidth >= x2 && x1 + tableWidth <= x2 + tableWidth) { - // - x1 -= 14; - x2 -= 14; - } else if (x1 >= x2 && x1 <= x2 + tableWidth) { - // x1-=19; - // x2-=14; - } else { - x1 -= 14; - x2 -= 14; - } - } - x1 *= zoom; - x2 *= zoom; - y1 *= zoom; - y2 *= zoom; - - let r = 10 * zoom; - const offsetX = 8 * zoom; - const midX = (x2 + x1 + tableWidth) / 2; - const endX = x2 + tableWidth < x1 ? x2 + tableWidth : x2; - // const startTableY = y1 - startFieldId * 36 - 50 - 18; - // const endTableY = y2 - endFieldId * 36 - 50; - - if (Math.abs(y1 - y2) <= 36 * zoom) { - r = Math.abs(y2 - y1) / 3; - if (r <= 2) { - if (x1 + tableWidth <= x2) - return `M ${x1 + tableWidth - 2 * offsetX} ${y1} L ${x2} ${y2 + 0.1}`; - else if (x2 + tableWidth < x1) - return `M ${x1} ${y1} L ${x2 + tableWidth} ${y2 + 0.1}`; - } - } - - if (y1 <= y2) { - if (x1 + tableWidth <= x2) { - return `M ${x1 + tableWidth - offsetX * 2} ${y1} L ${ - midX - r - } ${y1} A ${r} ${r} 0 0 1 ${midX} ${y1 + r} L ${midX} ${ - y2 - r - } A ${r} ${r} 0 0 0 ${midX + r} ${y2} L ${endX} ${y2}`; - } else if (x2 <= x1 + tableWidth && x1 <= x2) { - return `M ${x1 + tableWidth - 2 * offsetX} ${y1} L ${ - x2 + tableWidth - } ${y1} A ${r} ${r} 0 0 1 ${x2 + tableWidth + r} ${y1 + r} L ${ - x2 + tableWidth + r - } ${y2 - r} A ${r} ${r} 0 0 1 ${x2 + tableWidth} ${y2} L ${ - x2 + tableWidth - 2 * offsetX - } ${y2}`; - } else if (x2 + tableWidth >= x1 && x2 + tableWidth <= x1 + tableWidth) { - return `M ${x1} ${y1} L ${x2 - r} ${y1} A ${r} ${r} 0 0 0 ${x2 - r - r} ${ - y1 + r - } L ${x2 - r - r} ${y2 - r} A ${r} ${r} 0 0 0 ${ - x2 - r - } ${y2} L ${x2} ${y2}`; - } else { - return `M ${x1} ${y1} L ${midX + r} ${y1} A ${r} ${r} 0 0 0 ${midX} ${ - y1 + r - } L ${midX} ${y2 - r} A ${r} ${r} 0 0 1 ${ - midX - r - } ${y2} L ${endX} ${y2}`; - } - } else { - if (x1 + tableWidth <= x2) { - return `M ${x1 + tableWidth - offsetX * 2} ${y1} L ${ - midX - r - } ${y1} A ${r} ${r} 0 0 0 ${midX} ${y1 - r} L ${midX} ${ - y2 + r - } A ${r} ${r} 0 0 1 ${midX + r} ${y2} L ${endX} ${y2}`; - } else if (x1 + tableWidth >= x2 && x1 + tableWidth <= x2 + tableWidth) { - return `M ${x1} ${y1} L ${x1 - r - r} ${y1} A ${r} ${r} 0 0 1 ${ - x1 - r - r - r - } ${y1 - r} L ${x1 - r - r - r} ${y2 + r} A ${r} ${r} 0 0 1 ${ - x1 - r - r - } ${y2} L ${endX} ${y2}`; - } else if (x1 >= x2 && x1 <= x2 + tableWidth) { - return `M ${x1 + tableWidth - 2 * offsetX} ${y1} L ${ - x1 + tableWidth - 2 * offsetX + r - } ${y1} A ${r} ${r} 0 0 0 ${x1 + tableWidth - 2 * offsetX + r + r} ${ - y1 - r - } L ${x1 + tableWidth - 2 * offsetX + r + r} ${ - y2 + r - } A ${r} ${r} 0 0 0 ${x1 + tableWidth - 2 * offsetX + r} ${y2} L ${ - x2 + tableWidth - 2 * offsetX - } ${y2}`; - } else { - return `M ${x1} ${y1} L ${midX + r} ${y1} A ${r} ${r} 0 0 1 ${midX} ${ - y1 - r - } L ${midX} ${y2 + r} A ${r} ${r} 0 0 0 ${ - midX - r - } ${y2} L ${endX} ${y2}`; - } - } -}; - export { - enterFullscreen, - exitFullscreen, - jsonDiagramIsValid, - ddbDiagramIsValid, - dataURItoBlob, jsonToMySQL, jsonToPostgreSQL, validateDiagram, - arrayIsEqual, isSized, getSize, hasPrecision, validateDateStr, hasCheck, - calcPath, jsonToSQLite, jsonToMariaDB, jsonToSQLServer, diff --git a/src/utils/utils.js b/src/utils/utils.js new file mode 100644 index 0000000..bf07b99 --- /dev/null +++ b/src/utils/utils.js @@ -0,0 +1,18 @@ +function dataURItoBlob(dataUrl) { + const byteString = atob(dataUrl.split(",")[1]); + const mimeString = dataUrl.split(",")[0].split(":")[1].split(";")[0]; + const arrayBuffer = new ArrayBuffer(byteString.length); + const intArray = new Uint8Array(arrayBuffer); + + for (let i = 0; i < byteString.length; i++) { + intArray[i] = byteString.charCodeAt(i); + } + + return new Blob([intArray], { type: mimeString }); +} + +function arrayIsEqual(arr1, arr2) { + return JSON.stringify(arr1) === JSON.stringify(arr2); +} + +export { dataURItoBlob, arrayIsEqual }; diff --git a/src/utils/validateSchema.js b/src/utils/validateSchema.js new file mode 100644 index 0000000..926ebfa --- /dev/null +++ b/src/utils/validateSchema.js @@ -0,0 +1,12 @@ +import { Validator } from "jsonschema"; +import { ddbSchema, jsonSchema } from "../data/schemas"; + +function jsonDiagramIsValid(obj) { + return new Validator().validate(obj, jsonSchema).valid; +} + +function ddbDiagramIsValid(obj) { + return new Validator().validate(obj, ddbSchema).valid; +} + +export { jsonDiagramIsValid, ddbDiagramIsValid };