Build a Box Plot Calculator in Pure JavaScript — No Libraries Needed
A box plot (or box-and-whisker plot) is one of the most powerful tools in exploratory data analysis. In one compact graphic, it reveals the median, spread, skewness, and outliers of a dataset — all from just five numbers.
In this tutorial, I'll walk through building a complete box plot calculator from scratch using vanilla JavaScript and SVG. No D3, no Chart.js, no dependencies. By the end, you'll understand:
- How to compute quartiles the right way
- How to detect outliers with Tukey's fences
- How to render a box plot as SVG
- Why all of this matters for real-world data analysis
If you want to skip the code and use a ready-made tool, I built too.
Try it now → , you can switch between these thresholds in real time.
4. Rendering as SVG
Now for the fun part — turning numbers into a chart. Here's the core SVG rendering logic:
CODEfunction renderBoxPlot(stats, width = 500, height = 200) {
const { min, q1, median, q3, max, outliers } = stats;
// Scale setup
const padL = 50, padR = 30, padT = 20, padB = 40;
const plotW = width - padL - padR;
const plotH = height - padT - padB;
const dataMin = Math.min(min, ...outliers);
const dataMax = Math.max(max, ...outliers);
const range = dataMax - dataMin || 1;
const paddedMin = dataMin - range * 0.08;
const paddedMax = dataMax + range * 0.08;
const paddedRange = paddedMax - paddedMin;
// Map data value → SVG x-coordinate
const sx = (v) => padL + plotW * ((v - paddedMin) / paddedRange);
const boxY = padT + plotH * 0.2;
const boxH = plotH * 0.6;
const yc = padT + plotH / 2;
const color = "#2563eb";
return `
<svg viewBox="0 0 ${width} ${height}" xmlns="http://www.w3.org/2000/svg">
<!-- Axis -->
<line x1="${padL}" y1="${padT + plotH}"
x2="${padL + plotW}" y2="${padT + plotH}"
stroke="#d1d5db" stroke-width="0.5"/>
<!-- Left whisker -->
<line x1="${sx(min)}" y1="${yc - boxH / 4}"
x2="${sx(min)}" y2="${yc + boxH / 4}"
stroke="${color}" stroke-width="1.5" stroke-linecap="round"/>
<line x1="${sx(min)}" y1="${yc}"
x2="${sx(q1)}" y2="${yc}"
stroke="${color}" stroke-width="0.5" stroke-dasharray="3 3"/>
<!-- Box (Q1 to Q3) -->
<rect x="${sx(q1)}" y="${boxY}"
width="${sx(q3) - sx(q1)}" height="${boxH}"
fill="${color}" opacity="0.15" stroke="${color}" stroke-width="1.5" rx="2"/>
<!-- Median line -->
<line x1="${sx(median)}" y1="${boxY}"
x2="${sx(median)}" y2="${boxY + boxH}"
stroke="${color}" stroke-width="2" stroke-linecap="round"/>
<!-- Right whisker -->
<line x1="${sx(q3)}" y1="${yc}"
x2="${sx(max)}" y2="${yc}"
stroke="${color}" stroke-width="0.5" stroke-dasharray="3 3"/>
<line x1="${sx(max)}" y1="${yc - boxH / 4}"
x2="${sx(max)}" y2="${yc + boxH / 4}"
stroke="${color}" stroke-width="1.5" stroke-linecap="round"/>
<!-- Outlier dots -->
${outliers.map(o => `<circle cx="${sx(o)}" cy="${yc}" r="4"
fill="none" stroke="${color}" stroke-width="1.5"/>`).join("")}
</svg>
`;
}
The key insight: SVG is just XML. A box plot is just
<line>,<rect>, and<circle>elements — no canvas, no external libraries.
5. Putting It All Together
CODE// Example: exam scores from two classes
const dataA = [72, 85, 78, 90, 65, 88, 76, 92, 70, 84, 79, 86, 74, 91, 68, 83, 77, 89, 71, 95];
const dataB = [60, 62, 58, 70, 55, 68, 72, 64, 68, 61, 75, 66, 53, 77, 69, 71, 59, 63, 67, 74];
const statsA = calculateStats(dataA);
const statsB = calculateStats(dataB);
console.log("Class A — Median:", statsA.median, "IQR:", statsA.iqr);
console.log("Class B — Median:", statsB.median, "IQR:", statsB.iqr);
console.log("Outliers in A:", statsA.outliers);
console.log("Outliers in B:", statsB.outliers);
document.getElementById("chart-a").innerHTML = renderBoxPlot(statsA);
document.getElementById("chart-b").innerHTML = renderBoxPlot(statsB);
Side-by-side comparison instantly reveals:
- Class A has a higher median and wider spread
- No outliers in either class
- Class B scores are more tightly clustered
This kind of insight takes seconds with a box plot — and pages of text to describe otherwise.
From Demo to Production
Building a working box plot is straightforward. Building a great one takes more:
Multi-dataset comparison — stacking boxes vertically with independent colors
Notched boxes — 95% confidence intervals around the median (McGill-Tukey-Kramer method)
Jitter scatter overlays — showing every raw data point without overlap
Responsive scaling — charts that look sharp at any screen size
Export to PNG/SVG — for papers, presentations, and reports
AI-powered analysis — automatic insights about distribution shape and skewness
I built so you can see exactly how every calculation and SVG element is constructed.
Make your first box plot → a try.
↗ Original-Artikel auf dev.to lesenVollständiger Original-BerichtAusführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
SOCIAL SHARE CARD GENERATOR