chart = {
const container = d3
.create("div")
.attr("class", "container")
.style("background", background)
.style("font-family", "sans-serif")
.style("font-size", "12px")
.style("user-select", "none");
const svg = container
.append("svg")
.attr("shape-rendering", "optimizeSpeed")
.attr("width", width)
.attr("height", height);
const defs = svg.append("defs");
const g = svg.append("g");
data.sort((a, b) => b.Start - a.Start).reverse();
let xOffset = 10;
let yOffset = 50;
data.forEach((d, i) => {
const gradient = defs
.append("linearGradient")
.attr("id", `textGradient_${i}`)
.attr("x1", "0%")
.attr("y1", "0%")
.attr("x2", "100%")
.attr("y2", "0%");
gradient.append("stop").attr("offset", "0%").attr("stop-color", color1);
gradient.append("stop").attr("offset", "25%").attr("stop-color", color2);
const color = categoryColors[d.Category] || "black";
gradient.append("stop").attr("offset", "100%").attr("stop-color", color);
g.append("text")
.attr("x", xOffset)
.attr("y", yOffset)
.text(d.Title)
.attr("fill", `url(#textGradient_${i})`);
if (i < data.length - 1 && data[i].Start === data[i + 1].Start) {
xOffset += 20;
yOffset -= 20;
} else {
xOffset += 80;
yOffset = 50;
}
});
const zoomed = ({ transform }) => {
g.attr("transform", transform);
};
const zoom = d3.zoom().scaleExtent([0, 8]).on("zoom", zoomed);
svg.call(zoom);
return container.node();
}