{
const features = ["sepalLength", "sepalWidth", "petalLength", "petalWidth"];
const subGraphSize = 200;
const margin = { left: 125, right: 0, top: 20, bottom: 20 };
const width = margin.left + margin.right + features.length * subGraphSize;
const height = margin.top + margin.bottom + features.length * subGraphSize;
const buffer = 50;
const svg = d3
.create("svg")
.attr("viewbox", [0, 0, width, height])
.style("height", `${height}px`)
.style("width", `${width}px`);
const legend = svg.append("g").attr("transform", "translate(0, 0)");
const entries = legend.selectAll("g").data(features).join("g");
for (let i = 0; i < features.length; ++i) {
svg
.append("text")
.attr("text-anchor", "middle")
.style("font-weight", "bold")
.style("font-size", "12px")
.attr("x", margin.left / 2 - 10)
.attr("y", margin.top + i * subGraphSize + (subGraphSize - buffer) / 2)
.text(features[i]);
svg
.append("text")
.attr("text-anchor", "middle")
.style("font-weight", "bold")
.style("font-size", "12px")
.attr("x", margin.left + i * subGraphSize + (subGraphSize - buffer) / 2)
.attr("y", height - margin.bottom / 2 - margin.top)
.text(features[i]);
for (let j = 0; j < features.length; ++j) {
if (j >= i) {
let g = make_scatterplot(
svg,
irisData,
features[i],
features[j],
subGraphSize - buffer
);
const graph_x_pos = margin.left + i * subGraphSize;
const graph_y_pos = margin.top + j * subGraphSize;
g.attr("transform", `translate(${graph_x_pos}, ${graph_y_pos})`);
}
}
}
function make_scatterplot(svg, data, fieldX, fieldY, graphSize) {
const x = d3
.scaleLinear()
.range([0, graphSize])
.domain([0, d3.extent(data, (d) => d[fieldX])[1]]);
const y = d3
.scaleLinear()
.range([graphSize, 0])
.domain([0, d3.extent(data, (d) => d[fieldY])[1]]);
const color = d3
.scaleOrdinal()
.range(d3.schemeCategory10)
.domain(data.map((d) => d.species));
const subgraph = svg.append("g");
subgraph
.selectAll("circle")
.data(data)
.join("circle")
.attr("cx", (d) => x(d[fieldX]))
.attr("cy", (d) => y(d[fieldY]))
.attr("r", 3)
.style("fill", (d) => color(d.species))
.style("opacity", 0.8);
subgraph
.append("g")
.call(d3.axisBottom(x).ticks(6))
.attr("transform", `translate(0, ${graphSize})`);
subgraph.append("g").call(d3.axisLeft(y).ticks(6));
return subgraph;
}
return svg.node();
}