function chart(data, comment, symbols, hachures) {
const x = d3.scaleLinear(d3.extent(data, d => d.x), [20, width - 20]);
const y = d3.scaleLinear(d3.extent(data, d => d.y), [20, height - 23]);
const s = d3.scaleOrdinal(new Set(data.map(d => d.type)), symbols);
const r = d3.scaleSqrt();
const svg = d3
.create("svg")
.attr("viewBox", `0 0 ${width} ${height + 60}`)
.attr("width", width)
.classed("chart", true);
if (hachures) svg.call(hachures);
svg
.append("rect")
.attr("x", 1)
.attr("y", 1)
.attr("width", width - 2)
.attr("height", height - 2)
.attr("fill", "none")
.attr("stroke-width", 1.5)
.attr("stroke", "black");
svg
.append("defs")
.selectAll()
.data(symbols)
.join("g")
.attr("id", d => d[0])
.html(d => d[1]);
svg
.append("g")
.selectAll()
.data(data)
.join("use")
.attr("href", d => "#" + s(d.type)[0])
.attr("transform", d => `translate(${x(d.x)},${y(d.y)})scale(${r(3.8)})`);
svg
.append("foreignObject")
.attr("width", width)
.attr("height", 55)
.attr("y", height + 5)
.append("xhtml:div")
.html(comment);
return svg.node();
}