chart = {
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height])
.attr("font-family", "sans-serif")
.attr("font-size", 10);
svg.append("g")
.attr("text-anchor", "middle")
.selectAll("g")
.data(data.columns)
.join("g")
.attr("transform", (d, i) => `translate(${x(i)},20)`)
.call(g => g.append("text").text(d => d))
.call(g => g.append("line").attr("y1", 3).attr("y2", 9).attr("stroke", "currentColor"));
svg.append("g")
.attr("fill", "none")
.attr("stroke", "currentColor")
.selectAll("path")
.data(data)
.join("path")
.attr("d", d => line(d.values))
.attr("class", (d) => "item" + d.id)
.attr("stroke", (d) => d.values.reduce((a,b) => a-b) < 0 ? "green" : "red" );
svg.append("g")
.selectAll("g")
.data(data.columns)
.join("g")
.attr("transform", (d, i) => `translate(${x(i) + (i === 0 ? -padding : i === n - 1 ? padding : 0)},0)`)
.attr("text-anchor", (d, i) => i === 0 ? "end" : i === n - 1 ? "start" : "middle")
.selectAll("text")
.data((d, i) => d3.zip(
data.map(i === 0 ? d => `${d.name} ${formatNumber(d.values[i])}`
: i === n - 1 ? d => `${formatNumber(d.values[i])} ${d.name}`
: d => `${formatNumber(d.values[i])}`),
dodge(data.map(d => y(d.values[i]))),
data.map((d) => d.id)
))
.join("text")
.attr("class", (d) => "itemtexts item" + d[2])
.attr("y", ([, y]) => y)
.attr("dy", "0.35em")
.text(([text]) => text)
.call(halo);
svg
.selectAll("path")
.on("touchmove mouseover", (event, d) => {
svg
.selectAll(".item" + d.id)
.style("font-weight", "bold")
.style("stroke-width", 3);
})
.on("touchend mouseout", (event, d) => {
svg
.selectAll(".item" + d.id)
.style("font-weight", "normal")
.style("stroke-width", 1);
});
svg
.selectAll(".itemtexts")
.on("touchmove mouseover", (event, d) => {
svg
.selectAll(".item" + d[2])
.style("font-weight", "bold")
.style("stroke-width", 3);
})
.on("touchend mouseout", (event, d) => {
svg
.selectAll(".item" + d[2])
.style("font-weight", "normal")
.style("stroke-width", 1);
});
return svg.node();
}