{
const width = 800;
const height = 300;
const margin = { top: 30, right: 30, bottom: 30, left: 120 };
const xScale = d3
.scaleLinear()
.domain([0, 4])
.range([margin.left, width - margin.right]);
const yScale = d3
.scaleBand()
.domain([...dataOfDatesTimes.keys()])
.range([margin.top, height - margin.bottom]);
const xAxis = d3
.axisBottom()
.scale(xScale)
.ticks(4)
.tickFormat((d) => [0, 6, 12, 18, 24][d])
.tickSize(-(height - margin.top - margin.bottom));
const yAxis = d3
.axisLeft()
.scale(yScale)
.ticks(7)
.tickFormat(dateFormat)
.tickSize(-(width - margin.left - margin.right));
const svg = d3.create("svg").attr("width", width).attr("height", height);
svg
.append("rect")
.attr("width", width)
.attr("height", height)
.attr("opacity", 0.1);
svg
.append("g")
.attr("class", "xAxis")
.attr("transform", `translate(0, ${height - margin.bottom})`)
.call(xAxis);
svg
.append("g")
.attr("class", "yAxis")
.attr("transform", `translate(${margin.left}, 0)`)
.call(yAxis);
const dayG = svg
.selectAll("g.day")
.data(dataOfDatesTimes)
.join("g")
.attr("class", "day")
.attr("transform", (d) => `translate(0, ${yScale(d[0])})`);
const timeG = dayG
.selectAll("g.time")
.data((d) => d[1])
.join("g")
.attr("class", "time")
.attr("transform", (d) => `translate(${xScale(d[0])}, 0)`);
const circleX = d3
.scaleBand()
.range([10, xScale(1) - xScale(0) - 10]);
timeG
.append("rect")
.attr("x", 5)
.attr("y", 5)
.attr("width", xScale(1) - xScale(0) - 10)
.attr("height", yScale.bandwidth() - 10)
.attr("rx", 10)
.attr("fill", "#fff")
.attr("fill-opacity", 0.5)
.attr("stroke", "steelblue")
.attr("stroke-width", 1);
timeG
.selectAll("circle")
.data((d) => d[1])
.join("circle")
.attr("cx", (d, i, nodes) => {
circleX.domain(d3.range(nodes.length));
return circleX(i) + circleX.bandwidth() / 2;
})
.attr("cy", yScale.bandwidth() / 2)
.attr("r", 10)
.attr("fill", "steelblue")
.attr("opacity", 0.5);
svg
.selectAll("g.xAxis, g.yAxis")
.selectAll("line, path")
.attr("stroke", "white")
.attr("opacity", 0.5);
svg.selectAll("g.xAxis, g.yAxis").selectAll("text").attr("font-size", 16);
return svg.node();
}