Design techniques

Let users set the thresholds: a settings panel in Power BI

Move thresholds out of DAX and into a settings panel: a parameter table, one measure with a default, a synced slicer and a hidden page. The whole report follows.

8 min read

Six page thumbnails wired to one gold 95 % setting in the Colis Pro settings panel

In most Power BI reports, thresholds live inside DAX. A pickup point is "saturated" above 95 % occupancy because someone once typed >= 0.95 in a measure. Want 90 % instead? Open the model, edit the measure, republish. And the person who knows the right threshold is rarely the person who can edit the model.

In Colis Pro, a free Power BI report built with an AI agent, the user sets them. A settings panel holds three thresholds: the on-time target, the pickup point saturation threshold and the payment time target. Move one, and the whole report follows, on every page.

This article shows how it works, and how to build it in Power BI Desktop with no script and no bookmark.

What it does

Same data, same page. Only the saturation threshold moved, from 85 % to 95 %.

The Network page at 85 % shows 105 saturated pickup points, at 95 % it shows 42
At 85 %, 105 pickup points are saturated and the map is full of red. At 95 %, 42 remain.

The map colours change, each point's status pill changes, and the saturated count and its trend update. So do the bars of the busiest points: navy means saturated.

At 85 % four of the busiest points are saturated, at 95 % only Relais Part-Dieu is
Relais Part-Dieu, at 96 % occupancy, stays saturated in both cases. The others switch back to gold at 95 %.

The effect is not limited to one page. The on-time target moves the target line on the Performance page, and the bell in the header of every page counts the active alerts. More on that at the end.

Before and after

The change is smaller than it looks. Everything that judges against the threshold stays exactly as it is. Only the source of the threshold moves: from a constant written in a measure to a value the user picks.

BEFOREAFTERNo setting.0.95 is written inside the DAX:to change it, edit the modeland republish.Settings slicer85 % · 90 % · 95 % · 100 %filtersRéglage saturationtable, related to nothingdefault 0.95Seuil saturationSELECTEDVALUE ( …, 0.95 )read byPoints saturés[Occupation] >= [Seuil saturation]Map, statuses, alertseverything that judgesPoints saturés[Occupation] >= 0.95Map, statuses, alertseverything that judgesDownstream stays the same. Only the source of the threshold changes.

How it works

Four pieces, all native Power BI:

  1. A parameter table related to nothing. It holds the choices: a label for the user ("95 %") and a value for DAX (0.95).
  2. One measure with a default. It reads the selected value, or falls back to the default when nothing is picked.
  3. One slicer, synced to every page. It is visible on the settings page only. Every other page holds a hidden copy, so the selection applies everywhere.
  4. A hidden page as the panel. A gear button opens it, and a Back action closes it.
Settings pagebutton slicer, visiblesync group 'Reglage saturation'a hidden copy on each pageOverviewShipmentsCustomersNetworkPerformanceAlertsfilterRéglage saturation"95 %" | 0.95readsSeuil saturationdefault 0.9523 measures read itMap colourred when saturatedPoint statuspill on each sheetOccupancy barsnavy above thresholdSaturated count105 at 85 %, 42 at 95 %Network alerton when count > 0Bell badgesum of active alertsOne slicer, one measure. Everything that judges against the threshold reads that measure.
In Colis Pro, 23 measures depend on the saturation threshold, across 15 visuals.

Step 1: a parameter table and a measure with a default

In Power BI Desktop, go to Modeling > New table and create the choices:

DAX
Réglage saturation =
DATATABLE (
    "Seuil de saturation", STRING,
    "Valeur", DOUBLE,
    {
        { "85 %", 0.85 },
        { "90 %", 0.9 },
        { "95 %", 0.95 },
        { "100 %", 1.0 }
    }
)

Two settings make it behave:

  • Select the label column and set Sort by column to Valeur, so "100 %" comes after "95 %" and not before "85 %".
  • Hide Valeur. The user only ever sees the labels.

Do not relate this table to anything. It is a list of choices, not data.

Then the measure that every other measure will read:

DAX
Seuil saturation =
SELECTEDVALUE ( 'Réglage saturation'[Valeur], 0.95 )

The second argument matters. When the slicer is empty, SELECTEDVALUE returns that default instead of blank. Without it, an empty slicer returns blank, [Occupation] >= BLANK() is true for every point, and the whole network turns red.

Finally, replace the constant wherever the threshold was used:

DAX
Points saturés =
COUNTROWS (
    FILTER (
        VALUES ( DimPointDepot[PointID] ),
        [Occupation] >= [Seuil saturation]
    )
)

Why not a What-if parameter? Modeling > New parameter > Numeric range builds the same table and measure for you, with a slider over a numeric series. A table gives you named choices instead ("30 days", "95 %"), which render as pills and read better in a panel. Both work with the rest of this article.

Colis Pro has three of these tables, one per threshold:

TableChoicesDefaultMeasure
Réglage ponctualité93 % to 97 %95 %[Objectif ponctualité]
Réglage saturation85 %, 90 %, 95 %, 100 %95 %[Seuil saturation]
Réglage délai paiement25, 30, 35, 45 days30 days[Objectif délai de paiement]

Step 2: one slicer, synced to every page

On the settings page, add a button slicer on the label column, 'Réglage saturation'[Seuil de saturation]. In Format > Selection, turn on Single select: with two pills picked, SELECTEDVALUE would fall back to the default.

Then open View > Sync slicers. For this slicer, tick Sync on every page, and tick Visible on the settings page only.

