DAX SVG measure · Status

Status pill in a Power BI table with a DAX SVG measure

Words beat colours for status: 'At risk' survives greyscale printing, screen readers that read the table and readers who don't know your colour code. The pill draws the word in a tinted or solid capsule picked by two thresholds, with your own labels.

By · Founder & Reliability Engineer · Updated

Status pill rendered from the DAX below with sample data
Rendered from the measure below with sample data at 2× (88×22 px in Power BI). 428 characters.

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 (measure)
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] )

DAX query view script
-- 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

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.