Public
Edited
Mar 12, 2023
Insert cell
Insert cell
{
// Usual SVG setup
let w = 800;
let h = 500;
let pad = 30;
let svg = d3
.create("svg")
.attr("viewBox", `0 0 ${w} ${h}`)
.style("max-width", `${w}px`)
.style("border", "solid 1px black");

let [xmin, xmax] = d3.extent(data, (o) => o.AverageSalary);
let [ymin, ymax] = [0, 100];
let x_scale = d3
.scaleLinear()
.domain([xmin, xmax])
.range([pad, w - pad]);
let y_scale = d3
.scaleLinear()
.domain([ymin, ymax])
.range([h - pad, pad]);

// Draw the scatter points
let points = svg.append("g");
points
.selectAll("circle")
.data(data)
.join("circle")
.attr("cx", (d) => x_scale(d.AverageSalary))
.attr("cy", (d) => y_scale(d.RetentionRate))

.attr("r", (d) => (d.UnitID == 199111 ? 5 : 3))
.attr("fill", (d) => (d.UnitID == 199111 ? "#002366" : "lightgray"))
.attr("fill-opacity", (d) => (d.UnitID == 199111 ? 1 : 0.6))

// Highlight the points on pointerenter
.attr("stroke-width", 2)
.on("pointerenter", function () {
d3.select(this).attr("stroke", "black");
})
.on("pointerleave", function () {
d3.select(this).attr("stroke", null);
})

// Add an extra groovy tooltip using TippyJS
.each(function (datum) {
tippy(this, {
theme: "light-border",
allowHTML: true,
content: `<span style="font-weight: bold">${
datum.University
}</span>:<br> Average Salary: ${
datum.AverageSalary
}<br> Retention Rate: ${datum.RetentionRate / 100}`
});
});

// Compute and draw the regression line
let regression_result = regression
.regressionLinear()
.x((d) => d.AverageSalary)
.y((d) => d.RetentionRate)(data);
let [x1, y1, x2, y2] = regression_result.flat();
svg
.append("line")
.attr("x1", x_scale(x1))
.attr("y1", y_scale(y1))
.attr("x2", x_scale(x2))
.attr("y2", y_scale(y2))
.attr("stroke", d3.schemeCategory10[0])
.attr("stroke-width", 3);

// Axes
svg
.append("g")
.attr("transform", `translate(${pad})`)
.call(d3.axisLeft(y_scale).tickSizeOuter(0));
svg
.append("g")
.attr("transform", `translate(0,${h - pad})`)
.call(d3.axisBottom(x_scale).tickSizeOuter(0));

return svg.node();
}
Insert cell
data = (
await FileAttachment("salary_and_retention.csv").csv({ typed: true })
).filter((o) => o.AverageSalary && o.RetentionRate)
Insert cell
<link rel="stylesheet" href="${await require.resolve(
`tippy.js/themes/light-border.css`
)}">
Insert cell
tippy = require("tippy.js@6")
Insert cell
regression = require("d3-regression")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more