import { ResultSet, sqlite } from "https://esm.town/v/std/sqlite?v=6";
import { Hono } from "npm:hono@3";
await sqlite.batch([
`CREATE TABLE IF NOT EXISTS draggable_circles (
idx INTEGER NOT NULL UNIQUE,
x REAL NOT NULL,
y REAL NOT NULL
)`,
]);
function parseResultSet<T>(row: ResultSet): T[] {
return row.rows.map((r) => Object.fromEntries(r.map((c, i) => [row.columns[i], c]))) as T[];
}
type Circle = {
x: number;
y: number;
idx: number;
};
const getCircles = async () => {
return parseResultSet<Circle>(await sqlite.execute("select * from draggable_circles"));
};
function diffCircles(array1: Circle[], array2: Circle[]): Circle[] {
const changes: Circle[] = [];
const map1 = new Map(array1.map(row => [row.idx, row]));
const map2 = new Map(array2.map(row => [row.idx, row]));
for (const [idx, row1] of map1) {
const row2 = map2.get(idx);
if (row2 && (row1.x !== row2.x || row1.y !== row2.y)) {
changes.push(row2);
}
}
return changes;
}
const clientCode = () => {
const height = 600;
const width = 600;
const radius = 32;
const svg = d3.select("svg");
const drag = (() => {
function dragstarted() {
d3.select(this).attr("stroke", "black");
}
function dragged(event, d) {
d3.select(this).raise().attr("cx", d.x = event.x).attr("cy", d.y = event.y);
}
function dragended() {
const x = d3.select(this).attr("cx");
const y = d3.select(this).attr("cy");
fetch(`/update?x=${x}&y=${y}&i=${d3.select(this).attr("idx")}`, { method: "post" });
d3.select(this).attr("stroke", null);
}
return d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended);
})();
window.circleObjects = svg.selectAll("circle")
.data(circles)
.join("circle")
.attr("cx", d => d.x)