{
const svg = d3
.create("svg")
.attr("width", width)
.attr("height", height);
const g = svg.append("g").attr("transform", "translate(0,0)");
g.on("mousemove", function() {
const [x, y] = d3.mouse(this);
let { offsetX, offsetY } = d3.event;
console.log(x, y);
d3.select(this).attr(
"transform",
`translate(${(width / 2 - offsetX) * -1},${(height / 2 - offsetY) * -1})`
);
});
let d = `M${width / 2},${height / 2}`;
d +=
"a-1,-1 0 0 0-1,-1a-1.25,-1.25 0 0 0-1.25,1.25a-2.25,-2.25 0 0 02.25,2.25a-3.5,-3.5 0 0 03.5,-3.5a-5.75,-5.75 0 0 0-5.75,-5.75a-9.25,-9.25 0 0 0-9.25,9.25a-15,-15 0 0 015,15a-24.25,-24.25 0 0 024.25,-24.25a-39.25,-39.25 0 0 0-39.25,-39.25a-63.5,-63.5 0 0 0-63.5,63.5a-102.75,-102.75 0 0 0102.75,102.75a-166.25,-166.25 0 0 0166.25,-166.25a-269,-269 0 0 0-269,-269a-435.25,-435.25 0 0 0-435.25,435.25a-704.25,-704.25 0 0 0704.25,704.25";
const myPath = g
.append("path")
.attr("d", d)
.attr("fill", "transparent")
.attr("stroke", "steelblue");
const myPathNode = myPath.node();
const pathLength = myPathNode.getTotalLength();
const range = function* range(start = 0, end = undefined, step = 1) {
if (arguments.length === 1) {
(end = start), (start = 0);
}
[...arguments].forEach(arg => {
if (typeof arg !== 'number') {
throw new TypeError("Invalid argument");
}
});
if (arguments.length === 0) {
throw new TypeError("range requires at least 1 argument, got 0");
}
if (start >= end) return;
yield start;
yield* range(parseInt(start + step), end, step);
};
const circleData = [
...range(circleRadius, pathLength - circleRadius, circleInterval)
].map(l => {
return myPathNode.getPointAtLength(l);
});
const circles = g
.selectAll("circle.int")
.data(circleData)
.enter()
.append("circle")
.attr("fill", "transparent")
.attr("stroke", "black")
.attr("stroke-width", 2)
.attr("r", (d, i) => `${circleRadius * i}`)
.attr("cx", d => `${d.x}`)
.attr("cy", d => `${d.y}`);
return svg.node();
}