clock = {
const width = 400;
const radius = width / 2;
const height = width;
const [cx, cy] = [width / 2, height / 2];
const minTickLength = 20;
const hourTickLength = 40;
const hourTickWidth = 10;
const svg = d3
.create("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [0, 0, width, height]);
const center = svg.append("g").attr("transform", `translate(${cx}, ${cy})`);
const sixty = d3.range(0, 60);
const twelve = d3.range(0, 12);
const scaleSixty = d3
.scaleLinear()
.domain([0, 60])
.range([0, 2 * Math.PI]);
const scaleTwelve = d3
.scaleLinear()
.domain([0, 12])
.range([0, 2 * Math.PI]);
const minuteTicks = center
.selectAll("line.minute-ticks")
.data(sixty)
.join("line")
.attr("class", "minute-ticks")
.attr("x1", radius)
.attr("x2", radius - 12)
.attr("stroke", "black")
.attr("stroke-width", 4)
.attr("transform", (m) => `rotate(${min2deg(m)})`);
const hourTicks = center
.selectAll("line.marker-hours")
.data(twelve)
.join("line")
.attr("class", "marker-hours")
.attr("x2", hourTickLength)
.attr("stroke", "black")
.attr("stroke-width", 10)
.attr(
"transform",
(h) => `rotate(${hour2deg(h)})translate(${radius - hourTickLength}, 0)`
);
const handles = center.append("g");
const handleHours = center.append("g");
handleHours
.append("line")
.attr("x1", -40)
.attr("x2", radius - 60)
.attr("stroke", "black")
.attr("stroke-width", 18);
const handleMinutes = center.append("g");
handleMinutes
.append("line")
.attr("x1", -40)
.attr("x2", radius - 10)
.attr("stroke", "black")
.attr("stroke-width", 16);
const secondHandleColor = "red";
const handleSeconds = center.append("g");
handleSeconds.append("circle").attr("r", 8).attr("fill", secondHandleColor);
handleSeconds
.append("line")
.attr("x1", -60)
.attr("x2", 140)
.attr("stroke-width", 6)
.attr("stroke", secondHandleColor);
handleSeconds
.append("circle")
.attr("cx", 140)
.attr("r", 14)
.attr("fill", secondHandleColor);
function updateClock() {
const { hours, minutes, secondsDecimal } = getDateParts(new Date());
handleHours
.data([hours + minutes / 60])
.attr("transform", (h) => `rotate(${hour2deg(h)})`);
handleMinutes
.data([minutes])
.attr("transform", (m) => `rotate(${min2deg(m)})`);
handleSeconds
.data([secondsDecimal])
.attr("transform", (s) => `rotate(${sec2deg(s)})`);
}
const intervalId = setInterval(() => {
updateClock();
}, 1000 / 10);
return svg.node();
}