{
const width = 1200;
const height = 700;
const margin = { top: 20, right: 20, bottom: 20, left: 20 };
const svg = d3
.create("svg")
.attr("viewBox", [0, 0, width, height])
.attr("width", width)
.attr("height", height);
const angle = d3
.scaleUtc()
.domain([0, 24 * 60 * 60 * 1000])
.range([-90, 270]);
const dayAngle = d3
.scaleBand()
.domain([...dataOfDates.keys()])
.range([200, 360]);
const xScale = d3
.scaleBand()
.domain([...dataOfDates.keys()])
.range([margin.left, width - margin.right]);
const yScale = d3.scaleUtc().domain([0, 59]).range([30, 130]);
const dayScale = d3
.scaleLinear()
.domain([0, 30])
.range([0, height - margin.top]);
svg
.append("rect")
.attr("width", width)
.attr("height", height)
.attr("fill", "#ddddff")
.attr("opacity", 0.2);
svg
.append("g")
.selectAll("line")
.data(dataOfDates)
.join("line")
.attr(
"x1",
(d) =>
margin.left +
width / 2 +
Math.cos(dayAngle(d[0]) * (Math.PI / 180)) * dayScale(d[1].length)
)
.attr("y1", 0)
.attr(
"x2",
(d) =>
margin.left +
width / 2 +
Math.cos(dayAngle(d[0]) * (Math.PI / 180)) * dayScale(d[1].length)
)
.attr(
"y2",
(d) =>
height +
Math.sin(dayAngle(d[0]) * (Math.PI / 180)) * dayScale(d[1].length)
)
.attr("stroke", "#000");
const dayG = svg
.append("g")
.selectAll("g")
.data(dataOfDates)
.join("g")
.attr("class", "day")
.attr(
"transform",
(d) =>
`translate(${
margin.left +
width / 2 +
Math.cos(dayAngle(d[0]) * (Math.PI / 180)) * dayScale(d[1].length)
}, ${
height +
Math.sin(dayAngle(d[0]) * (Math.PI / 180)) * dayScale(d[1].length)
})`
);
dayG
.selectAll("rect")
.data((d) => d[1])
.join("rect")
.attr("transform", "rotate(180)")
.attr("height", (d) => yScale(d.minutes))
.attr("width", 0)
.transition()
.duration(2000)
.delay((d, i) => i * 80)
.attr("transform", (d) => `rotate(${angle(d.msec)})`)
.attr("height", (d) => yScale(d.minutes))
.attr("width", 10)
.attr("rx", 4)
.attr("ry", 4)
.attr("fill", (d, i) => {
if (d.turning === "ON") {
return "white";
} else if (d.turning === "OFF") {
return "black";
} else if (d.turning === "OTHER") {
return "orange";
}
})
.attr("stroke", "black")
.attr("opacity", 1);
svg
.append("g")
.selectAll("circle")
.data(dataOfDates)
.join("circle")
.attr(
"cx",
(d) =>
margin.left +
width / 2 +
Math.cos(dayAngle(d[0]) * (Math.PI / 180)) * dayScale(d[1].length)
)
.attr(
"cy",
(d) =>
height +
Math.sin(dayAngle(d[0]) * (Math.PI / 180)) * dayScale(d[1].length)
)
.attr("r", 13)
.attr("stroke", "black")
.attr("fill", "white");
return svg.node();
}