chart = {
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);
const arrowId = DOM.uid("arrow");
const gradientIds = data.map(() => DOM.uid("gradient"));
svg.append("defs")
.append("marker")
.attr("id", arrowId.id)
.attr("markerHeight", 10)
.attr("markerWidth", 10)
.attr("refX", 5)
.attr("refY", 2.5)
.attr("orient", "auto")
.append("path")
.attr("fill", endColor)
.attr("d", "M0,0v5l7,-2.5Z");
svg.append("defs")
.selectAll("linearGradient")
.data(data)
.join("linearGradient")
.attr("id", (d, i) => gradientIds[i].id)
.attr("gradientUnits", "userSpaceOnUse")
.attr("x1", d => x(d.x1))
.attr("x2", d => x(d.x2))
.attr("y1", d => y(d.y1))
.attr("y2", d => y(d.y2))
.call(g => g.append("stop").attr("stop-color", startColor).attr("stop-opacity", 0.5))
.call(g => g.append("stop").attr("offset", "100%").attr("stop-color", endColor));
svg.append("g")
.call(grid);
svg.append("g")
.call(xAxis);
svg.append("g")
.call(yAxis);
svg.append("g")
.attr("fill", "none")
.selectAll("path")
.data(data)
.join("path")
.attr("stroke", (d, i) => gradientIds[i])
.attr("marker-end", arrowId)
.attr("d", d => arc(x(d.x1), y(d.y1), x(d.x2), y(d.y2)));
svg.append("g")
.attr("fill", "currentColor")
.selectAll("circle")
.data(data)
.join("circle")
.attr("r", 1.75)
.attr("cx", d => x(d.x1))
.attr("cy", d => y(d.y1));
svg.append("g")
.attr("fill", "currentColor")
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.attr("stroke", "white")
.attr("stroke-linejoin", "round")
.attr("stroke-width", 4)
.attr("paint-order", "stroke fill")
.selectAll("text")
.data(data.filter(d => true))
.join("text")
.attr("dy", "0.1em")
.attr("x", d => x(d.x1))
.attr("y", d => y(d.y1))
.text(d => d.cc);
return svg.node();
}