PageSyncVisibleRéglages (hidden page)OverviewShipmentsCustomersNetworkPerformanceAlertshidden copy:the selectionapplies here tooView ribbon, Sync slicers pane: tick Sync for every page, untick Visible except on the settings page.
Power BI Desktop with the saturation slicer selected on the hidden settings page: in the Sync slicers pane it is synced on every page except the check page, and visible on Réglages only
The Sync slicers pane for the saturation slicer: synced on every report page and the Alerts panel, visible on Réglages only.

This is the step that makes it work everywhere. Sync without Visible puts a hidden copy of the slicer on each page, and the selection applies wherever a copy exists. In the report files (PBIR), each copy is an ordinary slicer marked hidden, in the same sync group:

JSON
"isHidden": true,
"visual": {
  "visualType": "advancedSlicerVisual",
  "syncGroup": {
    "groupName": "Reglage saturation",
    "fieldChanges": true,
    "filterChanges": true
  }
}

A page without a copy ignores the setting and uses the default. That includes pages you might forget: in Colis Pro, the Alerts panel has its own copies, so its alert texts follow the thresholds too.

Step 3: the panel is a hidden page

The panel is not a group of visuals that you show and hide. It is a page of its own.

  1. Create the page and hide it. Right-click its tab and choose Hide page. Readers never see it in the page list.
  2. Draw its background. Take a screenshot of your report, blur it, and draw a white drawer on the right with a grey row per setting. Figma's layer blur is enough, and so is PowerPoint's Blur effect. Export it, then set it as the page background: Format page > Canvas background > Image, scaling Fit.
  3. Place the native visuals on the drawer: the titles, the help texts, the three button slicers, and a Restore defaults button.
  4. Add an invisible Back button over the blurred area, with its fill turned off and the action Back. A click anywhere outside the drawer closes it. A ✕ in the corner does the same.
1 Background imageblur + drawer + grey rows2 Native visualstitles, help, 3 slicers, button3 Invisible buttonaction: Backblurred report(transparent)Backfill: off×✕ = Back too++The surface of the drawer is pixels. Only what changes, or what you click, is a visual.
On the left, the background image alone. On the right, the same page with its native visuals.
Left: the background image, with the blur, the drawer and its grey rows. Right: the page with its titles, help texts and pills.

Then wire the buttons:

  • On every report page, the gear icon is a button with the action Page navigation, destination the settings page.
  • Restore defaults uses the action Clear all slicers. Empty slicers mean every threshold measure returns its default.
The gear button selected in the page header, and its Format button pane open on Action: type Page navigation, destination Réglages
The gear button, selected, and its action: Page navigation to the hidden page Réglages.
Any report pageOverview, Network, …Réglageshidden pagegear · Page navigationBack · blur or ✕containsRestore defaultsbuttonClear all slicersDefaults apply95 % · 95 % · 30 daysOne panel serves every page.No bookmark is involved.

Why a hidden page and not bookmarks

The classic panel is a group of visuals shown and hidden with bookmarks. It works, but it scales badly.

Show / hide with bookmarksA hidden page
Panels to maintainOne copy on every pageOne for the whole report
BookmarksTwo per page, kept in syncNone
Adding a visual laterUpdate every bookmarkNothing to update
ClosingA bookmark per pageBack returns to the page you came from

The trade-off: the blurred background is a fixed image, so it shows the same page whichever page you came from. Capture it from your busiest page. Behind a blur, nobody notices.

The traps

  • A hidden copy on every page that reads a threshold, the alerts page included. A page without a copy silently uses the default.
  • Clear all slicers clears every slicer on that page. Keep only the settings slicers on the settings page, or the Restore button will reset more than the thresholds.
  • Single select on. Two pills picked means no single value, and SELECTEDVALUE falls back to the default.
  • Always give SELECTEDVALUE a default. Blank compared with a number is treated as zero, and every comparison flips.
  • Sort the labels by their value, or "100 %" sorts before "85 %".

Going further: alerts that follow the thresholds

Once thresholds are measures, alerts come almost for free. In Colis Pro, each alert is a measure that returns 1 when it is active, and the bell badge is their sum:

DAX
Alertes : nombre =
    [Alerte réseau : active] + [Alerte paiements : active]
  + [Alerte ponctualité : active] + [Alerte envois : active]
  + [Alerte délai : active]

Change the on-time target from 97 % to 93 % and the bell on every page drops from 5 alerts to 4, while the target line on the Performance page moves down to 93 %.

With an on-time target of 97 % the bell shows 5 alerts, at 93 % it shows 4
The on-time delivery chart of the Performance page, with its dashed target line at 93 %

For alerts that reach people outside the report, by e-mail or in Teams, point a Fabric Activator rule at the same measures in the Power BI Service. The thresholds stay in one place.

Try it

Download Colis Pro, free. The panel is the hidden page Réglages. The three parameter tables and their measures ([Objectif ponctualité], [Seuil saturation], [Objectif délai de paiement]) are in the model, ready to read.

If you want this kind of finish on your own model without building it by hand, ChartCraft generates designed Power BI projects, and its MCP server lets your agent do it on your semantic model.

FAQ

Can I use a What-if parameter instead of a table?

Yes. Modeling > New parameter > Numeric range creates a table, a SELECTEDVALUE measure and a slider in one step. Use a table when you want named choices shown as pills.

Does it work once published to the Power BI Service?

Yes. Synced slicers, hidden pages and button actions (Page navigation, Back, Clear all slicers) behave the same in the Service.

How many thresholds can I add?

As many as you need. Each one is a table, a measure and a synced slicer with its own sync group, plus a row in the drawer background.

With your consent, we use Google Analytics cookies to measure audience. Cookies needed for sign-in and payment are always on. Learn more