Fix fit window, move hardcoded constants to constants.js (#482)

* fix fit window, move hardcoded constants to constants.js

* comment fixes

* change import from utils.js to utils
This commit is contained in:
Karen Mkrtumyan
2025-06-08 00:22:31 +04:00
committed by GitHub
parent 938ad7c01d
commit f85adf0577
7 changed files with 99 additions and 45 deletions

View File

@@ -28,6 +28,7 @@ import { useTranslation } from "react-i18next";
import { useEventListener } from "usehooks-ts"; import { useEventListener } from "usehooks-ts";
import { areFieldsCompatible } from "../../utils/utils"; import { areFieldsCompatible } from "../../utils/utils";
import { getRectFromEndpoints, isInsideRect } from "../../utils/rect"; import { getRectFromEndpoints, isInsideRect } from "../../utils/rect";
import { noteWidth } from "../../data/constants";
export default function Canvas() { export default function Canvas() {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -154,7 +155,7 @@ export default function Canvas() {
{ {
x: note.x, x: note.x,
y: note.y, y: note.y,
width: 180, width: noteWidth,
height: note.height, height: note.height,
}, },
rect, rect,

View File

@@ -15,11 +15,9 @@ import {
useSaveState, useSaveState,
} from "../../hooks"; } from "../../hooks";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { noteWidth, noteRadius, noteFold } from "../../data/constants";
export default function Note({ data, onPointerDown }) { export default function Note({ data, onPointerDown }) {
const w = 180;
const r = 3;
const fold = 24;
const [editField, setEditField] = useState({}); const [editField, setEditField] = useState({});
const [hovered, setHovered] = useState(false); const [hovered, setHovered] = useState(false);
const { layout } = useLayout(); const { layout } = useLayout();
@@ -102,15 +100,15 @@ export default function Note({ data, onPointerDown }) {
}} }}
> >
<path <path
d={`M${data.x + fold} ${data.y} L${data.x + w - r} ${ d={`M${data.x + noteFold} ${data.y} L${data.x + noteWidth - noteRadius} ${
data.y data.y
} A${r} ${r} 0 0 1 ${data.x + w} ${data.y + r} L${data.x + w} ${ } A${noteRadius} ${noteRadius} 0 0 1 ${data.x + noteWidth} ${data.y + noteRadius} L${data.x + noteWidth} ${
data.y + data.height - r data.y + data.height - noteRadius
} A${r} ${r} 0 0 1 ${data.x + w - r} ${data.y + data.height} L${ } A${noteRadius} ${noteRadius} 0 0 1 ${data.x + noteWidth - noteRadius} ${data.y + data.height} L${
data.x + r data.x + noteRadius
} ${data.y + data.height} A${r} ${r} 0 0 1 ${data.x} ${ } ${data.y + data.height} A${noteRadius} ${noteRadius} 0 0 1 ${data.x} ${
data.y + data.height - r data.y + data.height - noteRadius
} L${data.x} ${data.y + fold}`} } L${data.x} ${data.y + noteFold}`}
fill={data.color} fill={data.color}
stroke={ stroke={
hovered hovered
@@ -124,11 +122,11 @@ export default function Note({ data, onPointerDown }) {
strokeWidth="2" strokeWidth="2"
/> />
<path <path
d={`M${data.x} ${data.y + fold} L${data.x + fold - r} ${ d={`M${data.x} ${data.y + noteFold} L${data.x + noteFold - noteRadius} ${
data.y + fold data.y + noteFold
} A${r} ${r} 0 0 0 ${data.x + fold} ${data.y + fold - r} L${ } A${noteRadius} ${noteRadius} 0 0 0 ${data.x + noteFold} ${data.y + noteFold - noteRadius} L${
data.x + fold data.x + noteFold
} ${data.y} L${data.x} ${data.y + fold} Z`} } ${data.y} L${data.x} ${data.y + noteFold} Z`}
fill={data.color} fill={data.color}
stroke={ stroke={
hovered hovered
@@ -144,7 +142,7 @@ export default function Note({ data, onPointerDown }) {
<foreignObject <foreignObject
x={data.x} x={data.x}
y={data.y} y={data.y}
width={w} width={noteWidth}
height={data.height} height={data.height}
onPointerDown={onPointerDown} onPointerDown={onPointerDown}
> >

View File

@@ -22,6 +22,7 @@ import { useTranslation } from "react-i18next";
import { dbToTypes } from "../../data/datatypes"; import { dbToTypes } from "../../data/datatypes";
import { isRtl } from "../../i18n/utils/rtl"; import { isRtl } from "../../i18n/utils/rtl";
import i18n from "../../i18n/i18n"; import i18n from "../../i18n/i18n";
import { getTableHeight } from "../../utils/utils";
export default function Table(props) { export default function Table(props) {
const [hoveredField, setHoveredField] = useState(null); const [hoveredField, setHoveredField] = useState(null);
@@ -45,8 +46,7 @@ export default function Table(props) {
[settings.mode], [settings.mode],
); );
const height = const height = getTableHeight(tableData);
tableData.fields.length * tableFieldHeight + tableHeaderHeight + 7;
const isSelected = useMemo(() => { const isSelected = useMemo(() => {
return ( return (

View File

@@ -42,6 +42,7 @@ import {
SIDESHEET, SIDESHEET,
DB, DB,
IMPORT_FROM, IMPORT_FROM,
noteWidth,
} from "../../data/constants"; } from "../../data/constants";
import jsPDF from "jspdf"; import jsPDF from "jspdf";
import { useHotkeys } from "react-hotkeys-hook"; import { useHotkeys } from "react-hotkeys-hook";
@@ -79,6 +80,7 @@ import { socials } from "../../data/socials";
import { toDBML } from "../../utils/exportAs/dbml"; import { toDBML } from "../../utils/exportAs/dbml";
import { exportSavedData } from "../../utils/exportSavedData"; import { exportSavedData } from "../../utils/exportSavedData";
import { nanoid } from "nanoid"; import { nanoid } from "nanoid";
import { getTableHeight } from "../../utils/utils";
export default function ControlPanel({ export default function ControlPanel({
diagramId, diagramId,
@@ -516,19 +518,52 @@ export default function ControlPanel({
const resetView = () => const resetView = () =>
setTransform((prev) => ({ ...prev, zoom: 1, pan: { x: 0, y: 0 } })); setTransform((prev) => ({ ...prev, zoom: 1, pan: { x: 0, y: 0 } }));
const fitWindow = () => { const fitWindow = () => {
const diagram = document.getElementById("diagram").getBoundingClientRect();
const canvas = document.getElementById("canvas").getBoundingClientRect(); const canvas = document.getElementById("canvas").getBoundingClientRect();
const scaleX = canvas.width / diagram.width; const minMaxXY = {
const scaleY = canvas.height / diagram.height; minX: Infinity,
const scale = Math.min(scaleX, scaleY); minY: Infinity,
const translateX = canvas.left; maxX: -Infinity,
const translateY = canvas.top; maxY: -Infinity,
};
tables.forEach((table) => {
minMaxXY.minX = Math.min(minMaxXY.minX, table.x);
minMaxXY.minY = Math.min(minMaxXY.minY, table.y);
minMaxXY.maxX = Math.max(minMaxXY.maxX, table.x + settings.tableWidth);
minMaxXY.maxY = Math.max(minMaxXY.maxY, table.y + getTableHeight(table));
});
areas.forEach((area) => {
minMaxXY.minX = Math.min(minMaxXY.minX, area.x);
minMaxXY.minY = Math.min(minMaxXY.minY, area.y);
minMaxXY.maxX = Math.max(minMaxXY.maxX, area.x + area.width);
minMaxXY.maxY = Math.max(minMaxXY.maxY, area.y + area.height);
});
notes.forEach((note) => {
minMaxXY.minX = Math.min(minMaxXY.minX, note.x);
minMaxXY.minY = Math.min(minMaxXY.minY, note.y);
minMaxXY.maxX = Math.max(minMaxXY.maxX, note.x + noteWidth);
minMaxXY.maxY = Math.max(minMaxXY.maxY, note.y + note.height);
});
const padding = 10;
const width = minMaxXY.maxX - minMaxXY.minX + padding;
const height = minMaxXY.maxY - minMaxXY.minY + padding;
const scaleX = canvas.width / width;
const scaleY = canvas.height / height;
// Making sure the scale is a multiple of 0.05
const scale = Math.floor(Math.min(scaleX, scaleY) * 20) / 20;
const centerX = (minMaxXY.minX + minMaxXY.maxX) / 2;
const centerY = (minMaxXY.minY + minMaxXY.maxY) / 2;
setTransform((prev) => ({ setTransform((prev) => ({
...prev, ...prev,
zoom: scale - 0.01, zoom: scale,
pan: { x: translateX, y: translateY }, pan: { x: centerX, y: centerY },
})); }));
}; };
const edit = () => { const edit = () => {

View File

@@ -1,4 +1,10 @@
import { tableFieldHeight, tableHeaderHeight } from "../data/constants"; import {
tableFieldHeight,
tableHeaderHeight,
noteWidth,
noteRadius,
noteFold,
} from "../data/constants";
export default function Thumbnail({ diagram, i, zoom, theme }) { export default function Thumbnail({ diagram, i, zoom, theme }) {
return ( return (
@@ -111,37 +117,34 @@ export default function Thumbnail({ diagram, i, zoom, theme }) {
{diagram.notes?.map((n) => { {diagram.notes?.map((n) => {
const x = n.x; const x = n.x;
const y = n.y; const y = n.y;
const w = 180;
const r = 3;
const fold = 24;
const h = n.height; const h = n.height;
return ( return (
<g key={n.id}> <g key={n.id}>
<path <path
d={`M${x + fold} ${y} L${x + w - r} ${y} A${r} ${r} 0 0 1 ${ d={`M${x + noteFold} ${y} L${x + noteWidth - noteRadius} ${y} A${noteRadius} ${noteRadius} 0 0 1 ${
x + w x + noteWidth
} ${y + r} L${x + w} ${y + h - r} A${r} ${r} 0 0 1 ${ } ${y + noteRadius} L${x + noteWidth} ${y + h - noteRadius} A${noteRadius} ${noteRadius} 0 0 1 ${
x + w - r x + noteWidth - noteRadius
} ${y + h} L${x + r} ${y + h} A${r} ${r} 0 0 1 ${x} ${ } ${y + h} L${x + noteRadius} ${y + h} A${noteRadius} ${noteRadius} 0 0 1 ${x} ${
y + h - r y + h - noteRadius
} L${x} ${y + fold}`} } L${x} ${y + noteFold}`}
fill={n.color} fill={n.color}
stroke="rgb(168 162 158)" stroke="rgb(168 162 158)"
strokeLinejoin="round" strokeLinejoin="round"
strokeWidth="0.5" strokeWidth="0.5"
/> />
<path <path
d={`M${x} ${y + fold} L${x + fold - r} ${ d={`M${x} ${y + noteFold} L${x + noteFold - noteRadius} ${
y + fold y + noteFold
} A${r} ${r} 0 0 0 ${x + fold} ${y + fold - r} L${ } A${noteRadius} ${noteRadius} 0 0 0 ${x + noteFold} ${y + noteFold - noteRadius} L${
x + fold x + noteFold
} ${y} L${x} ${y + fold} Z`} } ${y} L${x} ${y + noteFold} Z`}
fill={n.color} fill={n.color}
stroke={"rgb(168 162 158)"} stroke={"rgb(168 162 158)"}
strokeLinejoin="round" strokeLinejoin="round"
strokeWidth="0.5" strokeWidth="0.5"
/> />
<foreignObject x={x} y={y} width={w} height={h}> <foreignObject x={x} y={y} width={noteWidth} height={h}>
<div className="text-gray-900 w-full h-full px-4 py-2"> <div className="text-gray-900 w-full h-full px-4 py-2">
<label htmlFor={`note_${n.id}`} className="ms-4"> <label htmlFor={`note_${n.id}`} className="ms-4">
{n.title} {n.title}

View File

@@ -1,5 +1,8 @@
export const defaultBlue = "#175e7a"; export const defaultBlue = "#175e7a";
export const defaultNoteTheme = "#fcf7ac"; export const defaultNoteTheme = "#fcf7ac";
export const noteWidth = 180;
export const noteRadius = 3;
export const noteFold = 24;
export const darkBgTheme = "#16161A"; export const darkBgTheme = "#16161A";
export const stringColor = "text-orange-500"; export const stringColor = "text-orange-500";
export const intColor = "text-yellow-500"; export const intColor = "text-yellow-500";

View File

@@ -1,5 +1,11 @@
import { dbToTypes } from "../data/datatypes"; import { dbToTypes } from "../data/datatypes";
import {
tableFieldHeight,
tableHeaderHeight,
tableColorStripHeight,
} from "../data/constants";
export function dataURItoBlob(dataUrl) { export function dataURItoBlob(dataUrl) {
const byteString = atob(dataUrl.split(",")[1]); const byteString = atob(dataUrl.split(",")[1]);
const mimeString = dataUrl.split(",")[0].split(":")[1].split(";")[0]; const mimeString = dataUrl.split(",")[0].split(":")[1].split(";")[0];
@@ -46,3 +52,11 @@ export function areFieldsCompatible(db, field1, field2) {
} }
return same; return same;
} }
export function getTableHeight(table) {
return (
table.fields.length * tableFieldHeight +
tableHeaderHeight +
tableColorStripHeight
);
}