Don't miss your chance to take the Fabric Data Engineer (DP-600) exam for FREE! Find out how by attending the DP-600 session on April 23rd (pacific time), live or on-demand.
Learn moreNext up in the FabCon + SQLCon recap series: The roadmap for Microsoft SQL and Maximizing Developer experiences in Fabric. All sessions are available on-demand after the live show. Register now
Your file has been submitted successfully. We’re processing it now - please check back in a few minutes to view your report.
04-23-2025 07:57 AM
Hey everyone,
I had a requirement to use a gauge visual in one of my reports, but the users didn't like the stock gauge visual so I built my own in DAX using SVGs. It's fully customizable using the settings section, but also feel free to take the code and tweak it however you want. Hopefully this helps others who wanted more control over their gauge.
GaugeWithTargetLabel =
// ─────────── Measures ───────────
VAR ProgressMeasure = [Progress Measure]
VAR TargetMeasure = [Target Measure]
// ─────────── Settings ───────────
VAR KPI_LabelText = "Marketing"
VAR KPI_LabelFontSize = 10
VAR KPI_LabelFontColor = "#666666"
VAR Progress_Color = "#3CB371"
VAR Bg_Color = "#e0e0e0"
VAR KPI_FontSize = 20
VAR KPI_FontColor = "#666666"
VAR Target_FontSize = 10
VAR Target_FontColor = "#1A1A1A"
VAR Target_Color = "#FF0000"
VAR Top_Margin = 12
VAR Bottom_Spacing = 5
VAR Bottom_Margin = KPI_FontSize
// normalize 0→1
VAR ProgressPct = DIVIDE(ProgressMeasure,100,0)
VAR TargetPct = DIVIDE(TargetMeasure, 100,0)
// gauge geometry
VAR Radius = 50
VAR StrokeWidth = 10
VAR HalfStroke = StrokeWidth/2
// center of circle (inside the inner drawing area)
VAR CX = Radius + HalfStroke
VAR CY = Radius + HalfStroke
// size of inner area
VAR InnerW = CX*2
VAR InnerH = CY + HalfStroke
// full canvas size (with left/top margin + bottom margin)
VAR Width = InnerW + 2*Top_Margin
VAR Height = InnerH + Bottom_Spacing + KPI_FontSize + Top_Margin + Bottom_Margin
// ── Progress arc endpoint ───────────────────────────────────
VAR EndAngleDeg = ProgressPct * 180
VAR EndTheta = 180 - EndAngleDeg
VAR EndRad = RADIANS(EndTheta)
VAR EndX = CX + Radius * COS(EndRad)
VAR EndY = CY - Radius * SIN(EndRad)
// ── Paths ────────────────────────────────────────────────────
VAR BgPath =
"M " & (CX-Radius) & "," & CY &
" A " & Radius & "," & Radius & " 0 0,1 " & (CX+Radius) & "," & CY
VAR ProgPath =
"M " & (CX-Radius) & "," & CY &
" A " & Radius & "," & Radius & " 0 0,1 " & EndX & "," & EndY
// ── Target tick endpoints ────────────────────────────────────
VAR TickAngleDeg = TargetPct * 180
VAR TickTheta = 180 - TickAngleDeg
VAR TickRad = RADIANS(TickTheta)
VAR InnerR = Radius - HalfStroke
VAR OuterR = Radius + HalfStroke
VAR TX1 = CX + InnerR * COS(TickRad)
VAR TY1 = CY - InnerR * SIN(TickRad)
VAR TX2 = CX + OuterR * COS(TickRad)
VAR TY2 = CY - OuterR * SIN(TickRad)
// ── Floating target % label coords ───────────────────────────
VAR LabelR = OuterR + Top_Margin
VAR LX = CX + LabelR * COS(TickRad)
VAR LY = CY - LabelR * SIN(TickRad)
// ── KPI positions ────────────────────────────────────────────
VAR KPITextY = CY + HalfStroke // bottom of the arc
VAR KPILabelY = KPITextY + Bottom_Spacing // top of KPI label
RETURN
"data:image/svg+xml;utf8," &
"<svg xmlns='http://www.w3.org/2000/svg' width='" & Width & "' height='" & Height &
"' viewBox='0 0 " & Width & " " & Height & "'>" &
// Shift everything right & down by Top_Margin
"<g transform='translate(" & Top_Margin & "," & Top_Margin & ")'>" &
// gray rail
"<path d='" & BgPath & "' fill='none' stroke='" & Bg_Color & "' stroke-width='" & StrokeWidth &
"' stroke-linecap='round'/>" &
// green progress
"<path d='" & ProgPath & "' fill='none' stroke='" & Progress_Color & "' stroke-width='" & StrokeWidth &
"' stroke-linecap='round'/>" &
// target tick
"<line x1='" & TX1 & "' y1='" & TY1 & "' x2='" & TX2 & "' y2='" & TY2 &
"' stroke='" & Target_Color & "' stroke-width='2'/>" &
// floating target %
"<text x='" & LX & "' y='" & LY & "' text-anchor='middle' font-family='Segoe UI' " &
"font-size='" & Target_FontSize & "' fill='" & Target_FontColor &
"' dominant-baseline='middle'>" &
FORMAT(TargetPct,"0%") &
"</text>" &
// main KPI %
"<text x='" & CX & "' y='" & KPITextY & "' text-anchor='middle' font-family='Segoe UI' " &
"font-size='" & KPI_FontSize & "' fill='" & KPI_FontColor &
"' dominant-baseline='text-after-edge'>" &
FORMAT(ProgressPct,"0%") &
"</text>" &
// KPI label below
"<text x='" & CX & "' y='" & KPILabelY & "' text-anchor='middle' font-family='Segoe UI' " &
"font-size='" & KPI_LabelFontSize & "' fill='" & KPI_LabelFontColor &
"' dominant-baseline='hanging'>" &
KPI_LabelText &
"</text>" &
"</g>" &
"</svg>"