Skip to content
Plume Visuals
← Back
Core range

Dumbbell chart for Power BI Dumbbell Plume

The gap between two values, for every category, at a glance: before / after, plan / actual, last year / this year.

Tutorials ↓
Get it on Microsoft MarketplaceThe visual's official Microsoft listing · free to install

Interactive demo

The real Power BI visual, running in your browser with the sample report's fictitious data. Switch scenario, style or year: the visual updates as it does in Power BI. Premium ★ features are shown here without the watermark; in Power BI, without a license, they show “Plume Visuals · Premium preview”.

Power BI has no dumbbell chart: you have to hack error bars. Dumbbell Plume joins the two values of each category with a bar, writes the gap as a value, a % or percentage points with ▲ ▼, colors it by direction (a decrease can be favorable) and sorts by gap. A legend (year, scenario) gives one point per value. With premium: a play axis where dumbbells slide from one year to the next and change rank before your eyes, a stability threshold, averages of each series, a logarithmic scale, more than two points, arrows and gradient bars, embedded logos or photos, min–max ranges, targets reached or missed, groups and small multiples.

Use cases

  • Last year / this year sales by store, sorted by largest increase
  • Planned / actual budget by item, where a decrease is favorable
  • Men / women pay gap by job, animated from 2018 to 2025
  • Satisfaction before / after an action, with each team's target

FreeIncluded for free

  • Two points per category: two measures (Start, End) or a Legend (year, scenario)
  • Gap written as a value, %, value and % or percentage points, with ▲ ▼; as a column, after the point or above the bar
  • Color by series or by direction (favorable / unfavorable, "a decrease is favorable")
  • Sort by last point, gap, absolute gap, %, name…; Top N; horizontal or vertical; scrolling
  • Labels at the ends, series names on the first row, hollow first point
  • Gridlines (value lines and guide lines), category drill-down, nearby labels moved apart
  • Selection, cross-filtering, highlighting, tooltips, keyboard, high contrast, dynamic formats

PremiumPremium features

  • Play axis: dumbbells slide to their new values and their new rank
  • Stability threshold (● stable), ratio gap (×), average of each series, logarithmic scale
  • More than two points per category (dot plot)
  • Arrows and gradient bar from the first to the last point
  • Embedded images (base64): logo or flag per category, image inside the points
  • Min–max range behind each dumbbell, historical range over the play axis
  • Target per category with ✓ / ✗, groups with an average dumbbell, small multiples, highlight
  • Catalog-wide styles (Neon, Newspaper, Nordic…), palettes, theme JSON

Usable without a key to try them, with a watermark.

Tutorials

Start with Getting started, then pick from the how-to guides. The Fields and settings page describes every option of the Format pane.

  1. Getting startedBeginner6 min readDumbbell chart in Power BI: the gap between two valuesGet started with Dumbbell Plume: prepare the data, create two measures, insert the visual, sort by gap, read the ▲▼ gap and color by direction.
  2. How-to guidesIntermediate6 min readDumbbell Plume: 9 use casesStep by step: plan versus actual, an animated pay gap ★, one point per year, target reached or missed, market range, logos, groups by region.
  3. Fields and settingsIntermediate22 min readDumbbell Plume: every field and setting explainedEvery field well and every Format pane setting of Dumbbell Plume: what it does, its possible values and its default value, ★ features included.
  4. BasicsGetting started with Plume visualsInstallation, license, styles and the settings shared by every visual.

Fields to drop into the visual

FieldContent
Category (one dumbbell each)Store, product, country; several fields = a hierarchy to drillOptional
Start (first point)Measure of the first point (or Legend + Values)Required
End (last point)Measure of the last point: the gap is End − StartRequired
Values (more points)A measure with the Legend, or more measures (more than two points ★)Optional
Legend (one point each)Year, scenario: one point per valueOptional
Group (parent category)Group headers and average dumbbellOptionalPremium
TargetTarget tick per category (✓ / ✗)OptionalPremium
Range minimum, Range maximumBand behind each dumbbellOptionalPremium
Category image, Point imageEmbedded base64 images (never a web address)OptionalPremium
HighlightMeasure: highlighted categoriesOptionalPremium
Play axisA year or a date: the dumbbells moveOptionalPremium
Small multiplesOne chart per valueOptionalPremium
TooltipsExtra measuresOptional
Dynamic formatMeasures renamed card.setting (e.g. title.text): the Format pane driven by DAXOptional

Missing a feature? We adapt our visuals or build custom ones. Request a custom visual

Found a bug in Dumbbell Plume, or have an idea to improve it? Report a bug · Suggest an idea

Technical reference for AI assistants

This section is meant for AI assistants (ChatGPT, Claude, Copilot…): every field, every Format pane option with its internal name, the expected data shape and DAX examples. Generated from the visual's code, version 1.1.0.0. Paste it into your assistant so it can guide you.

Raw Markdown version (/ai/visuals/dumbbell.md)
# Dumbbell Plume: technical reference for AI assistants

> Power BI custom visual by Plume Studio (Plume Visuals). Visual version **1.1.0.0**. This page is generated from the visual's source code at each site build: field names, option names and defaults are exact for this version.

Use it to help someone build a report with Dumbbell Plume: which fields to drag, how to shape the data, which Format pane option to change, or how to write the visual's settings in a PBIP `visual.json` file.

- Product page: https://plumevisuals.com/en/visuals/dumbbell (French: https://plumevisuals.com/fr/visuels/dumbbell)
- Summary: The gap between two values, for every category, at a glance: before / after, plan / actual, last year / this year.
- Power BI visual GUID (`visualType`): `plumeDumbbell1F438EFD90304AF8992B164EFBAA8481`
- Power BI visuals API: 5.11.1
- Support: https://plumevisuals.com/support · contact@plumevisuals.com
- Index of everything on the site for AI assistants: https://plumevisuals.com/llms.txt

## What the visual does

Dumbbell Plume (identifier `dumbbell`) is a Power BI custom visual (version 1.1.0.0, installed from its `.pbiviz` file; not yet on AppSource) that draws **dumbbell charts** (also called connected dot plots, range plots or barbell charts): two or more values per category joined by a bar, to read a **gap** (before / after, plan / actual, last year / this year, men / women). Power BI Desktop has no native dumbbell chart (the usual workaround is error bars on a clustered bar chart).

**New in version 1.1.0.0 (30/10/2026):** Free native-parity additions: shared **Gridlines** card (value and guide lines, zero line, banding) and **drill-down** of the category.

