Selected work · 02 / Custom visuals
Charts we had to build.
Power BI ships with a fixed set of charts. Ours weren't in it, so I built some myself and guided the team on the rest: six custom visuals so far, a body-map heatmap, a bar visual, a gauge, a stacked-change column and KPI cards, all TypeScript. Rebuilt below, live.
Demo data notice. Every value, date, injury count, percentage, trend and comparison here is fictional sample data, built only to demonstrate the visuals. None of it represents real people, incidents, organizations or business performance.
How it works
Power BI talks. Your code draws.
Built once. Then update() fires on every data, size or setting change. Run the loop
constructor
Host builds the visual, hands over the DOM element. You set up your <svg>.
data / size / setting changes
Someone filters, resizes, or tweaks a format control.
update(options)
The host calls your update() with fresh options.
options.dataViews[0]
You pull out the reshaped data and current settings.
render() → SVG
Clear the canvas, redraw at the new size.
bodyRegion grouping + injuryCount measure categorical dataView purpose-drawn SVG.
categories[] + values[]
Visual one · the injury body mapSample data
Injuries, mapped onto a body.
Two fields in: a body region and an injury count. Each region colours on a five-band scale; the panel groups them and flags the worst. Click a region to focus it
Injuries by Body Group
Bands: 1–5 · 6–15 · 16–40 · 41+, all format-pane colours. This is the prototype. Its shipped twin bodyInjuryHeatmap swaps the bands for a smooth min→max gradient, tells left from right, and wires up Power BI selection, cross-highlight and tooltips.
The data behind it
Two fields in. A picture out.
It declares what it accepts: one grouping, one measure. Power BI reshapes the report into a categorical dataView. Toggle a row, watch the dataView
dataViewwhat update() receives: categorical
Visual two · the bar visualSample data
A bar chart that does what the built-in one won't.
The details the built-in bar chart skips, each one a control in the format pane. Change the pane. The chart follows
Where the pane comes from
Declare a control. Power BI draws the pane.
You never build the pane by hand. Declare each property's type; the host renders the control. Pick a type
A boolean becomes a switch, and arrives in your settings model as true / false.
Visual three · the semi-circle gaugeSample data
On target, at a glance.
One value, three states. Arc, number and status move together. Drag the value
Min/max, zones and markers are all format-pane controls.Sample data
Also on the shelfSample data
Same instinct, a few more times.
Two more: a stacked column that annotates its change between periods, and a strip of KPI cards. Poke them
Stacked column + change
v3.5.8 · legend · drilldown · change deltasMultiCard
v1.3.2 · KPI cards · row or columnIteration
One good version is really six.
Each release added one thing a report asked for. The old package was never overwritten, only superseded. Walk the versions
The Values role takes a measure or a grouping, so “Don't summarize” gives raw category values instead of a forced sum.
By the numbers
The family, counted.
Both raw SVG on the powerbi-visuals API. No D3 helpers, no third-party charting. Every colour, font and border is a format-pane control.