Dynamic KPI Gauge
A healthcare KPI card that combines the latest monthly value, a selected-data scale and goal-based color in one SVG.
Meets goal · Goal < 5 days
Illustrative healthcare data · Apr–Sep 2026 · no patient data or live Qlik connection.
Preview dataset
| Month | Value (days) |
|---|---|
| 2026-04 | 5.6 |
| 2026-05 | 5.3 |
| 2026-06 | 4.7 |
| 2026-07 | 5.1 |
| 2026-08 | 4.8 |
| 2026-09 | 4.9 |
From sample data to Qlik selections
Choose one of four metrics to update the browser gauge instantly. These controls use a small illustrative dataset, not a Qlik app. The copied expression uses your selected Qlik data dynamically instead of these sample values.
In Qlik, select one Metric and display the expression in an image-capable object. Month must be a sortable Qlik date with a YYYY-MM text representation compatible with the latest-month set modifier. Each metric should have a single MonthlyUnit, MonthlyGoal and MonthlyGoalOperator across the selection.
Expected fields
Metric, Month, Value, MonthlyUnit, MonthlyGoal, MonthlyGoalOperator
Use numeric Value and MonthlyGoal fields, and operators < or >. For example: Length of Stay · 2026-09 · 4.9 · days · 5 · <.
The Qlik expression
Complete expression, preserved exactly as supplied, including percent-encoded SVG colors.
= 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 360 250" preserveAspectRatio="xMidYMid meet">' &
'<rect x="1" y="1" width="358" height="248" rx="28" fill="%23ffffff" stroke="%23d7dddf" stroke-width="2"/>' &
'<text x="30" y="39" font-family="Arial,sans-serif" font-size="20" font-weight="700" fill="%23293840">' & If(Count(DISTINCT Metric)=1,Only(Metric),'Select Metric') & '</text>' &
'<text x="30" y="65" font-family="Arial,sans-serif" font-size="14" fill="%2365727a">Latest month: ' & If(Count(DISTINCT Metric)=1,Date(Max(Month),'MMM YYYY'),'Select one metric') & '</text>' &
'<path d="M68 202 A112 112 0 0 1 292 202" fill="none" stroke="%23e8ebec" stroke-width="20" stroke-linecap="butt"/>' &
If(Count(DISTINCT Metric)=1,'<path d="M68 202 A112 112 0 0 1 ' & Num(180-112*Cos(Pi()*If(Max(TOTAL Value)=Min(TOTAL Value),0.5,RangeMax(0,RangeMin(1,(Avg({<Month={'$(=Date(Max(Month),'YYYY-MM'))'}>} Value)-Min(TOTAL Value))/(Max(TOTAL Value)-Min(TOTAL Value)))))),'0.0') & ' ' & Num(202-112*Sin(Pi()*If(Max(TOTAL Value)=Min(TOTAL Value),0.5,RangeMax(0,RangeMin(1,(Avg({<Month={'$(=Date(Max(Month),'YYYY-MM'))'}>} Value)-Min(TOTAL Value))/(Max(TOTAL Value)-Min(TOTAL Value)))))),'0.0') & '" fill="none" stroke="' & If(Count(DISTINCT MonthlyGoal)=1 and Count(DISTINCT MonthlyGoalOperator)=1,If(Only(MonthlyGoalOperator)='<',If(Avg({<Month={'$(=Date(Max(Month),'YYYY-MM'))'}>} Value)<Only(MonthlyGoal),'%23258ba0','%23e28b80'),If(Avg({<Month={'$(=Date(Max(Month),'YYYY-MM'))'}>} Value)>Only(MonthlyGoal),'%23258ba0','%23e28b80')),'%23258ba0') & '" stroke-width="20" stroke-linecap="butt"/>','') &
'<text x="180" y="158" text-anchor="middle" font-family="Arial,sans-serif" font-size="34" font-weight="700" fill="%23111820">' & If(Count(DISTINCT Metric)=1,Num(Avg({<Month={'$(=Date(Max(Month),'YYYY-MM'))'}>} Value),'0.0'),'') & '</text>' &
'<text x="180" y="181" text-anchor="middle" font-family="Arial,sans-serif" font-size="13" fill="%2357656c">' & If(Count(DISTINCT Metric)=1,Only(MonthlyUnit),'') & '</text>' &
'<text x="58" y="229" font-family="Arial,sans-serif" font-size="12" fill="%2365727a">' & If(Count(DISTINCT Metric)=1,Num(Min(TOTAL Value),'0.0'),'') & '</text>' &
'<text x="302" y="229" text-anchor="end" font-family="Arial,sans-serif" font-size="12" fill="%2365727a">' & If(Count(DISTINCT Metric)=1,Num(Max(TOTAL Value),'0.0'),'') & '</text>' &
'</svg>'How the expression works
- 1
SVG canvas and card
viewBox="0 0 360 250" · <rect … rx="28" />viewBox defines a 360 × 250 drawing area. The white rounded rectangle and light border create the card; width and height of 100% let it scale with its container.
- 2
Metric title and latest month
Count(DISTINCT Metric) · Only(Metric) · Date(Max(Month),'MMM YYYY')Qlik reads the current selection. When exactly one metric is available, Only(Metric) supplies its title and Max(Month) finds the latest selected month. With multiple metrics, the card asks you to select one and hides its numeric content. Set analysis reads the average Value for that latest month.
- 3
Gauge track and progress arc
(latest value − Min(TOTAL Value)) / (Max(TOTAL Value) − Min(TOTAL Value))The pale semicircle is the full scale. The colored arc places the latest value between the selected data’s minimum and maximum. RangeMin and RangeMax clamp the position to 0–1; an equal minimum and maximum uses the midpoint, 0.5. Cos and Sin convert that position into the arc endpoint: x = 180 − 112 × Cos(π × position), y = 202 − 112 × Sin(π × position). TOTAL ignores chart dimensions, not selections.
- 4
Goal-based color
Only(MonthlyGoalOperator)='<' · Only(MonthlyGoal)Teal means the KPI meets its goal; coral means it misses. The '<' operator treats lower values as better; otherwise the expression uses a higher-is-better '>' comparison. Comparisons are strict: equality misses the goal. If a single goal and operator cannot be determined, the arc defaults to teal, which is not confirmation that a goal was met.
- 5
KPI value and scale labels
Num(Avg(… Value),'0.0') · Only(MonthlyUnit) · Min/Max(TOTAL Value)The center shows the latest month’s average value to one decimal place, with its unit beneath. The labels at the bottom show the minimum and maximum of Value within the current selection, independent of chart dimensions. Select a single metric so that this scale compares compatible units.