- **Two ways to give the points**: `start` ("Start (first point)") and `end` ("End (last point)") measures, plus extra measures in `values`; or a `legend` column (year, scenario) with one measure in `values` (one point per legend value, in the field's order, years and dates sorted). The gap is always **last point − first point**.
- **Gap written next to each dumbbell** (`gap` card): value, percentage, both, percentage points (automatic for % measures: "+3.2 pp"), or premium ratio (×) ★; in a right-hand column (on top when vertical), after the last point or above the bar; with ▲ (increase), ▼ (decrease), ● (stable) so the direction never depends on color alone.
- **Direction** (`direction` card): favorable / unfavorable colors, `lowerIsBetter` for costs and delays, and a premium **stability threshold** ★ (in % of the first value or in measure units) under which gaps are "stable".
- **Sorting** (`sort` card): model order, name, first point, last point (default, largest first), gap, absolute gap, gap in %, largest value, gap to target; Top N.
- Horizontal (default) or vertical; rows scroll below a minimum height; hollow first point; 5 point shapes; neutral / direction / last-point colored connector.
- **Play axis ★** (`play` role, premium since the 22/10/2026 rebalancing: watermark as soon as the field holds data), shared Plume player: play / pause, start / end buttons, slider with ticks, speed button (×0.5 to ×4), loop, autoplay, current value in large type; **animated transitions** (points, bars and ranks slide to the next frame); re-sort on every frame or keep the first frame's order; "reduce motion" respected.

## Free vs premium (★)

- Every feature works without a key and nothing is ever blocked. Free features never show a watermark.
- Shared Style card (the same in every Plume visual): the styles `none`, `minimal` and `blackWhite`, the two Plume gradient palettes (`crest`, `crestDiverging`), "Follow report theme" and all custom colors are **free**; every other `style.preset`, the other gradient palettes and `style.themeJson` are **premium**.
- Free in Dumbbell Plume: two points, start / end or legend; the gap column (value, %, both, percentage points; every position); colors by series, by direction or single; "a decrease is favorable"; sorting and Top N; labels; horizontal and vertical; linear value axis.
- Premium features: the **Play axis** field (with its transitions, re-sort and historical range); `direction.stable` > 0 (stability threshold); the **Averages** analytics card (`means.show`); `valAxis.scale` = `log`; `gap.content` = `ratio`; **more than two points** (a 3rd measure or a 3rd legend value); connector `colorMode` = `gradient`; `arrow` = `end`, `middle` or `replace`; the **Target** field (tick, ✓ / ✗ in the gap column, last point colored by the target); the **Range minimum / maximum** fields (band behind each dumbbell) and `band.history` (min–max over all play-axis frames); **Category image** and **Point image** fields; the **Group** field (headers, group average dumbbell, sorted groups); **Small multiples**; **Highlight** (names or measure); reference lines (Analytics pane).
- Without a valid key, a premium feature in use shows, in edit mode, a "Premium preview" note in the footer; in reading view, **"Plume Visuals · Premium preview"** (French « Plume Visuals · Aperçu premium ») is repeated lightly across the whole visual, without catching the mouse. It disappears once a key is pasted in **Format › Plume Studio License › License key** (`license.key`), the **first card** of the Format pane. Premium options and list values have " ★" appended to their label.
- Accepted keys: only keys starting with `PLUM1.` shown in the buyer's account on plumevisuals.com, checked offline (Ed25519 signature), covering `dumbbell` or the whole catalog. In edit mode, a wrong key shows "Invalid license key", "License expired (date)" or "This key does not cover this visual".
- Licenses last one year (one-time payment, no automatic renewal). Prices: 39 € personal, 99 € SME, 299 € enterprise per year, or the catalog pack.

## Expected data shape

One row per category with two measures:

| Category (`category`) | Start (`start`) | End (`end`) |
|---|---|---|
| Bristol | 412,000 | 468,000 |
| Bath | 386,000 | 352,000 |

Or one row per category and per legend value with one measure:

| Category (`category`) | Legend (`legend`) | Values (`values`) |
|---|---|---|
| Bristol | 2024 | 412,000 |
| Bristol | 2025 | 468,000 |

- **Category (one dumbbell each)** (`category`, « Catégorie (une haltère par valeur) », one column). Without it, a single dumbbell.
- **Start (first point)** (`start`), **End (last point)** (`end`), **Values (more points)** (`values`, up to 8 measures). At least one of them is required.
- **Legend (one point each)** (`legend`, one column): one point per value with the first `values` measure (else `end`, else `start`). An ordered legend (years, dates, numbers) gets a light-to-dark gradient by default.
- **Group (parent category) ★** (`group`), **Target ★** (`target`), **Range minimum ★** (`bandLow`), **Range maximum ★** (`bandHigh`), **Category image ★** (`image`), **Point image ★** (`pointImage`), **Highlight ★** (`highlight`: not blank and not 0 = highlighted), **Play axis ★** (`play`), **Small multiples ★** (`multiples`), **Tooltips** (`tooltips`), **Dynamic format** (`format`).
- **Images**: embedded only: `data:image/png;base64,…` (also jpeg, gif, webp, bmp, svg+xml) or raw base64 recognized by its signature. Web addresses (http…) are never loaded (Microsoft certification): they are skipped with a message in edit mode. Without a Legend, the point image goes on the last point, the first or both (`images.pointOn`).
- Volume of data: windows of 30,000 rows, more fetched with `fetchMoreData` up to 100,000 rows; at most 2,000 dumbbells are drawn (message in edit mode; use the sort and Top N).

## DAX recipes

```dax
// One row per store: a simple sum returns the store's value
Sales 2024 = SUM ( Stores[Sales 2024] )
Sales 2025 = SUM ( Stores[Sales 2025] )

// From a dated sales table
Sales LY = CALCULATE ( [Sales], DATEADD ( 'Calendar'[Date], -1, YEAR ) )

// Embedded logo (base64 text column) for the Category image role
Logo = "data:image/png;base64," & SELECTEDVALUE ( Stores[Logo base64] )

// Dynamic title, renamed title.text in the Dynamic format well
Dynamic title = "Sales 2025 vs 2024: " & FORMAT ( DIVIDE ( CALCULATE ( [Sales 2025], ALLSELECTED () ), CALCULATE ( [Sales 2024], ALLSELECTED () ) ) - 1, "+0.0%;-0.0%" )
```

## Interactions with the report

- Click a dumbbell: cross-filter on its category; Ctrl for several; click in the empty area to clear. In Legend mode, click a point: its category and series; click a legend item: the whole series.
- Cross-highlighting from other visuals: highlighted values drawn as the dumbbell, full values as a faint ghost; rows without highlights dimmed.
- Hover: Power BI tooltip with every point, the gap, the gap in %, target (reached / missed), range and Tooltips measures; report-page tooltips are supported. Context menu everywhere (dumbbell, point, empty area, legend, landing page).
- Keyboard: Tab to the chart, arrows from one dumbbell to the next (values, gap and direction announced), Enter selects, Esc clears; the play bar has its own keys (Space / Enter play or pause, arrows previous / next frame, Page Up / Down, Home, End). High contrast (host colors, hollow first point, one shape per series), French and English.

## Dynamic formats

- **fx button** on colors and texts of the Format pane (e.g. `gap.header`, `title.color`).
- **"Dynamic format" well** (`format`): measures renamed `card.setting` (e.g. `title.text`, `gap.content`, `direction.lowerIsBetter`, `sort.topN`) drive any setting and win over the fixed value. Driving a ★ setting by DAX still shows the watermark without a key.

## Format pane: option IDs

- Card order: `license`, `style`, `dataColors`, `dumbbells`, `direction`, `gap`, `labels`, `catAxis`, `valAxis`, `legend`, `sort`, `images` ★, `target` ★, `band` ★, `groups` ★, `play` ★, `smallMultiples` ★, `highlight` ★, `interaction`, then `title`, `source`, `container`, `texts`; Analytics pane: `reference` ★, `means` ★. Format pane in version 1.1.0.0 (30/10/2026), top to bottom: `license`, `style`, `dataColors`, `dumbbells`, `direction`, `gap`, `labels`, `catAxis`, `valAxis`, `gridlines`, `legend`, `sort`, `images`, `target`, `band`, `groups`, `highlight`, `smallMultiples`, `play`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`; Analytics pane: `reference`, `means`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- `dataColors` (dynamic card): `mode` (`series` | `direction` | `single`), `single`, `startLight` (on), one `fill` per series.
- `dumbbells`: `orientation` (`horizontal` | `vertical`), `rowMin` (10–80, 22), `rowMax` (16–200, 48), `scrollStart` (`start` | `end`), `shape` (`circle` | `square` | `diamond` | `triangle` | `bar` | `series`), `size` (4–40, 12), `hollowFirst`, `outline`, `outlineColor`, `connector`, `width` (0.5–24, 3), `lineStyle` (`solid` | `dashed` | `dotted`), `colorMode` (`neutral` | `direction` | `last` | `gradient` ★), `color`, `opacity` (10–100), `arrow` (`none` | `end` ★ | `middle` ★ | `replace` ★).
- `direction`: `lowerIsBetter`, `favorable` (#2E7D4F), `unfavorable` (#C0392B), `neutral`, `stable` ★ (0), `stableUnit` (`percent` | `value`).
- `gap`: `show`, `content` (`value` | `percent` | `both` | `points` | `ratio` ★), `position` (`column` | `end` | `middle`), `arrows`, `header`, `fontSize` (10), `bold`, `colorBy` (`direction` | `text`), `units`, `decimals`, `prefix`, `suffix`, `pctDecimals` (−1 = auto).
- `labels`: `show` (on), `content` (`value` | `seriesValue` | `series`), `position` (`outside` | `above` | `below`), `which` (`ends` | `all` | `last`), `namesOnFirst`, `fontSize`, `color`, `bold`, `halo`, `declutter`, `units`, `decimals`, `prefix`, `suffix`.
- `catAxis`: `show`, `fontSize` (9), `color`, `bold`, `maxSize` (30 %), `wrap`, `gridlines.cShow`, `gridlines.cStyle`, `gridlines.banding`, `showTitle`, `titleText`.
- `valAxis`: `show`, `position` (`bottom` | `top`), `fontSize`, `color`, `units`, `decimals`, `prefix`, `suffix`, `line`, `scale` (`linear` | `log` ★), `min`, `max`, `zero` (off), `ticks` (5), `invert`, `showTitle`, `titleText`, `gridlines.vShow`, `gridlines.vStyle`, `gridlines.vColor`, `gridlines.zeroLine`.
- `sort`: `by` (`data` | `name` | `start` | `end` | `gap` | `absGap` | `percent` | `max` | `target`), `order` (`desc` = largest first / names A to Z | `asc`), `topN` (0 = all), `groupsSorted`.
- `images`: `catPosition` (`label` | `instead` | `after`), `catSize` (22), `catShape` (`circle` | `rounded` | `square` | `contain`), `catBorder`, `pointSize` (24), `pointOn` (`end` | `start` | `both`), `pointBorder`.
- `target`: `shape` (`tick` | `diamond` | `triangle`), `color`, `width` (2), `status` (on), `colorLast`.
- `band`: `color`, `opacity` (16), `height` (70 % of the row), `history` ★.
- `groups`: `fontSize`, `color`, `separator`, `spacing` (6), `summary`.
- `play` ★ (card "Playback ★", shared player): `start` (`last` | `first`), `speed` (100–10000 ms, 1000), `loop`, `autoPlay`, `transition` (on), `controls` (on), `position` (`bottom` | `top`), `ticks` (`auto` | `all` | `none`), `tickLabels`, `stepButtons`, `speedButton`, `showLabel` (on), `labelSize` (44), `labelPosition` (`bottomRight` | `topRight` | `topLeft` | `bottomLeft` | `center`), `resort` (on).
- `smallMultiples`: `columns` (0 = auto), `minWidth` (200), `gap` (14), `titleSize`, `border`. `highlight`: `names`, `othersGray`, `othersOpacity` (45), `bold`. `means`: `show` ★, `style`, `width`, `label`. `interaction`: `hover`, `dim`.

## Editing a PBIP report (visual.json)

`visualType` is the visual GUID `plumeDumbbell1F438EFD90304AF8992B164EFBAA8481`, `queryState` keys are the data role names (`category`, `start`, `end`, `values`, `legend`, `group`, `target`, `bandLow`, `bandHigh`, `image`, `pointImage`, `highlight`, `play`, `multiples`, `tooltips`, `format`), `objects` keys are the option IDs. Booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes, e.g. `"gap": [ { "properties": { "content": { "expr": { "Literal": { "Value": "'both'" } } } } } ]`.

## Common pitfalls

- A single dumbbell: no field in Category.
- Points without a bar or gap: a single point measure.
- Gap with the wrong sign: Start and End swapped.
- "No dumbbell to show (all values are blank)": every value is blank for the current filters.
- The gap shows "pp": the measure has a % format (the gap of two rates is in percentage points); use `gap.content` = `percent` for a relative gap.
- Images not shown: web addresses (http…) are never loaded; build a base64 data URI in a measure.
- Watermark visible: a filled play axis, a stability threshold, averages, a logarithmic scale, the ratio gap, more than two points, gradient connector, arrow, target or range values, a valid image, Group, Small multiples, Highlight, reference lines, historical range, a ★ style or a theme JSON, without a valid key.
- The visual makes no network request: data and license key stay in the report.

## Features that do NOT exist (do not suggest them)

Loading images from web addresses, a separate variance bar chart next to the dumbbells (the gap column replaces it), dragging rows to reorder them, movable labels or annotations, exporting the chart as an image, writing data back to the model.

## Data fields (wells)

Internal name = data role name (PBIP `queryState` key). Labels as shown in Power BI (English / French). ★ = premium.

| Internal name | Label (EN) | Label (FR) | Kind | Max fields | Description |
|---|---|---|---|---|---|
| `category` | Category (one dumbbell each) | Catégorie (une haltère par valeur) | column | 4 |  |
| `start` | Start (first point) | Début (premier point) | measure | 1 | First value of each dumbbell (before, plan, last year…) |
| `end` | End (last point) | Fin (dernier point) | measure | 1 | Last value of each dumbbell (after, actual, this year…); the gap is End − Start |
| `values` | Values (more points) | Valeurs (plus de points) | measure | 8 | With a Legend: one point per legend value (dot plot). Without: each measure adds a point. More than two points ★ |
| `legend` | Legend (one point each) | Légende (un point par valeur) | column | 1 | A year, a scenario or a group: one point per value, in the order of the field |
| `group` | Group (parent category) ★ | Groupe (catégorie parente) ★ | column | 1 | Gathers the dumbbells under a header per value (region > country, department > product) |
| `target` | Target ★ | Objectif ★ | measure | 1 | A tick per dumbbell; the last point can show whether it is reached |
| `bandLow` | Range minimum ★ | Plage : minimum ★ | measure | 1 | Lower bound of a band drawn behind each dumbbell (historical low, market range…) |
| `bandHigh` | Range maximum ★ | Plage : maximum ★ | measure | 1 | Upper bound of the band drawn behind each dumbbell |
| `image` | Category image ★ | Image de la catégorie ★ | measure | 1 | An embedded image per category (data:image/…;base64 or raw base64), next to its name; web addresses are never loaded |
| `pointImage` | Point image ★ | Image des points ★ | measure | 1 | An embedded image drawn inside the points (one per legend value, or on the start / end point); web addresses are never loaded |
| `highlight` | Highlight ★ | Mise en avant ★ | measure | 1 | Not blank and not 0: the dumbbell stands out, the others turn gray |
| `play` | Play axis ★ | Axe de lecture ★ | column | 1 | A date, a year or an ordered category: the dumbbells move from one value to the next (play button) |
| `multiples` | Small multiples ★ | Petits multiples ★ | column | 1 | One small dumbbell chart per value, sharing the same scale |
| `tooltips` | Tooltips | Infobulles | measure | several |  |
| `format` | Dynamic format | Format dynamique | measure | several | Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX |

Data view: categorical, categories = `category` + `group` + `play` + `multiples` (one row per combination), 30,000 rows per data window (more fetched automatically); measures = `start`, `end`, `values`, `target`, `bandLow`, `bandHigh`, `image`, `pointImage`, `highlight`, `tooltips`, `format`, grouped into series by `legend`.
Capabilities: supportsHighlight, supportsKeyboardFocus, supportsMultiVisualSelection, supportsLandingPage, supportsEmptyDataView.
Network access: none (no privileges requested, no external request).

## Format pane options (256)

Columns: option ID (`object.property`), labels EN / FR as shown in Power BI, control type, PBIP literal type, default value, allowed values, notes.

### Plume Studio License / Licence Plume Studio (`license`, Format pane)

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `license.buy` | Get a license | Obtenir une licence | info | text | `plumevisuals.com` |  |  |
| `license.key` | License key | Clé de licence | text | text | (empty) |  | Paste the key received after purchase on plumevisuals.com (starts with PLUM1.). Checked offline. |
| `license.showOwner` | Show license holder (edit mode) | Afficher le titulaire (mode édition) | toggle | bool | `true` | true / false |  |

### Style (`style`, Format pane)

**Style**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `style.preset` | Style | Style | dropdown | enumeration | `none` | `none` None; `minimal` Minimal; `blackWhite` Black & White; `press` Newspaper ★; `vintage` Vintage (antique plate) ★; `earth` Earth ★; `nordic` Nordic ★; `executive` Executive ★; `accessible` Accessible (high legibility) ★; `pastel` Pastel ★; `bauhaus` Bauhaus (pop) ★; `climate` Climate ★; `blueprint` Blueprint ★; `unknownPleasures` Unknown Pleasures ★; `dark` Graphite (dark) ★; `neon` Neon ★; `terminal` Terminal (Matrix) ★; `infographic` Infographic ★; `cockpit` Cockpit (HUD) ★; `hologram` Hologram ★ | Complete look shared by all Plume visuals: colors, three palettes, fonts, frame, table header, marks and effects. Customize colors below. |
| `style.themeJson` | Theme JSON ★ | Thème JSON ★ | textarea | text | (empty) |  | Paste a JSON theme: see the 'JSON themes' tutorial on plumevisuals.com |
| `style.followTheme` | Follow report theme | Suivre le thème du rapport | toggle | bool | `false` | true / false | Text, background, accent and data colors come from the Power BI report theme. |
| `style.reverse` | Reverse gradients | Inverser les dégradés | toggle | bool | `false` | true / false |  |

**Custom colors / Couleurs personnalisées**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `style.customColors` | Customize colors | Personnaliser les couleurs | toggle | bool | `false` | true / false | Start from the style and pick your own colors. A color left empty keeps the style's color. |
| `style.colorBackground` | Background | Fond | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.colorText` | Text | Texte | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.colorMuted` | Secondary text | Texte secondaire | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.colorGrid` | Lines and grid | Traits et grille | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.colorAccent` | Accent | Accent | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.colorPositive` | Favorable | Favorable | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.colorNegative` | Unfavorable | Défavorable | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.series1` | Series 1 | Série 1 | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.series2` | Series 2 | Série 2 | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.series3` | Series 3 | Série 3 | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.series4` | Series 4 | Série 4 | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.series5` | Series 5 | Série 5 | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.series6` | Series 6 | Série 6 | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.series7` | Series 7 | Série 7 | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.series8` | Series 8 | Série 8 | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.palette` | Gradient palette | Palette du dégradé | dropdown | enumeration | `auto` | `auto` Style or theme palette; `crest` Plume (sequential); `crestDiverging` Plume (diverging); `viridis` Viridis ★; `magma` Magma ★; `inferno` Inferno ★; `cividis` Cividis (colorblind-safe) ★; `warmingStripes` Warming stripes ★; `rdYlBu` Red–Yellow–Blue ★; `brBG` Brown–Teal (drought) ★; `spectral` Spectral ★; `blues` Blues ★; `reds` Reds ★; `grays` Grays ★; `press` Press (ink and paper) ★; `nordic` Nordic ★; `earth` Earth (ochre to umber) ★; `pastel` Pastel ★; `okabeIto` Okabe-Ito (colorblind-safe) ★ | Visible when `style.customColors` = `true`. Gradient from the catalog (Viridis, Magma…). The start, middle and end colors below replace it. |
| `style.scaleLow` | Gradient: start | Dégradé : début | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.scaleMid` | Gradient: middle (diverging) | Dégradé : milieu (écarts) | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |
| `style.scaleHigh` | Gradient: end | Dégradé : fin | color | fill | (empty) | hex color | Visible when `style.customColors` = `true` |

**Text / Texte**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `style.fontFamily` | Font | Police | font | formatting | `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif` |  | Used by every text of the visual (title, axes, labels, cells). |

**Animations**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `style.animate` | Animations | Animations | toggle | bool | `true` | true / false | Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion. |

### Data colors / Couleurs des données (`dataColors`, Format pane)

Per-item card: Power BI shows it once per series, category, column or KPI (an "Apply settings to" list where relevant). In PBIP `visual.json`, each entry of `objects.dataColors` carries a `selector` (`metadata` = the field's queryRef, or `data` for a category value); an entry without a selector applies to all items.

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `dataColors.mode` | Coloring | Coloration | dropdown | enumeration | `series` | `series` One color per point (series); `direction` By direction of the gap; `single` Single color |  |
| `dataColors.single` | Color | Couleur | color | fill | (empty) | hex color |  |
| `dataColors.fill` | Color | Couleur | color | fill | (empty) | hex color |  |
| `dataColors.startLight` | Lighter first point | Premier point plus clair | toggle | bool | `true` | true / false | With two points of the same color (single color, direction): the first point is drawn lighter, the last one darker. |

### Dumbbells / Haltères (`dumbbells`, Format pane)

**Layout / Disposition**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `dumbbells.orientation` | Orientation | Orientation | dropdown | enumeration | `horizontal` | `horizontal` Horizontal (categories as rows); `vertical` Vertical (categories as columns) |  |
| `dumbbells.rowMin` | Minimum row height before scrolling (px) | Hauteur minimale d'une ligne avant défilement (px) | number | integer | `22` | 10 to 80 | Below that, the chart scrolls. |
| `dumbbells.rowMax` | Maximum row height (px) | Hauteur maximale d'une ligne (px) | number | integer | `48` | 16 to 200 | With few categories, rows stop growing and the chart stays compact at the top. |
| `dumbbells.scrollStart` | Initial scroll position | Défilement au départ | dropdown | enumeration | `start` | `start` At the start; `end` At the end |  |

**Points**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `dumbbells.shape` | Shape | Forme | dropdown | enumeration | `circle` | `circle` Circle; `square` Square; `diamond` Diamond; `triangle` Triangle; `bar` Tick; `series` One shape per series | One shape per series helps when colors are hard to tell apart. |
| `dumbbells.size` | Size (px) | Taille (px) | number | integer | `12` | 4 to 40 |  |
| `dumbbells.hollowFirst` | Hollow first point | Premier point creux | toggle | bool | `false` | true / false | The first point (before) is drawn as a ring: the eye goes from the ring to the full point. |
| `dumbbells.outline` | Outline | Contour | toggle | bool | `true` | true / false |  |
| `dumbbells.outlineColor` | Outline color (empty = background) | Couleur du contour (vide = fond) | color | fill | (empty) | hex color | Visible when `dumbbells.outline` = `true` |

**Connector / Barre de liaison**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `dumbbells.connector` | Show | Afficher | toggle | bool | `true` | true / false |  |
| `dumbbells.width` | Width (px) | Épaisseur (px) | number | numeric | `3` | 0.5 to 24 |  |
| `dumbbells.lineStyle` | Line style | Style du trait | dropdown | enumeration | `solid` | `solid` Solid; `dashed` Dashed; `dotted` Dotted |  |
| `dumbbells.colorMode` | Color | Couleur | dropdown | enumeration | `neutral` | `neutral` Neutral; `direction` By direction of the gap; `last` Color of the last point; `gradient` Gradient from first to last point ★ |  |
| `dumbbells.color` | Neutral color (empty = automatic) | Couleur neutre (vide = automatique) | color | fill | (empty) | hex color | Visible when `dumbbells.colorMode` = `neutral` |
| `dumbbells.opacity` | Opacity (%) | Opacité (%) | number | integer | `100` | 10 to 100 |  |
| `dumbbells.arrow` | Arrow | Flèche | dropdown | enumeration | `none` | `none` None; `end` At the last point ★; `middle` In the middle ★; `replace` Instead of the last point ★ | The arrow goes from the first point to the last one: the direction is read without color. |

### Gap direction / Sens de l'écart (`direction`, Format pane)

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `direction.lowerIsBetter` | A decrease is favorable | Une baisse est favorable | toggle | bool | `false` | true / false | Costs, delays, churn: a decrease is shown in the favorable color. |
| `direction.favorable` | Favorable | Favorable | color | fill | `#2E7D4F` | hex color |  |
| `direction.unfavorable` | Unfavorable | Défavorable | color | fill | `#C0392B` | hex color |  |
| `direction.neutral` | Stable (empty = secondary text) | Stable (vide = texte secondaire) | color | fill | (empty) | hex color |  |
| `direction.stable` | Stability threshold ★ | Seuil de stabilité ★ | number | numeric | `0` | 0 to … | Gaps at or below this threshold are “stable” (● and neutral color) instead of up or down. |
| `direction.stableUnit` | Threshold unit | Unité du seuil | dropdown | enumeration | `percent` | `percent` % of the first value; `value` Value (measure unit) |  |

### Gap / Écart (`gap`, Format pane)

The card header toggle is `gap.show`.

**Gap / Écart**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `gap.show` | Show | Afficher | toggle | bool | `true` | true / false |  |
| `gap.content` | Content | Contenu | dropdown | enumeration | `value` | `value` Value (end − start); `percent` Percentage; `both` Value and percentage; `points` Percentage points (% measures); `ratio` Ratio (× end ÷ start) ★ |  |
| `gap.position` | Position | Position | dropdown | enumeration | `column` | `column` Column on the right (or on top); `end` After the last point; `middle` Above the connector |  |
| `gap.arrows` | ▲▼ arrows | Flèches ▲▼ | toggle | bool | `true` | true / false |  |
| `gap.header` | Column title | Titre de la colonne | text | text | (empty) |  | Visible when `gap.position` = `column` |
| `gap.fontSize` | Size | Taille | number | formatting | `10` | 6 to 24 |  |
| `gap.bold` | Bold | Gras | toggle | bool | `true` | true / false |  |
| `gap.colorBy` | Color | Couleur | dropdown | enumeration | `direction` | `direction` By direction; `text` Text |  |

**Numbers / Nombres**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `gap.units` | Display units | Unités d'affichage | dropdown | enumeration | `auto` | `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions |  |
| `gap.decimals` | Decimals (-1 = auto) | Décimales (-1 = auto) | number | integer | `-1` | -1 to 6 |  |
| `gap.prefix` | Prefix | Préfixe | text | text | (empty) |  |  |
| `gap.suffix` | Suffix (e.g. €) | Suffixe (ex. €) | text | text | (empty) |  |  |
| `gap.pctDecimals` | Percentage decimals (-1 = auto) | Décimales du pourcentage (-1 = auto) | number | integer | `-1` | -1 to 4 | Automatic: one decimal under 10 %, none above. |

### Data labels / Étiquettes de données (`labels`, Format pane)

The card header toggle is `labels.show`.

**Labels / Étiquettes**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `labels.show` | Show | Afficher | toggle | bool | `true` | true / false |  |
| `labels.content` | Content | Contenu | dropdown | enumeration | `value` | `value` Value; `seriesValue` Series and value; `series` Series |  |
| `labels.position` | Position | Position | dropdown | enumeration | `outside` | `outside` At the ends (outside); `above` Above the points; `below` Below the points |  |
| `labels.which` | Labeled points | Points étiquetés | dropdown | enumeration | `ends` | `ends` First and last; `all` All; `last` The last one |  |
| `labels.namesOnFirst` | Name the points on the first row | Nommer les points sur la première ligne | toggle | bool | `false` | true / false | Writes the series names above the points of the first dumbbell: no legend needed. |
| `labels.fontSize` | Size | Taille | number | formatting | `10` | 6 to 24 |  |
| `labels.color` | Color (empty = automatic) | Couleur (vide = automatique) | color | fill | (empty) | hex color | Automatic: readable color depending on the background (inside bars: white or dark). |
| `labels.bold` | Bold | Gras | toggle | bool | `false` | true / false |  |
| `labels.halo` | Text halo | Halo autour du texte | toggle | bool | `true` | true / false |  |
| `labels.declutter` | Hide overlapping labels | Masquer les étiquettes qui se chevauchent | toggle | bool | `true` | true / false |  |

**Numbers / Nombres**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `labels.units` | Display units | Unités d'affichage | dropdown | enumeration | `auto` | `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions |  |
| `labels.decimals` | Decimals (-1 = auto) | Décimales (-1 = auto) | number | integer | `-1` | -1 to 6 |  |
| `labels.prefix` | Prefix | Préfixe | text | text | (empty) |  |  |
| `labels.suffix` | Suffix (e.g. €) | Suffixe (ex. €) | text | text | (empty) |  |  |

### Category axis / Axe des catégories (`catAxis`, Format pane)

The card header toggle is `catAxis.show`.

**Values / Valeurs**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `catAxis.show` | Show | Afficher | toggle | bool | `true` | true / false |  |
| `catAxis.fontSize` | Size | Taille | number | formatting | `9` | 6 to 24 |  |
| `catAxis.color` | Color (empty = text) | Couleur (vide = texte) | color | fill | (empty) | hex color |  |
| `catAxis.bold` | Bold | Gras | toggle | bool | `false` | true / false |  |
| `catAxis.maxSize` | Maximum room (% of the visual) | Place maximale (% du visuel) | number | integer | `30` | 10 to 60 |  |
| `catAxis.wrap` | Long names on two lines | Noms longs sur deux lignes | toggle | bool | `true` | true / false |  |

**Axis title / Titre de l'axe**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `catAxis.showTitle` | Show | Afficher | toggle | bool | `false` | true / false |  |
| `catAxis.titleText` | Text | Texte | text | text | (empty) |  | Visible when `catAxis.showTitle` = `true` |

### Value axis / Axe des valeurs (`valAxis`, Format pane)

The card header toggle is `valAxis.show`.

**Values / Valeurs**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `valAxis.show` | Show | Afficher | toggle | bool | `true` | true / false |  |
| `valAxis.position` | Position | Position | dropdown | enumeration | `bottom` | `bottom` Bottom; `top` Top |  |
| `valAxis.fontSize` | Size | Taille | number | formatting | `9` | 6 to 24 |  |
| `valAxis.color` | Color (empty = secondary text) | Couleur (vide = texte secondaire) | color | fill | (empty) | hex color |  |
| `valAxis.units` | Display units | Unités d'affichage | dropdown | enumeration | `auto` | `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions |  |
| `valAxis.decimals` | Decimals (-1 = auto) | Décimales (-1 = auto) | number | integer | `-1` | -1 to 6 |  |
| `valAxis.prefix` | Prefix | Préfixe | text | text | (empty) |  |  |
| `valAxis.suffix` | Suffix (e.g. €) | Suffixe (ex. €) | text | text | (empty) |  |  |
| `valAxis.line` | Axis line | Trait de l'axe | toggle | bool | `false` | true / false |  |

**Range / Échelle**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `valAxis.scale` | Scale | Échelle | dropdown | enumeration | `linear` | `linear` Linear; `log` Logarithmic ★ |  |
| `valAxis.min` | Minimum | Minimum | text | text | (empty) |  |  |
| `valAxis.max` | Maximum | Maximum | text | text | (empty) |  |  |
| `valAxis.zero` | Always include zero | Toujours inclure zéro | toggle | bool | `false` | true / false | Visible when `valAxis.scale` = `linear` |
| `valAxis.ticks` | Number of ticks (approx.) | Nombre de graduations (environ) | number | integer | `5` | 2 to 20 |  |
| `valAxis.invert` | Invert axis | Inverser l'axe | toggle | bool | `false` | true / false |  |

**Axis title / Titre de l'axe**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `valAxis.showTitle` | Show | Afficher | toggle | bool | `false` | true / false |  |
| `valAxis.titleText` | Text | Texte | text | text | (empty) |  | Visible when `valAxis.showTitle` = `true` |

### Gridlines / Quadrillage (`gridlines`, Format pane)

**Values / Valeurs**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `gridlines.vShow` | Show | Afficher | toggle | bool | `true` | true / false |  |
| `gridlines.vColor` | Color (empty = style grid) | Couleur (vide = grille du style) | color | fill | (empty) | hex color |  |
| `gridlines.vWidth` | Width | Épaisseur | number | numeric | `1` | 0.5 to 6 |  |
| `gridlines.vStyle` | Line style | Style de trait | dropdown | enumeration | `solid` | `solid` Solid; `dashed` Dashed; `dotted` Dotted |  |
| `gridlines.zeroLine` | Zero line | Ligne du zéro | toggle | bool | `true` | true / false |  |

**Categories (guide lines) / Catégories (lignes guides)**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `gridlines.cShow` | Show | Afficher | toggle | bool | `true` | true / false | A thin line across each row, from the name to the dumbbell. |
| `gridlines.cColor` | Color (empty = softened grid) | Couleur (vide = grille adoucie) | color | fill | (empty) | hex color |  |
| `gridlines.cWidth` | Width | Épaisseur | number | numeric | `1` | 0.5 to 6 |  |
| `gridlines.cStyle` | Line style | Style de trait | dropdown | enumeration | `dotted` | `solid` Solid; `dashed` Dashed; `dotted` Dotted |  |
| `gridlines.banding` | Banded rows | Lignes alternées | toggle | bool | `false` | true / false |  |

### Legend / Légende (`legend`, Format pane)

The card header toggle is `legend.show`.

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `legend.show` | Show | Afficher | toggle | bool | `true` | true / false | Shown when the chart has several series. |
| `legend.position` | Position | Position | dropdown | enumeration | `top` | `top` Top; `bottom` Bottom; `right` Right; `left` Left |  |
| `legend.align` | Alignment | Alignement | dropdown | enumeration | `left` | `left` Start; `center` Center; `right` End | Visible when `legend.position` = `top` or `bottom` |
| `legend.showTitle` | Legend title | Titre de la légende | toggle | bool | `false` | true / false |  |
| `legend.titleText` | Title text | Texte du titre | text | text | (empty) |  | Visible when `legend.showTitle` = `true` |
| `legend.fontSize` | Size | Taille | number | formatting | `9` | 6 to 24 |  |
| `legend.color` | Color (empty = secondary text) | Couleur (vide = texte secondaire) | color | fill | (empty) | hex color |  |
| `legend.interactive` | Click = select the series | Clic = sélectionner la série | toggle | bool | `true` | true / false |  |

### Sort / Tri (`sort`, Format pane)

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `sort.by` | Sort by | Trier par | dropdown | enumeration | `end` | `data` Model order (as in Power BI); `name` Category name; `start` First point; `end` Last point; `gap` Gap (end − start); `absGap` Absolute gap; `percent` Gap in %; `max` Largest value; `target` Gap to target |  |
| `sort.order` | Order | Ordre | dropdown | enumeration | `desc` | `desc` Largest first (names A to Z); `asc` Smallest first (names Z to A) |  |
| `sort.topN` | Show the first N (0 = all) | Afficher les N premières (0 = toutes) | number | integer | `0` | 0 to 5000 |  |
| `sort.groupsSorted` | Sort the groups too | Trier aussi les groupes | toggle | bool | `false` | true / false | Groups follow the average of their dumbbells; otherwise they keep the model order. |

### Images ★ (`images`, Format pane)

This card controls premium features (★): they work without a license key but show the watermark while in use.

**Category image / Image de la catégorie**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `images.catPosition` | Position | Position | dropdown | enumeration | `label` | `label` Next to the name; `instead` Instead of the name; `after` After the last point |  |
| `images.catSize` | Size (px) | Taille (px) | number | integer | `22` | 8 to 120 |  |
| `images.catShape` | Shape | Forme | dropdown | enumeration | `circle` | `circle` Round; `rounded` Rounded corners; `square` Square; `contain` Whole image (no crop) |  |
| `images.catBorder` | Border | Bordure | toggle | bool | `false` | true / false |  |

**Point images / Images des points**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `images.pointSize` | Size of a point with an image (px) | Taille d'un point avec image (px) | number | integer | `24` | 8 to 120 |  |
| `images.pointOn` | Without Legend: image on | Sans Légende : image sur | dropdown | enumeration | `end` | `end` The last point; `start` The first point; `both` Both points |  |
| `images.pointBorder` | Border in the point color | Bordure de la couleur du point | toggle | bool | `true` | true / false |  |

### Target ★ / Objectif ★ (`target`, Format pane)

This card controls premium features (★): they work without a license key but show the watermark while in use.

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `target.shape` | Marker | Repère | dropdown | enumeration | `tick` | `tick` Tick; `diamond` Diamond; `triangle` Triangle |  |
| `target.color` | Color (empty = text) | Couleur (vide = texte) | color | fill | (empty) | hex color |  |
| `target.width` | Width | Épaisseur | number | numeric | `2` | 0.5 to 8 |  |
| `target.status` | Mark the target as reached (✓) or missed (✗) | Marquer l'objectif atteint (✓) ou manqué (✗) | toggle | bool | `true` | true / false | Written in the gap column; “A decrease is favorable” also applies to the target. |
| `target.colorLast` | Last point colored by the target | Dernier point coloré selon l'objectif | toggle | bool | `false` | true / false |  |

### Range ★ / Plage ★ (`band`, Format pane)

This card controls premium features (★): they work without a license key but show the watermark while in use.

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `band.color` | Color (empty = secondary text) | Couleur (vide = texte secondaire) | color | fill | (empty) | hex color |  |
| `band.opacity` | Opacity (%) | Opacité (%) | number | integer | `16` | 3 to 80 |  |
| `band.height` | Thickness (% of the row) | Épaisseur (% de la ligne) | number | integer | `70` | 10 to 100 |  |
| `band.history` | Historical range (play axis) ★ | Plage historique (axe de lecture) ★ | toggle | bool | `false` | true / false | With a play axis: the band goes from the lowest to the highest value of the dumbbell over all frames. |

### Groups ★ / Groupes ★ (`groups`, Format pane)

This card controls premium features (★): they work without a license key but show the watermark while in use.

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `groups.fontSize` | Group header size | Taille des titres de groupe | number | formatting | `10` | 6 to 24 |  |
| `groups.color` | Header color (empty = text) | Couleur des titres (vide = texte) | color | fill | (empty) | hex color |  |
| `groups.separator` | Line between groups | Trait entre les groupes | toggle | bool | `true` | true / false |  |
| `groups.spacing` | Space before a group (px) | Espace avant un groupe (px) | number | integer | `6` | 0 to 40 |  |
| `groups.summary` | Group average dumbbell | Haltère moyenne du groupe | toggle | bool | `false` | true / false | Adds a dumbbell with the average of each point under the header. |

### Highlight ★ / Mise en avant ★ (`highlight`, Format pane)

This card controls premium features (★): they work without a license key but show the watermark while in use.

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `highlight.names` | Highlighted categories ★ | Catégories mises en avant ★ | textarea | text | (empty) |  | Names of the Category field (case and accents ignored). The “Highlight” field does the same with a measure. |
| `highlight.othersGray` | Other dumbbells in gray | Autres haltères en gris | toggle | bool | `true` | true / false |  |
| `highlight.othersOpacity` | Other dumbbells opacity (%) | Opacité des autres haltères (%) | number | integer | `45` | 5 to 100 |  |
| `highlight.bold` | Bold name | Nom en gras | toggle | bool | `true` | true / false |  |

### Small multiples ★ / Petits multiples ★ (`smallMultiples`, Format pane)

This card controls premium features (★): they work without a license key but show the watermark while in use.

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `smallMultiples.columns` | Columns (0 = automatic) | Colonnes (0 = automatique) | number | integer | `0` | 0 to 12 |  |
| `smallMultiples.minWidth` | Minimum chart width (px) | Largeur minimale d'un graphique (px) | number | integer | `200` | 80 to 800 |  |
| `smallMultiples.gap` | Spacing (px) | Espacement (px) | number | integer | `14` | 0 to 60 |  |
| `smallMultiples.titleSize` | Title size | Taille des titres | number | formatting | `10` | 6 to 24 |  |
| `smallMultiples.border` | Frame around each chart | Cadre autour de chaque graphique | toggle | bool | `false` | true / false |  |

### Playback ★ / Lecture ★ (`play`, Format pane)

This card controls premium features (★): they work without a license key but show the watermark while in use.

**Playback / Lecture**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `play.start` | Frame shown on opening | Image affichée à l'ouverture | dropdown | enumeration | `last` | `last` The last one (most recent); `first` The first one |  |
| `play.speed` | Duration of a frame (ms) | Durée d'une image (ms) | number | integer | `1000` | 100 to 10000 | At speed ×1; the speed button of the play bar multiplies it (×0.5 to ×4) for the session. |
| `play.loop` | Loop | Lecture en boucle | toggle | bool | `false` | true / false |  |
| `play.autoPlay` | Play automatically on opening | Lecture automatique à l'ouverture | toggle | bool | `false` | true / false | Once, from the first frame. Not when animations are reduced (Style › Animations or the system) nor on a dashboard tile. |
| `play.transition` | Animated transitions | Transitions animées | toggle | bool | `true` | true / false | Values, positions and colors move smoothly from one frame to the next. |

**Play bar / Barre de lecture**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `play.controls` | Play bar | Barre de lecture | toggle | bool | `true` | true / false |  |
| `play.position` | Bar position | Position de la barre | dropdown | enumeration | `bottom` | `bottom` Bottom; `top` Top | Visible when `play.controls` = `true` |
| `play.ticks` | Tick marks | Graduations | dropdown | enumeration | `auto` | `auto` Automatic; `all` Every frame; `none` None | Visible when `play.controls` = `true` |
| `play.tickLabels` | Tick labels | Étiquettes des graduations | toggle | bool | `true` | true / false | Visible when `play.controls` = `true` |
| `play.stepButtons` | Start and end buttons | Boutons début et fin | toggle | bool | `true` | true / false | Visible when `play.controls` = `true` |
| `play.speedButton` | Speed button | Bouton de vitesse | toggle | bool | `true` | true / false | Visible when `play.controls` = `true` |

**Large value / Valeur en grand**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `play.showLabel` | Current value in large type | Valeur en cours en grand | toggle | bool | `true` | true / false |  |
| `play.labelSize` | Large value size | Taille de la valeur en grand | number | formatting | `44` | 12 to 160 | Visible when `play.showLabel` = `true` |
| `play.labelPosition` | Large value position | Position de la valeur en grand | dropdown | enumeration | `bottomRight` | `bottomRight` Bottom right; `topRight` Top right; `topLeft` Top left; `bottomLeft` Bottom left; `center` Center | Visible when `play.showLabel` = `true` |

**More settings / Autres réglages**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `play.resort` | Re-sort on every frame | Retrier à chaque image | toggle | bool | `true` | true / false | The rows slide to their new rank (animated). Off: the order of the opening frame is kept. |

### Reference lines ★ / Lignes de référence ★ (`reference`, Analytics pane)

This card controls premium features (★): they work without a license key but show the watermark while in use.

**Line 1 / Ligne 1**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `reference.show1` | Show | Afficher | toggle | bool | `false` | true / false |  |
| `reference.kind1` | Value | Valeur | dropdown | enumeration | `average` | `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile; `measure` Average of the target |  |
| `reference.value1` | Constant value | Valeur constante | number | numeric | `0` |  | Visible when `reference.kind1` = `constant` |
| `reference.pct1` | Percentile | Centile | number | integer | `90` | 1 to 99 | Visible when `reference.kind1` = `percentile` |
| `reference.label1` | Label | Libellé | text | text | (empty) |  |  |
| `reference.showValue1` | Show the value | Afficher la valeur | toggle | bool | `true` | true / false |  |
| `reference.color1` | Color (empty = accent) | Couleur (vide = accent) | color | fill | (empty) | hex color |  |
| `reference.style1` | Line style | Style de trait | dropdown | enumeration | `dashed` | `solid` Solid; `dashed` Dashed; `dotted` Dotted |  |
| `reference.width1` | Width | Épaisseur | number | numeric | `1.5` | 0.5 to 6 |  |
| `reference.labelPos1` | Label position | Position du libellé | dropdown | enumeration | `end` | `end` End; `start` Start; `none` None |  |

**Line 2 / Ligne 2**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `reference.show2` | Show | Afficher | toggle | bool | `false` | true / false |  |
| `reference.kind2` | Value | Valeur | dropdown | enumeration | `constant` | `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile; `measure` Average of the target |  |
| `reference.value2` | Constant value | Valeur constante | number | numeric | `0` |  | Visible when `reference.kind2` = `constant` |
| `reference.pct2` | Percentile | Centile | number | integer | `90` | 1 to 99 | Visible when `reference.kind2` = `percentile` |
| `reference.label2` | Label | Libellé | text | text | (empty) |  |  |
| `reference.showValue2` | Show the value | Afficher la valeur | toggle | bool | `true` | true / false |  |
| `reference.color2` | Color (empty = accent) | Couleur (vide = accent) | color | fill | (empty) | hex color |  |
| `reference.style2` | Line style | Style de trait | dropdown | enumeration | `dashed` | `solid` Solid; `dashed` Dashed; `dotted` Dotted |  |
| `reference.width2` | Width | Épaisseur | number | numeric | `1.5` | 0.5 to 6 |  |
| `reference.labelPos2` | Label position | Position du libellé | dropdown | enumeration | `end` | `end` End; `start` Start; `none` None |  |

**Line 3 / Ligne 3**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `reference.show3` | Show | Afficher | toggle | bool | `false` | true / false |  |
| `reference.kind3` | Value | Valeur | dropdown | enumeration | `median` | `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile; `measure` Average of the target |  |
| `reference.value3` | Constant value | Valeur constante | number | numeric | `0` |  | Visible when `reference.kind3` = `constant` |
| `reference.pct3` | Percentile | Centile | number | integer | `90` | 1 to 99 | Visible when `reference.kind3` = `percentile` |
| `reference.label3` | Label | Libellé | text | text | (empty) |  |  |
| `reference.showValue3` | Show the value | Afficher la valeur | toggle | bool | `true` | true / false |  |
| `reference.color3` | Color (empty = accent) | Couleur (vide = accent) | color | fill | (empty) | hex color |  |
| `reference.style3` | Line style | Style de trait | dropdown | enumeration | `dashed` | `solid` Solid; `dashed` Dashed; `dotted` Dotted |  |
| `reference.width3` | Width | Épaisseur | number | numeric | `1.5` | 0.5 to 6 |  |
| `reference.labelPos3` | Label position | Position du libellé | dropdown | enumeration | `end` | `end` End; `start` Start; `none` None |  |

**Reference band / Bande de référence**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `reference.band` | Show | Afficher | toggle | bool | `false` | true / false |  |
| `reference.bandFrom` | From | De | number | numeric | `0` |  |  |
| `reference.bandTo` | To | À | number | numeric | `0` |  |  |
| `reference.bandLabel` | Label | Libellé | text | text | (empty) |  |  |
| `reference.bandColor` | Color (empty = accent) | Couleur (vide = accent) | color | fill | (empty) | hex color |  |
| `reference.bandOpacity` | Opacity (%) | Opacité (%) | number | integer | `12` | 2 to 60 |  |

### Averages ★ / Moyennes ★ (`means`, Analytics pane)

This card controls premium features (★): they work without a license key but show the watermark while in use.

The card header toggle is `means.show`.

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `means.show` | Show ★ | Afficher ★ | toggle | bool | `false` | true / false | A line at the average of each point (series), in its color. |
| `means.style` | Line style | Style du trait | dropdown | enumeration | `dashed` | `solid` Solid; `dashed` Dashed; `dotted` Dotted |  |
| `means.width` | Width | Épaisseur | number | numeric | `1.5` | 0.5 to 6 |  |
| `means.label` | Show the value | Afficher la valeur | toggle | bool | `true` | true / false |  |

### Interactions (`interaction`, Format pane)

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `interaction.hover` | Highlight on hover | Mettre en avant au survol | toggle | bool | `true` | true / false |  |
| `interaction.dim` | Dimmed items opacity (%) | Opacité des éléments estompés (%) | number | integer | `25` | 5 to 80 |  |

### Tooltips / Infobulles (`tooltip`, Format pane)

The card header toggle is `tooltip.show`.

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `tooltip.show` | Show | Afficher | toggle | bool | `true` | true / false | Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips). |

### Title / Titre (`title`, Format pane)

The card header toggle is `title.show`.

**Title / Titre**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `title.show` | Show | Afficher | toggle | bool | `true` | true / false |  |
| `title.text` | Text | Texte | text | text | (empty) |  | Leave empty for an automatic title built from the fields. |
| `title.fontSize` | Size | Taille | number | formatting | `14` | 7 to 40 |  |
| `title.bold` | Bold | Gras | toggle | bool | `true` | true / false |  |
| `title.italic` | Italic | Italique | toggle | bool | `false` | true / false |  |
| `title.underline` | Underline | Souligné | toggle | bool | `false` | true / false |  |
| `title.color` | Color (empty = text) | Couleur (vide = texte) | color | fill | (empty) | hex color |  |
| `title.bgColor` | Background color | Couleur d'arrière-plan | color | fill | (empty) | hex color |  |
| `title.align` | Horizontal alignment | Alignement horizontal | dropdown | enumeration | `left` | `left` Left; `center` Center; `right` Right |  |
| `title.wrap` | Text wrap | Retour automatique à la ligne | toggle | bool | `true` | true / false |  |

**Subtitle / Sous-titre**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `title.subtitle` | Subtitle | Sous-titre | text | text | (empty) |  | Several lines allowed: type \n to go to the next line. |
| `title.subFontSize` | Size | Taille | number | formatting | `11` | 7 to 30 | Visible when `title.subtitle` =  |
| `title.subColor` | Color (empty = secondary text) | Couleur (vide = texte secondaire) | color | fill | (empty) | hex color | Visible when `title.subtitle` =  |
| `title.subItalic` | Italic | Italique | toggle | bool | `false` | true / false | Visible when `title.subtitle` =  |

**Divider / Séparateur**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `title.divider` | Show divider | Afficher le séparateur | toggle | bool | `false` | true / false |  |
| `title.dividerColor` | Color (empty = lines) | Couleur (vide = traits) | color | fill | (empty) | hex color | Visible when `title.divider` = `true` |
| `title.dividerStyle` | Line style | Style de trait | dropdown | enumeration | `solid` | `solid` Solid; `dashed` Dashed; `dotted` Dotted | Visible when `title.divider` = `true` |
| `title.dividerWidth` | Width | Épaisseur | number | integer | `1` | 1 to 6 | Visible when `title.divider` = `true` |

**Spacing / Espacement**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `title.spaceBelow` | Space below the title (px) | Espace sous le titre (px) | number | integer | `4` | 0 to 40 |  |

### Source note / Note de source (`source`, Format pane)

The card header toggle is `source.show`.

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `source.show` | Show | Afficher | toggle | bool | `false` | true / false |  |
| `source.text` | Text | Texte | text | text | (empty) |  |  |
| `source.fontSize` | Size | Taille | number | formatting | `9` | 6 to 20 |  |
| `source.italic` | Italic | Italique | toggle | bool | `false` | true / false |  |
| `source.color` | Color (empty = secondary text) | Couleur (vide = texte secondaire) | color | fill | (empty) | hex color |  |
| `source.align` | Alignment | Alignement | dropdown | enumeration | `left` | `left` Left; `center` Center; `right` Right |  |

### Frame / Cadre (`container`, Format pane)

**Background / Arrière-plan**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `container.bgShow` | Background | Arrière-plan | toggle | bool | `false` | true / false |  |
| `container.bgColor` | Color | Couleur | color | fill | `#FFFFFF` | hex color | Visible when `container.bgShow` = `true` |
| `container.bgColor2` | Gradient end (optional) | Fin du dégradé (optionnel) | color | fill | (empty) | hex color | Visible when `container.bgShow` = `true` |
| `container.bgTransparency` | Transparency (%) | Transparence (%) | slider | numeric | `0` | 0 to 100 | Visible when `container.bgShow` = `true` |

**Border / Bordure**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `container.border` | Border | Bordure | toggle | bool | `false` | true / false |  |
| `container.borderColor` | Color (empty = lines) | Couleur (vide = traits) | color | fill | (empty) | hex color | Visible when `container.border` = `true` |
| `container.borderWidth` | Width | Épaisseur | number | integer | `1` | 0 to 6 | Visible when `container.border` = `true` |
| `container.radius` | Rounded corners | Coins arrondis | number | integer | `8` | 0 to 24 |  |

**Shadow / Ombre**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `container.shadow` | Shadow | Ombre | toggle | bool | `false` | true / false |  |
| `container.shadowColor` | Color (empty = soft) | Couleur (vide = douce) | color | fill | (empty) | hex color | Visible when `container.shadow` = `true` |
| `container.shadowSize` | Blur (px) | Flou (px) | number | integer | `12` | 0 to 40 | Visible when `container.shadow` = `true` |

**Spacing / Marges**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `container.padding` | Inner padding | Marge intérieure | number | integer | `8` | 0 to 40 |  |

### Language and numbers / Langue et nombres (`texts`, Format pane)

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `texts.language` | Interface language | Langue de l'interface | dropdown | enumeration | `auto` | `auto` Same as Power BI; `fr` French; `en` English |  |
| `texts.numberLocale` | Number format locale (e.g. en-GB) | Format des nombres (ex. fr-FR) | text | text | (empty) |  | Thousands and decimal separators. Empty: same as Power BI. |