Vanilla Breeze

nfr-radar

11-axis radar viz for an NFR vector vs the project's capacity envelope. Pairs with via data-bind-to and re-renders an inline on every selection change.

Overview

The <nfr-radar> component is the visual companion to <nfr-compass>. Where the compass owns the decision (which ilities are critical, where the rationales live, what the budget is), the radar owns the read — one glance and you can see how the team's quality vector compares to the capacity envelope. Reach for it on status dashboards, ADR appendices, the home page of an internal product wiki, anywhere a stakeholder wants to know "how's the shape of our quality bet?" without opening the picker.

Light DOM, theme-token driven, no external dependency. The component listens for nfr-compass:change events from a bound compass and rewrites a fresh inline <svg> on each update.

Live demo

Pick priorities in the compass — the radar polygon updates live. Hover a vector dot to see the ility's name, level, and cost weight in a native tooltip.

What the SVG shows

The radar has two layers and a thin grid:

  • Capacity envelope (background polygon, soft success-tinted fill) — the ring at radius × min(1, capacityPoints / sum(costWeights)). Tells you how much of the radius the budget would fill if costs were spread uniformly.
  • Vector overlay (foreground polygon + per-axis dots) — places each ility at radius × level ratio: critical = 1.0, important = 0.6, acceptable = 0.3, not-relevant = 0. The dots colorize by level.
  • Spokes — dashed lines from origin to each axis tip; pure orientation aid.

When capacityPoints is Infinity (no triangle bound, no fallback), the envelope hides — the radar becomes informational.

Driving without a compass

You don't need the compass. Set radar.value directly from anywhere — a saved vector loaded from disk, a server-rendered snapshot, an ADR appendix.

You can also customize the ility list — the radar's axis count follows it.

Attributes

AttributeTypeDefaultDescription
data-bind-to string ID of a sibling <nfr-compass> whose nfr-compass:change drives the radar.
data-radius number 90 Base radius in SVG units. Clamped to [30, 400].
data-show-envelope boolean present Show the capacity envelope polygon. Set data-show-envelope="false" to hide.

Properties

PropertyTypeDescription
value { vector, costWeights, capacityPoints } Read or write the radar's data snapshot. Setter triggers a re-render and a nfr-radar:change event.
ilities string[] Defaults to the same 11 the compass ships. Re-assigning rewrites the radar's axes.

Events

EventDetailWhen
nfr-radar:change { value, source } Fires after every re-render — bound compass change or property write. source is 'iron-compass' or 'property'.

Theme tokens

Every color comes from a VB theme token. Override per-instance with the --nfr-radar-* hooks below or globally via theme tokens.

TokenDefaultPurpose
--nfr-radar-max 24rem Max inline size of the SVG container.
--nfr-radar-envelope-fill 14% mix of --color-success Capacity envelope fill.
--nfr-radar-envelope-stroke 60% mix of --color-success Capacity envelope stroke.
--nfr-radar-vector-fill 28% mix of --color-interactive Vector polygon fill.
--nfr-radar-vector-stroke --color-interactive Vector polygon stroke.

Relationship to other planning components

  • <iron-triangle> — supplies capacityPoints to the compass, which the radar reads via the bound compass.
  • <nfr-compass> — owns the prioritization decision; the radar mirrors its value.
  • <requirement-card> — renders one ility's row outside the compass; pair on a status dashboard alongside the radar for both the headline and the detail.