{
const svg = d3.create("svg").attr("viewBox", [0, 0, width, height]);
const color = d3.scaleSequentialSqrt([0, 40], d3.interpolateBlues);
svg
.append("g")
.selectAll()
.data(bins)
.join("path")
.attr("d", d => `M${d.polygon.map(e => [e.x, e.y]).join("L")}Z`)
.attr("fill", d => color(d.values.length));
svg
.append("g")
.selectAll()
.data(
[]
.concat(d3.range(0, 1, 1 / ticks).map(x => [[x, 0], [x, 1 - x]]))
.concat(d3.range(0, 1, 1 / ticks).map(x => [[0, x], [1 - x, x]]))
.concat(d3.range(0, 1, 1 / ticks).map(x => [[1 - x, 0], [0, 1 - x]]))
)
.join("path")
.attr(
"d",
d =>
`M${d
.map(transform)
.map(e => [e.x, e.y])
.join("L")}Z`
)
.attr("fill", "none")
.attr("stroke", "black")
.attr("stroke-width", .125);
svg
.append("g")
.append("path")
.attr(
"d",
d =>
`M${[[0, 0], [0, 1], [1, 0]]
.map(transform)
.map(e => [e.x, e.y])
.join("L")}Z`
)
.attr("fill", "none")
.attr("stroke", "black");
svg
.append("g")
.selectAll()
.data(data)
.join("circle")
.attr("r", 1.5)
.attr("transform", d => {
const e = transform([+d.agriculture / 100, +d.industry / 100]);
return `translate(${[e.x, e.y]})`;
});
svg
.append("g")
.style("text-anchor", "middle")
.style("font-size", "13px")
.selectAll()
.data(bins)
.join("text")
.attr("transform", d => `translate(${[d.x, d.y]})`)
.text(d => d.values.length)
.attr("dy", "0.35em")
.call(g => g.clone(true))
.attr("stroke", "white")
.attr("stroke-width", 3);
svg
.append("g")
.style("text-anchor", "middle")
.style("font-size", "13px")
.selectAll()
.data([
{ label: "Agriculture", ...transform([1, 0]) },
{ label: "Industry", ...transform([0, 1]) },
{ label: "Services", ...transform([0, 0]) }
])
.join("text")
.attr("transform", d => `translate(${[d.x, d.y]})`)
.text(d => d.label)
.attr("dy", "0.35em")
.call(g => g.clone(true))
.attr("stroke", "white")
.attr("stroke-width", 3);
return svg.node();
}