DAX SVG measure · Status
Status pill in a Power BI table with a DAX SVG measure
By Nawaf Sharaf · Founder & Reliability Engineer · Updated
Use it when
- Project, ticket or SLA tables where status is the first thing people look for.
- Your organisation has fixed status vocabulary (Met / At risk / Breached).
Skip it when
You need to sort or filter by status: an image can't be sorted meaningfully. Add a status text column for that and use the pill for display.
Three looks
The status pill in three palettes; click one to edit it.
Data it needs
The builder asks for exactly these fields; type your own measure and column names there.
- Value measure
- A ratio or score; the thresholds pick one of three labels.
The full DAX
Swap [Schedule Index] for your own names.
Status Pill =
-- VizForge SVG measure: status pill.
-- Set Measure tools > Data category = Image URL, then size it under Format > Visual > Image size.
-- Solid pills use white text: check your three colours reach 4.5:1 against white.
-- Made with the free VizForge SVG measure builder: vizforge.ai/tools/svg-measure-builder
-- Need per-point tooltips, click-to-select inside the chart or Format-pane settings? Generate it as a real custom visual: vizforge.ai/visuals
VAR _Value = [Schedule Index]
VAR _State = SWITCH ( TRUE (), _Value >= 1, 2, _Value >= 0.9, 1, 0 )
VAR _Colour = SWITCH ( TRUE (), _State >= 2, "%231AAB40", _State >= 1, "%23D9B300", "%23D64554" )
VAR _Label = SWITCH ( TRUE (), _State >= 2, "On track", _State >= 1, "At risk", "Off track" )
RETURN
IF (
ISBLANK ( _Value ),
BLANK (),
"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='88' height='22' viewBox='0 0 88 22'><rect x='0.5' y='0.5' width='87' height='21' rx='10.5' fill='"
& _Colour
& "' fill-opacity='0.14'/><circle cx='11' cy='11' r='3.08' fill='"
& _Colour
& "'/><text x='20.9' y='11' dy='0.35em' text-anchor='start' font-family='Segoe UI, Helvetica, Arial, sans-serif' font-size='11' font-weight='600' fill='"
& _Colour
& "'>"
& _Label
& "</text></svg>"
)DAX user-defined function variant (VizForge.SvgStatusPill)
One-line call: Status Pill = VizForge.SvgStatusPill ( [Schedule Index] )
-- 1) Paste into DAX query view and choose 'Update model with changes'.
-- Needs DAX user-defined functions (generally available since the June 2026 Power BI release).
DEFINE
/// Status pill as an SVG image URL (VizForge). Optional parameters default to the colours you picked.
FUNCTION VizForge.SvgStatusPill = (
pValue : NUMERIC,
pHighAt : NUMERIC = 1,
pLowAt : NUMERIC = 0.9,
pGoodColor : STRING = "#1AAB40",
pWarnColor : STRING = "#D9B300",
pBadColor : STRING = "#D64554"
) =>
VAR _Value = pValue
VAR _State = SWITCH ( TRUE (), _Value >= pHighAt, 2, _Value >= pLowAt, 1, 0 )
VAR _Colour = SWITCH (
TRUE (),
_State >= 2,
SUBSTITUTE ( pGoodColor, "#", "%23" ),
_State >= 1,
SUBSTITUTE ( pWarnColor, "#", "%23" ),
SUBSTITUTE ( pBadColor, "#", "%23" )
)
VAR _Label = SWITCH ( TRUE (), _State >= 2, "On track", _State >= 1, "At risk", "Off track" )
RETURN
IF (
ISBLANK ( _Value ),
BLANK (),
"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='88' height='22' viewBox='0 0 88 22'><rect x='0.5' y='0.5' width='87' height='21' rx='10.5' fill='"
& _Colour
& "' fill-opacity='0.14'/><circle cx='11' cy='11' r='3.08' fill='"
& _Colour
& "'/><text x='20.9' y='11' dy='0.35em' text-anchor='start' font-family='Segoe UI, Helvetica, Arial, sans-serif' font-size='11' font-weight='600' fill='"
& _Colour
& "'>"
& _Label
& "</text></svg>"
)
EVALUATE { VizForge.SvgStatusPill ( [Schedule Index] ) }
-- 2) Then create the measure and set Measure tools > Data category = Image URL:
-- Status Pill = VizForge.SvgStatusPill ( [Schedule Index] )
-- Colours and thresholds are optional parameters: pass a value after the fields to override one.
-- Pass colours as plain "#RRGGBB"; the function encodes the # for the data URI.Placing it in a report
Size 22 × 88 matches a default table row height. Put it next to the project or task name; sort the table by the underlying index measure, because the image column itself can't be sorted meaningfully. Remember the Image URL data category. All setup steps.
Gotchas
- Labels are XML-escaped and percent-encoded for you, so 'R&D' or '50%' won't break the image.
- Solid pills use white text: check that each of your three colours reaches 4.5:1 against white.
- Text width isn't measured: keep labels to about 12 characters at the default width or widen the pill.
- Length. 428 characters whatever the data; no iteration.
- Context. [Schedule Index] is read per row; the label text (On track / At risk / Off track) is part of the image, so screen readers and exports don't see it. Keep the index or the label as a separate text column for accessibility.
- Tooltip. Hovering shows the SVG text; a blank report-page tooltip hides it.
When an SVG measure isn't enough
A custom project table can sort by severity, show the reason on hover and drill through to the item. See the Gantt chart custom visual for what an interactive version can do.
KPI card designs using it
Finished designs built on this pattern, from the KPI card gallery.