feat: add debug coordinate overlay

Makes debugging issues in conversion from screen space
to diagram space easier.

Only adding english translations as I do not speak the
other languages.
This commit is contained in:
Felix Zedén Yverås 2024-06-27 18:03:44 +02:00
parent 354ea47529
commit 32c82168fe
4 changed files with 184 additions and 91 deletions

View File

@ -433,100 +433,173 @@ export default function Canvas() {
const theme = localStorage.getItem("theme"); const theme = localStorage.getItem("theme");
return ( return (
<div className="flex-grow h-full touch-none" id="canvas"> <>
<div ref={canvas} className="w-full h-full"> <div className="flex-grow h-full touch-none" id="canvas">
<svg <div ref={canvas} className="w-full h-full">
onPointerMove={handlePointerMove} <svg
onPointerDown={handlePointerDown} onPointerMove={handlePointerMove}
onPointerUp={handlePointerUp} onPointerDown={handlePointerDown}
className="w-full h-full" onPointerUp={handlePointerUp}
style={{ className="w-full h-full"
cursor: cursor, style={{
backgroundColor: theme === "dark" ? "rgba(22, 22, 26, 1)" : "white", cursor: cursor,
}} backgroundColor:
> theme === "dark" ? "rgba(22, 22, 26, 1)" : "white",
{settings.showGrid && ( }}
<> >
<defs> {settings.showGrid && (
<pattern <>
id="pattern-circles" <defs>
<pattern
id="pattern-circles"
x="0"
y="0"
width="24"
height="24"
patternUnits="userSpaceOnUse"
patternContentUnits="userSpaceOnUse"
>
<circle
id="pattern-circle"
cx="4"
cy="4"
r="0.85"
fill="rgb(99, 152, 191)"
></circle>
</pattern>
</defs>
<rect
x="0" x="0"
y="0" y="0"
width="24" width="100%"
height="24" height="100%"
patternUnits="userSpaceOnUse" fill="url(#pattern-circles)"
patternContentUnits="userSpaceOnUse" ></rect>
> </>
<circle
id="pattern-circle"
cx="4"
cy="4"
r="0.85"
fill="rgb(99, 152, 191)"
></circle>
</pattern>
</defs>
<rect
x="0"
y="0"
width="100%"
height="100%"
fill="url(#pattern-circles)"
></rect>
</>
)}
<g
style={{
transform: `translate(${transform.pan.x}px, ${transform.pan.y}px) scale(${transform.zoom})`,
transformOrigin: "top left",
}}
id="diagram"
>
{areas.map((a) => (
<Area
key={a.id}
data={a}
onPointerDown={(e) =>
handlePointerDownOnElement(e, a.id, ObjectType.AREA)
}
setResize={setAreaResize}
setInitCoords={setInitCoords}
/>
))}
{relationships.map((e, i) => (
<Relationship key={i} data={e} />
))}
{tables.map((table) => (
<Table
key={table.id}
tableData={table}
setHoveredTable={setHoveredTable}
handleGripField={handleGripField}
setLinkingLine={setLinkingLine}
onPointerDown={(e) =>
handlePointerDownOnElement(e, table.id, ObjectType.TABLE)
}
/>
))}
{linking && (
<path
d={`M ${linkingLine.startX} ${linkingLine.startY} L ${linkingLine.endX} ${linkingLine.endY}`}
stroke="red"
strokeDasharray="8,8"
/>
)} )}
{notes.map((n) => ( <g
<Note style={{
key={n.id} transform: `translate(${transform.pan.x}px, ${transform.pan.y}px) scale(${transform.zoom})`,
data={n} transformOrigin: "top left",
onPointerDown={(e) => }}
handlePointerDownOnElement(e, n.id, ObjectType.NOTE) id="diagram"
} >
/> {areas.map((a) => (
))} <Area
</g> key={a.id}
</svg> data={a}
onPointerDown={(e) =>
handlePointerDownOnElement(e, a.id, ObjectType.AREA)
}
setResize={setAreaResize}
setInitCoords={setInitCoords}
/>
))}
{relationships.map((e, i) => (
<Relationship key={i} data={e} />
))}
{tables.map((table) => (
<Table
key={table.id}
tableData={table}
setHoveredTable={setHoveredTable}
handleGripField={handleGripField}
setLinkingLine={setLinkingLine}
onPointerDown={(e) =>
handlePointerDownOnElement(e, table.id, ObjectType.TABLE)
}
/>
))}
{linking && (
<path
d={`M ${linkingLine.startX} ${linkingLine.startY} L ${linkingLine.endX} ${linkingLine.endY}`}
stroke="red"
strokeDasharray="8,8"
/>
)}
{notes.map((n) => (
<Note
key={n.id}
data={n}
onPointerDown={(e) =>
handlePointerDownOnElement(e, n.id, ObjectType.NOTE)
}
/>
))}
</g>
</svg>
</div>
{settings.showDebugCoordinates && (
<div className="fixed flex flex-col flex-wrap gap-6 bg-[rgba(var(--semi-grey-1),var(--tw-bg-opacity))]/40 border border-color bottom-4 right-4 p-4 rounded-xl backdrop-blur-sm pointer-events-none select-none">
<table className="table-auto grow">
<thead>
<tr>
<th className="text-left" colSpan={3}>
{t("transform")}
</th>
</tr>
<tr className="italic [&_th]:font-normal [&_th]:text-right">
<th>pan x</th>
<th>pan y</th>
<th>scale</th>
</tr>
</thead>
<tbody className="[&_td]:text-right [&_td]:min-w-[8ch]">
<tr>
<td>{transform.pan.x.toFixed(2)}</td>
<td>{transform.pan.y.toFixed(2)}</td>
<td>{transform.zoom.toFixed(4)}</td>
</tr>
</tbody>
</table>
<table className="table-auto grow [&_th]:text-left [&_th:not(:first-of-type)]:text-right [&_td:not(:first-of-type)]:text-right [&_td]:min-w-[8ch]">
<thead>
<tr>
<th colSpan={4}>{t("viewbox")}</th>
</tr>
<tr className="italic [&_th]:font-normal">
<th>left</th>
<th>top</th>
<th>width</th>
<th>height</th>
</tr>
</thead>
<tbody>
<tr>
<td>TODO</td>
<td>TODO</td>
<td>TODO</td>
<td>TODO</td>
</tr>
</tbody>
</table>
<table className="table-auto grow [&_th]:text-left [&_th:not(:first-of-type)]:text-right [&_td:not(:first-of-type)]:text-right [&_td]:min-w-[8ch]">
<thead>
<tr>
<th colSpan={3}>{t("cursor_coordinates")}</th>
</tr>
<tr className="italic [&_th]:font-normal">
<th>{t("coordinate_space")}</th>
<th>x</th>
<th>y</th>
</tr>
</thead>
<tbody>
<tr>
<td>{t("coordinate_space_screen")}</td>
<td>TODO</td>
<td>TODO</td>
</tr>
<tr>
<td>{t("coordinate_space_diagram")}</td>
<td>TODO</td>
<td>TODO</td>
</tr>
</tbody>
</table>
</div>
)}
</div> </div>
</div> </>
); );
} }

