Free tool · no sign-up · runs in your browser
DAX SVG measure builder for Power BI
Live preview: Sparkline (line)
120×32px · 405 charactersYour DAX
Paste into Home > New measure. Numbers are formatted with the en-US locale argument so the SVG coordinates never get decimal commas.
Sparkline =
-- VizForge SVG measure: line sparkline.
-- Set Measure tools > Data category = Image URL. Put it in a table or matrix next to a category column.
-- The axis must be a date or number column so points are spaced in time order.
-- 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 _Base = FILTER (
ADDCOLUMNS (
ALLSELECTED ( 'Date'[Month Start] ),
"@x", CONVERT ( 'Date'[Month Start], DOUBLE ),
"@v", [Sales]
),
NOT ISBLANK ( [@v] )
)
VAR _XMin = MINX ( _Base, [@x] )
VAR _XMax = MAXX ( _Base, [@x] )
VAR _VMin = MINX ( _Base, [@v] )
VAR _VMax = MAXX ( _Base, [@v] )
VAR _Points = CONCATENATEX (
_Base,
FORMAT ( 3.5 + DIVIDE ( [@x] - _XMin, _XMax - _XMin, 0.5 ) * 113, "0.0", "en-US" )
& ","
& FORMAT ( 3.5 + ( 1 - DIVIDE ( [@v] - _VMin, _VMax - _VMin, 0.5 ) ) * 25, "0.0", "en-US" ),
" ",
[@x], ASC
)
RETURN
IF (
COUNTROWS ( _Base ) < 2,
BLANK (),
"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='32' viewBox='0 0 120 32'><polyline fill='none' stroke='%23118DFF' stroke-width='1.5' stroke-linejoin='round' stroke-linecap='round' points='"
& _Points
& "'/><circle cx='"
& MAXX ( TOPN ( 1, _Base, [@x], DESC ), FORMAT ( 3.5 + DIVIDE ( [@x] - _XMin, _XMax - _XMin, 0.5 ) * 113, "0.0", "en-US" ) )
& "' cy='"
& MAXX ( TOPN ( 1, _Base, [@x], DESC ), FORMAT ( 3.5 + ( 1 - DIVIDE ( [@v] - _VMin, _VMax - _VMin, 0.5 ) ) * 25, "0.0", "en-US" ) )
& "' r='2.6' fill='%23118DFF'/></svg>"
)Set it up in Power BI Desktop
- Create the measure. Home > New measure, paste the DAX and press Enter. For the UDF variant, run the script in DAX query view and choose Update model with changes first.
- Set the data category. With the measure selected, go to Measure tools > Data category and pick Image URL. Without it the table shows the text of the data URI.
- Add it to a table or matrix. Put a category column on the rows and add the measure. Do not put the axis column itself on the rows: each row needs the whole series.
- Size the image. Format > Visual > Image size: set Height to 32 and Width to 120 so the SVG is drawn at 1:1.
- Use it in the new Card visual. Format > Visual > Image: turn Image on, set Image source to Select from data and pick the measure. For a small icon beside the value use Callout > Image instead, where the control is called Image type.
- Pick the fit. Choose an Image fit; with categories on the card, set Apply settings to the specific callout so each card gets its own image.
Steps checked against Microsoft Learn on 4 Nov 2026: Display images in a table, matrix, or slicer, Create card visuals, DAX user-defined functions.
How a DAX SVG measure works
Every pattern here follows the same four rules. If you edit the DAX by hand, keep them.
Status Dot =
VAR _Colour = IF ( [Attainment %] >= 1, "%231AAB40", "%23D64554" ) -- # written as %23
RETURN
"data:image/svg+xml;utf8," -- the image type
& "<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14'>" -- single quotes inside
& "<circle cx='7' cy='7' r='7' fill='" & _Colour & "'/>"
& "</svg>"- 1. Return an image URL. The text starts with
data:image/svg+xml;utf8,and the measure's data category is Image URL. - 2. Single quotes inside, double quotes outside. DAX strings use double quotes, so SVG attributes use single quotes and nothing needs escaping.
- 3. Encode # and %. Colours are
%23RRGGBB; a percentage label replaces % with %25. - 4. Iterate for series. Trend patterns build the point list with
CONCATENATEXover the axis values inALLSELECTED, ordered by date, with numbers formatted in en-US.
The previews on this page are not drawings of the idea: the builder evaluates the same expression it prints against sample data, so the picture is the string your measure returns. For example, the default sparkline above returns 405 characters.
All 17 patterns
Each pattern page explains when to use it, the data it needs and the gotchas, with the full DAX.
TrendSparkline (line)A word-sized line chart per row: the shape of the trend without axes, built from CONCATENATEX over the date axis.
TrendSparkline (area)A filled sparkline with an optional zero baseline and a line that turns green or red with the direction of the period.
TrendColumn sparkline (small multiple bars)Tiny columns per period with the latest or the highest period highlighted: better than a line when periods are discrete.
TrendWin/loss barsEqual-height up and down ticks per period: shows streaks of beating or missing a goal, not the size of the miss.
Progress to targetBullet chartActual as a bar, target as a tick, and poor/satisfactory/good bands behind: Stephen Few's gauge replacement in one table cell.
Progress to targetProgress barA percent-complete bar with an optional label and red/amber/green thresholds, from one ratio measure.
Progress to targetProgress ringA circular percent-complete ring with the value in the middle, sized for a table row or a Card visual image.
Progress to targetData bar with targetA bar per row on one shared scale with a target tick and the value printed: conditional-formatting data bars that know the goal.
StatusKPI arrow / delta badgeAn up or down arrow with the % change against a comparison measure, coloured by whether the change is good.
StatusTraffic light / RAG dotA red, amber or green status from two thresholds: a single dot, a ring, or a three-lamp traffic light that also reads in greyscale.
StatusStatus pillA tinted pill with a word (On track, At risk, Off track) chosen by thresholds: the status column every project table needs.
StatusRating starsCustomer or quality ratings as stars with exact partial fill (3.7 fills 3.7 stars), clipped with a nested SVG instead of rounding.
StatusIcon + valueOne of the Design Studio's line icons in a tinted circle next to the formatted value, with the icon colour driven by a threshold if you want.
ComparisonVariance bar (IBCS style)Actual minus plan as a green or red bar from a shared zero axis, or the relative variance as an IBCS pin, with the signed value printed.
ComparisonDumbbell (before / after)Two dots joined by a line per row (last year and this year, plan and actual) on one shared scale: the change and the level at once.
CompositionMini donutTwo or three parts of a whole (new vs returning, channel mix) as a small donut with the first part's share in the middle.
KPI cardKPI card (value, delta, sparkline)A whole KPI tile in one image: caption, big value, change vs a comparison and a trend line, for the new Card visual or a matrix.
Want finished designs instead? The KPI card gallery has ready-made cards in minimal, editorial, dark, IBCS and operations styles, each one opening here pre-configured. Need a design none of the patterns covers? Describe it to the AI SVG measure generator (1 credit, refunded if it fails).
DAX SVG measure FAQ
What is a DAX SVG measure?
A measure that returns text starting with data:image/svg+xml;utf8, followed by SVG markup. When the measure's data category is Image URL, Power BI draws that text as an image in a table, matrix or the new Card visual. Because the markup is built with DAX, the picture changes with the filter context of each row.
Why does my table show the code instead of the picture?
The data category isn't set. Select the measure, then Measure tools > Data category > Image URL. In a table or matrix, also set the image size under Format > Visual > Image size.
Why are colours written as %23 instead of #?
In a URL, # starts a fragment and everything after it is ignored, so a colour like #118DFF would cut the SVG short. %23 is the percent-encoded #. For the same reason, a % printed by FORMAT has to become %25. The builder does both for you, including inside labels you type.
Why does the DAX use FORMAT with "en-US"?
Coordinates must use a decimal point. Without the locale argument, a model with German or French regional settings formats 12.5 as 12,5 and the SVG breaks. FORMAT ( value, "0.0", "en-US" ) keeps the output identical everywhere.
Does it work in the new Card visual?
Yes. Microsoft's Card visual can take an image from a data field: Format > Visual > Image, turn Image on, set Image source to Select from data and pick the measure. For a small icon next to the value, use Callout > Image and set Image type to Select from data.
What is the UDF variant and do I need it?
A DAX user-defined function packages the drawing logic once; each measure then becomes a one-line call such as VizForge.SvgSparkline ( [Sales], 'Date'[Month Start] ). Microsoft Learn lists UDFs as generally available from the June 2026 Power BI release, with database compatibility level 1702 or higher. If your model or tooling is older, use the plain measure: it does exactly the same thing.
How long can the SVG get, and is it slow?
The builder shows the length of the text for its preview data; most patterns are a few hundred to a few thousand characters. Series patterns grow with the number of periods because CONCATENATEX adds a point or a bar per period, and the measure runs once per visible row. Keep series to the periods people read (12–24) and tables to the rows on screen.
Can an SVG measure have tooltips or cross-filter other visuals?
Partly. The table row or card that holds the image behaves like any other: clicking the row cross-filters the page, right-click drill-through works, and you can assign a report-page tooltip to the visual. What you can't get is interactivity inside the picture: no tooltip for the bar or point under the cursor, no clicking one bar to select it, and no Format-pane settings for its colours. The default tooltip also shows the raw SVG text; a small blank report-page tooltip hides it. When you need per-point interaction, generate a custom visual from the same design with VizForge's AI generator.