chart = {
const svg = d3.create("svg").attr("width", config.w).attr("height", config.h);
const scaleTimeY = d3
.scaleTime()
.domain([essentials.start, essentials.end])
.range([config.my, config.h - config.my * 2]);
const axisY = d3
.axisLeft(scaleTimeY)
.tickFormat(d3.timeFormat("%H:%M"))
.ticks(d3.timeHour);
const gAxisY = svg.append("g");
gAxisY.attr("transform", `translate(${config.mx},0)`);
gAxisY.call(axisY);
gAxisY
.selectAll(".tick > line")
.attr("x1", -config.w + config.mx * 2)
.attr("transform", `translate(${config.w - config.mx * 2})`);
const chartMain = svg
.append("g")
.attr("transform", `translate(${config.mx},0)`);
const scaleColor = d3
.scaleOrdinal(d3.schemeCategory10)
.domain(Array.from(groupedData.keys()));
const chartCateg = svg
.append("g")
.attr("transform", `translate(${config.mx + 45},0)`);
const scaleCategX = d3
.scaleBand()
.domain(Array.from(groupedData.keys()))
.range([0, 150])
.paddingInner(0.5);
const gLegend = svg.append("g");
gLegend.attr("transform", `translate(${config.w - config.mx},${config.my})`);
function render() {
chartMain
.selectAll(".main-chart-item")
.data(schedules, (d) => d.id)
.join((enter) =>
enter
.append("rect")
.attr("class", "main-chart-item")
.attr("rx", 3)
.attr("ry", 3)
.attr("fill", (d) => scaleColor(d.content))
.attr("opacity", 0.5)
.attr("transform", (d) => `translate(0, ${scaleTimeY(d.time)})`)
.attr("width", (d) => 30)
.attr("height", (d) => scaleTimeY(d.nextTime) - scaleTimeY(d.time))
);
chartCateg
.selectAll(".categ-chart-item")
.data(schedules)
.join((enter) =>
enter
.append("rect")
.attr("class", "categ-chart-item")
.attr("rx", 3)
.attr("ry", 3)
.attr("fill", (d) => scaleColor(d.content))
.attr("width", (d) => scaleCategX.bandwidth())
.attr("height", (d) => scaleTimeY(d.nextTime) - scaleTimeY(d.time))
.attr(
"transform",
(d) => `translate(${scaleCategX(d.content)},${scaleTimeY(d.time)})`
)
);
gLegend
.selectAll(".legend-item")
.data(Array.from(groupedData))
.join((enter) =>
enter
.append("g")
.attr("class", "legend-item")
.attr("transform", (d, i) => `translate(-30, ${i * 30})`)
.attr("text-anchor", "end")
.attr("dominant-baseline", "hanging")
.call((l) =>
l
.append("text")
.text(
([k, v]) =>
`${k} - ${luxon.Duration.fromMillis(v).toFormat(
"hh'h'mm'm'"
)}`
)
)
.call((l) =>
l
.append("rect")
.attr("width", "10")
.attr("height", "10")
.attr("fill", ([k, v]) => scaleColor(k))
)
);
}
render();
return Object.assign(svg.node(), { render });
}