You Might Also Like
Skills Assessment Radar Chart — Free SVG Spider Chart UI
Skills Assessment Radar Chart · Charts · Plain HTML, CSS & JS · Live preview
What's included
Features
About this UI Snippet
Skills Assessment Radar Chart — Trig-Plotted SVG Spider Chart

The skills assessment radar chart plots several skill dimensions — communication, technical, leadership, and more — as a polygon on a spoke grid, so a reviewer can read strengths and gaps at a glance. This snippet computes every point with real trigonometry and draws it as raw SVG, no charting library involved.
The actual angle formula
For axisCount axes, axis i's angle is i * (2 * Math.PI / axisCount) - Math.PI / 2. The 2 * Math.PI / axisCount term divides the full circle evenly between axes; subtracting Math.PI / 2 rotates the whole chart so axis 0 points straight up instead of straight right — matching how radar charts are conventionally drawn.
Value to point, honestly
pointFor(index, value) turns a score into a radius with (value / maxValue) * maxRadius, then projects it along that axis's angle with center + r * Math.cos(angle) for x and center + r * Math.sin(angle) for y — the standard polar-to-Cartesian conversion. A score of 0 collapses to the center; a perfect score reaches maxRadius exactly.
Two polygons, one grid
Both the dashed benchmark polygon and the solid score polygon reuse the same pointFor/pointsAttr functions, just with different value arrays — so they're guaranteed to sit on the same axes and scale, making them directly comparable. The background grid rings are drawn the same way at 20/40/60/80/100% of maxRadius, confirming the geometry is consistent at every level.
A closed polygon, always
Because SVG's <polygon> element automatically connects its last point back to its first, and every axis contributes exactly one point in a fixed order, the shape is guaranteed closed with no separate "closing point" to remember or get wrong.
Everything generated, nothing hardcoded
Grid rings, spokes, axis labels, both polygons, and the score dot markers are all built from the same axes array in a loop — add a seventh skill axis and the whole chart, including its labels and angles, adapts automatically.
Customizing it
Change axisCount by adding or removing entries in axes, adjust maxValue/maxRadius for a different scale, or add a second candidate's polygon for direct comparison. Pair it with circular progress for single-metric summaries, or a quiz result breakdown for assessment scoring elsewhere in a hiring flow.
Build with AI
Build, Understand, Optimize, and Extend It With AI
Radar charts are one of the few UI patterns where getting the math wrong produces a subtly broken-looking shape rather than an obvious error, so it's worth pasting this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and asking it to verify the angle formula (index * (2*Math.PI/axisCount) - Math.PI/2) actually distributes any number of axes evenly around a full circle, and to walk through why polar-to-Cartesian conversion (center + r*cos(angle), center + r*sin(angle)) is the correct way to place each axis's value point. The same assistant is useful for extending the chart correctly — ask it how to add a second overlaid polygon for a candidate-vs-benchmark or before-vs-after comparison while keeping both polygons aligned to identical axis angles, how to animate the polygon growing in from the center on load, or how to make the SVG chart accessible to screen readers via a companion data table.
Prompt to recreate it
Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:
Build a "skills assessment radar chart" as pure SVG generated with vanilla JavaScript — no charting library, no canvas.
Requirements:
- A data array of 5 or 6 skill axes, each with a label, a score, and a benchmark value on a 0-5 scale.
- Compute each axis's angle using real trigonometry: angle = index * (2 * Math.PI / axisCount) - Math.PI / 2, so any number of axes distributes evenly around a full circle starting from straight up.
- Convert a value on a given axis to an absolute SVG point using standard polar-to-Cartesian conversion: radius = (value / maxValue) * maxRadius, then x = centerX + radius * Math.cos(angle) and y = centerY + radius * Math.sin(angle).
- Generate, entirely from the axes array (nothing hardcoded per-axis): concentric background grid rings at several value fractions (e.g. 20/40/60/80/100%), a spoke line from center to each axis's maximum point, a text label positioned just beyond each axis's outer point, a benchmark polygon (dashed stroke) built from each axis's benchmark value, a score polygon (solid fill+stroke) built from each axis's score value, and small circle markers at each score polygon vertex.
- The polygon points must form a genuinely valid closed shape — rely on SVG's polygon element auto-closing from last point to first, with exactly one point generated per axis in consistent order; verify by reasoning through what happens with both 5 and 6 axes.
- Include a legend distinguishing the score polygon from the benchmark polygon.
- Keep it in a dark theme, and make sure the JavaScript only references classnames/ids that exist in the HTML you write.Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.
Step by step
How to Use
- 1Paste the HTML, CSS, and JSAn empty SVG and legend render.
- 2The script runs on loadGrid rings, spokes, labels, and polygons are generated.
- 3Compare the two polygonsSolid candidate score vs. dashed role benchmark.
- 4Edit the axes arrayChange labels, scores, or benchmark values.
- 5Add or remove an axisThe angle math adapts to any axisCount automatically.
- 6Change maxValue or maxRadiusRescale the whole chart from two variables.
Real-world uses
Common Use Cases
Got questions?
Frequently Asked Questions
Axis i's angle is i * (2 * Math.PI / axisCount) - Math.PI / 2. The term 2 * Math.PI / axisCount is the full circle (2*PI radians) divided evenly by however many axes exist, so each axis is offset from the last by exactly that fraction of a full turn regardless of whether there are 5, 6, or 8 axes. Subtracting Math.PI / 2 rotates the whole layout by a quarter turn so axis 0 points straight up rather than straight right.
pointFor first computes a radius as (value / maxValue) * maxRadius — a value of 0 gives radius 0 (the center) and a value equal to maxValue gives radius maxRadius (the outer edge). That radius is then projected along the axis's angle using the standard polar-to-Cartesian formulas: x = center + r * cos(angle), y = center + r * sin(angle). This is the same math used to plot any point at a given distance and direction from an origin.
SVG's polygon element automatically draws a closing segment from its last listed point back to its first — there's no need to repeat the first point at the end of the points string. Since pointsAttr generates exactly one point per axis in a fixed order (via Array.map over the axes array), and every axis's point sits on its own angle computed from the same formula, the resulting shape is always a valid, fully closed polygon with no gaps or self-intersections from mismatched ordering.
Add a second scores array (or a scores field per candidate) and call pointsAttr on it the same way the benchmark and score polygons are built, then append a new polygon element with its own CSS class for distinct styling (color, dash pattern). Because pointFor and pointsAttr only depend on the axes array's length and order, any number of overlaid polygons stay aligned to the same axes automatically.
Keep the axes data as component state or a prop, and either render the SVG children (polygon, line, text, circle elements) declaratively from that array using your framework's templating, or run the same imperative DOM-building functions inside a mount/update effect against an SVG ref. The trigonometry functions (angleFor, pointFor) are plain JavaScript and need no changes either way.