View File

@ -1158,6 +1158,18 @@ export default function ControlPanel({
showCardinality: !prev.showCardinality, showCardinality: !prev.showCardinality,
})), })),
}, },
show_debug_coordinates: {
state: settings.showDebugCoordinates ? (
<i className="bi bi-toggle-on" />
) : (
<i className="bi bi-toggle-off" />
),
function: () =>
setSettings((prev) => ({
...prev,
showDebugCoordinates: !prev.showDebugCoordinates,
})),
},
theme: { theme: {
children: [ children: [
{ {

View File

@ -13,6 +13,7 @@ export default function SettingsContextProvider({ children }) {
panning: true, panning: true,
showCardinality: true, showCardinality: true,
tableWidth: tableWidth, tableWidth: tableWidth,
showCursorCoordinates: false,
}); });
return ( return (

View File

@ -59,6 +59,13 @@ const en = {
show_timeline: "Show timeline", show_timeline: "Show timeline",
autosave: "Autosave", autosave: "Autosave",
panning: "Panning", panning: "Panning",
show_debug_coordinates: "Show debug coordinates",
transform: "Transform",
viewbox: "View Box",
cursor_coordinates: "Cursor Coordinates",
coordinate_space: "Space",
coordinate_space_screen: "Screen",
coordinate_space_diagram: "Diagram",
table_width: "Table width", table_width: "Table width",
language: "Language", language: "Language",
flush_storage: "Flush storage", flush_storage: "Flush storage",