# Plume Visuals: all Power BI custom visuals, compiled for AI assistants

> You are helping someone use the Power BI custom visuals sold by Plume Studio (Plume Visuals, https://plumevisuals.com). This text is generated from the visuals' source code at each site build: field names, option IDs, defaults and allowed values are exact. Answer in the user's language; Power BI shows English or French labels depending on its language (both are given).

## How the catalog works (common to every visual)

- Install: download the `.pbiviz` file from the buyer's account (Downloads), then in Power BI Desktop: Visualizations pane › **…** › **Import a visual from a file**. Sample `.pbix` reports are available for every visual.
- Free version without watermark and without time limit. Premium features (marked ★) also work without a key but show a discreet « Premium preview » watermark until a one-year license key (`PLUM1.…`) is pasted in **Format › Plume Studio License › License key** (`license.key`, the first card of the Format pane). Keys are checked offline; no network request is ever made.
- Shared **Style** card (`style.preset`): the same 20 styles exist in every visual: None, Minimal and Black & White are free; Newspaper, Vintage (antique plate), Earth, Nordic, Executive, Accessible (high legibility), Pastel, Bauhaus (pop), Climate, Blueprint, Unknown Pleasures, Graphite (dark), Neon, Terminal (Matrix), Infographic, Cockpit (HUD) and Hologram are ★. Free custom colors (`style.customColors`, « Customize colors », and the colors under it) and a theme JSON ★ (`style.themeJson`) complete them, so a whole report stays consistent.
- **Dynamic format** field (`format`): any Format pane option can be driven by a DAX measure renamed `card.setting` (for example a measure named `title.text`). The fx button works on colors and texts too.
- PBIP: in `visual.json`, `visualType` is the visual's GUID (given below) and each option is written under `objects.<card>[0].properties.<option>` with the literal type given.
- Visuals in this file (35): Ridgeline Plume, Bar Slicer Plume, Range Plume, Period Plume, Filter Bar Plume, Basic Slicer Plume, Date Picker Plume, Text Plume, Table Plume, Matrix Plume, Bar Plume, Line Plume, Scatter Plume, KPI Plume, Sankey Plume, Waterfall Plume, Gantt Plume, Candle Plume, Chord Plume, Sunburst Plume, Stream Plume, Bump Plume, Dumbbell Plume, Image Plume, Shape Gauge Plume, Word Cloud Plume, Pie Plume, Treemap Plume, Pyramid Plume, Gauge Plume, Waffle Plume, Beeswarm Plume, Hexbin Plume, Heatmap Plume, Radar Plume.
- Detailed reference of one visual (full tables, help texts): https://plumevisuals.com/ai/visuals/<slug>.md · everything incl. tutorials: https://plumevisuals.com/llms-full.txt

---

# Ridgeline Plume

- Overlapping ridges that tell decades of data at a glance, with time animation.
- Slug `ridgeline-pulse` · version 1.8.0.0 · GUID (`visualType`) `ridgelinePulseCF957CB0A5DC40138058B1F71340838F` · page https://plumevisuals.com/en/visuals/ridgeline-pulse

### What the visual does

Ridgeline Plume is a Power BI custom visual that draws a ridgeline chart (also called joy plot): one filled curve per category ("ridge"), stacked vertically with overlap. Typical use: one ridge per year, X = day of year, Height = a daily measure (temperature, sales, response time…). Alternative display modes: minimal sparkline, comparison overlay ★, heatmap / warming stripes ★, perspective ★. Premium features also include time animation, focus mode (a ridge unfolds into a detailed chart), reference curve and anomalies, cursor, annotations.

**New in version 1.8.0.0 (30/10/2026):** Format pane reorganized to the shared v2 order; free native-parity additions: Tooltips switch, gridlines, Y-axis range (fixed or measures, scale kept under filters), data labels on the curves, X-axis unit; premium 2D comparison of all ridges (spaghetti mode ★); playback can start from the final state.

### Free vs premium (★)

- Every feature works without a key. 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 (`style.customColors` and the colors under it) are **free**; every other `style.preset`, the other gradient palettes (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium** (watermark without a key). See "Styles and theme JSON" below.
- A ★ in a label marks a premium feature. Choosing a ★ option, or filling a ★ field, shows a "Premium preview" watermark until a license key is pasted in **Format › Plume Studio License › License key** (first card of the Format pane) (`license.key`).
- The ▶ play button (`animation.enabled`) and focus mode (`focus.enabled`) are ON by default as a showcase: the watermark only appears while they are being used, then disappears.
- Accepted keys: only the key starting with `PLUM1.` shown in the buyer's account on plumevisuals.com (since version 1.4.1.0; short 10-character keys are no longer accepted).

### Expected data shape

The visual reads a **long table: one row per (Ridge, X) pair**.

| Ridge (`ridge`) | X axis (`x`) | Height (`height`) |
|---|---|---|
| 2003 | 1 | 4.2 |
| 2003 | 2 | 4.5 |
| … | … | … |
| 2004 | 1 | 3.9 |

- **Ridge** (column, optional): one ridge per distinct value. Without a Ridge field the visual draws a single ridge named after the Height measure. Numeric names (years) are sorted numerically; text names keep Power BI's sort order (use "Sort by column" in the model).
- **X axis** (column, required). The column's data type decides the axis:
  - number / whole number → numeric axis (e.g. day of year 1–366, hour 0–23, week 1–53);
  - **date / datetime → converted to day of year**: every ridge runs from January 1st to December 31st. Putting a full `Date` column in X and `Year` in Ridge works directly;
  - text → ordinal axis in Power BI's sort order of that column (for month names, set "Sort by column" on the month number).
- **Height** (measure, required): evaluated by Power BI for each (Ridge, X) row.
- If a ridge receives several rows for the same X (for example a Date in X but no Year in Ridge, so several years fold onto the same day), the values are **averaged** and a warning is shown in edit mode. Fix: put the year (or the right grain) in Ridge.
- Each well accepts one field, except **Tooltips** (several measures).
- Volume: 30,000 rows per data window, more rows are fetched automatically (`fetchMoreData`). Example: 70 years × 366 days ≈ 25,600 rows.

#### How each optional measure is read

| Field | Evaluated per | Notes |
|---|---|---|
| Color (`color`) | (Ridge, X) | Default coloring is a gradient along the curve (`colors.colorMode` = `alongCurve`). `byRidge` uses the mean of Color per ridge. |
| Tooltips (`tooltips`) | (Ridge, X) | Added to the standard Power BI tooltip; report-page tooltips are supported. |
| Order (`sortBy`) | (Ridge, X), then **averaged per ridge** (blank rows ignored) | Used when `ridges.order` = `sortAsc` / `sortDesc`, or `ridges.topNFrom` = `top`. |
| Ridge label (`label`) | first non-empty value per ridge | Text shown instead of the ridge name (e.g. "2003 — heatwave"). |
| Reference ★ (`reference`) | (Ridge, X) | Dashed curve on each ridge; `analytics.anomaly` colors the gap above / below it. |
| Band low / high ★ (`bandLow`, `bandHigh`) | (Ridge, X) | Shaded envelope (min–max, P10–P90, confidence interval). |
| Cursor: current ridge ★ (`cursor`) | **single value** (first non-blank) | Matched against the ridge name (raw value, number) or the ridge label. |
| Cursor: X position ★ (`cursorX`) | **single value** | Vertical line at this X (same type as the X field: a date is converted to day of year). |
| Annotation text ★ (`annotation`) | (Ridge, X) | Return BLANK() everywhere except where a text must appear. |

### DAX recipes

```dax
// Calculated columns on a daily table 'Meteo'
Year = YEAR ( Meteo[Date] )
DayOfYear = DATEDIFF ( DATE ( YEAR ( Meteo[Date] ), 1, 1 ), Meteo[Date], DAY ) + 1

// 7-day moving average for Height (keeps the year filter set by the ridge)
Temp smoothed 7d =
VAR d = SELECTEDVALUE ( Meteo[DayOfYear] )
RETURN
    CALCULATE (
        AVERAGE ( Meteo[TempMax] ),
        FILTER ( ALL ( Meteo[DayOfYear] ), Meteo[DayOfYear] >= d - 3 && Meteo[DayOfYear] <= d + 3 )
    )

// Reference (normal) and anomaly
Normal 1961-1990 = CALCULATE ( [Temp smoothed 7d], Meteo[Year] >= 1961, Meteo[Year] <= 1990 )
Anomaly = [Temp smoothed 7d] - [Normal 1961-1990]

// Annotation: text only where an event is recorded
Event = VAR e = MAX ( Meteo[Event] ) RETURN IF ( e = "", BLANK (), e )

// Cursor driven by a disconnected slicer table
// New table: CursorYear = SELECTCOLUMNS ( GENERATESERIES ( 1959, 2026, 1 ), "Year", [Value] )
Selected year = SELECTEDVALUE ( CursorYear[Year] )
```

The visual also has a built-in moving average ★ (`ridges.smoothing`, in points) if you prefer not to write DAX.

### Interactions with the report

- **Click on a ridge** applies a slicer-like basic filter (`In`) on the Ridge field to the other visuals (`interaction.crossFilter`, on by default). Ctrl+click adds ridges. Click in empty space clears. The filter can be synced across pages ("Sync slicers").
- **Incoming highlight**: when another visual highlights some ridges, `interaction.highlightMode` decides: `dim` the others (default), `hide` them, show a `cursor` only, or open focus automatically (`autoFocus`).
- **"Where am I" cursor ★ when the page is filtered**: a slicer that *filters* the visual removes the other years. Two solutions: (1) select the slicer, Format › Edit interactions, set Ridgeline Plume to **Highlight** instead of Filter; the visual keeps all ridges and marks the highlighted one with `interaction.cursorStyle`; or (2) feed the `cursor` / `cursorX` fields with a measure on a disconnected table (see DAX above).
- Standard Power BI behaviors are supported: tooltips and report-page tooltips, context menu, drill-through, keyboard navigation (Tab between ridges, Enter to select, Esc), screen readers, high contrast, bookmarks (focus and mode chosen in the visual are persisted).

### Format pane: how to read the tables below

- Each option has an ID `card.option` (for example `ridges.overlap`). The card is the capabilities.json **object name**, the option is the **property name**.
- Labels are shown in English and French: the Format pane follows the language of Power BI Desktop (File › Options › Regional settings › Application language). Data field names follow the same rule.
- "Visible when" means the option only appears in the Format pane when another option of the same card has one of the listed values.
- The `Reference & analytics ★` card lives in the **Analytics pane** (magnifying glass icon), not in the Format pane.
- The `state` card is internal (persists focus / mode chosen in the visual) and never appears in the Format pane: do not set it by hand.

### Editing a PBIP report (visual.json)

In a PBIP project, the visual's `visual.json` uses the visual GUID as `visualType`, the data role names as `queryState` keys, and the option IDs as `objects`. Literal syntax: booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes, colors wrapped in `solid.color`.

```json
{
  "visualType": "ridgelinePulseCF957CB0A5DC40138058B1F71340838F",
  "query": {
    "queryState": {
      "ridge":  { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Meteo" } }, "Property": "Year" } }, "queryRef": "Meteo.Year" } ] },
      "x":      { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Meteo" } }, "Property": "DayOfYear" } }, "queryRef": "Meteo.DayOfYear" } ] },
      "height": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Meteo" } }, "Property": "Temp smoothed 7d" } }, "queryRef": "Meteo.Temp smoothed 7d" } ] }
    }
  },
  "objects": {
    "ridges":  [ { "properties": { "overlap": { "expr": { "Literal": { "Value": "250D" } } },
                                    "normalization": { "expr": { "Literal": { "Value": "'global'" } } } } } ],
    "style":   [ { "properties": { "palette": { "expr": { "Literal": { "Value": "'warmingStripes'" } } } } } ],
    "colors":  [ { "properties": { "singleColor": { "solid": { "color": { "expr": { "Literal": { "Value": "'#1d3557'" } } } } } } } ],
    "license": [ { "properties": { "key": { "expr": { "Literal": { "Value": "'PLUM1.…'" } } } } } ]
  }
}
```

The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from AppSource or from the `.pbiviz` file).

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`.
- `style.themeJson` (Format › Style › Theme JSON ★) takes a JSON theme as plain text. Format v2: an object with an optional `extends` (a style ID above) and optional groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`; the v1 flat format (`style`, `palette`, `accent`, `background`…) is still read. Every field is optional. Colors are `#RRGGBB` (`#RGB` and `#RRGGBBAA` accepted, opacity ignored). Unknown fields and values outside the allowed lists are ignored, out-of-range numbers are clamped. Invalid JSON shows "Invalid theme JSON: ignored" in edit mode and the visual keeps its look.
- Full field list with allowed values, examples and troubleshooting: tutorial https://plumevisuals.com/ai/tutorials/en/themes-json.md (French: https://plumevisuals.com/ai/tutorials/fr/themes-json.md). The same JSON can be pasted in every Plume visual of a page.
- Priority (the last one wins): visual defaults → `style.preset` → `style.themeJson` → `style.palette` (if not "Style or theme palette") → `style.followTheme` → custom colors → options set by hand in the other cards → DAX formats (fx button, "Dynamic format" field) → Windows high contrast.

### Common pitfalls

- Empty visual or "Add a measure in Height" / "Add a field in X axis": a required field is missing, or the measure is blank for the current filters.
- Ridges look flat or identical: check `ridges.normalization` (`global` keeps ridges comparable, `perRidge` stretches each ridge to its own range).
- "Several values per X on a ridge: averaged": the Ridge field is missing or too coarse (see "Expected data shape").
- Too many ridges to read: raise `ridges.overlap`, use `labels.everyN` to thin labels, `ridges.topN` ★ to keep N ridges, or `display.scrollable` ★ to scroll.
- Month names in X appear in alphabetical order: set "Sort by column" on the month number in the model.
- Watermark visible: a ★ option is selected or a ★ field is filled without a valid key. Free features never show it.
- The visual makes no network request: data and license key stay in the report.

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

Horizon chart, spiral, small multiples, morphing animation, lasso selection, X-range brush, magnifier, density (KDE) from raw values, ridge groups, image per ridge, image / GIF export. Some of them appeared in early marketing material but were removed before version 1.4.

## Ridgeline Plume: data fields

- `ridge` Ridge (one per value) / Crête (une par valeur) (column, 1 max): Year, station, product…
- `x` X axis / Axe X (column, 1 max): Day of year, month, date or number
- `height` Height / Hauteur (measure, 1 max): Ridge amplitude
- `color` Color / Couleur (measure, 1 max): Colors the ridge (e.g. max temperature)
- `tooltips` Tooltips / Infobulles (measure, several max): Extra values in the tooltip
- `sortBy` Order / Ordre (measure, 1 max): Sort ridges by this value
- `label` Ridge label / Étiquette de crête (measure, 1 max): Text shown instead of the ridge name
- `reference` Reference ★ / Référence ★ ★ (measure, 1 max): Normal, target, previous year…
- `bandLow` Band low ★ / Bande basse ★ ★ (measure, 1 max): Lower bound of the envelope
- `bandHigh` Band high ★ / Bande haute ★ ★ (measure, 1 max): Upper bound of the envelope
- `cursor` Cursor: current ridge ★ / Curseur : crête courante ★ ★ (measure, 1 max): e.g. SELECTEDVALUE of a disconnected table
- `cursorX` Cursor: X position ★ / Curseur : position X ★ ★ (measure, 1 max): Vertical line at this X
- `annotation` Annotation text ★ / Texte d'annotation ★ ★ (measure, 1 max): Text shown at this ridge and X
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Ridgeline Plume: Format pane options (232)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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) ★; `custom` Custom ★. Visible when `style.customColors` = `true`. Gradient from the catalog (Viridis, Magma…). The start, middle and end colors below replace it.
- `style.custom1` Color 1 / Couleur 1: color, default `#264653`; values: hex color. Visible when `style.palette` = `custom`
- `style.custom2` Color 2 / Couleur 2: color, default `#2a9d8f`; values: hex color. Visible when `style.palette` = `custom`
- `style.custom3` Color 3 / Couleur 3: color, default `#e9c46a`; values: hex color. Visible when `style.palette` = `custom`
- `style.custom4` Color 4 / Couleur 4: color, default `#f4a261`; values: hex color. Visible when `style.palette` = `custom`
- `style.custom5` Color 5 / Couleur 5: color, default `#e76f51`; values: hex color. Visible when `style.palette` = `custom`
- `style.scaleLow` Gradient: start / Dégradé : début: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: dropdown, default `Segoe UI`; values: `Segoe UI` Segoe UI; `Segoe UI Semibold` Segoe UI Semibold; `Arial` Arial; `Georgia` Georgia; `Verdana` Verdana; `Tahoma` Tahoma; `Trebuchet MS` Trebuchet MS; `Courier New` Courier New; `DIN` DIN; `Segoe UI Light` Segoe UI Light; `Bahnschrift` Bahnschrift; `Consolas` Consolas; `Times New Roman` Times New Roman. Used by every text of the visual (title, axes, labels, playback bar).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.
- `style.transitionMs` Filter change transition (ms) / Transition au changement de filtre (ms): num, default `400`; values: 0 to 5000. 400 = free default; other values ★

### Layout / Disposition (`layout`)
- `layout.mode` Display mode / Mode d'affichage: dropdown, default `ridgeline`; values: `ridgeline` Ridgeline; `minimal` Minimal / sparkline; `comparison` Comparison (overlay) ★; `heatmap` Heatmap / stripes ★; `perspective` Perspective ★
- `layout.modeSwitcher` Mode buttons in visual ★ / Boutons de mode dans le visuel ★ ★: toggle, default `false`; values: true / false
- `layout.orientation` Orientation: dropdown, default `horizontal`; values: `horizontal` Horizontal; `vertical` Vertical ★
- `layout.perspectiveTilt` Perspective tilt / Inclinaison perspective: slider, default `35`; values: 0 to 80. Visible when `layout.mode` = `perspective`
- `layout.marginTop` Top / Haut: num, default `8`; values: 0 to 200
- `layout.marginRight` Right / Droite: num, default `12`; values: 0 to 200
- `layout.marginBottom` Bottom / Bas: num, default `6`; values: 0 to 200
- `layout.marginLeft` Left / Gauche: num, default `6`; values: 0 to 200
- `layout.scrollable` Scroll when crowded ★ / Défilement si trop de crêtes ★ ★: toggle, default `false`; values: true / false
- `layout.minRidgeHeight` Min. ridge spacing (px) / Espacement mini (px): num, default `14`; values: 4 to 200. Visible when `layout.scrollable` = `true`
- `layout.autoHide` Adapt to small sizes / S'adapter aux petites tailles: toggle, default `true`; values: true / false

### Data colors / Couleurs des données (`dataColors`)
- `dataColors.colorMode` Color by / Colorer selon: dropdown, default `alongCurve`; values: `alongCurve` Gradient along the curve (each X value); `byRidge` One color per ridge (mean of Color); `perRidge` Color chosen per ridge; `single` Single color
- `dataColors.colorTarget` Apply color to / Appliquer la couleur à: dropdown, default `area`; values: `area` Area under the curve; `line` Crest line only
- `dataColors.singleColor` Color / Couleur: color, default `#1d3557`; values: hex color. Visible when `dataColors.colorMode` = `single`
- `dataColors.fillOpacity` Fill opacity (%) / Opacité du remplissage (%): slider, default `90`; values: 0 to 100. Visible when `dataColors.colorTarget` = `area`
- `dataColors.fillStyle` Fill style / Style de remplissage: dropdown, default `solid`; values: `solid` Solid; `fade` Fade to baseline ★; `hatch` Hatched ★. Visible when `dataColors.colorTarget` = `area`
- `dataColors.strokeColor` Outline color / Couleur du contour: color, default `#ffffff`; values: hex color. Visible when `dataColors.colorTarget` = `area`
- `dataColors.strokeWidth` Outline width / Épaisseur du contour: num, default `1`; values: 0 to 10. Visible when `dataColors.colorTarget` = `area`
- `dataColors.strokeTopOnly` Outline on top edge only / Contour sur le haut seulement: toggle, default `true`; values: true / false. Visible when `dataColors.colorTarget` = `area`
- `dataColors.lineWidth` Crest line width / Épaisseur de la ligne de crête: num, default `2`; values: 0.5 to 10. Visible when `dataColors.colorTarget` = `line`
- `dataColors.hideBehind` Hide ridges behind (opaque) / Masquer les crêtes de derrière (opaque): toggle, default `true`; values: true / false. Visible when `dataColors.colorTarget` = `line`
- `dataColors.underColor` Color under the line / Couleur sous la ligne: color, default `#ffffff`; values: hex color. Visible when `dataColors.colorTarget` = `line`. Use your report background color
- `dataColors.shadow` Shadow / Ombre: dropdown, default `none`; values: `none` None; `drop` Drop shadow ★; `glow` Glow ★

### Ridges / Crêtes (`ridges`)
- `ridges.overlap` Overlap (%) / Chevauchement (%): slider, default `120`; values: 0 to 600
- `ridges.fixedHeight` Ridge spacing px (0 = auto) / Espacement px (0 = auto): num, default `0`; values: 0 to 400
- `ridges.curve` Curve / Courbe: dropdown, default `monotone`; values: `linear` Linear; `monotone` Smooth; `basis` B-spline ★; `step` Step ★
- `ridges.smoothing` Moving average (points) ★ / Moyenne mobile (points) ★ ★: num, default `0`; values: 0 to 60
- `ridges.normalization` Height scale / Échelle des hauteurs: dropdown, default `global`; values: `global` Shared by all ridges; `perRidge` Per ridge; `percentile` Clip at percentile ★; `log` Logarithmic ★
- `ridges.percentile` Percentile: num, default `98`; values: 50 to 100. Visible when `ridges.normalization` = `percentile`
- `ridges.baseline` Baseline / Ligne de base: dropdown, default `zero`; values: `zero` Zero; `min` Minimum ★; `center` Centered (stream) ★
- `ridges.negatives` Negative values / Valeurs négatives: dropdown, default `down`; values: `down` Below baseline; `color` Other color ★; `hide` Hide ★
- `ridges.negativeColor` Negative color / Couleur des négatifs: color, default `#2166ac`; values: hex color. Visible when `ridges.negatives` = `color`

### Data labels / Étiquettes de données (`labels`)
- `labels.showValue` Value next to label ★ / Valeur à côté ★ ★: dropdown, default `none`; values: `none` None; `max` Maximum ★; `mean` Mean ★; `last` Last ★; `sum` Sum ★; `color` Mean of Color ★
- `labels.showRank` Show rank ★ / Afficher le rang ★ ★: toggle, default `false`; values: true / false
- `labels.peakShow` Label on each ridge / Étiquette sur chaque crête: dropdown, default `none`; values: `none` None; `max` At the peak (maximum); `last` At the end of the curve. Like the data labels of the native area chart: one value per ridge, overlapping labels are dropped.
- `labels.peakSize` Size / Taille: num, default `9`; values: 6 to 30. Visible when `labels.peakShow` = `max` or `last`
- `labels.peakColor` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color. Visible when `labels.peakShow` = `max` or `last`
- `labels.decimals` Decimals / Décimales: num, default `1`; values: 0 to 6
- `labels.prefix` Prefix / Préfixe: text, default (empty)
- `labels.suffix` Suffix (°C, mm…) / Suffixe (°C, mm…): text, default (empty)

### Category labels / Étiquettes des catégories (`categoryLabels`)
- `categoryLabels.show` Show / Afficher: toggle, default `true`; values: true / false
- `categoryLabels.position` Position: dropdown, default `left`; values: `left` Left; `right` Right; `baseline` On baseline; `end` End of curve
- `categoryLabels.everyN` Show 1 label every N / 1 étiquette sur N: num, default `1`; values: 1 to 100
- `categoryLabels.fontSize` Size / Taille: num, default `10`; values: 6 to 40
- `categoryLabels.bold` Bold / Gras: toggle, default `false`; values: true / false
- `categoryLabels.italic` Italic / Italique: toggle, default `false`; values: true / false
- `categoryLabels.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color

### X axis / Axe X (`xAxis`)
- `xAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `xAxis.format` Format: dropdown, default `auto`; values: `auto` Automatic; `month` Month (January); `monthShort` Month (Jan); `dayMonth` Day + month; `number` Number; `date` Full date
- `xAxis.unit` Unit of numeric values / Unité des valeurs numériques: text, default (empty). Added after each number of a numeric X axis (e.g. 10 km). Not repeated when the label already ends with it.
- `xAxis.ticks` Tick count (0 = auto) / Graduations (0 = auto): num, default `0`; values: 0 to 50
- `xAxis.rotation` Label rotation / Rotation: num, default `0`; values: -90 to 90
- `xAxis.fontSize` Size / Taille: num, default `9`; values: 6 to 30
- `xAxis.color` Color / Couleur: color, default `#6B6862`; values: hex color
- `xAxis.title` Axis title / Titre de l'axe: text, default (empty)

### Y axis / Axe Y (`yAxis`)
- `yAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `yAxis.decimals` Decimals / Décimales: num, default `0`; values: 0 to 6
- `yAxis.suffix` Unit suffix / Suffixe d'unité: text, default (empty)
- `yAxis.min` Start (empty = auto) / Début (vide = auto): text, default (empty). Lower bound of the heights. Drive it with a measure (fx or Dynamic format 'yAxis.min') to keep the scale when the report is filtered.
- `yAxis.max` End (empty = auto) / Fin (vide = auto): text, default (empty). Upper bound of the heights (all modes with a shared scale). E.g. a measure CALCULATE(MAX(...), REMOVEFILTERS()) keeps the scale under a filter.
- `yAxis.title` Axis title / Titre de l'axe: text, default (empty)

### Gridlines / Quadrillage (`gridlines`)
- `gridlines.vertical` Vertical gridlines / Quadrillage vertical: toggle, default `true`; values: true / false
- `gridlines.verticalColor` Color / Couleur: color, default `#E4E2DD`; values: hex color. Visible when `gridlines.vertical` = `true`
- `gridlines.verticalStyle` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `gridlines.vertical` = `true`
- `gridlines.verticalWidth` Width / Épaisseur: num, default `1`; values: 0.5 to 6. Visible when `gridlines.vertical` = `true`
- `gridlines.horizontal` Horizontal gridlines / Quadrillage horizontal: toggle, default `true`; values: true / false
- `gridlines.horizontalColor` Color / Couleur: color, default `#E4E2DD`; values: hex color. Visible when `gridlines.horizontal` = `true`
- `gridlines.horizontalStyle` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `gridlines.horizontal` = `true`
- `gridlines.horizontalWidth` Width / Épaisseur: num, default `1`; values: 0.5 to 6. Visible when `gridlines.horizontal` = `true`

### Legend / Légende (`legend`)
- `legend.show` Show / Afficher: toggle, default `true`; values: true / false
- `legend.position` Position: dropdown, default `bottom`; values: `bottom` Bottom; `top` Top; `right` Right
- `legend.showTitle` Title / Titre: toggle, default `true`; values: true / false
- `legend.title` Title text (empty = field name) / Texte du titre (vide = nom du champ): text, default (empty). Visible when `legend.showTitle` = `true`
- `legend.fontSize` Size / Taille: num, default `9`; values: 6 to 24
- `legend.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `legend.interactive` Click to filter ridges ★ / Clic pour filtrer les crêtes ★ ★: toggle, default `false`; values: true / false

### Sort / Tri (`sort`)
- `sort.order` Ridge order / Ordre des crêtes: dropdown, default `natural`; values: `natural` Oldest on top; `reverse` Newest on top; `alpha` Alphabetical; `sortAsc` By 'Order' field ↑; `sortDesc` By 'Order' field ↓; `maxDesc` By maximum ↓; `meanDesc` By mean ↓
- `sort.topN` Keep N ridges (0 = all) ★ / Garder N crêtes (0 = toutes) ★ ★: num, default `0`; values: 0 to 500
- `sort.topNFrom` Keep / Garder: dropdown, default `last`; values: `first` First N; `last` Last N; `top` Top N by 'Order'. Visible when `sort.topN` = any non-zero / non-empty value

### Comparison ★ / Comparaison ★ (`comparison`)
- `comparison.highlight` Ridges in color (names) / Crêtes en couleur (noms): text, default (empty). Comparison mode: every ridge is drawn on the same axes; the ridges listed here (and those selected with Ctrl+click) are in color.
- `comparison.highlightLast` Last ridge in color / Dernière crête en couleur: toggle, default `false`; values: true / false
- `comparison.highlightWidth` Width of the colored ridges / Épaisseur des crêtes en couleur: num, default `2.8`; values: 0.5 to 10
- `comparison.othersGray` In gray (spaghetti) / En gris (spaghetti): toggle, default `false`; values: true / false. Off: each ridge keeps its color.
- `comparison.othersColor` Color (empty = soft gray) / Couleur (vide = gris doux): color, default (empty); values: hex color. Visible when `comparison.othersGray` = `true`
- `comparison.othersOpacity` Opacity (%) / Opacité (%): slider, default `50`; values: 5 to 100
- `comparison.othersWidth` Width / Épaisseur: num, default `1.5`; values: 0.3 to 6
- `comparison.reference` Reference curve / Courbe de référence: dropdown, default `none`; values: `none` None; `field` Reference field; `mean` Mean of all ridges; `median` Median of all ridges; `first` First ridge
- `comparison.referenceColor` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color. Visible when `comparison.reference` = `field` or `mean` or `median` or `first`
- `comparison.gapFill` Color the gap to the reference / Colorer l'écart à la référence: toggle, default `false`; values: true / false. Visible when `comparison.reference` = `field` or `mean` or `median` or `first`. Areas between each colored ridge and the reference, above / below colors of the Analytics pane.

### Focus mode ★ / Mode focus ★ (`focus`)
- `focus.enabled` Enable / Activer: toggle, default `true`; values: true / false
- `focus.trigger` Open focus with / Ouvrir le focus par: dropdown, default `dblclick`; values: `click` Click; `dblclick` Double-click; `button` Button on hover
- `focus.duration` Animation duration (ms) / Durée de l'animation (ms): num, default `700`; values: 0 to 5000
- `focus.transition` Transition: dropdown, default `zoom`; values: `fade` Fade; `slide` Slide; `zoom` Zoom
- `focus.ghosts` Keep other ridges as ghosts / Garder les autres en fantôme: toggle, default `false`; values: true / false
- `focus.ghostOpacity` Ghost opacity (%) / Opacité des fantômes (%): slider, default `12`; values: 2 to 60. Visible when `focus.ghosts` = `true`
- `focus.filterReport` Focus also filters the report / Le focus filtre aussi le rapport: toggle, default `true`; values: true / false
- `focus.backText` Text / Texte: text, default (empty). Empty = '← Back'
- `focus.backPosition` Position: dropdown, default `topRight`; values: `topLeft` Top left; `topRight` Top right; `bottomLeft` Bottom left; `bottomRight` Bottom right
- `focus.backStyle` Style: dropdown, default `pill`; values: `pill` Pill button; `text` Text link; `icon` Icon only
- `focus.backColor` Color / Couleur: color, default `#1d3557`; values: hex color
- `focus.prevNext` ◀ ▶ previous / next / ◀ ▶ précédente / suivante: toggle, default `true`; values: true / false
- `focus.breadcrumb` Breadcrumb / Fil d'Ariane: toggle, default `true`; values: true / false
- `focus.breadcrumbRoot` Breadcrumb root text / Texte racine du fil: text, default (empty). Empty = 'All'

### Annotations ★ (`annotations`)
- `annotations.show` Show / Afficher: toggle, default `true`; values: true / false
- `annotations.style` Style: dropdown, default `line`; values: `line` Callout line; `bubble` Bubble; `dot` Dot + text
- `annotations.color` Color / Couleur: color, default `#1F1E1C`; values: hex color
- `annotations.fontSize` Size / Taille: num, default `9`; values: 6 to 24

### Playback ★ / Lecture ★ (`play`)
- `play.enabled` Show ▶ play button / Afficher le bouton ▶: toggle, default `true`; values: true / false
- `play.playMode` Animation: dropdown, default `draw`; values: `draw` Each ridge is drawn; `reveal` Ridges appear one by one
- `play.startFrom` Playback starts from / La lecture part de: dropdown, default `empty`; values: `empty` An empty chart; `final` The final state (all ridges, redrawn one by one). Final state: the chart stays complete and each ridge is redrawn in turn, so readers never see an empty visual.
- `play.speed` Time per ridge (ms) / Durée par crête (ms): num, default `600`; values: 30 to 10000
- `play.accelerate` Accelerate progressively / Accélérer progressivement: toggle, default `false`; values: true / false
- `play.loop` Repeat / Répétition: dropdown, default `once`; values: `once` Once; `loop` Loop; `bounce` Back and forth
- `play.autoplay` Autoplay on load / Lecture automatique: toggle, default `false`; values: true / false
- `play.filterReport` Current ridge filters the report / La crête courante filtre le rapport: toggle, default `false`; values: true / false
- `play.respectReducedMotion` Respect 'reduce motion' / Respecter « réduire les animations »: toggle, default `true`; values: true / false
- `play.counterShow` Big counter in background / Grand compteur en fond: toggle, default `false`; values: true / false
- `play.counterSize` Size (% of height) / Taille (% de la hauteur): slider, default `28`; values: 5 to 80
- `play.counterOpacity` Opacity (%) / Opacité (%): slider, default `14`; values: 2 to 100
- `play.counterPosition` Position: dropdown, default `center`; values: `center` Center; `topRight` Top right; `bottomRight` Bottom right
- `play.progressShow` Progress bar (draggable) / Barre de progression (déplaçable): toggle, default `true`; values: true / false
- `play.trail` Keep past ridges in gray / Garder les crêtes passées en gris: toggle, default `true`; values: true / false
- `play.pauseOnAnnotations` Pause on annotated ridges / Pause sur les crêtes annotées: toggle, default `false`; values: true / false
- `play.pauseMs` Pause duration (ms) / Durée de pause (ms): num, default `1500`; values: 0 to 20000. Visible when `play.pauseOnAnnotations` = `true`

### Interactions (`interaction`)
- `interaction.crossFilter` Click filters other visuals / Le clic filtre les autres visuels: toggle, default `true`; values: true / false. Persistent slicer-like filter on the Ridge field. Ctrl+click = several ridges.
- `interaction.hoverEmphasis` Emphasize hovered ridge / Mettre en avant la crête survolée: toggle, default `true`; values: true / false
- `interaction.crosshair` Crosshair across ridges ★ / Réticule sur toutes les crêtes ★ ★: toggle, default `false`; values: true / false
- `interaction.highlightMode` Highlighted ridges / Crêtes en surbrillance: dropdown, default `dim`; values: `dim` Dim the others; `hide` Hide the others ★; `cursor` Cursor only ★; `autoFocus` Open focus automatically ★
- `interaction.cursorStyle` Cursor style ★ / Style du curseur ★ ★: dropdown, default `halo`; values: `halo` Halo on ridge; `arrow` Arrow on label; `line` Vertical line (X cursor); `grayOthers` Color it, gray the others
- `interaction.cursorLabel` Cursor label / Libellé du curseur: text, default (empty). Empty = 'You are here'
- `interaction.cursorColor` Cursor color / Couleur du curseur: color, default `#e63946`; values: hex color
- `interaction.keyboard` Keyboard navigation / Navigation au clavier: toggle, default `true`; values: true / false

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `false`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields. Variables ★: {first} {last} {count} {min} {max} {focus} {playing}
- `title.fontSize` Size / Taille: num, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: num, default `11`; values: 7 to 30. Visible when `title.subtitle` = any non-zero / non-empty value
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = any non-zero / non-empty value
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = any non-zero / non-empty value
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: num, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): num, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: num, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: num, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: num, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): num, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: num, default `0`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

### Reference & analytics ★ / Référence et analytique ★ (`analytics`, Analytics pane)
- `analytics.refShow` Show reference (field) / Afficher la référence (champ): toggle, default `true`; values: true / false
- `analytics.refStyle` Line style / Style de ligne: dropdown, default `dashed`; values: `dashed` Dashed; `dotted` Dotted; `solid` Solid
- `analytics.refColor` Color / Couleur: color, default `#333333`; values: hex color
- `analytics.refWidth` Width / Épaisseur: num, default `1`; values: 0.5 to 6
- `analytics.anomaly` Color the gap to reference / Colorer l'écart à la référence: toggle, default `false`; values: true / false
- `analytics.anomalyAbove` Above / Au-dessus: color, default `#d62828`; values: hex color. Visible when `analytics.anomaly` = `true`
- `analytics.anomalyBelow` Below / En dessous: color, default `#1d4e89`; values: hex color. Visible when `analytics.anomaly` = `true`
- `analytics.meanShow` Overlay mean curve / Superposer la courbe moyenne: toggle, default `false`; values: true / false
- `analytics.meanColor` Color / Couleur: color, default `#111111`; values: hex color. Visible when `analytics.meanShow` = `true`
- `analytics.bandShow` Show band / Afficher la bande: toggle, default `true`; values: true / false
- `analytics.bandColor` Color / Couleur: color, default `#8d99ae`; values: hex color
- `analytics.bandOpacity` Opacity (%) / Opacité (%): slider, default `25`; values: 0 to 100
- `analytics.thresholdShow` Show threshold / Afficher un seuil: toggle, default `false`; values: true / false
- `analytics.thresholdValue` Value / Valeur: num, default `0`. Visible when `analytics.thresholdShow` = `true`
- `analytics.thresholdColor` Color / Couleur: color, default `#d62828`; values: hex color. Visible when `analytics.thresholdShow` = `true`
- `analytics.thresholdFill` Color parts above / Colorer les parties au-dessus: toggle, default `true`; values: true / false. Visible when `analytics.thresholdShow` = `true`
- `analytics.markersMaxMin` Max / min of each ridge / Max / min de chaque crête: toggle, default `false`; values: true / false
- `analytics.recordMarker` Absolute record / Record absolu: toggle, default `false`; values: true / false
- `analytics.markerColor` Color / Couleur: color, default `#111111`; values: hex color
- `analytics.extremesN` N extreme ridges (0 = off) / N crêtes extrêmes (0 = désactivé): num, default `0`; values: 0 to 50
- `analytics.extremesBy` Ranked by / Classées selon: dropdown, default `mean`; values: `mean` Mean; `max` Maximum; `color` Mean of Color
- `analytics.trendShow` Sparkline of ridge means in margin / Sparkline des moyennes en marge: toggle, default `false`; values: true / false
- `analytics.trendColor` Color / Couleur: color, default `#e63946`; values: hex color. Visible when `analytics.trendShow` = `true`

---

# Bar Slicer Plume

- The list slicer that shows the weight of each value: measure bars, search, Top N, paste a list.
- Slug `bar-slicer` · version 1.4.0.0 · GUID (`visualType`) `plumeBarSlicer7D3E91A64C2B4F0E9A15C8B2E6F4D701` · page https://plumevisuals.com/en/visuals/bar-slicer

### What the visual does

Bar Slicer Plume is a Power BI custom visual that works as a list slicer which also shows the weight of each value: next to every value, a bar and a figure for a measure (revenue, count…), plus its share of the total. Clicking values filters the rest of the report, like the native slicer. It adds accent-insensitive search, quick actions ("Top N ★", "Invert selection", "Paste a list ★" from Excel), sorting by the measure or by any other measure, a selection summary ("3 selected · 1.0M of 1.8M"; French « 3 sélectionné(s) · 1,0 M sur 1,8 M »), and three layouts: "List", "Tile grid ★" and "Chips ★".

**New in version 1.4.0.0 (30/10/2026):** Shared slicer cards (Preselection, Frame); tooltips use **each measure's own format** by default (`tooltip.format` = `model`), share of total can be hidden, fixed tile height; `items.*` layout settings moved to **Layout**.

### 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 (`style.customColors` and the colors under it) are **free**; every other `style.preset`, the other gradient palettes (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium** (watermark without a key). See "Styles and theme JSON" below.
- Using a premium feature without a valid key shows **"Plume Visuals · Premium preview"** (French: « Plume Visuals · Aperçu premium ») in the footer of the visual, with an "Unlock →" link to the pricing page. It disappears once a key is pasted in **Format › Plume Studio License › License key** (`license.key`; French: « Licence Plume Studio › Clé de licence »), the **first card** of the Format pane.
- Premium features of Bar Slicer Plume:
  - the **"Top N ★"** button (`actions.topN`) and the **"Paste a list ★"** button (`actions.paste`): the buttons are shown by default, the watermark appears once one of them has been **clicked** and stays until the report is reopened;
  - `layout.mode` = `grid` ("Tile grid ★") or `chips` ("Chips ★");
  - a custom summary text in `summary.template` ("Text ★").
- In the Format pane, every premium option and premium list value has " ★" appended to its label and carries the description "Premium feature: usable for free with a « Premium preview » watermark…". The generated tables below star the same options.
- Accepted keys: only keys starting with `PLUM1.` shown in the buyer's account on plumevisuals.com. They are checked offline (Ed25519 signature) and must cover `bar-slicer` 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". `license.showOwner` displays "Licensed to <holder>".
- Licenses last one year (one-time payment, no automatic renewal, key accepted for 30 more days, reminders 30 and 7 days before the end), per segment: 19 € personal, 49 € SME, 149 € enterprise per year, or the full catalog pack. Renewing gives a new key to paste instead of the old one.

### Expected data shape

The visual reads **one row per distinct value of the Field**, with the measures evaluated for that value.

| Field (`category`) | Measure (bars) (`measure`) | Sort by (`sortBy`) |
|---|---|---|
| Lighting | 412 300 | 395 100 |
| Garden | 288 950 | 301 400 |
| … | … | … |

- **Field** (`category`, label "Field" / « Champ », grouping, exactly one column, required): the column to filter. Text, number and boolean columns work; a date column works too, but Period Plume is designed for dates.
- **Measure (bars)** (`measure`, « Mesure (barres) », one measure, optional): bar length, displayed value, share of total, and the ranking used by Top N. Without it the visual is a plain list (no bars, no Top N button). Share of total = value ÷ sum of the positive values of the list.
- **Sort by** (`sortBy`, « Trier par », one measure, optional): used only when `sort.by` = `sortDesc` / `sortAsc`.
- **Tooltips** (`tooltips`, « Infobulles », several measures, optional): added to the standard Power BI tooltip. Report-page tooltips are supported.
- Volume: 30,000 values per data window; more are fetched automatically up to a **fixed limit of 100,000 values**. Beyond that a warning icon is shown ("Only the first n values are loaded"; details: "The visual loads at most 100,000 values. Filter the page or use a less detailed column.") and the extra values are not listed. (There is no "Data" card any more since 1.0.1.0.)
- Values without data under the current filters are only received if **"Show items with no data"** is enabled on the field (right-click the field in the Field well). `layout.empty` then groups them at the bottom, dims them in place, or hides them.

### DAX recipes

```dax
// Measure (bars)
Revenue = SUM ( Sales[Amount] )
Orders = COUNTROWS ( Sales )

// Sort by: rank this year's list by last year's revenue
Revenue LY = CALCULATE ( [Revenue], SAMEPERIODLASTYEAR ( 'Date'[Date] ) )

// Tooltips
Average basket = DIVIDE ( [Revenue], [Orders] )
Margin % = DIVIDE ( SUM ( Sales[Margin] ), [Revenue] )
```

Power BI never filters a slicer by its own selection: the bars always show the measure under the *other* filters of the page.

### Filter sent to the report

A `BasicFilter` with operator `In` on the Field column (table and column taken from the field), for example `{ "target": { "table": "Sales", "column": "Category" }, "operator": "In", "values": ["Lighting", "Garden"] }`. No selection = filter removed.

- **Invert** sends `In` with the complementary values (values without data are left out), never `NotIn`.
- **Top N** sends `In` with the N values that have the highest measure *at the moment of the click*: it is a static selection, not a dynamic Top N.
- **Paste a list** matches the pasted values (one per line, or separated by `;` or `,`) against the list, then replaces or adds to the selection.

### Interactions with the report

- Click = toggle (`selection.mode` = `multi`), Ctrl + click (`multiCtrl`), or one value only (`single`, with `selection.forceOne` to always keep one value; it then selects the first value when nothing is selected). Alt + click = only this value (`selection.altOnly`), Shift + click = range (`selection.shiftRange`).
- Keyboard: ↑ ↓ Home End to move, Space / Enter to toggle, Ctrl + A to select all visible values, Ctrl + F to jump to the search box (no on-screen hint since 1.0.1.0), Esc clears the search. ARIA `listbox` / `option` roles and screen-reader announcements.
- Context menu on each value, Power BI tooltips, high contrast mode, landing page when no field is set, read-only behavior on dashboards.
- **Bookmarks** and **Sync slicers** (View › Sync slicers) work: the visual declares `supportsSynchronizingFilterState` and re-reads the restored filter. Values that are filtered out by other slicers stay selected.
- Other visuals cross-filter Bar Slicer Plume (it does not support highlighting).

### Format pane: how to read the tables below

- Each option has an ID `card.option` (for example `bars.position`). The card is the capabilities.json **object name**, the option is the **property name**.
- Card order: `license` (always first), `style` (Style card shared by every Plume visual: `preset`, `themeJson`, `followTheme`, then `customColors`, the colors, `palette` (Gradient palette), font, size, density, radius, animations), `header`, then the visual's own cards (`selection`, `search`, `actions`, `sort`, `bars`, `values`, `layout`, `summary`), then `container` and `texts`. Format pane in version 1.4.0.0 (30/10/2026), top to bottom: `license`, `style`, `header`, `layout`, `selection`, `bars`, `values`, `sort`, `search`, `actions`, `summary`, `preselect`, `tooltip`, `container`, `texts`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- Labels follow the language of Power BI Desktop (File › Options › Regional settings › Application language); `texts.language` can force French or English inside the visual. Data role labels are translated too.
- "Visible when" means the option only appears when another option has one of the listed values.
- `general.filter` is where Power BI stores the filter applied by the visual: never write it by hand.

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. Literal syntax: booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes, colors wrapped in `solid.color`.

```json
{
  "visualType": "plumeBarSlicer7D3E91A64C2B4F0E9A15C8B2E6F4D701",
  "query": {
    "queryState": {
      "category": { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Category" } }, "queryRef": "Sales.Category", "nativeQueryRef": "Category" } ] },
      "measure":  { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Revenue" } }, "queryRef": "Sales.Revenue", "nativeQueryRef": "Revenue" } ] },
      "tooltips": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Orders" } }, "queryRef": "Sales.Orders", "nativeQueryRef": "Orders" } ] }
    }
  },
  "objects": {
    "selection": [ { "properties": { "mode": { "expr": { "Literal": { "Value": "'single'" } } },
                                      "indicator": { "expr": { "Literal": { "Value": "'radio'" } } } } } ],
    "bars":      [ { "properties": { "position": { "expr": { "Literal": { "Value": "'background'" } } },
                                      "colorOn": { "solid": { "color": { "expr": { "Literal": { "Value": "'#b8462a'" } } } } } } } ],
    "actions":   [ { "properties": { "topNCount": { "expr": { "Literal": { "Value": "10D" } } } } } ],
    "values":    [ { "properties": { "suffix": { "expr": { "Literal": { "Value": "' €'" } } } } } ],
    "license":   [ { "properties": { "key": { "expr": { "Literal": { "Value": "'PLUM1.…'" } } } } } ]
  }
}
```

The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from AppSource or from the `.pbiviz` file).

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`.
- `style.themeJson` (Format › Style › Theme JSON ★) takes a JSON theme as plain text. Format v2: an object with an optional `extends` (a style ID above) and optional groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`; the v1 flat format (`style`, `palette`, `accent`, `background`…) is still read. Every field is optional. Colors are `#RRGGBB` (`#RGB` and `#RRGGBBAA` accepted, opacity ignored). Unknown fields and values outside the allowed lists are ignored, out-of-range numbers are clamped. Invalid JSON shows "Invalid theme JSON: ignored" in edit mode and the visual keeps its look.
- Full field list with allowed values, examples and troubleshooting: tutorial https://plumevisuals.com/ai/tutorials/en/themes-json.md (French: https://plumevisuals.com/ai/tutorials/fr/themes-json.md). The same JSON can be pasted in every Plume visual of a page.
- Priority (the last one wins): visual defaults → `style.preset` → `style.themeJson` → `style.palette` (if not "Style or theme palette") → `style.followTheme` → custom colors → options set by hand in the other cards → DAX formats (fx button, "Dynamic format" field) → Windows high contrast.
- What this slicer uses from a theme JSON: `colors` (`background`, `foreground`, `muted`, `grid`, `accent`, `borderColor`, `glowColor`), `typography` (`fontFamily`, `titleFamily`, `headerCase`, `letterSpacing`), `shape` (`radius`, `border`, `borderWidth`, `borderStyle`, `shadow`) and `effects` (`glow`, `texture`). `fontFamily`, `radius`, `border`, `borderWidth` and `shadow` only apply while the matching Format pane options are left at their default. The `palettes`, `table` and `marks` groups and the other fields (`surface`, `background2`, `stroke`, `accent2`, `positive`, `negative`, `numberFamily`…) are accepted but have no visible effect on it.

### Common pitfalls

- No bars and no Top N button: no measure in Measure (bars), or `bars.show` / `actions.topN` is off.
- Some values disappear when the page is filtered: enable "Show items with no data" on the field, then choose `layout.empty`.
- Month names sorted by the measure: set `sort.by` = `data` (model order) and "Sort by column" on the month number in the model, or `labelAsc` with `sort.natural` for codes like "M2" / "M10".
- The visual selects a value on its own: `selection.forceOne` is on in single mode.
- Warning icon "Only the first n values are loaded" ("The visual loads at most 100,000 values. Filter the page or use a less detailed column."): more than 100,000 distinct values; filter the page or use a coarser column.
- Watermark visible: a ★ layout or summary text is set, or "Top N ★" / "Paste a list ★" was clicked, or a ★ style, palette or theme JSON, without a valid key. Free features never show it.
- The visual makes no network request: data and license key stay in the report.

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

Several fields or a hierarchy in one slicer (use Filter Bar Plume), tree / parent-child levels, dropdown or collapsed mode, images or icons per value, colors driven by a field or a measure (conditional formatting per value), dynamic Top N re-evaluated at each refresh, exclude mode (`NotIn`), filtering on a measure value, numeric range or date range selection (use Range Plume or Period Plume), saved selection lists, export of the list.

## Bar Slicer Plume: data fields

- `category` Field / Champ (column, 1 max): 
- `measure` Measure (bars) / Mesure (barres) (measure, 1 max): 
- `sortBy` Sort by / Trier par (measure, 1 max): 
- `tooltips` Tooltips / Infobulles (measure, several max): 
- `preselect` Preselection / Présélection (measure, 1 max): Optional measure returning the value(s) selected when the report opens, e.g. "Paris;Lyon" or "2026-01-01;2026-03-31"
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Bar Slicer Plume: Format pane options (125)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: true / false. Text, background, accent and data colors come from the Power BI report theme.
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorTrack` Bar track / Fond des barres: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`
- `style.fontSize` Text size / Taille du texte: number, default `12`; values: 8 to 28
- `style.density` Density / Densité: dropdown, default `normal`; values: `compact` Compact; `normal` Normal; `comfortable` Comfortable
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Header / En-tête (`header`)
- `header.show` Show / Afficher: toggle, default `true`; values: true / false
- `header.title` Text / Texte: text, default (empty). Leave empty to use the field name.
- `header.fontSize` Size / Taille: number, default `14`; values: 7 to 36
- `header.bold` Bold / Gras: toggle, default `true`; values: true / false
- `header.italic` Italic / Italique: toggle, default `false`; values: true / false
- `header.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `header.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `header.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `header.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `header.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false. A long title goes on two lines instead of being cut.
- `header.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `header.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `header.divider` = `true`
- `header.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `header.divider` = `true`
- `header.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `header.divider` = `true`
- `header.showCount` Show value / selection count / Afficher le nombre de valeurs / sélection: toggle, default `true`; values: true / false
- `header.showClear` "Clear" button / Bouton « Effacer »: toggle, default `true`; values: true / false
- `header.clearLabel` Clear button label / Libellé du bouton Effacer: text, default (empty). Visible when `header.showClear` = `true`

### Layout / Disposition (`layout`)
- `layout.mode` Style: dropdown, default `list`; values: `list` Vertical list; `grid` Tile grid ★; `chips` Chips (horizontal) ★
- `layout.columns` Columns / Colonnes: number, default `2`; values: 1 to 8. Visible when `layout.mode` = `grid`
- `layout.tileHeight` Fixed tile height (px, 0 = auto) / Hauteur fixe des tuiles (px, 0 = auto): number, default `0`; values: 0 to 300. Visible when `layout.mode` = `grid`. Like "Fixed size" in the button slicer: tiles keep their height, a scroll bar appears when needed.
- `layout.labelWidth` Label width (%) / Largeur des libellés (%): number, default `38`; values: 15 to 70. Visible when `layout.mode` = `list`
- `layout.wrap` Wrap labels / Libellés sur plusieurs lignes: toggle, default `false`; values: true / false
- `layout.alternate` Alternate rows / Lignes alternées: toggle, default `false`; values: true / false. Visible when `layout.mode` = `list`
- `layout.separators` Separators / Séparateurs: toggle, default `false`; values: true / false. Visible when `layout.mode` = `list`
- `layout.selectedBg` Tinted background when selected / Fond coloré si sélectionné: toggle, default `true`; values: true / false
- `layout.blankLabel` Blank label / Libellé des vides: text, default (empty)
- `layout.empty` Values without data / Valeurs sans données: dropdown, default `group`; values: `group` Grouped at the bottom, dimmed; `inline` In place, dimmed; `hide` Hidden. Activate "Show items with no data" on the field to receive them.
- `layout.emptyLabel` Empty group title / Titre du groupe vide: text, default (empty). Visible when `layout.empty` = `group`

### Selection / Sélection (`selection`)
- `selection.mode` Mode: dropdown, default `multi`; values: `multi` Multiple (click = toggle); `multiCtrl` Multiple with Ctrl; `single` Single value
- `selection.indicator` Indicator / Indicateur: dropdown, default `auto`; values: `auto` Automatic; `checkbox` Checkbox; `radio` Radio button; `none` None (highlight)
- `selection.forceOne` Always keep one value selected / Toujours une valeur sélectionnée: toggle, default `false`; values: true / false. Visible when `selection.mode` = `single`
- `selection.altOnly` Alt + click: only this value / Alt + clic : seulement cette valeur: toggle, default `true`; values: true / false
- `selection.shiftRange` Shift + click: select a range / Maj + clic : sélectionner une plage: toggle, default `true`; values: true / false
- `selection.selectAll` "Select all" row / Ligne « Tout sélectionner »: toggle, default `false`; values: true / false. Visible when `selection.mode` = `multi` or `multiCtrl`
- `selection.selectAllLabel` "Select all" label / Libellé « Tout sélectionner »: text, default (empty). Visible when `selection.selectAll` = `true`
- `selection.selectedFirst` Move selection to the top / Remonter la sélection en tête: toggle, default `false`; values: true / false

### Bars / Barres (`bars`)
- `bars.show` Show / Afficher: toggle, default `true`; values: true / false
- `bars.position` Position: dropdown, default `inline`; values: `inline` Between label and value; `below` Below the label; `background` Row background
- `bars.scale` Scale / Échelle: dropdown, default `max`; values: `max` Relative to maximum; `total` Share of total
- `bars.thickness` Thickness / Épaisseur: number, default `8`; values: 2 to 30. Visible when `bars.position` = `inline` or `below`
- `bars.rounded` Rounded ends / Bouts arrondis: toggle, default `true`; values: true / false
- `bars.track` Show track / Afficher le rail: toggle, default `true`; values: true / false
- `bars.colorOn` Selected color (empty = accent) / Couleur sélection (vide = accent): color, default (empty); values: hex color
- `bars.colorOff` Unselected color (empty = auto) / Couleur hors sélection (vide = auto): color, default (empty); values: hex color
- `bars.colorNegative` Negative values color / Couleur des valeurs négatives: color, default `#c0392b`; values: hex color
- `bars.minWidth` Minimum width (px) / Largeur minimale (px): number, default `60`; values: 20 to 400. Visible when `bars.position` = `inline`

### Displayed values / Valeurs affichées (`values`)
- `values.show` Show / Afficher: toggle, default `true`; values: true / false
- `values.display` Content / Contenu: dropdown, default `value`; values: `value` Value; `percent` Share of total; `both` Value and share
- `values.units` Display units / Unités: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `values.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `values.prefix` Prefix / Préfixe: text, default (empty)
- `values.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)
- `values.color` Color (empty = secondary) / Couleur (vide = secondaire): color, default (empty); values: hex color
- `values.mono` Tabular figures / Chiffres alignés (tabulaires): toggle, default `true`; values: true / false

### Sort / Tri (`sort`)
- `sort.by` Sort by / Trier par: dropdown, default `valueDesc`; values: `valueDesc` Measure, descending; `valueAsc` Measure, ascending; `labelAsc` Label A → Z; `labelDesc` Label Z → A; `sortDesc` "Sort by" field, descending; `sortAsc` "Sort by" field, ascending; `data` Model order
- `sort.natural` Natural sort (2 before 10) / Tri naturel (2 avant 10): toggle, default `true`; values: true / false
- `sort.userToggle` Sort toggle in the visual / Bouton de tri dans le visuel: toggle, default `true`; values: true / false

### Search / Recherche (`search`)
- `search.show` Show / Afficher: toggle, default `true`; values: true / false
- `search.placeholder` Placeholder / Texte indicatif: text, default (empty)
- `search.match` Matching / Correspondance: dropdown, default `contains`; values: `contains` Contains; `starts` Starts with; `words` Word start
- `search.highlight` Highlight matches / Surligner le texte trouvé: toggle, default `true`; values: true / false
- `search.selectResults` "Select results" button / Bouton « Sélectionner les résultats »: toggle, default `true`; values: true / false

### Quick actions / Actions rapides (`actions`)
- `actions.show` Show / Afficher: toggle, default `true`; values: true / false
- `actions.topN` Top N ★ ★: toggle, default `true`; values: true / false
- `actions.topNCount` N: number, default `5`; values: 1 to 100. Visible when `actions.topN` = `true`
- `actions.invert` Invert selection / Inverser la sélection: toggle, default `true`; values: true / false
- `actions.paste` Paste a list ★ / Coller une liste ★ ★: toggle, default `true`; values: true / false
- `actions.style` Style: dropdown, default `chips`; values: `chips` Text chips; `icons` Icons only

### Selection summary / Résumé de la sélection (`summary`)
- `summary.show` Show / Afficher: toggle, default `true`; values: true / false
- `summary.template` Text ★ / Texte ★ ★: text, default (empty). Tokens: {n} selected count, {count} values, {sel} selected measure, {total} total measure, {pct} share.
- `summary.showShare` Share of total on the right / Part du total à droite: toggle, default `true`; values: true / false
- `summary.hideWhenEmpty` Hide when nothing selected / Masquer sans sélection: toggle, default `true`; values: true / false

### Preselection / Présélection (`preselect`)
- `preselect.when` Apply / Appliquer: dropdown, default `session`; values: `session` Once per session; `always` Reapply on every display. Drop in "Preselection" a measure that returns a value or a list ("Paris;Lyon"): the slicer selects it when the report opens. Premium feature ★.
- `preselect.force` Force / Forcer: toggle, default `false`; values: true / false. Replaces an existing selection: saved in the report, recalled by a bookmark or by persistent filters. Otherwise it is kept.
- `preselect.separator` Value separator / Séparateur des valeurs: text, default `;`
- `preselect.warn` Report values not found (edit mode) / Signaler les valeurs introuvables (mode édition): toggle, default `true`; values: true / false

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).
- `tooltip.format` Measure format / Format des mesures: dropdown, default `model`; values: `model` Each measure's format (model); `visual` Visual format (Displayed values). Each measure of the "Tooltips" well keeps its own format (%, €, decimals), as in native visuals.
- `tooltip.share` Share of total / Part du total: toggle, default `true`; values: true / false

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.transparent` Transparent background / Fond transparent: toggle, default `false`; values: true / false. The visual lets what is behind it show through (useful for a dropdown placed over another visual).
- `container.border` Border / Bordure: toggle, default `true`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `10`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Range Plume

- The numeric range slicer: pick a range on the column's histogram (price, age, lead time), with handles, exact input and impact.
- Slug `range-pulse` · version 1.4.0.0 · GUID (`visualType`) `plumeRangePulse4B8C2E7F19A04D6C8E3B5A7F2C91D0E3` · page https://plumevisuals.com/en/visuals/range-pulse

### What the visual does

Range Plume is a Power BI custom visual that works as a numeric range slicer drawn over the distribution of the column: a histogram of the values (price, age, lead time, surface…), two handles, a brush to draw the range directly on the histogram, exact min / max inputs ("1.2k", "3.5M", "1 200 €"), presets (quartiles, "without outliers", top / bottom 10 %, above median, "Custom ranges ★") and an impact summary (rows kept, share of rows, measure kept and its share, median of the range). The chosen range filters the rest of the report.

**New in version 1.4.0.0 (30/10/2026):** Shared slicer cards (Preselection: measure "100;500" ★ or free shortcuts); **Between / Less than or equal to / Greater than or equal to** styles like the native numeric slicer; histogram hover moved to Tooltips (`tooltip.show`).

### 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 (`style.customColors` and the colors under it) are **free**; every other `style.preset`, the other gradient palettes (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium** (watermark without a key). See "Styles and theme JSON" below.
- The only premium feature of Range Plume is **custom named ranges** (`presets.custom`, label "Custom ranges ★" / « Plages personnalisées ★ »). When that text is not empty and no valid key is set, the footer shows **"Plume Visuals · Premium preview"** (French: « Plume Visuals · Aperçu premium ») with an "Unlock →" link to the pricing page.
- The watermark disappears once a key is pasted in **Format › Plume Studio License › License key** (`license.key`; French: « Licence Plume Studio › Clé de licence »), the **first card** of the Format pane. In the Format pane, premium options have " ★" appended to their label and carry the description "Premium feature: usable for free with a « Premium preview » watermark…".
- Accepted keys: only keys starting with `PLUM1.` shown in the buyer's account on plumevisuals.com, checked offline (Ed25519 signature), covering `range-pulse` 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". `license.showOwner` displays "Licensed to <holder>".
- Licenses last one year (one-time payment, no automatic renewal, key accepted for 30 more days, reminders 30 and 7 days before the end), per segment: 19 € personal, 49 € SME, 149 € enterprise per year, or the full catalog pack. Renewing gives a new key to paste instead of the old one.

### Expected data shape

The visual reads **one row per distinct value of the numeric column**, with the measures evaluated for that value.

| Numeric field (`value`) | Row count (weight) (`weight`) | Measure (impact) (`measure`) |
|---|---|---|
| 185 000 | 12 | 2 220 000 |
| 192 500 | 3 | 577 500 |
| … | … | … |

- **Numeric field** (`value`, label "Numeric field" / « Champ numérique », grouping, exactly one column, required): the column to filter. Only number / whole number columns are accepted (text and date columns are refused by the well).
- **Row count (weight)** (`weight`, « Nombre de lignes (poids) », one measure, optional but strongly recommended): how many rows have this value, normally `COUNTROWS`. It gives exact histogram heights and weighted quantiles (median, quartiles, deciles). Without it every distinct value counts 1 and an ⓘ is shown in the summary. Values whose weight is blank or 0 are ignored.
- **Measure (impact)** (`measure`, « Mesure (impact) », one measure, optional): an **additive** measure (revenue, volume…) whose kept amount and share are shown in the summary.
- There is no Tooltips well: the tooltip per histogram bin (bounds, rows and share, measure) is built in (`tooltip.show`).
- Volume: 30,000 distinct values per data window, more fetched automatically up to a **fixed limit of 100,000 distinct values**; beyond, a warning icon is shown ("Only the first n values are loaded"; details: "The visual loads at most 100,000 values. Filter the page or use a less detailed column."). There is no "Data" card any more since 1.0.1.0. Amounts with cents create many distinct values: round the column.

### DAX recipes

```dax
// Weight and impact
Listings = COUNTROWS ( Listings )
Total value = SUM ( Listings[Price] )

// Calculated column with fewer distinct values (use it in Numeric field)
Price rounded = ROUND ( Listings[Price], -3 )          // nearest thousand
Amount rounded = ROUND ( Orders[Amount], 0 )

// Measures that react to the range (cards next to the slicer)
Median price = MEDIAN ( Listings[Price] )
Share of listings = DIVIDE ( [Listings], CALCULATE ( [Listings], REMOVEFILTERS ( Listings[Price] ) ) )
```

### Filter sent to the report

An `AdvancedFilter` with logical operator `And` on the numeric column: `GreaterThanOrEqual` min and `LessThanOrEqual` max, for example `{ "target": { "table": "Listings", "column": "Price" }, "logicalOperator": "And", "conditions": [ { "operator": "GreaterThanOrEqual", "value": 150000 }, { "operator": "LessThanOrEqual", "value": 300000 } ] }`.

- With `behavior.clampOutside` (on by default), a handle left at the end of the scale drops that condition: the bound is open and values beyond it stay included. Both handles at the ends = filter removed.
- Presets (quartiles, deciles, "without outliers"…) are computed from the current data and sent as a fixed range: they are not re-evaluated when the data changes.
- `behavior.apply` = `release` filters when the mouse is released; `button` shows Apply / Cancel.

### Interactions with the report

- Drag a handle, drag the whole range (`slider.moveWindow`), draw a range on the histogram (`slider.brush`), type in the min / max boxes, or click a preset. Snapping: `slider.snap` = `step` (`slider.step`, 0 = auto), `bins`, `data` (existing values) or `none`.
- Keyboard on the handles (ARIA `slider`): ← → ↑ ↓ (Shift = ×10), Page Up / Page Down, Home / End. Enter validates a typed value, Esc in a min / max box restores the current value.
- "Clear" in the header (`header.showClear`) removes the filter. Context menu, high contrast, landing page, read-only on dashboards.
- **Bookmarks** and **Sync slicers** work: the visual declares `supportsSynchronizingFilterState` and restores the range from the filter.
- Other visuals cross-filter Range Plume (it does not support highlighting).

### Format pane: how to read the tables below

- Each option has an ID `card.option` (for example `histogram.style`). The card is the capabilities.json **object name**, the option is the **property name**.
- Card order: `license` (always first), `style` (Style card shared by every Plume visual: `preset`, `themeJson`, `followTheme`, then `customColors`, the colors, `palette` (Gradient palette), font, size, density, radius, animations), `header`, then `histogram`, `slider`, `inputs`, `presets`, `values` (number format), `summary` (range impact), `behavior`, then `container` and `texts`. Format pane in version 1.4.0.0 (30/10/2026), top to bottom: `license`, `style`, `header`, `histogram`, `slider`, `inputs`, `presets`, `values`, `summary`, `behavior`, `preselect`, `tooltip`, `container`, `texts`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- Labels follow the language of Power BI Desktop; `texts.language` can force French or English inside the visual, `texts.numberLocale` the number format (e.g. `en-GB`).
- "Visible when" means the option only appears when another option has one of the listed values.
- `general.filter` is where Power BI stores the filter applied by the visual: never write it by hand.

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. Literal syntax: booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes, colors wrapped in `solid.color`.

```json
{
  "visualType": "plumeRangePulse4B8C2E7F19A04D6C8E3B5A7F2C91D0E3",
  "query": {
    "queryState": {
      "value":   { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Listings" } }, "Property": "Price" } }, "queryRef": "Listings.Price", "nativeQueryRef": "Price" } ] },
      "weight":  { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Listings" } }, "Property": "Listings" } }, "queryRef": "Listings.Listings", "nativeQueryRef": "Listings" } ] },
      "measure": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Listings" } }, "Property": "Total value" } }, "queryRef": "Listings.Total value", "nativeQueryRef": "Total value" } ] }
    }
  },
  "objects": {
    "histogram": [ { "properties": { "style": { "expr": { "Literal": { "Value": "'area'" } } },
                                      "mean": { "expr": { "Literal": { "Value": "true" } } },
                                      "colorIn": { "solid": { "color": { "expr": { "Literal": { "Value": "'#1d3557'" } } } } } } } ],
    "presets":   [ { "properties": { "custom": { "expr": { "Literal": { "Value": "'Small: -50; Medium: 50-200; Large: 200-'" } } },
                                      "trimPct": { "expr": { "Literal": { "Value": "10D" } } } } } ],
    "summary":   [ { "properties": { "rowsLabel": { "expr": { "Literal": { "Value": "'listings'" } } } } } ],
    "behavior":  [ { "properties": { "apply": { "expr": { "Literal": { "Value": "'button'" } } } } } ],
    "license":   [ { "properties": { "key": { "expr": { "Literal": { "Value": "'PLUM1.…'" } } } } } ]
  }
}
```

The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from AppSource or from the `.pbiviz` file).

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`.
- `style.themeJson` (Format › Style › Theme JSON ★) takes a JSON theme as plain text. Format v2: an object with an optional `extends` (a style ID above) and optional groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`; the v1 flat format (`style`, `palette`, `accent`, `background`…) is still read. Every field is optional. Colors are `#RRGGBB` (`#RGB` and `#RRGGBBAA` accepted, opacity ignored). Unknown fields and values outside the allowed lists are ignored, out-of-range numbers are clamped. Invalid JSON shows "Invalid theme JSON: ignored" in edit mode and the visual keeps its look.
- Full field list with allowed values, examples and troubleshooting: tutorial https://plumevisuals.com/ai/tutorials/en/themes-json.md (French: https://plumevisuals.com/ai/tutorials/fr/themes-json.md). The same JSON can be pasted in every Plume visual of a page.
- Priority (the last one wins): visual defaults → `style.preset` → `style.themeJson` → `style.palette` (if not "Style or theme palette") → `style.followTheme` → custom colors → options set by hand in the other cards → DAX formats (fx button, "Dynamic format" field) → Windows high contrast.
- What this slicer uses from a theme JSON: `colors` (`background`, `foreground`, `muted`, `grid`, `accent`, `borderColor`, `glowColor`), `typography` (`fontFamily`, `titleFamily`, `headerCase`, `letterSpacing`), `shape` (`radius`, `border`, `borderWidth`, `borderStyle`, `shadow`) and `effects` (`glow`, `texture`). `fontFamily`, `radius`, `border`, `borderWidth` and `shadow` only apply while the matching Format pane options are left at their default. The `palettes`, `table` and `marks` groups and the other fields (`surface`, `background2`, `stroke`, `accent2`, `positive`, `negative`, `numberFamily`…) are accepted but have no visible effect on it.

### Common pitfalls

- The field is refused: the column is text or date. Change its data type, or create a numeric calculated column.
- Histogram heights all equal / ⓘ in the summary: no measure in Row count (weight).
- Slow, or warning "The visual loads at most 100,000 values. Filter the page or use a less detailed column.": too many distinct values (e.g. amounts with cents); round the column.
- Squeezed histogram: a long tail of large values. `histogram.xScale` = `auto` switches to a log scale when the distribution is very skewed (only for positive values); force `log`, or use `histogram.yScale` = `sqrt`.
- Custom ranges syntax: `Label: min-max`, one per line or separated by `;`, min or max left empty for an open range (`Large: 200-`). The `-` is the separator, so negative bounds cannot be written in this field.
- The scale does not start at 0: it follows the data; set `behavior.boundsMin` / `behavior.boundsMax` to impose bounds.
- Watermark visible: `presets.custom` is filled, or a ★ style, palette or theme JSON is used, 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)

Several ranges at once or a list of discrete values (use Bar Slicer Plume), date or time ranges (use Period Plume), more than one numeric field, a Tooltips well, a filter on a measure value (only columns are filtered), dynamic presets that move with each refresh, a histogram of a measure (the histogram counts rows per column value), two-dimensional brush, logarithmic scale for zero or negative values.

## Range Plume: data fields

- `value` Numeric field / Champ numérique (column, 1 max): 
- `weight` Row count (weight) / Nombre de lignes (poids) (measure, 1 max): 
- `measure` Measure (impact) / Mesure (impact) (measure, 1 max): 
- `preselect` Preselection / Présélection (measure, 1 max): Optional measure returning the value(s) selected when the report opens, e.g. "Paris;Lyon" or "2026-01-01;2026-03-31"
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Range Plume: Format pane options (118)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: true / false. Text, background, accent and data colors come from the Power BI report theme.
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorTrack` Bar track / Fond des barres: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`
- `style.fontSize` Text size / Taille du texte: number, default `12`; values: 8 to 28
- `style.density` Density / Densité: dropdown, default `normal`; values: `compact` Compact; `normal` Normal; `comfortable` Comfortable
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Header / En-tête (`header`)
- `header.show` Show / Afficher: toggle, default `true`; values: true / false
- `header.title` Text / Texte: text, default (empty). Leave empty to use the field name.
- `header.fontSize` Size / Taille: number, default `14`; values: 7 to 36
- `header.bold` Bold / Gras: toggle, default `true`; values: true / false
- `header.italic` Italic / Italique: toggle, default `false`; values: true / false
- `header.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `header.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `header.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `header.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `header.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false. A long title goes on two lines instead of being cut.
- `header.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `header.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `header.divider` = `true`
- `header.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `header.divider` = `true`
- `header.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `header.divider` = `true`
- `header.showCount` Show value / selection count / Afficher le nombre de valeurs / sélection: toggle, default `true`; values: true / false
- `header.showClear` "Clear" button / Bouton « Effacer »: toggle, default `true`; values: true / false
- `header.clearLabel` Clear button label / Libellé du bouton Effacer: text, default (empty). Visible when `header.showClear` = `true`

### Histogram / Histogramme (`histogram`)
- `histogram.show` Show / Afficher: toggle, default `true`; values: true / false
- `histogram.bins` Number of bins (0 = auto) / Nombre de classes (0 = auto): number, default `0`; values: 0 to 200
- `histogram.xScale` Horizontal scale / Échelle horizontale: dropdown, default `auto`; values: `auto` Auto (log when very skewed); `linear` Linear; `log` Logarithmic
- `histogram.yScale` Bar height / Hauteur des barres: dropdown, default `linear`; values: `linear` Linear; `sqrt` Square root (softens peaks)
- `histogram.style` Style: dropdown, default `bars`; values: `bars` Bars; `area` Filled curve; `dots` Dots (units)
- `histogram.gap` Gap between bars (px) / Espace entre barres (px): number, default `2`; values: 0 to 8. Visible when `histogram.style` = `bars`
- `histogram.colorIn` In-range color (empty = accent) / Couleur dans la plage (vide = accent): color, default (empty); values: hex color
- `histogram.colorOut` Out-of-range color (empty = auto) / Couleur hors plage (vide = auto): color, default (empty); values: hex color
- `histogram.median` Median marker / Repère de la médiane: toggle, default `true`; values: true / false
- `histogram.mean` Mean marker / Repère de la moyenne: toggle, default `false`; values: true / false
- `histogram.axis` Axis / Axe gradué: toggle, default `true`; values: true / false
- `histogram.ticks` Tick count / Nombre de graduations: number, default `5`; values: 2 to 12. Visible when `histogram.axis` = `true`

### Slider / Curseur (`slider`)
- `slider.handle` Handle shape / Forme des poignées: dropdown, default `circle`; values: `circle` Circle; `bar` Vertical bar; `pill` Pill
- `slider.handleSize` Handle size / Taille des poignées: number, default `16`; values: 10 to 30
- `slider.thickness` Track thickness / Épaisseur du rail: number, default `4`; values: 2 to 12
- `slider.labels` Handle values / Valeurs des poignées: dropdown, default `hover`; values: `always` Always; `hover` On hover and drag; `never` Never
- `slider.step` Step (0 = auto) / Pas (0 = auto): number, default `0`; values: 0 to …
- `slider.snap` Snap to / Accrocher aux: dropdown, default `step`; values: `step` Step; `bins` Bin edges; `data` Existing values; `none` Nothing
- `slider.brush` Draw range on the histogram / Dessiner la plage sur l'histogramme: toggle, default `true`; values: true / false
- `slider.moveWindow` Drag the whole range / Déplacer la plage d'un bloc: toggle, default `true`; values: true / false

### Min / max inputs / Saisie min / max (`inputs`)
- `inputs.show` Show / Afficher: toggle, default `true`; values: true / false
- `inputs.position` Position: dropdown, default `below`; values: `below` Below the slider; `above` Above the histogram
- `inputs.labels` "Minimum / Maximum" labels / Étiquettes « Minimum / Maximum »: toggle, default `true`; values: true / false
- `inputs.minLabel` Minimum label / Libellé du minimum: text, default (empty)
- `inputs.maxLabel` Maximum label / Libellé du maximum: text, default (empty)

### Presets / Préréglages (`presets`)
- `presets.show` Show / Afficher: toggle, default `true`; values: true / false
- `presets.custom` Custom ranges ★ / Plages personnalisées ★ ★: textarea, default (empty). One range per line or separated by ; — "Label: min-max". Leave min or max empty for an open range.
- `presets.quartiles` Quartiles (Q1 to Q4) / Quartiles (Q1 à Q4): toggle, default `false`; values: true / false
- `presets.trim` "Without outliers" / « Sans les valeurs extrêmes »: toggle, default `true`; values: true / false
- `presets.trimPct` Share removed on each side (%) / Part retirée de chaque côté (%): number, default `5`; values: 1 to 25. Visible when `presets.trim` = `true`
- `presets.aboveMedian` "Above median" / « Au-dessus de la médiane »: toggle, default `false`; values: true / false
- `presets.topDecile` "Top 10%" / « 10 % les plus élevés »: toggle, default `true`; values: true / false
- `presets.bottomDecile` "Bottom 10%" / « 10 % les plus bas »: toggle, default `false`; values: true / false
- `presets.position` Position: dropdown, default `bottom`; values: `top` Top; `bottom` Bottom

### Number format / Format des nombres (`values`)
- `values.units` Display units / Unités: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `values.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `values.prefix` Prefix / Préfixe: text, default (empty)
- `values.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)

### Range impact / Impact de la plage (`summary`)
- `summary.show` Show / Afficher: toggle, default `true`; values: true / false
- `summary.count` Rows kept / Nombre de lignes retenues: toggle, default `true`; values: true / false
- `summary.share` Share of rows / Part des lignes: toggle, default `true`; values: true / false
- `summary.measure` Measure kept and its share / Mesure retenue et sa part: toggle, default `true`; values: true / false
- `summary.median` Median of the range / Médiane de la plage: toggle, default `true`; values: true / false
- `summary.rowsLabel` Row name (e.g. orders) / Nom des lignes (ex. commandes): text, default (empty)

### Behavior / Comportement (`behavior`)
- `behavior.operator` Style: dropdown, default `between`; values: `between` Between; `lessEq` Less than or equal to; `greaterEq` Greater than or equal to. Like the native numeric slicer styles: two handles (Between) or one (≤ or ≥).
- `behavior.apply` Apply the filter / Appliquer le filtre: dropdown, default `release`; values: `release` On mouse release; `button` With an "Apply" button
- `behavior.boundsMin` Fixed lower bound / Borne minimale imposée: text, default (empty)
- `behavior.boundsMax` Fixed upper bound / Borne maximale imposée: text, default (empty)
- `behavior.clampOutside` Open-ended at the extremes / Bornes ouvertes aux extrémités: toggle, default `true`; values: true / false. When a handle is at the end of the scale, values beyond it are kept.

### Preselection / Présélection (`preselect`)
- `preselect.shortcut` Shortcut (no DAX) / Raccourci (sans DAX): dropdown, default `none`; values: `none` None (measure only); `trim` Without outliers; `iqr` Middle half (Q1 to Q3); `aboveMedian` Above median; `top10` Top 10%; `bottom10` Bottom 10%. Drop in "Preselection" a measure that returns a range ("100;500"), or pick a shortcut below (free). Measure: premium feature ★.
- `preselect.when` Apply / Appliquer: dropdown, default `session`; values: `session` Once per session; `always` Reapply on every display
- `preselect.force` Force / Forcer: toggle, default `false`; values: true / false. Replaces an existing selection: saved in the report, recalled by a bookmark or by persistent filters. Otherwise it is kept.
- `preselect.separator` Value separator / Séparateur des valeurs: text, default `;`
- `preselect.warn` Report values not found (edit mode) / Signaler les valeurs introuvables (mode édition): toggle, default `true`; values: true / false

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip for each histogram bin (row count, measure).

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.transparent` Transparent background / Fond transparent: toggle, default `false`; values: true / false. The visual lets what is behind it show through (useful for a dropdown placed over another visual).
- `container.border` Border / Bordure: toggle, default `true`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `10`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Period Plume

- The date slicer: pick a period on a measure's trend, with rolling periods, calendar and year-over-year comparison.
- Slug `period-pulse` · version 1.4.0.0 · GUID (`visualType`) `plumePeriodPulse2E6A9C4D81B74F3A9D0C6E2B7A15F8C4` · page https://plumevisuals.com/en/visuals/period-pulse

### What the visual does

Period Plume is a Power BI custom visual that works as a date slicer drawn over the trend of a measure: a small timeline (area, line or bars) of the measure, on which the user draws or drags the period, plus business presets (last 7 / 30 / 90 days, this month, last month, this quarter, last quarter, last 6 months, year to date, last year, last 12 months, all time), start / end date boxes with a calendar, and an optional comparison ★ with the same period last year or the previous period. Rolling presets are saved as relative date filters, so "Last 30 days" is still the last 30 days after tomorrow's refresh. Monthly, quarterly and yearly data are detected automatically.

**New in version 1.4.0.0 (30/10/2026):** Shared slicer cards (Preselection: today, latest date, last N days, current week, ISO range measure); hide the standard presets; **Between / Before / After** styles like the native date slicer; `compare.*` → `comparison.*`, `behavior.defaultPreset` → `preselect.shortcut`.

### 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 (`style.customColors` and the colors under it) are **free**; every other `style.preset`, the other gradient palettes (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium** (watermark without a key). See "Styles and theme JSON" below.
- Premium features of Period Plume:
  - the **Comparison ★** card: `comparison.show` is **off by default**; when it is on and a measure is in Measure (trend), the comparison is drawn and the watermark appears without a key ("Compare with ★" chooses `previousYear` or `previousPeriod`);
  - **custom periods** (`presets.custom` not empty, label "Custom periods ★" / « Périodes personnalisées ★ »).
- Without a valid key, a premium feature in use shows **"Plume Visuals · Premium preview"** (French: « Plume Visuals · Aperçu premium ») in the footer, with an "Unlock →" link to the pricing page. It disappears once a key is pasted in **Format › Plume Studio License › License key** (`license.key`; French: « Licence Plume Studio › Clé de licence »), the **first card** of the Format pane. Premium options have " ★" appended to their label and carry the description "Premium feature: usable for free with a « Premium preview » watermark…".
- Accepted keys: only keys starting with `PLUM1.` shown in the buyer's account on plumevisuals.com, checked offline (Ed25519 signature), covering `period-pulse` 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". `license.showOwner` displays "Licensed to <holder>".
- Licenses last one year (one-time payment, no automatic renewal, key accepted for 30 more days, reminders 30 and 7 days before the end), per segment: 19 € personal, 49 € SME, 149 € enterprise per year, or the full catalog pack. Renewing gives a new key to paste instead of the old one.

### Expected data shape

The visual reads **one row per distinct date** (or per year), with the measure evaluated for that date.

| Date (`date`) | Measure (trend) (`measure`) |
|---|---|
| 2025-03-01 | 12 480 |
| 2025-03-02 | 9 915 |
| … | … |

- **Date** (`date`, label "Date" / « Date », grouping, exactly one field, required). Best: the date column of a marked date table (`'Date'[Date]`), used as **Date**, not as the Date Hierarchy (right-click the field in the well › Date). Date/time columns are accepted (grouped by day). A whole-number **year column** (2001, 2002…) is accepted too.
- **Measure (trend)** (`measure`, « Mesure (tendance) », one measure, optional): draws the timeline and feeds the comparison. Without it, the timeline counts the dates.
- **Tooltips** (`tooltips`, « Infobulles », several measures, optional): added to the Power BI tooltip.
- **Granularity**: `timeline.granularity` = `auto` picks day (≤ 4 months of data), week (≤ 2.5 years), month (≤ 10 years), quarter (≤ 25 years) or year. It is never finer than the data: if every date is the 1st of a month the data is treated as **monthly**; if every date is the 1st of January, April, July or October, as **quarterly**; if every date is January 1st, or the field holds years, as **yearly**. Only **yearly** data replaces the presets with "Latest year", "5 years", "10 years", "20 years" (plus "All time" if enabled), hides the calendar and shows labels like "2016". For **monthly or quarterly** data the usual presets stay: those shorter than one period are hidden and the others snap to whole periods; labels read like "March 2024". For monthly, quarterly or yearly data whose last date is in the past, presets are anchored on the last date of the data.
- Date bounds are sent as the instant of local midnight (since 1.0.2.0), so the first day of the period is included whatever the time zone of Power BI Desktop. Filters restored from older versions (UTC midnight) are read correctly.
- Volume: 30,000 dates per data window, more fetched automatically up to a fixed limit of 100,000 (no "Data" card since 1.0.1.0).

### DAX recipes

```dax
// Measure (trend)
Revenue = SUM ( Sales[Amount] )

// Report measures that follow the period chosen in the slicer
Revenue LY = CALCULATE ( [Revenue], SAMEPERIODLASTYEAR ( 'Date'[Date] ) )
Revenue previous period =
VAR _start = MIN ( 'Date'[Date] )
VAR _end = MAX ( 'Date'[Date] )
VAR _days = _end - _start + 1
RETURN CALCULATE ( [Revenue], DATESBETWEEN ( 'Date'[Date], _start - _days, _start - 1 ) )
Change vs LY = DIVIDE ( [Revenue] - [Revenue LY], [Revenue LY] )

// Date table (Modeling › New table), then mark it as a date table and relate 'Date'[Date] 1 → * Sales[Date]
Date = ADDCOLUMNS ( CALENDAR ( DATE ( 2024, 1, 1 ), DATE ( 2025, 12, 31 ) ), "Year", YEAR ( [Date] ) )
```

The comparison ★ shown inside the visual is computed by the visual for display only; use measures like the ones above for the rest of the report.

### Filter sent to the report

Target: the field's column, with two special cases. If the field is the **Year level of an automatic date hierarchy**, the filter targets the **underlying date column** (a filter on the level itself would filter nothing). If the field is a **whole-number year column**, a numeric filter is sent.

- **Fixed period**: `AdvancedFilter` `And` with `GreaterThanOrEqual` start date and `LessThan` the day after the end date (dates at midnight UTC of the chosen day).
- **Rolling preset**: `RelativeDateFilter`, e.g. "in the last 12 months, including today" (`last7`, `last30`, `last90`, `thisMonth`, `lastMonth`, `last6m`, `ytd`, `lastYear`, `last12m`). Only when `presets.rolling` is on and `presets.anchor` = `today`; then a "Rolling" badge is shown in the header. "This quarter", "Last quarter", custom periods and presets anchored on the last data date are sent as fixed periods.
- **Year column**: `AdvancedFilter` `GreaterThanOrEqual` start year `And` `LessThanOrEqual` end year (never relative).
- Whole range or "All" = filter removed. `preselect.shortcut` applies a period once when the report opens without a date filter.

### Interactions with the report

- Click a preset, draw the period on the timeline (`timeline.brush`), drag it (`timeline.moveWindow`), move the start / end handles, or type a date (`15/03/2025`, `2025-03-15`, `15.03.25`; day/month order follows the language). Clicking a date box opens the calendar (`inputs.calendar`).
- Snapping: `timeline.snap` (displayed granularity, day, week, month), never finer than the data. Granularity buttons in the visual (`timeline.userGranularity`) offer only granularities that make sense.
- Keyboard on the handles (ARIA `slider`): ← → by day, week or month depending on snapping, Shift = one month, Home / End. Esc closes the calendar.
- `behavior.apply` = `button` shows Apply / Cancel; `behavior.minDays` sets a minimum length.
- **Bookmarks** and **Sync slicers** work for fixed and relative filters (`supportsSynchronizingFilterState`). Context menu, tooltips, high contrast, landing page, read-only on dashboards. Other visuals cross-filter it (no highlighting).

### Format pane: how to read the tables below

- Each option has an ID `card.option` (for example `timeline.chart`). The card is the capabilities.json **object name**, the option is the **property name**.
- Card order: `license` (always first), `style` (Style card shared by every Plume visual: `preset`, `themeJson`, `followTheme`, then `customColors`, the colors, `palette` (Gradient palette), font, size, density, radius, animations), `header`, then `presets`, `timeline`, `inputs` (start and end dates), `comparison` (Comparison ★), `values` (number format), `behavior`, then `container` and `texts`. Format pane in version 1.4.0.0 (30/10/2026), top to bottom: `license`, `style`, `header`, `presets`, `timeline`, `inputs`, `comparison`, `values`, `behavior`, `preselect`, `tooltip`, `container`, `texts`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- Labels follow the language of Power BI Desktop; `texts.language` can force French or English inside the visual.
- "Visible when" means the option only appears when another option has one of the listed values (e.g. `presets.rolling` only when `presets.anchor` = `today`).
- `general.filter` is where Power BI stores the filter applied by the visual: never write it by hand.

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. Literal syntax: booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes, colors wrapped in `solid.color`.

```json
{
  "visualType": "plumePeriodPulse2E6A9C4D81B74F3A9D0C6E2B7A15F8C4",
  "query": {
    "queryState": {
      "date":    { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Date" } }, "Property": "Date" } }, "queryRef": "Date.Date", "nativeQueryRef": "Date" } ] },
      "measure": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Revenue" } }, "queryRef": "Sales.Revenue", "nativeQueryRef": "Revenue" } ] }
    }
  },
  "objects": {
    "presets":  [ { "properties": { "anchor": { "expr": { "Literal": { "Value": "'lastDate'" } } },
                                     "last90": { "expr": { "Literal": { "Value": "true" } } } } } ],
    "timeline": [ { "properties": { "chart": { "expr": { "Literal": { "Value": "'bars'" } } },
                                     "granularity": { "expr": { "Literal": { "Value": "'month'" } } },
                                     "colorIn": { "solid": { "color": { "expr": { "Literal": { "Value": "'#b8462a'" } } } } } } } ],
    "compare":  [ { "properties": { "show": { "expr": { "Literal": { "Value": "true" } } },
                                     "mode": { "expr": { "Literal": { "Value": "'previousYear'" } } } } } ],
    "behavior": [ { "properties": { "minDays": { "expr": { "Literal": { "Value": "7D" } } } } } ],
    "license":  [ { "properties": { "key": { "expr": { "Literal": { "Value": "'PLUM1.…'" } } } } } ]
  }
}
```

The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from AppSource or from the `.pbiviz` file).

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`.
- `style.themeJson` (Format › Style › Theme JSON ★) takes a JSON theme as plain text. Format v2: an object with an optional `extends` (a style ID above) and optional groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`; the v1 flat format (`style`, `palette`, `accent`, `background`…) is still read. Every field is optional. Colors are `#RRGGBB` (`#RGB` and `#RRGGBBAA` accepted, opacity ignored). Unknown fields and values outside the allowed lists are ignored, out-of-range numbers are clamped. Invalid JSON shows "Invalid theme JSON: ignored" in edit mode and the visual keeps its look.
- Full field list with allowed values, examples and troubleshooting: tutorial https://plumevisuals.com/ai/tutorials/en/themes-json.md (French: https://plumevisuals.com/ai/tutorials/fr/themes-json.md). The same JSON can be pasted in every Plume visual of a page.
- Priority (the last one wins): visual defaults → `style.preset` → `style.themeJson` → `style.palette` (if not "Style or theme palette") → `style.followTheme` → custom colors → options set by hand in the other cards → DAX formats (fx button, "Dynamic format" field) → Windows high contrast.
- What this slicer uses from a theme JSON: `colors` (`background`, `foreground`, `muted`, `grid`, `accent`, `borderColor`, `glowColor`), `typography` (`fontFamily`, `titleFamily`, `headerCase`, `letterSpacing`), `shape` (`radius`, `border`, `borderWidth`, `borderStyle`, `shadow`) and `effects` (`glow`, `texture`). `fontFamily`, `radius`, `border`, `borderWidth` and `shadow` only apply while the matching Format pane options are left at their default. The `palettes`, `table` and `marks` groups and the other fields (`surface`, `background2`, `stroke`, `accent2`, `positive`, `negative`, `numberFamily`…) are accepted but have no visible effect on it.

### Common pitfalls

- Only years appear (yearly timeline) although the column has days: the Date Hierarchy was dropped and only its Year level is used. Right-click the field in the well › **Date**. Filtering still works (on the underlying date column), but by whole years.
- Off-by-one dates: use a Date column, not text. Dates are sent at midnight UTC of the chosen day, end excluded the next day.
- "Last 30 days" shows nothing: the data stops in the past and `presets.anchor` = `today`. Use `lastDate` (the filter is then a fixed period, not rolling).
- Comparison shows nothing or no watermark: `comparison.show` is off by default, and a measure is required in Measure (trend). Last year's dates must exist in the visual's data.
- The date table is not related to the fact table: the slicer filters the date table only.
- Watermark visible: Comparison ★ is on with a measure, or `presets.custom` is filled, or a ★ style, palette or 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)

Several disjoint periods at once, time-of-day (hour / minute) selection, fiscal years or custom fiscal calendars, week numbers other than Monday / Sunday start, relative filters "next N days" or offsets ("N days ago"), a comparison written back to the report as a filter or a measure, more than one comparison at a time, a play / animation button, filtering on a measure value, a list of years as checkboxes (use Bar Slicer Plume or Filter Bar Plume).

## Period Plume: data fields

- `date` Date (column, 1 max): 
- `measure` Measure (trend) / Mesure (tendance) (measure, 1 max): 
- `tooltips` Tooltips / Infobulles (measure, several max): 
- `preselect` Preselection / Présélection (measure, 1 max): Optional measure returning the value(s) selected when the report opens, e.g. "Paris;Lyon" or "2026-01-01;2026-03-31"
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Period Plume: Format pane options (118)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: true / false. Text, background, accent and data colors come from the Power BI report theme.
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorTrack` Bar track / Fond des barres: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`
- `style.fontSize` Text size / Taille du texte: number, default `12`; values: 8 to 28
- `style.density` Density / Densité: dropdown, default `normal`; values: `compact` Compact; `normal` Normal; `comfortable` Comfortable
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Header / En-tête (`header`)
- `header.show` Show / Afficher: toggle, default `true`; values: true / false
- `header.title` Text / Texte: text, default (empty). Leave empty to use the field name.
- `header.fontSize` Size / Taille: number, default `14`; values: 7 to 36
- `header.bold` Bold / Gras: toggle, default `true`; values: true / false
- `header.italic` Italic / Italique: toggle, default `false`; values: true / false
- `header.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `header.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `header.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `header.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `header.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false. A long title goes on two lines instead of being cut.
- `header.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `header.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `header.divider` = `true`
- `header.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `header.divider` = `true`
- `header.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `header.divider` = `true`
- `header.showCount` Show value / selection count / Afficher le nombre de valeurs / sélection: toggle, default `true`; values: true / false
- `header.showClear` "Clear" button / Bouton « Effacer »: toggle, default `true`; values: true / false
- `header.clearLabel` Clear button label / Libellé du bouton Effacer: text, default (empty). Visible when `header.showClear` = `true`

### Presets / Préréglages (`presets`)
- `presets.show` Show / Afficher: toggle, default `true`; values: true / false
- `presets.standard` Standard presets / Préréglages standard: toggle, default `true`; values: true / false. Off: only the custom periods are shown.
- `presets.last7` Last 7 days / 7 derniers jours: toggle, default `true`; values: true / false. Visible when `presets.standard` = `true`
- `presets.last30` Last 30 days / 30 derniers jours: toggle, default `true`; values: true / false. Visible when `presets.standard` = `true`
- `presets.last90` Last 90 days / 90 derniers jours: toggle, default `false`; values: true / false. Visible when `presets.standard` = `true`
- `presets.thisMonth` This month / Mois en cours: toggle, default `true`; values: true / false. Visible when `presets.standard` = `true`
- `presets.lastMonth` Last month / Mois dernier: toggle, default `false`; values: true / false. Visible when `presets.standard` = `true`
- `presets.thisQuarter` This quarter / Trimestre en cours: toggle, default `true`; values: true / false. Visible when `presets.standard` = `true`
- `presets.lastQuarter` Last quarter / Trimestre dernier: toggle, default `false`; values: true / false. Visible when `presets.standard` = `true`
- `presets.last6m` Last 6 months / 6 derniers mois: toggle, default `false`; values: true / false. Visible when `presets.standard` = `true`
- `presets.ytd` Year to date / Cumul annuel: toggle, default `true`; values: true / false. Visible when `presets.standard` = `true`
- `presets.lastYear` Last year / Année dernière: toggle, default `false`; values: true / false. Visible when `presets.standard` = `true`
- `presets.last12m` Last 12 months / 12 mois glissants: toggle, default `true`; values: true / false. Visible when `presets.standard` = `true`
- `presets.all` All time / Toute la période: toggle, default `false`; values: true / false. Visible when `presets.standard` = `true`
- `presets.custom` Custom periods ★ / Périodes personnalisées ★ ★: textarea, default (empty). One period per line or separated by ; — "Label: start - end" (yyyy-mm-dd or dd/mm/yyyy).
- `presets.anchor` Reference date / Date de référence: dropdown, default `today`; values: `today` Today; `lastDate` Last date in the data
- `presets.rolling` Rolling preset (moves with each refresh) / Préréglage glissant (se recale à chaque actualisation): toggle, default `true`; values: true / false. Visible when `presets.anchor` = `today`. Saved as a relative date filter: "Last 30 days" stays the last 30 days tomorrow.
- `presets.position` Position: dropdown, default `top`; values: `top` Top; `bottom` Bottom

### Trend timeline / Frise de tendance (`timeline`)
- `timeline.show` Show / Afficher: toggle, default `true`; values: true / false
- `timeline.granularity` Granularity / Granularité: dropdown, default `auto`; values: `auto` Automatic; `day` Day; `week` Week; `month` Month; `quarter` Quarter; `year` Year
- `timeline.userGranularity` Granularity toggle in the visual / Choix de la granularité dans le visuel: toggle, default `true`; values: true / false
- `timeline.chart` Chart type / Type de tracé: dropdown, default `area`; values: `area` Area; `line` Line; `bars` Bars
- `timeline.colorIn` Period color (empty = accent) / Couleur de la période (vide = accent): color, default (empty); values: hex color
- `timeline.colorOut` Outside color (empty = auto) / Couleur hors période (vide = auto): color, default (empty); values: hex color
- `timeline.axis` Date axis / Axe des dates: toggle, default `true`; values: true / false
- `timeline.brush` Draw the period with the mouse / Dessiner la période à la souris: toggle, default `true`; values: true / false
- `timeline.moveWindow` Drag the period / Faire glisser la période: toggle, default `true`; values: true / false
- `timeline.snap` Snap to / Accrocher à: dropdown, default `auto`; values: `auto` Displayed granularity; `day` Day; `week` Week; `month` Month

### Start and end dates / Dates de début et de fin (`inputs`)
- `inputs.show` Show / Afficher: toggle, default `true`; values: true / false
- `inputs.format` Format: dropdown, default `long`; values: `short` Short (04/07/2025); `medium` Medium (Apr 7, 2025); `long` Long (Mon, April 7, 2025)
- `inputs.calendar` Calendar on click / Calendrier au clic: toggle, default `true`; values: true / false
- `inputs.weekStart` First day of the week / Premier jour de la semaine: dropdown, default `monday`; values: `monday` Monday; `sunday` Sunday
- `inputs.showDuration` Show duration / Afficher la durée: toggle, default `true`; values: true / false
- `inputs.fromLabel` "From" label / Libellé « Du »: text, default (empty)
- `inputs.toLabel` "To" label / Libellé « Au »: text, default (empty)

### Comparison ★ / Comparaison ★ (`comparison`)
- `comparison.show` Show ★ / Afficher ★ ★: toggle, default `false`; values: true / false
- `comparison.mode` Compare with ★ / Comparer à ★ ★: dropdown, default `previousYear`; values: `previousYear` Same period last year; `previousPeriod` Previous period
- `comparison.band` Comparison period on the timeline / Période de comparaison sur la frise: toggle, default `true`; values: true / false
- `comparison.delta` Numeric difference / Écart chiffré: toggle, default `true`; values: true / false
- `comparison.userChoice` Last year / previous toggle in the visual / Choix N-1 / précédente dans le visuel: toggle, default `true`; values: true / false
- `comparison.goodUp` An increase is good / Une hausse est positive: toggle, default `true`; values: true / false

### Number format / Format des nombres (`values`)
- `values.units` Display units / Unités: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `values.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `values.prefix` Prefix / Préfixe: text, default (empty)
- `values.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)

### Behavior / Comportement (`behavior`)
- `behavior.operator` Style: dropdown, default `between`; values: `between` Between; `before` Before; `after` After. Like the native date slicer styles: a period (Between), or everything up to a date (Before) or from a date (After).
- `behavior.apply` Apply the filter / Appliquer le filtre: dropdown, default `release`; values: `release` On mouse release; `button` With an "Apply" button
- `behavior.minDays` Minimum length (days) / Durée minimale (jours): number, default `1`; values: 1 to 366

### Preselection / Présélection (`preselect`)
- `preselect.shortcut` Shortcut (no DAX) / Raccourci (sans DAX): dropdown, default `none`; values: `none` None (measure only); `today` Today; `latest` Latest date in the data; `last7` Last 7 days; `last30` Last 30 days; `lastN` Last N days; `thisWeek` This week; `thisMonth` This month; `lastMonth` Previous month; `ytd` Year to date (YTD); `last12m` Last 12 months. Drop in "Preselection" a measure that returns a date or a range ("2026-01-01;2026-03-31", ISO dates), or pick a shortcut below (free). Measure: premium feature ★.
- `preselect.days` N (days) / N (jours): number, default `30`; values: 1 to 3660. Visible when `preselect.shortcut` = `lastN`
- `preselect.when` Apply / Appliquer: dropdown, default `session`; values: `session` Once per session; `always` Reapply on every display
- `preselect.force` Force / Forcer: toggle, default `false`; values: true / false. Replaces an existing selection: saved in the report, recalled by a bookmark or by persistent filters. Otherwise it is kept.
- `preselect.separator` Value separator / Séparateur des valeurs: text, default `;`
- `preselect.warn` Report values not found (edit mode) / Signaler les valeurs introuvables (mode édition): toggle, default `true`; values: true / false

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.transparent` Transparent background / Fond transparent: toggle, default `false`; values: true / false. The visual lets what is behind it show through (useful for a dropdown placed over another visual).
- `container.border` Border / Bordure: toggle, default `true`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `10`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Filter Bar Plume

- Up to 8 fields in one slicer: menus or panel, faceted counts, chips, “Apply” button.
- Slug `filter-bar` · version 1.5.0.0 · GUID (`visualType`) `plumeFilterBar9C1F5B3E7A2D4E8B6F0A3C9D5E7B1F26` · page https://plumevisuals.com/en/visuals/filter-bar

### What the visual does

Filter Bar Plume is a Power BI custom visual that puts up to 8 slicers in a single compact visual: a horizontal bar of dropdown menus, or a vertical panel of expandable sections. Each menu has accent-insensitive search, a three-state "Select all" row and **faceted counts** (each count takes into account the choices made in the *other* fields of the bar). Active filters are shown as removable chips with a "Clear all" button and the total after filters ("→ 10,960 orders"). Below a configurable width (420 px by default for the bar, 220 px at most for the panel) the visual collapses into a "Filters (n)" button that opens a full-frame panel, which suits mobile layouts. An "Apply" button ★ lets users tick values in several fields and send one single query.

**New in version 1.5.0.0 (30/10/2026):** Shared slicer cards; **preselection per field** (one measure per field) and **automatic collapse** into a "Filters" button depending on the frame size.

### 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 (`style.customColors` and the colors under it) are **free**; every other `style.preset`, the other gradient palettes (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium** (watermark without a key). See "Styles and theme JSON" below.
- Premium features of Filter Bar Plume:
  - **4 to 8 fields** in the Fields well (1 to 3 fields are free);
  - the **Apply button**: `applying.mode` = `button` (value label: "Apply" button (single query) ★).
- Without a valid key, a premium feature in use shows **"Plume Visuals · Premium preview"** (French: « Plume Visuals · Aperçu premium ») in the footer, with an "Unlock →" link to the pricing page. It disappears once a key is pasted in **Format › Plume Studio License › License key** (`license.key`; French: « Licence Plume Studio › Clé de licence »), the **first card** of the Format pane. In the Format pane, every premium option and premium list value has " ★" appended to its label (the generated tables below star them too). The Fields well itself is not starred: the 4-to-8-fields rule above is the reference.
- Accepted keys: only keys starting with `PLUM1.` shown in the buyer's account on plumevisuals.com, checked offline (Ed25519 signature), covering `filter-bar` 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". `license.showOwner` displays "Licensed to <holder>".
- Licenses last one year (one-time payment, no automatic renewal, key accepted for 30 more days, reminders 30 and 7 days before the end), per segment: 19 € personal, 49 € SME, 149 € enterprise per year, or the full catalog pack. Renewing gives a new key to paste instead of the old one.

### Expected data shape

The visual reads **one row per existing combination of the fields**, with the Count measure evaluated for that combination. It derives the value lists and the faceted counts from these rows.

| Fields (`fields`): Team | Fields: Channel | Fields: Priority | Count (`count`) |
|---|---|---|---|
| Billing | Email | High | 42 |
| Billing | Phone | Low | 17 |
| … | … | … | … |

- **Fields** (`fields`, label "Fields" / « Champs », grouping, 1 to 8 columns, required): the columns to filter, ideally from the same fact table or from dimension tables related to it. The menus appear in the order of the well.
- **Count** (`count`, label "Count (e.g. COUNTROWS)" / « Décompte (ex. COUNTROWS) », one measure, optional but recommended): shown next to each value and used for the total after filters. It must be **additive** (COUNTROWS, SUM): counts are summed over combinations inside the visual. It also makes Power BI return only combinations that exist in the data.
- No Tooltips well.
- Volume: the number of rows is the number of **combinations**, which multiplies quickly with each field. 30,000 rows per data window, more fetched automatically up to a fixed limit of 100,000 rows; beyond, a warning icon is shown ("Only the first n values are loaded"; details: "The visual loads at most 100,000 values. Filter the page or use a less detailed column."). There is no "Data" card any more since 1.0.1.0.

### DAX recipes

```dax
// Count (additive)
Tickets = COUNTROWS ( Tickets )
Orders = COUNTROWS ( Sales )
Units = SUM ( Sales[Quantity] )

// Year column usable as a field (single selection: menus.single = "Year")
Year = YEAR ( Tickets[Opened on] )
```

Do not use DISTINCTCOUNT or averages as Count: they are not additive across combinations and the faceted counts would be wrong.

### Filter sent to the report

**One `BasicFilter` `In` per filtered field**, all sent together as an array in a single call, for example `[ { "target": { "table": "Tickets", "column": "Team" }, "operator": "In", "values": ["Billing"] }, { "target": { "table": "Tickets", "column": "Channel" }, "operator": "In", "values": ["Email", "Chat"] } ]`. A field with nothing ticked sends no filter; nothing ticked anywhere = filters removed.

- `applying.mode` = `instant` (default): every click sends the filters. `button` ★: changes stay as a draft ("n change(s) not applied") until Apply; Cancel restores the applied state.
- Fields listed in `menus.single` (field names separated by `;`, as displayed in the well, case- and accent-insensitive) use radio buttons: one value at a time.

### Interactions with the report

- `layout.mode` = `bar` (dropdowns, `layout.fieldWidth`, `layout.wrap`) or `panel` (expandable sections, `layout.openFirst`). Field names above the value, inline, or hidden (`layout.labels`).
- `layout.collapseBelow` (420 px by default, 0 = never): below that width, a "Filters (n)" button opens a full-frame panel. In panel mode (`layout.mode = "panel"`) the threshold is capped at 220 px, so a typical 250–350 px side panel stays expanded. When the visual is too short for a menu, the menu fills the visual's frame.
- Alt + click = only this value. Keyboard: the bar is an ARIA `toolbar`; ← → between fields, ↓ opens the menu, ↑ ↓ in the values, Space / Enter ticks, Esc closes.
- Chips (`chips.style` = values (up to 2) or count), "Clear all" (`chips.clearAll`), total after filters (`chips.result`, unit in `chips.resultLabel`).
- **Bookmarks** and **Sync slicers** restore every filter of the bar (`supportsSynchronizingFilterState`). High contrast, landing page, read-only on dashboards. Other visuals cross-filter it (no highlighting).
- The header is hidden by default for this visual (`header.show` = false) and the inner padding is 8 px.

### Format pane: how to read the tables below

- Each option has an ID `card.option` (for example `layout.mode`). The card is the capabilities.json **object name**, the option is the **property name**.
- Card order: `license` (always first), `style` (Style card shared by every Plume visual: `preset`, `themeJson`, `followTheme`, then `customColors`, the colors, `palette` (Gradient palette), font, size, density, radius, animations), `header`, then `layout`, `menus` (value lists), `applying`, `chips` (active filters summary), then `container` and `texts`. Format pane in version 1.5.0.0 (30/10/2026), top to bottom: `license`, `style`, `header`, `layout`, `menus`, `applying`, `chips`, `preselect`, `container`, `texts`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- Labels follow the language of Power BI Desktop; `texts.language` can force French or English inside the visual.
- "Visible when" means the option only appears when another option has one of the listed values.
- `general.filter` is where Power BI stores the filters applied by the visual: never write it by hand.

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names (several projections in `fields`), `objects` keys are the option IDs. Literal syntax: booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes, colors wrapped in `solid.color`.

```json
{
  "visualType": "plumeFilterBar9C1F5B3E7A2D4E8B6F0A3C9D5E7B1F26",
  "query": {
    "queryState": {
      "fields": { "projections": [
        { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Tickets" } }, "Property": "Year" } }, "queryRef": "Tickets.Year", "nativeQueryRef": "Year" },
        { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Tickets" } }, "Property": "Team" } }, "queryRef": "Tickets.Team", "nativeQueryRef": "Team" },
        { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Tickets" } }, "Property": "Channel" } }, "queryRef": "Tickets.Channel", "nativeQueryRef": "Channel" } ] },
      "count":  { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Tickets" } }, "Property": "Tickets" } }, "queryRef": "Tickets.Tickets", "nativeQueryRef": "Tickets" } ] }
    }
  },
  "objects": {
    "layout":   [ { "properties": { "mode": { "expr": { "Literal": { "Value": "'panel'" } } },
                                     "openFirst": { "expr": { "Literal": { "Value": "true" } } } } } ],
    "menus":    [ { "properties": { "single": { "expr": { "Literal": { "Value": "'Year'" } } },
                                     "sort": { "expr": { "Literal": { "Value": "'count'" } } } } } ],
    "chips":    [ { "properties": { "resultLabel": { "expr": { "Literal": { "Value": "'tickets'" } } } } } ],
    "header":   [ { "properties": { "show": { "expr": { "Literal": { "Value": "true" } } } } } ],
    "style":    [ { "properties": { "customColors": { "expr": { "Literal": { "Value": "true" } } }, "accent": { "solid": { "color": { "expr": { "Literal": { "Value": "'#1d3557'" } } } } } } } ],
    "license":  [ { "properties": { "key": { "expr": { "Literal": { "Value": "'PLUM1.…'" } } } } } ]
  }
}
```

`style.colorAccent` and the other custom colors (`colorBackground`, `colorText`, `colorMuted`, `colorGrid`, `colorTrack`, `colorPositive`, `colorNegative`, `series1`–`series8`, `scaleLow`/`scaleMid`/`scaleHigh`; empty = the style's color) are only used when `style.customColors` = `true`. A style (`style.preset`), a palette (`style.palette`) or a JSON theme (`style.themeJson`, same format in every Plume visual, see the "JSON themes" tutorial) can be used instead. The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from AppSource or from the `.pbiviz` file).

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`.
- `style.themeJson` (Format › Style › Theme JSON ★) takes a JSON theme as plain text. Format v2: an object with an optional `extends` (a style ID above) and optional groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`; the v1 flat format (`style`, `palette`, `accent`, `background`…) is still read. Every field is optional. Colors are `#RRGGBB` (`#RGB` and `#RRGGBBAA` accepted, opacity ignored). Unknown fields and values outside the allowed lists are ignored, out-of-range numbers are clamped. Invalid JSON shows "Invalid theme JSON: ignored" in edit mode and the visual keeps its look.
- Full field list with allowed values, examples and troubleshooting: tutorial https://plumevisuals.com/ai/tutorials/en/themes-json.md (French: https://plumevisuals.com/ai/tutorials/fr/themes-json.md). The same JSON can be pasted in every Plume visual of a page.
- Priority (the last one wins): visual defaults → `style.preset` → `style.themeJson` → `style.palette` (if not "Style or theme palette") → `style.followTheme` → custom colors → options set by hand in the other cards → DAX formats (fx button, "Dynamic format" field) → Windows high contrast.
- What this slicer uses from a theme JSON: `colors` (`background`, `foreground`, `muted`, `grid`, `accent`, `borderColor`, `glowColor`), `typography` (`fontFamily`, `titleFamily`, `headerCase`, `letterSpacing`), `shape` (`radius`, `border`, `borderWidth`, `borderStyle`, `shadow`) and `effects` (`glow`, `texture`). `fontFamily`, `radius`, `border`, `borderWidth` and `shadow` only apply while the matching Format pane options are left at their default. The `palettes`, `table` and `marks` groups and the other fields (`surface`, `background2`, `stroke`, `accent2`, `positive`, `negative`, `numberFamily`…) are accepted but have no visible effect on it.

### Common pitfalls

- Counts look wrong: the Count measure is not additive (DISTINCTCOUNT, average…), or it is missing.
- Values that do not exist together appear, or the visual is slow: fields from unrelated tables and no Count measure, so Power BI returns every combination. Add a COUNTROWS measure of the fact table and relate the tables.
- Warning icon "Only the first n values are loaded" ("The visual loads at most 100,000 values. Filter the page or use a less detailed column."): too many combinations (e.g. customer × product × day). Use fewer or coarser fields, or a dedicated Bar Slicer Plume for a high-cardinality field.
- A field stays multi-select: its name in `menus.single` does not match the name displayed in the well (renamed field).
- Long value lists are cut: `menus.maxItems` (300 by default); use the search box.
- Values that became empty under other choices: `menus.empty` = `dim` (bottom, greyed), `hide` or `keep`.
- Watermark visible: more than 3 fields, or the Apply button, or a ★ style, palette or 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)

More than 8 fields, numeric range or date range controls inside the bar (use Range Plume or Period Plume), hierarchies or cascading parent-child menus, measure bars (use Bar Slicer Plume), a Tooltips well, saved filter presets or "views", exclude mode (`NotIn`), filtering on a measure value, per-field colors or icons, drag-and-drop reordering of the menus inside the visual (the order is the well order), cross-report filtering.

## Filter Bar Plume: data fields

- `fields` Fields / Champs (column, 8 max): 
- `count` Count (e.g. COUNTROWS) / Décompte (ex. COUNTROWS) (measure, 1 max): 
- `preselect` Preselection / Présélection (measure, 8 max): Optional measure returning the value(s) selected when the report opens, e.g. "Paris;Lyon" or "2026-01-01;2026-03-31"
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Filter Bar Plume: Format pane options (93)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: true / false. Text, background, accent and data colors come from the Power BI report theme.
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorTrack` Bar track / Fond des barres: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`
- `style.fontSize` Text size / Taille du texte: number, default `12`; values: 8 to 28
- `style.density` Density / Densité: dropdown, default `normal`; values: `compact` Compact; `normal` Normal; `comfortable` Comfortable
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Header / En-tête (`header`)
- `header.show` Show / Afficher: toggle, default `false`; values: true / false
- `header.title` Text / Texte: text, default (empty). Leave empty to use the field name.
- `header.fontSize` Size / Taille: number, default `14`; values: 7 to 36
- `header.bold` Bold / Gras: toggle, default `true`; values: true / false
- `header.italic` Italic / Italique: toggle, default `false`; values: true / false
- `header.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `header.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `header.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `header.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `header.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false. A long title goes on two lines instead of being cut.
- `header.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `header.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `header.divider` = `true`
- `header.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `header.divider` = `true`
- `header.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `header.divider` = `true`
- `header.showCount` Show value / selection count / Afficher le nombre de valeurs / sélection: toggle, default `true`; values: true / false
- `header.showClear` "Clear" button / Bouton « Effacer »: toggle, default `true`; values: true / false
- `header.clearLabel` Clear button label / Libellé du bouton Effacer: text, default (empty). Visible when `header.showClear` = `true`

### Layout / Disposition (`layout`)
- `layout.mode` Layout / Disposition: dropdown, default `panel`; values: `bar` Horizontal bar (dropdowns); `panel` Vertical panel (expandable sections)
- `layout.fieldWidth` Minimum field width (px) / Largeur minimale d'un champ (px): number, default `150`; values: 80 to 400. Visible when `layout.mode` = `bar`
- `layout.wrap` Wrap when needed / Passer à la ligne si besoin: toggle, default `true`; values: true / false. Visible when `layout.mode` = `bar`
- `layout.labels` Field names / Nom des champs: dropdown, default `above`; values: `above` Small label above; `inline` Before the value; `hidden` Hidden
- `layout.openFirst` Expand the first section / Ouvrir la première section: toggle, default `false`; values: true / false. Visible when `layout.mode` = `panel`
- `layout.collapse` Collapse into a "Filters" button / Replier en bouton « Filtres »: dropdown, default `auto`; values: `auto` Automatic (when the fields do not fit the frame); `width` Below a chosen width; `never` Never. Automatic: the threshold depends on the frame size, the number of fields and the layout (width and height). The button opens the filters full frame.
- `layout.collapseBelow` Collapse width (px) / Largeur de repli (px): number, default `420`; values: 0 to 1200. Visible when `layout.collapse` = `width`
- `layout.buttonLabel` Collapsed button label / Libellé du bouton replié: text, default (empty)

### Value lists / Listes de valeurs (`menus`)
- `menus.search` Search / Recherche: toggle, default `true`; values: true / false
- `menus.counts` Counts next to values / Décomptes à côté des valeurs: toggle, default `true`; values: true / false. Uses the "Count" measure; each count takes the other fields of the bar into account.
- `menus.selectAll` "Select all" row / Ligne « Tout sélectionner »: toggle, default `true`; values: true / false
- `menus.sort` Value sort / Tri des valeurs: dropdown, default `label`; values: `label` Label A → Z; `count` Count, descending; `data` Model order
- `menus.empty` Values that became empty / Valeurs devenues vides: dropdown, default `dim`; values: `dim` Dimmed, at the bottom; `hide` Hidden; `keep` Unchanged
- `menus.single` Single-selection fields / Champs à sélection unique: text, default (empty). Field names separated by ;
- `menus.menuWidth` Menu width (px) / Largeur des menus (px): number, default `260`; values: 160 to 600. Visible when `layout.mode` = `bar`
- `menus.maxItems` Maximum values shown / Valeurs affichées au maximum: number, default `300`; values: 20 to 5000
- `menus.allLabel` Text when nothing is filtered / Texte quand rien n'est filtré: text, default (empty)
- `menus.blankLabel` Blank label / Libellé des vides: text, default (empty)

### Applying filters / Application des filtres (`applying`)
- `applying.mode` Mode: dropdown, default `instant`; values: `instant` Instant (each click); `button` "Apply" button (single query) ★
- `applying.applyLabel` Button label / Libellé du bouton: text, default (empty). Visible when `applying.mode` = `button`

### Active filters summary / Résumé des filtres actifs (`chips`)
- `chips.show` Show / Afficher: toggle, default `true`; values: true / false
- `chips.style` Chip content / Contenu des puces: dropdown, default `values`; values: `values` Values (up to 2); `count` Number of values
- `chips.clearAll` "Clear all" button / Bouton « Tout effacer »: toggle, default `true`; values: true / false
- `chips.result` Total after filters / Total après filtres: toggle, default `true`; values: true / false
- `chips.resultLabel` Total unit (e.g. orders) / Unité du total (ex. commandes): text, default (empty). Visible when `chips.result` = `true`
- `chips.prefix` Text before chips / Texte devant les puces: text, default (empty)

### Preselection / Présélection (`preselect`)
- `preselect.when` Apply / Appliquer: dropdown, default `session`; values: `session` Once per session; `always` Reapply on every display. Drop one measure per field in "Preselection" (in field order, or named like the field): it returns a value or a list ("Paris;Lyon"). Premium feature ★.
- `preselect.force` Force / Forcer: toggle, default `false`; values: true / false. Replaces an existing selection: saved in the report, recalled by a bookmark or by persistent filters. Otherwise it is kept.
- `preselect.separator` Value separator / Séparateur des valeurs: text, default `;`
- `preselect.warn` Report values not found (edit mode) / Signaler les valeurs introuvables (mode édition): toggle, default `true`; values: true / false

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.transparent` Transparent background / Fond transparent: toggle, default `false`; values: true / false. The visual lets what is behind it show through (useful for a dropdown placed over another visual).
- `container.border` Border / Bordure: toggle, default `true`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Basic Slicer Plume

- The everyday slicer, as a dropdown or a list: one closed line whose list opens over the report, or values always on show, with an optional hierarchy.
- Slug `basic-slicer` · version 1.2.0.0 · GUID (`visualType`) `plumeBasicSlicer7DA15E10126E4C62A508BE9893B439D9` · page https://plumevisuals.com/en/visuals/basic-slicer

### What the visual does

Basic Slicer Plume is a Power BI custom visual that works like the native slicer, in its two main layouts (`layout.mode`, Format › Layout › Display as; French « Présentation › Affichage »): **`dropdown`** (default, « Liste déroulante ») and **`list`** (« Liste »). As a dropdown, it is a collapsed box about 32 px high (`layout.boxHeight`) that shows "All" (French « Tout », or the text in `layout.allText`) or the chosen values separated by commas and truncated with "+n" (or "3 selected" with `layout.display` = `count`), a clear cross (`layout.showClear`) and a chevron. Clicking the box opens a menu with the values and their checkboxes. With **several columns in the Field well** (up to 6), the menu becomes a **hierarchy** (Category › Product): parents expand and collapse, ticking a parent ticks all its children, and a half-filled box shows a partial selection. Optional: search (`search.show`), a "Select all" row, single selection, an additive Count measure shown next to the values, "Expand all / Collapse all" buttons.

**New in version 1.2.0.0 (30/10/2026):** Shared slicer cards (Preselection, Frame); new **Tiles** style (`layout.mode` = `tiles`), "Restrict to leaf nodes" in hierarchies, preselection of a precise node; `dropdown.*` moved to **Layout** (`dropdown.layout` → `layout.mode`).

As a **list** (`layout.mode` = `list`), there is no collapsed box and no menu: the values (or the tree) stay visible in the visual's frame, under the header, with the search box and the "Expand all / Collapse all" buttons above them, and the list scrolls when it is taller than the frame, like the native vertical list slicer. Selection, hierarchy, count, sort, search and keyboard work the same way. The options that only concern the box and the menu (`layout.menuOpening`, `menuHeight`, `menuWidth`, `boxHeight`, `allText`, `display`, `showClear`, `hierarchy.parentInText`) are hidden; the header gets a "Clear" button (`header.showClear`, on by default, shown when something is selected) and an optional selected count (`header.showCount`, off by default). The list layout is free.

By default the visual's own frame is **transparent and borderless** (`container.transparent` = true, `container.border` = false, `container.padding` = 2): the box is the only thing drawn when the menu is closed. A Power BI visual cannot draw outside its frame (iframe), so to make the menu open **over the visual placed below**, the report author makes the Basic Slicer frame taller than the box, brings it to front (Format › Arrange › Bring to front, or a higher z-order) and turns off its container background (Format › General › Effects › Background: the container background is a Power BI setting that a custom visual cannot turn off itself). Limitation: even transparent, the frame still captures the mouse, so the visual underneath cannot be clicked or hovered in the covered area; cover titles, KPI cards or margins rather than interactive charts.

### Free vs premium (★)

- Every feature works without a key and nothing is ever blocked. Free features never show a watermark, and the visual inserted with its default settings never shows one.
- 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 (`style.customColors` and the colors under it) are **free**; every other `style.preset`, the other gradient palettes (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium** (watermark without a key). See "Styles and theme JSON" below.
- Premium features of Basic Slicer Plume:
  - a hierarchy of **3 to 6 levels** in the Field well (1 or 2 levels are free);
- Without a valid key, a premium feature in use shows **"Plume Visuals · Premium preview"** (French: « Plume Visuals · Aperçu premium ») in the footer, with an "Unlock →" link to the pricing page. It disappears once a key is pasted in **Format › Plume Studio License › License key** (`license.key`; French: « Licence Plume Studio › Clé de licence »), the **first card** of the Format pane. The landing page (no field yet) never shows the watermark.
- Accepted keys: only keys starting with `PLUM1.` shown in the buyer's account on plumevisuals.com, checked offline (Ed25519 signature), covering `basic-slicer` 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". `license.showOwner` displays "Licensed to <holder>".
- Licenses last one year (one-time payment, no automatic renewal, key accepted for 30 more days, reminders 30 and 7 days before the end), per segment: 19 € personal, 49 € SME, 149 € enterprise per year, or the full catalog pack.

### Expected data shape

The visual reads **one row per existing combination of the Field columns**, with the optional Count measure evaluated for that combination, and builds the tree from these rows.

| Field (`fields`): Category | Field: Product | Count (`count`, optional) |
|---|---|---|
| Kitchen | Knives | 412 |
| Kitchen | Saucepan | 388 |
| Decor | Vase | 251 |
| … | … | … |

- **Field (or hierarchy levels)** (`fields`, label "Field (or hierarchy levels)" / « Champ (ou niveaux de hiérarchie) », grouping, 1 to 6 columns, required): one column for a flat list, several columns for a hierarchy, in the order of the well (first = top level). Text, number, boolean and date columns work.
- **Count (optional)** (`count`, « Décompte (facultatif) », one measure): shown at the right of each value (`items.showValues`, `items.units`, `items.decimals`), used by the "Count, descending / ascending" sort and to detect values without data (`items.empty`). A parent shows the **sum** of its children, so use an additive measure (COUNTROWS, SUM).
- No Tooltips well.
- Volume: 30,000 rows per data window; more are fetched automatically up to a fixed limit of 100,000 rows (combinations). Long menus are virtualized (only the visible rows are created).

### Filter sent to the report

- **One level**, or only first-level values ticked: a `BasicFilter` `In` on the column of the first level, e.g. `{ "target": { "table": "Sales", "column": "Category" }, "operator": "In", "values": ["Kitchen", "Decor"] }`.
- **Deeper selection**: a `TupleFilter` `In` on the first *k* levels, *k* being the deepest level ticked; a parent fully ticked is expanded down to level *k*. Example: Kitchen (whole) + Decor › Vase → `{ "target": [ { "table": "Sales", "column": "Category" }, { "table": "Sales", "column": "Product" } ], "operator": "In", "values": [ [ { "value": "Kitchen" }, { "value": "Knives" } ], [ { "value": "Kitchen" }, { "value": "Saucepan" } ], [ { "value": "Decor" }, { "value": "Vase" } ] ] }`.
- Nothing ticked = filter removed. **Bookmarks** and **Sync slicers** restore the selection from these filters (`supportsSynchronizingFilterState`).

### Interactions with the report

- Menu opening (`layout.menuOpening`): `auto` (default: below the box when at least 120 px are available in the frame, otherwise a full-frame panel with a close button), `below`, `full`. `layout.menuHeight` (300 px by default) and `layout.menuWidth` (0 = width of the box) limit the menu below the box. In edit mode, a frame lower than 110 px shows "Make the visual taller to show the list".
- Closing: click on the box, Esc, click in the frame outside the menu, focus leaving the visual, and the choice of a value in single selection.
- Selection (`selection.mode`): `multi` (click = toggle, default), `multiCtrl`, `single` (radio buttons; `selection.forceOne` keeps one value). `selection.selectAll` adds a "Select all" row. `selection.selectedFirst` moves the selection to the top.
- Hierarchy (card shown with 2 levels or more): `hierarchy.expandLevel` (levels expanded when the menu opens), `hierarchy.expandAll` (buttons), `hierarchy.indent`, `hierarchy.childCount` ("(n)" on parents), `hierarchy.parentInText` ("Parent › Value" in the box).
- Search (`search.show`, off by default): accent-insensitive, `search.match` = contains / starts with / word start; in a hierarchy, matching values are shown with their parents expanded.
- Keyboard: Enter, Space or ↓ opens the menu; ↑ ↓ move, → expands (or moves to the first child), ← collapses (or moves to the parent), Space / Enter ticks, Home / End, Esc closes and gives the focus back to the box, Delete clears. ARIA: `combobox` box, `listbox` / `option` for a flat list, `tree` / `treeitem` with `aria-level`, `aria-expanded` and `aria-checked="mixed"` for a hierarchy. High contrast supported.
- Power BI context menu on a value (right click). Read-only on dashboard tiles. Other visuals cross-filter it (no highlighting).
- The header shows the field name (or "Level 1 › Level 2"), or `header.title`. As a dropdown, the header count and "Clear" button are not used (the clear cross is in the box); as a list, `header.showClear` (default on) and `header.showCount` (default off) apply.
- As a list: no opening or closing; Tab reaches the values directly, Esc does nothing, Delete on a row clears the selection, and the single-selection choice keeps the list visible. With `selection.forceOne`, no clear button, cross or Delete is offered (in both layouts).

### Format pane: how to read the tables below

- Each option has an ID `card.option` (for example `layout.menuOpening`). The card is the capabilities.json **object name**, the option is the **property name**.
- Card order: `license` (always first), `style` (Style card shared by every Plume visual), `layout` (displayed as "Layout" / « Présentation »), `selection`, `hierarchy`, `search`, `items` (values), `header`, `container` (frame), `texts`. Format pane in version 1.2.0.0 (30/10/2026), top to bottom: `license`, `style`, `header`, `layout`, `selection`, `hierarchy`, `items`, `search`, `preselect`, `container`, `texts`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- Defaults specific to this visual: `container.transparent` = true, `container.border` = false, `container.padding` = 2, `header.fontSize` = 13, `header.showCount` = false.
- `general.filter` is where Power BI stores the filter applied by the visual: never write it by hand.

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names (several projections in `fields` for a hierarchy), `objects` keys are the option IDs. Turn off the container background in `visualContainerObjects` and raise the `z` of the position to overlay the visual below. For the list layout, add `"layout": { "expr": { "Literal": { "Value": "'list'" } } }` to the `dropdown` properties (no need to turn off the background or raise `z`).

```json
{
  "position": { "x": 16, "y": 86, "z": 3000, "width": 300, "height": 250 },
  "visual": {
    "visualType": "plumeBasicSlicer7DA15E10126E4C62A508BE9893B439D9",
    "query": {
      "queryState": {
        "fields": { "projections": [
          { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Category" } }, "queryRef": "Sales.Category", "nativeQueryRef": "Category" },
          { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Product" } }, "queryRef": "Sales.Product", "nativeQueryRef": "Product" } ] }
      }
    },
    "objects": {
      "dropdown":  [ { "properties": { "menuOpening": { "expr": { "Literal": { "Value": "'below'" } } },
                                        "menuHeight": { "expr": { "Literal": { "Value": "200D" } } } } } ],
      "hierarchy": [ { "properties": { "expandAll": { "expr": { "Literal": { "Value": "true" } } } } } ],
      "search":    [ { "properties": { "show": { "expr": { "Literal": { "Value": "true" } } } } } ],
      "header":    [ { "properties": { "title": { "expr": { "Literal": { "Value": "'Category › Product'" } } } } } ]
    },
    "visualContainerObjects": {
      "background": [ { "properties": { "show": { "expr": { "Literal": { "Value": "false" } } } } } ],
      "title":      [ { "properties": { "show": { "expr": { "Literal": { "Value": "false" } } } } } ]
    }
  }
}
```

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`.
- `style.themeJson` (Format › Style › Theme JSON ★) takes a JSON theme as plain text. Format v2: an object with an optional `extends` (a style ID above) and optional groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`; the v1 flat format (`style`, `palette`, `accent`, `background`…) is still read. Every field is optional. Colors are `#RRGGBB` (`#RGB` and `#RRGGBBAA` accepted, opacity ignored). Unknown fields and values outside the allowed lists are ignored, out-of-range numbers are clamped. Invalid JSON shows "Invalid theme JSON: ignored" in edit mode and the visual keeps its look.
- Full field list with allowed values, examples and troubleshooting: tutorial https://plumevisuals.com/ai/tutorials/en/themes-json.md (French: https://plumevisuals.com/ai/tutorials/fr/themes-json.md). The same JSON can be pasted in every Plume visual of a page.
- Priority (the last one wins): visual defaults → `style.preset` → `style.themeJson` → `style.palette` (if not "Style or theme palette") → `style.followTheme` → custom colors → options set by hand in the other cards → DAX formats (fx button, "Dynamic format" field) → Windows high contrast.
- What this slicer uses from a theme JSON: `colors` (`background`, `foreground`, `muted`, `grid`, `accent`, `borderColor`, `glowColor`), `typography` (`fontFamily`, `titleFamily`, `headerCase`, `letterSpacing`), `shape` (`radius`, `border`, `borderWidth`, `borderStyle`, `shadow`) and `effects` (`glow`, `texture`). `fontFamily`, `radius`, `border`, `borderWidth` and `shadow` only apply while the matching Format pane options are left at their default. The `palettes`, `table` and `marks` groups and the other fields (`surface`, `background2`, `stroke`, `accent2`, `positive`, `negative`, `numberFamily`…) are accepted but have no visible effect on it.

### Common pitfalls

- The user wants the values always visible, like the native list slicer: set `layout.mode` to `list` (no need to overlay anything).
- A white square around the box: the Power BI container background is on (Format › General › Effects › Background); turn it off.
- The menu opens inside a small panel instead of over the visual below: the frame is too low (Auto switches to full frame under 120 px of room) or the visual is behind the other one; make it taller and bring it to front.
- The chart under the slicer no longer reacts in one area: that area is covered by the slicer's frame; reduce the frame or move it over a title or KPI cards.
- Parent counts look wrong: the Count measure is not additive.
- Watermark visible: 3 levels or more in Field, or a premium style / 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)

Measure bars (use Bar Slicer Plume), several independent fields side by side (use Filter Bar Plume), numeric or date ranges (use Range Plume or Period Plume), a Tooltips well, exclude mode (`NotIn`), drawing outside the visual's frame, an "Apply" button, saved selections, cross-report filtering.

## Basic Slicer Plume: data fields

- `fields` Field (or hierarchy levels) / Champ (ou niveaux de hiérarchie) (column, 6 max): 
- `count` Count (optional) / Décompte (facultatif) (measure, 1 max): 
- `preselect` Preselection / Présélection (measure, 1 max): Optional measure returning the value(s) selected when the report opens, e.g. "Paris;Lyon" or "2026-01-01;2026-03-31"
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Basic Slicer Plume: Format pane options (103)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: true / false. Text, background, accent and data colors come from the Power BI report theme.
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorTrack` Bar track / Fond des barres: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`
- `style.fontSize` Text size / Taille du texte: number, default `12`; values: 8 to 28
- `style.density` Density / Densité: dropdown, default `normal`; values: `compact` Compact; `normal` Normal; `comfortable` Comfortable
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Header / En-tête (`header`)
- `header.show` Show / Afficher: toggle, default `true`; values: true / false
- `header.title` Text / Texte: text, default (empty). Leave empty to use the field name.
- `header.fontSize` Size / Taille: number, default `13`; values: 7 to 36
- `header.bold` Bold / Gras: toggle, default `true`; values: true / false
- `header.italic` Italic / Italique: toggle, default `false`; values: true / false
- `header.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `header.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `header.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `header.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `header.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false. A long title goes on two lines instead of being cut.
- `header.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `header.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `header.divider` = `true`
- `header.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `header.divider` = `true`
- `header.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `header.divider` = `true`
- `header.showCount` Show value / selection count / Afficher le nombre de valeurs / sélection: toggle, default `false`; values: true / false
- `header.showClear` "Clear" button / Bouton « Effacer »: toggle, default `true`; values: true / false
- `header.clearLabel` Clear button label / Libellé du bouton Effacer: text, default (empty). Visible when `header.showClear` = `true`

### Layout / Disposition (`layout`)
- `layout.mode` Style: dropdown, default `dropdown`; values: `dropdown` Dropdown; `list` Vertical list; `tiles` Tile. Dropdown: a one-line box whose list opens on click. Vertical list: the values stay visible in the frame. Tile: one button per value, side by side (first level of a hierarchy), like the native slicer styles.
- `layout.menuOpening` Menu opening / Ouverture du menu: dropdown, default `auto`; values: `auto` Auto; `below` Below the box; `full` Full frame. Visible when `layout.mode` = `dropdown`. A Power BI visual cannot draw outside its frame: the menu opens inside it. To make it open over the visual below, make this visual taller, place it on top (Format › Arrange › Bring to front) and keep its background transparent. Automatic switches to full frame when there is not enough room below the box.
- `layout.menuHeight` Maximum menu height (px) / Hauteur maximale du menu (px): number, default `300`; values: 80 to 1200. Visible when `layout.menuOpening` = `auto` or `below`
- `layout.menuWidth` Menu width (px, 0 = box) / Largeur du menu (px, 0 = zone): number, default `0`; values: 0 to 1200. Visible when `layout.menuOpening` = `auto` or `below`
- `layout.boxHeight` Box height (px) / Hauteur de la zone (px): number, default `32`; values: 24 to 64. Visible when `layout.mode` = `dropdown`
- `layout.allText` Text when nothing is selected / Texte sans sélection: text, default (empty). Visible when `layout.mode` = `dropdown`
- `layout.display` Selection display / Sélection affichée: dropdown, default `values`; values: `values` Selected values (+n); `count` Count (3 selected). Visible when `layout.mode` = `dropdown`
- `layout.showClear` Clear (×) button / Croix d'effacement: toggle, default `true`; values: true / false. Visible when `layout.mode` = `dropdown`
- `layout.tileColumns` Columns (0 = fit the width) / Colonnes (0 = selon la largeur): number, default `0`; values: 0 to 12. Visible when `layout.mode` = `tiles`
- `layout.tileHeight` Fixed button height (px, 0 = auto) / Hauteur fixe des boutons (px, 0 = auto): number, default `0`; values: 0 to 200. Visible when `layout.mode` = `tiles`

### Selection / Sélection (`selection`)
- `selection.mode` Mode: dropdown, default `multi`; values: `multi` Multiple (click = toggle); `multiCtrl` Multiple with Ctrl; `single` Single value
- `selection.indicator` Indicator / Indicateur: dropdown, default `auto`; values: `auto` Automatic; `checkbox` Checkbox; `radio` Radio button; `none` None (highlight)
- `selection.forceOne` Always keep one value selected / Toujours une valeur sélectionnée: toggle, default `false`; values: true / false. Visible when `selection.mode` = `single`
- `selection.selectAll` "Select all" row / Ligne « Tout sélectionner »: toggle, default `false`; values: true / false. Visible when `selection.mode` = `multi` or `multiCtrl`
- `selection.selectAllLabel` "Select all" label / Libellé « Tout sélectionner »: text, default (empty). Visible when `selection.selectAll` = `true`
- `selection.selectedFirst` Move selection to the top / Remonter la sélection en tête: toggle, default `false`; values: true / false

### Hierarchy / Hiérarchie (`hierarchy`)
- `hierarchy.expandLevel` Levels expanded on open / Niveaux dépliés à l'ouverture: number, default `0`; values: 0 to 5. Drop up to 6 columns in Field to build a hierarchy (e.g. Category › Product). 1 or 2 levels are free; 3 to 6 levels are a premium feature ★.
- `hierarchy.expandAll` Expand all / Collapse all buttons / Boutons Tout déplier / Tout replier: toggle, default `false`; values: true / false
- `hierarchy.indent` Indent per level (px) / Retrait par niveau (px): number, default `16`; values: 0 to 40
- `hierarchy.childCount` Child count on parents / Nombre d'éléments des parents: toggle, default `false`; values: true / false
- `hierarchy.parentInText` Parent in the box (Parent › Value) / Parent dans la zone (Parent › Valeur): toggle, default `false`; values: true / false. Visible when `layout.mode` = `dropdown`
- `hierarchy.leafOnly` Restrict to leaf nodes / Restreindre aux nœuds feuilles: toggle, default `false`; values: true / false. Like the native list slicer: parents expand but cannot be selected.

### Values / Valeurs (`items`)
- `items.sort` Sort / Tri: dropdown, default `data`; values: `data` Model order; `labelAsc` Label A → Z; `labelDesc` Label Z → A; `valueDesc` Count, descending; `valueAsc` Count, ascending
- `items.natural` Natural sort (2 before 10) / Tri naturel (2 avant 10): toggle, default `true`; values: true / false
- `items.showValues` Show the count / Afficher le décompte: toggle, default `true`; values: true / false
- `items.units` Display units / Unités: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions. Visible when `items.showValues` = `true`
- `items.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6. Visible when `items.showValues` = `true`
- `items.empty` Values without data / Valeurs sans données: dropdown, default `group`; values: `group` Grouped at the bottom, dimmed; `inline` In place, dimmed; `hide` Hidden. Needs a measure in "Count". Activate "Show items with no data" on the field to receive them.
- `items.blankLabel` Blank label / Libellé des vides: text, default (empty)
- `items.wrap` Wrap labels / Libellés sur plusieurs lignes: toggle, default `false`; values: true / false
- `items.separators` Separators / Séparateurs: toggle, default `false`; values: true / false
- `items.selectedBg` Tinted background when selected / Fond coloré si sélectionné: toggle, default `true`; values: true / false

### Search / Recherche (`search`)
- `search.show` Show / Afficher: toggle, default `false`; values: true / false
- `search.placeholder` Placeholder / Texte indicatif: text, default (empty)
- `search.match` Matching / Correspondance: dropdown, default `contains`; values: `contains` Contains; `starts` Starts with; `words` Word start
- `search.highlight` Highlight matches / Surligner le texte trouvé: toggle, default `true`; values: true / false

### Preselection / Présélection (`preselect`)
- `preselect.when` Apply / Appliquer: dropdown, default `session`; values: `session` Once per session; `always` Reapply on every display. Drop in "Preselection" a measure that returns a value or a list ("Paris;Lyon"): the slicer selects it when the report opens. Premium feature ★.
- `preselect.force` Force / Forcer: toggle, default `false`; values: true / false. Replaces an existing selection: saved in the report, recalled by a bookmark or by persistent filters. Otherwise it is kept.
- `preselect.separator` Value separator / Séparateur des valeurs: text, default `;`
- `preselect.warn` Report values not found (edit mode) / Signaler les valeurs introuvables (mode édition): toggle, default `true`; values: true / false

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.transparent` Transparent background / Fond transparent: toggle, default `true`; values: true / false. The visual lets what is behind it show through (useful for a dropdown placed over another visual).
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `2`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Date Picker Plume

- The calendar date slicer: a range in two clicks, the latest date in one, days without data greyed out and selectable days set by rules.
- Slug `date-picker` · version 1.1.0.0 · GUID (`visualType`) `plumeDatePicker25D54D111C2643719FC6E7ACE9CFD170` · page https://plumevisuals.com/en/visuals/date-picker

### What the visual does

Date Picker Plume is a Power BI custom slicer that shows a **calendar** (1 to 12 months) built from a date column and filters the report with the chosen dates. Selection modes (`selection.mode`): **`range`** (default: first click = start, the range is previewed on hover, second click = end; Shift + click extends the range, Esc cancels a range in progress), **`single`** (one date), **`week`** (click a day or a week number: the whole week, following `calendar.weekStart`), **`month`** (the whole month) and **`multiple`** ★ (each click adds or removes a date; Shift + click adds the selectable dates in between).

**New in version 1.1.0.0 (30/10/2026):** Shared slicer cards (Preselection: shortcuts such as last N days, or a range measure); short month names "Jan ’26" and smaller cells; `behavior.defaultSelection` → `preselect.shortcut`.

Days **without data** are greyed out and cannot be picked by default (`rules.noData` = `disable`; `dim` = greyed but selectable, `normal` = like the others). A date "has data" when the optional **Value** measure is not blank for that day (`rules.zeroIsEmpty` also treats 0 as empty); without a Value measure, every date present in the column has data, so a full Calendar table greys nothing out: drop a measure such as `[Revenue]` in Value to grey out the days without sales.

**Selectable dates** (card `rules`, « Dates sélectionnables »): a date can be picked only if it passes every condition: weekday toggles (`rules.mon` … `rules.sun`), position in the period (`rules.position`: `monthEnd`, `monthStart`, `lastWorkday`, `firstWorkday`, `lastDataDay` = last date with data of the month, `weekEnd`, `weekStart`, `quarterEnd`, `yearEnd`), `rules.excludeHolidays`, `rules.noFuture`, and the advanced rules ★ (`rules.expression`, see below). Other dates are faded, faded and struck through, or hidden (`rules.inactiveStyle`). A range filters every date between start and end, or only the selectable dates (`selection.rangeFilter` = `active`, the summary then reads "· 4 selectable").

**Shortcuts** (card `presets`): "Latest date" (`presets.latest`, on by default) selects the **last selectable date with data** (with Fridays only: the last Friday with data); Today, Yesterday, last 7 and 30 days, this week, last week, this month, last month, this quarter, year to date, last year, last 12 months, each one with its own toggle. They adapt to the mode (single date → days only; week → weeks; month → months; several dates → every selectable date of the period). Reference date (`presets.anchor`): `latest` (last date in the data, default) or `today`. Named custom shortcuts ★ (`presets.custom`, one per line: `Summer sales: 2026-06-24 - 2026-07-21`). Position: top, bottom or left side.

**Default selection** (card `behavior`): `preselect.shortcut` (`none` by default, `latest`, `today`, `last7`, `last30`, `thisWeek`, `thisMonth`, `lastMonth`, `ytd`) applied when the report opens without a date filter (`behavior.defaultWhen` = `noFilter`) or **every time the page is shown** (`open`): the published report then always reopens on the latest date even if another date was saved in it (a bookmark applied afterwards is respected). `behavior.apply` = `button` adds Apply / Cancel buttons ("Selection not applied").

Calendar card (`calendar`): `display` = `inline` (always visible) or `popup` (**compact field**, one line such as "Oct 6, 2026 → Oct 12, 2026 · 7 days" that opens the calendar on click: below the field when 250 px remain in the frame, otherwise as a full-frame panel; the frame is **transparent by default** in this visual (`container.transparent` = true): in compact mode it stays transparent even with a style that has a background, without border, shadow or texture unless set by hand, so the field can overlay another visual (make the frame taller, bring it to front, turn off the Power BI container background in General › Effects); with such a style, the title and the field sit on a card with the style's background, and the open calendar is opaque; with the visible calendar, the frame becomes opaque as soon as the style has a background); `months` (0 = fitted to the frame, up to 12, side by side then in rows; `maxCell` = maximum cell size, 44 px by default); `openOn` (month of the selection, of the latest date, or today's); quick month and year picker (click the month name); `weekStart` (`monday` default, `sunday`, `saturday`); `weekNumbers` with `weekRule` `iso` (ISO 8601) or `us`; weekends tinted, today outlined, days of neighbouring months, cell shape, month names long or short; `holidays` (`fr`, `frAm` = France Alsace-Moselle, `uk` = England, `us` = federal with observed days, `be`, `ch` = Geneva, `de` = national) shown as a dot under the date with the name in the tooltip, plus `holidayList` (`2026-12-24 Christmas Eve ; 2026-08-10..2026-08-21 Summer closure`).

### Free vs premium (★)

- Every feature works without a key and nothing is ever blocked. Free features never show a watermark, and the visual inserted with its default settings never shows one.
- 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**.
- Premium features of Date Picker Plume: **several dates** (`selection.mode` = `multiple`), **advanced rules** (`rules.expression` not empty), the **heatmap** (`heatmap.show` with a Value measure; without a measure nothing is drawn and no watermark is shown), **custom shortcuts** (`presets.custom` not empty).
- Without a valid key, a premium feature in use shows **"Plume Visuals · Premium preview"** (French « Plume Visuals · Aperçu premium ») with an "Unlock →" link to the pricing page, until a key is pasted in **Format › Plume Studio License › License key** (`license.key`), the first card of the Format pane. The landing page never shows the watermark.
- Accepted keys: `PLUM1.` keys covering `date-picker` or the whole catalog, checked offline (Ed25519). Licenses last one year (one-time payment, no automatic renewal), per slicer: 19 € personal, 49 € SME, 149 € enterprise per year, or the full catalog pack.

### Advanced rules ★ (`rules.expression`)

One rule per line (or separated by `;`). A date is selectable if it matches **at least one** line; a line starting with `-`, `sauf` or `except` **excludes** the dates it describes. Inside a line, `&`, `et`, `and` combine terms; `non`, `not`, `!` negate a term. English or French, case and accents ignored. A rule that is not understood is ignored and flagged in edit mode ("Rule not understood, ignored: …"). No code is evaluated (each term is matched by a regular expression).

| Term (EN / FR) | Dates kept |
|---|---|
| `monday` … `sunday`, `mon-fri`, `mon,wed,fri`, `fridays` / `lundi`, `lun-ven` | weekdays |
| `workday`, `business day` / `ouvré`, `jours ouvrés` | Monday to Friday except holidays |
| `weekend` / `week-end`; `holiday` / `férié` | Saturday and Sunday; holidays of the list |
| `month end`, `month start`, `end of week`, `quarter end`, `year end`… / `fin de mois`, `début de mois`… | period bounds (week per `calendar.weekStart`) |
| `last workday`, `first workday` / `dernier ouvré`, `premier ouvré` | last / first working day of the month |
| `last day with data` / `dernière date avec données` | last date with data of the month |
| `day 1,15,-1`, `day 1-10` / `jour 1,15,-1`, `le 15` | days of the month (`-1` = last day) |
| `last friday`, `2nd tuesday` / `dernier vendredi`, `2e mardi` | n-th weekday of the month |
| `month 3,6,9,12`, `month jan-mar`, `december` / `mois 3,6,9,12` | months |
| `week 1-10`, `even week`, `odd week` / `semaine paire` | week numbers (ISO or US) |
| `year 2025,2026` / `année 2026` | years |
| `with data`, `no data` / `avec données`, `sans données` | according to the Value measure |
| `past`, `future`, `today` / `passé`, `futur`, `aujourd'hui` | relative to today |
| `2026-12-24`, `2026-01-01..2026-03-31`, `after 2026-01-01`, `before 2026-06-30` / `du 01/01/2026 au 31/03/2026` | dates and ranges |

Examples: `friday` (weekly closings); `last workday & month 3,6,9,12` (quarter-end closings); `workday` plus a line `- 2026-08-10..2026-08-21` (except the summer closure); `day 1,15` (twice a month).

### Heatmap ★ (`heatmap`)

Each day with data is colored by the Value measure: `heatmap.colors` = `style` (gradient palette of the style, follows the theme and custom colors), `accent` (background to accent) or `custom` (`low`, `high`); `reverse`; `intensity` (10 to 100 %); `scale` = `linear`, `quantile` (each color holds as many days) or `diverging` (around zero); `showValues` (values in enlarged cells, black or white text by contrast); `legend` (min – max with the measure name). The domain covers every date with data, not only the months shown, so colors stay stable from month to month. The selection stays visible (accent ring). High contrast: no heatmap.

### Expected data shape

| Date (`date`) | Value (`value`, optional) | Tooltips (`tooltips`, optional) |
|---|---|---|
| 2026-09-28 | 2 410 | 58 |
| 2026-09-29 | 1 980 | 47 |
| … | … | … |

- **Date** (`date`, grouping, required): a date column, e.g. `Calendar[Date]`. Use the column itself (right-click the field › Date), not the automatic date hierarchy; date/time columns are grouped by day; a column of years is refused with a clear message.
- **Value (data and heatmap)** (`value`, one measure, optional): blank = "without data"; also colors the heatmap ★.
- **Tooltips** (`tooltips`, measures): added to the Power BI tooltip of each day (date, value, tooltips, week, holiday, status).
- 30,000 rows per data window (one row per day).

### Filter sent to the report

- Date, range, week, month: an `AdvancedFilter` on the date column, `GreaterThanOrEqual` the first day and `LessThan` the day after the last one (local midnight, like Period Plume). A date hierarchy is resolved to its source column.
- Several dates ★, or a range limited to the selectable dates: a `BasicFilter` `In` with the exact values of the column (date/time values included), 5,000 dates at most (beyond: the whole range).
- Nothing selected = filter removed. **Bookmarks** and **Sync slicers** restore the selection (`supportsSynchronizingFilterState`).

### Interactions and accessibility

- Clicking a date never scrolls the months on show (since 1.0.1.0); a filter coming from elsewhere (bookmark, synced slicer) outside the view is brought into view.
- Keyboard: ← → day, ↑ ↓ week, Page Up / Down month, Shift + Page Up / Down year, Home / End start or end of the week, Enter / Space picks (Shift = extend), Esc cancels a range, closes the quick picker or the compact calendar. Only one cell is reachable with Tab (roving focus), and the focus stays on the date after each filter.
- ARIA grid (`grid`, `row`, `gridcell`, `aria-selected`, `aria-disabled`) with a full label per date (value, holiday, without data, not selectable). High contrast: outlines instead of fills.
- Power BI context menu and tooltip on each date. Read-only on dashboard tiles. FR/EN.
- Selection summary under the calendar (`selection.summary`), date format short / medium / long, text when nothing is selected ("All dates"), typed dates (`selection.inputs`: `15/03/2026`, `2026-03-15`, day/month order from the locale), maximum range length (`selection.maxDays`: the range is clipped, "Range limited to 7 days").

### Format pane

Card order: `license` (always first), `style`, `header`, `calendar`, `selection`, `rules` (« Dates sélectionnables » / "Selectable dates"), `heatmap` ("Heatmap ★"), `presets` ("Shortcuts"), `behavior`, `values` (number format), `container` (frame), `texts`. `general.filter` is where Power BI stores the filter: never write it by hand.

### Editing a PBIP report (visual.json)

```json
{
  "visual": {
    "visualType": "plumeDatePicker25D54D111C2643719FC6E7ACE9CFD170",
    "query": { "queryState": {
      "date":  { "projections": [ { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Date" } }, "queryRef": "Sales.Date", "nativeQueryRef": "Date" } ] },
      "value": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Revenue" } }, "queryRef": "Sales.Revenue", "nativeQueryRef": "Revenue" } ] }
    } },
    "objects": {
      "selection": [ { "properties": { "mode": { "expr": { "Literal": { "Value": "'single'" } } } } } ],
      "rules":     [ { "properties": { "mon": { "expr": { "Literal": { "Value": "false" } } }, "sat": { "expr": { "Literal": { "Value": "false" } } }, "sun": { "expr": { "Literal": { "Value": "false" } } } } } ],
      "behavior":  [ { "properties": { "defaultSelection": { "expr": { "Literal": { "Value": "'latest'" } } }, "defaultWhen": { "expr": { "Literal": { "Value": "'open'" } } } } } ],
      "calendar":  [ { "properties": { "holidays": { "expr": { "Literal": { "Value": "'uk'" } } }, "months": { "expr": { "Literal": { "Value": "2D" } } } } } ]
    }
  }
}
```

### Styles and theme JSON

Same Style card as every Plume visual (`style.preset`, `style.themeJson`, palettes, custom colors); see the theme JSON tutorial https://plumevisuals.com/ai/tutorials/en/themes-json.md. The heatmap uses the gradient palette of the style (`style.palette`), the diverging scale the diverging palette.

### Common pitfalls

- Nothing is greyed out: the Date column comes from a full Calendar table and no Value measure is set; add a measure in Value.
- The calendar shows years only, or an error: the date hierarchy or a Year column was dropped instead of the date column.
- "Latest date" picks an older day: the latest days are not selectable (rules, future dates, holidays) or have a blank Value.
- The report does not open on the latest date: `preselect.shortcut` is `none`, or `defaultWhen` is `noFilter` while a date filter was saved in the report; use `open`.
- Watermark visible: several dates, advanced rules, heatmap with a measure, custom shortcuts or a premium style, 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)

Fiscal calendars (4-4-5) and shifted fiscal years, a second comparison period (use Period Plume for year-over-year), a trend timeline under the dates (Period Plume), relative date filters that move by themselves (shortcuts send fixed dates; Period Plume sends relative filters), time-of-day selection, several independent ranges, drawing outside the visual's frame.

## Date Picker Plume: data fields

- `date` Date (column, 1 max): A date column (e.g. Calendar[Date]), not the date hierarchy
- `value` Value (data and heatmap) / Valeur (données et dégradé) (measure, 1 max): Optional measure: days where it is blank are greyed out; it also colors the calendar (heatmap)
- `tooltips` Tooltips / Infobulles (measure, several max): 
- `preselect` Preselection / Présélection (measure, 1 max): Optional measure returning the value(s) selected when the report opens, e.g. "Paris;Lyon" or "2026-01-01;2026-03-31"
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Date Picker Plume: Format pane options (139)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: true / false. Text, background, accent and data colors come from the Power BI report theme.
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorTrack` Bar track / Fond des barres: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`
- `style.fontSize` Text size / Taille du texte: number, default `12`; values: 8 to 28
- `style.density` Density / Densité: dropdown, default `normal`; values: `compact` Compact; `normal` Normal; `comfortable` Comfortable
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Header / En-tête (`header`)
- `header.show` Show / Afficher: toggle, default `true`; values: true / false
- `header.title` Text / Texte: text, default (empty). Leave empty to use the field name.
- `header.fontSize` Size / Taille: number, default `14`; values: 7 to 36
- `header.bold` Bold / Gras: toggle, default `true`; values: true / false
- `header.italic` Italic / Italique: toggle, default `false`; values: true / false
- `header.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `header.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `header.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `header.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `header.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false. A long title goes on two lines instead of being cut.
- `header.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `header.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `header.divider` = `true`
- `header.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `header.divider` = `true`
- `header.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `header.divider` = `true`
- `header.showCount` Show value / selection count / Afficher le nombre de valeurs / sélection: toggle, default `true`; values: true / false
- `header.showClear` "Clear" button / Bouton « Effacer »: toggle, default `true`; values: true / false
- `header.clearLabel` Clear button label / Libellé du bouton Effacer: text, default (empty). Visible when `header.showClear` = `true`

### Calendar / Calendrier (`calendar`)
- `calendar.display` Display as / Affichage: dropdown, default `inline`; values: `inline` Visible calendar; `popup` Compact field (calendar on click). Compact field: a one-line box showing the selection; the calendar opens on click, inside the visual's frame (make the frame taller and turn off its background so it opens over the visual below).
- `calendar.months` Number of months (0 = fit the size) / Nombre de mois (0 = selon la taille): number, default `0`; values: 0 to 12
- `calendar.weekStart` First day of the week / Premier jour de la semaine: dropdown, default `monday`; values: `monday` Monday; `sunday` Sunday; `saturday` Saturday
- `calendar.weekNumbers` Week numbers / Numéros de semaine: toggle, default `false`; values: true / false
- `calendar.weekRule` Week numbering / Numérotation des semaines: dropdown, default `iso`; values: `iso` ISO 8601 (Europe); `us` Week containing January 1 (US)
- `calendar.outsideDays` Days of adjacent months / Jours des mois voisins: toggle, default `false`; values: true / false
- `calendar.today` Highlight today / Mettre en évidence aujourd'hui: toggle, default `true`; values: true / false
- `calendar.weekends` Shade weekends / Teinter les week-ends: toggle, default `true`; values: true / false
- `calendar.holidays` Public holidays / Jours fériés: dropdown, default `none`; values: `none` None; `fr` France; `frAm` France (Alsace-Moselle); `uk` United Kingdom (England); `us` United States (federal); `be` Belgium; `ch` Switzerland (Geneva); `de` Germany (national)
- `calendar.holidayList` Extra holidays or closures / Jours fériés ou fermetures en plus: textarea, default (empty). One date (or range yyyy-mm-dd..yyyy-mm-dd) per line or separated by ;, followed by an optional label. Counted as holidays.
- `calendar.cellShape` Cell shape / Forme des cases: dropdown, default `rounded`; values: `rounded` Rounded; `square` Square; `circle` Circle
- `calendar.maxCell` Maximum cell size (px) / Taille maximale d'une case (px): number, default `44`; values: 14 to 120. Small values (14 to 24 px): compact calendar, more months in the same frame.
- `calendar.monthFormat` Month names / Nom des mois: dropdown, default `long`; values: `long` Long (October 2026); `short` Short (Oct '26)
- `calendar.jump` Quick month and year picker / Choix rapide du mois et de l'année: toggle, default `true`; values: true / false. Clicking the month name opens a grid of months and years.
- `calendar.openOn` Month shown on open / Mois affiché à l'ouverture: dropdown, default `selection`; values: `selection` The selection's (else latest date); `latest` The latest date in the data; `today` Today's

### Selection / Sélection (`selection`)
- `selection.mode` Mode: dropdown, default `range`; values: `range` Range (two clicks); `single` Single date; `week` Whole week; `month` Whole month; `multiple` Several dates ★. Range: first click = start, second click = end (Shift + click extends). Several dates: each click adds or removes a date, Shift + click adds the selectable dates in between.
- `selection.rangeFilter` A range filters / Une plage filtre: dropdown, default `between`; values: `between` Every date between start and end; `active` Only the selectable dates. Visible when `selection.mode` = `range` or `week` or `month`. With rules (e.g. Fridays only), "Only the selectable dates" filters the Fridays in the range and nothing else.
- `selection.maxDays` Maximum range length (days, 0 = no limit) / Durée maximale d'une plage (jours, 0 = sans limite): number, default `0`; values: 0 to 3660. Visible when `selection.mode` = `range`
- `selection.summary` Selection summary / Résumé de la sélection: toggle, default `true`; values: true / false
- `selection.inputs` Typed dates (From / To) / Saisie des dates au clavier (Du / Au): toggle, default `false`; values: true / false
- `selection.dateFormat` Date format / Format des dates: dropdown, default `medium`; values: `short` Short (10/06/2026); `medium` Medium (Oct 6, 2026); `long` Long (Tue, October 6, 2026)
- `selection.fromLabel` "From" label / Libellé « Du »: text, default (empty). Visible when `selection.inputs` = `true`
- `selection.toLabel` "To" label / Libellé « Au »: text, default (empty). Visible when `selection.inputs` = `true`
- `selection.emptyText` Text when nothing is selected / Texte sans sélection: text, default (empty)

### Selectable dates / Dates sélectionnables (`rules`)
- `rules.noData` Dates without data / Dates sans données: dropdown, default `disable`; values: `disable` Greyed out, not selectable; `dim` Greyed out but selectable; `normal` Like the others. A date has "no data" when it is not in the column, or when the Value measure is blank on it.
- `rules.zeroIsEmpty` Value equal to 0 = no data / Valeur égale à 0 = sans données: toggle, default `false`; values: true / false
- `rules.mon` Monday / Lundi: toggle, default `true`; values: true / false
- `rules.tue` Tuesday / Mardi: toggle, default `true`; values: true / false
- `rules.wed` Wednesday / Mercredi: toggle, default `true`; values: true / false
- `rules.thu` Thursday / Jeudi: toggle, default `true`; values: true / false
- `rules.fri` Friday / Vendredi: toggle, default `true`; values: true / false
- `rules.sat` Saturday / Samedi: toggle, default `true`; values: true / false
- `rules.sun` Sunday / Dimanche: toggle, default `true`; values: true / false
- `rules.position` Position in the period / Position dans la période: dropdown, default `any`; values: `any` Any date; `monthEnd` Last day of the month; `monthStart` First day of the month; `lastWorkday` Last working day of the month; `firstWorkday` First working day of the month; `lastDataDay` Last date with data in the month; `weekEnd` Last day of the week; `weekStart` First day of the week; `quarterEnd` Last day of the quarter; `yearEnd` Last day of the year
- `rules.excludeHolidays` Grey out public holidays / Griser les jours fériés: toggle, default `false`; values: true / false
- `rules.noFuture` Grey out future dates / Griser les dates futures: toggle, default `false`; values: true / false
- `rules.expression` Advanced rules ★ / Règles avancées ★ ★: textarea, default (empty). One rule per line: a date is selectable when it matches any line; a line starting with "-" excludes. Terms: monday…sunday, mon-fri, workday, weekend, holiday, month end, month start, last workday, first workday, week end, quarter end, year end, day 1,15,-1, last friday, 2nd tuesday, month 1,4,7,10, even week, year 2026, with data, past, future, 2026-01-01..2026-03-31; "&" to combine, "not" to negate. See the tutorial.
- `rules.inactiveStyle` Look of non-selectable dates / Aspect des dates non sélectionnables: dropdown, default `faded`; values: `faded` Faded; `struck` Faded and struck through; `hidden` Hidden (empty cell)

### Heatmap ★ / Dégradé de couleur ★ (`heatmap`)
- `heatmap.show` Show ★ / Afficher ★ ★: toggle, default `false`; values: true / false. Colors each cell by the Value measure.
- `heatmap.colors` Colors / Couleurs: dropdown, default `style`; values: `style` Gradient palette (style); `accent` From background to accent; `custom` Chosen start and end
- `heatmap.low` Low values color / Couleur des valeurs basses: color, default (empty); values: hex color. Visible when `heatmap.colors` = `custom`
- `heatmap.high` High values color / Couleur des valeurs hautes: color, default (empty); values: hex color. Visible when `heatmap.colors` = `custom`
- `heatmap.scale` Scale / Échelle: dropdown, default `linear`; values: `linear` Linear; `quantile` By rank (quantiles); `diverging` Distance from zero (diverging)
- `heatmap.reverse` Reverse / Inverser: toggle, default `false`; values: true / false
- `heatmap.intensity` Intensity (%) / Intensité (%): number, default `100`; values: 10 to 100
- `heatmap.showValues` Value in the cells / Valeur dans les cases: toggle, default `false`; values: true / false
- `heatmap.legend` Legend (min – max) / Légende (min – max): toggle, default `true`; values: true / false

### Shortcuts / Raccourcis (`presets`)
- `presets.show` Show / Afficher: toggle, default `true`; values: true / false
- `presets.latest` Latest date / Dernière date: toggle, default `true`; values: true / false
- `presets.today` Today / Aujourd'hui: toggle, default `false`; values: true / false
- `presets.yesterday` Yesterday / Hier: toggle, default `false`; values: true / false
- `presets.last7` Last 7 days / 7 derniers jours: toggle, default `true`; values: true / false
- `presets.last30` Last 30 days / 30 derniers jours: toggle, default `false`; values: true / false
- `presets.thisWeek` This week / Semaine en cours: toggle, default `false`; values: true / false
- `presets.lastWeek` Last week / Semaine dernière: toggle, default `false`; values: true / false
- `presets.thisMonth` Month to date / Mois en cours: toggle, default `true`; values: true / false
- `presets.lastMonth` Last month / Mois dernier: toggle, default `false`; values: true / false
- `presets.thisQuarter` Quarter to date / Trimestre en cours: toggle, default `false`; values: true / false
- `presets.ytd` Year to date / Cumul annuel: toggle, default `true`; values: true / false
- `presets.lastYear` Last year / Année dernière: toggle, default `false`; values: true / false
- `presets.last12m` Last 12 months / 12 mois glissants: toggle, default `false`; values: true / false
- `presets.anchor` Shortcuts reference date / Date de référence des raccourcis: dropdown, default `latest`; values: `latest` Latest date in the data; `today` Today. "Last 7 days" counts back from this date. Latest date = last selectable date with data.
- `presets.custom` Custom shortcuts ★ / Raccourcis personnalisés ★ ★: textarea, default (empty). One per line or separated by ; — "Label: start - end" (yyyy-mm-dd or dd/mm/yyyy).
- `presets.position` Position: dropdown, default `top`; values: `top` Top; `bottom` Bottom; `side` Left side

### Behavior / Comportement (`behavior`)
- `behavior.apply` Apply the filter / Appliquer le filtre: dropdown, default `instant`; values: `instant` As soon as selected; `button` With an "Apply" button

### Number format / Format des nombres (`values`)
- `values.units` Display units / Unités: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `values.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `values.prefix` Prefix / Préfixe: text, default (empty)
- `values.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)

### Preselection / Présélection (`preselect`)
- `preselect.shortcut` Shortcut (no DAX) / Raccourci (sans DAX): dropdown, default `none`; values: `none` None (measure only); `today` Today; `latest` Latest date in the data; `last7` Last 7 days; `last30` Last 30 days; `lastN` Last N days; `thisWeek` This week; `thisMonth` This month; `lastMonth` Previous month; `ytd` Year to date (YTD); `last12m` Last 12 months. Drop in "Preselection" a measure that returns a date or a range ("2026-01-01;2026-03-31", ISO dates), or pick a shortcut below (free). Measure: premium feature ★.
- `preselect.days` N (days) / N (jours): number, default `30`; values: 1 to 3660. Visible when `preselect.shortcut` = `lastN`
- `preselect.when` Apply / Appliquer: dropdown, default `session`; values: `session` Once per session; `always` Reapply on every display
- `preselect.force` Force / Forcer: toggle, default `false`; values: true / false. Replaces an existing selection: saved in the report, recalled by a bookmark or by persistent filters. Otherwise it is kept.
- `preselect.separator` Value separator / Séparateur des valeurs: text, default `;`
- `preselect.warn` Report values not found (edit mode) / Signaler les valeurs introuvables (mode édition): toggle, default `true`; values: true / false

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.transparent` Transparent background / Fond transparent: toggle, default `true`; values: true / false. The visual lets what is behind it show through (useful for a dropdown placed over another visual).
- `container.border` Border / Bordure: toggle, default `true`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `10`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Text Plume

- The free-text search slicer: type a few letters or paste a list, in one column or several, accents ignored, and the report filters.
- Slug `text-slicer` · version 1.1.0.0 · GUID (`visualType`) `plumeTextSlicer2FFF2CD495324564B38C02E87A8C23B5` · page https://plumevisuals.com/en/visuals/text-slicer

### What the visual does

Text Plume (version 1.1.0.0) is a Power BI custom slicer with a **free-text search box**: the user types (or pastes) some text and the visual filters the report with the values of the **Fields to search** columns (`fields`, 1 to 6 columns, same table or related tables) that match. Text, number, date and boolean columns are accepted; numbers and dates are compared with their displayed label. Up to 100,000 rows are loaded (`fetchMoreData`, 30,000 rows per data window).

**New in version 1.1.0.0 (30/10/2026):** Shared slicer cards (Preselection: the measure becomes the searched text); **"Also search in"** field (up to 2 columns) and search that treats dashes, spaces and apostrophes as equal.

**Matching** (`search.match`): `contains` (default), `starts`, `ends` ("ends with", done by the visual: there is no such Power BI operator), `exact`, `words` (start of any word of the value) and `regex` ★. Case is ignored unless `search.caseSensitive`; accents are ignored by default (`search.ignoreAccents`: "Rosch" finds "Rösch", "peri" finds "Périgueux"). `search.minChars` (1 by default) shows "Type at least n characters" until enough letters are typed (Enter or the Filter button override it).

**Search syntax** in the box:
- Several **terms** separated by `input.separator`: `auto` (default: `;`, line break, tab or `|`; in regex mode `|` is not a separator), `semicolon`, `newline`, `comma` (comma or line break), `none` (the whole text is one term). A term in double quotes (`"a; b"`) is kept whole and taken literally (no wildcards); `""` inside quotes is a literal quote. Duplicates are removed. Terms are combined with `input.combine` = `any` (OR, default) or `all` (AND). Several terms are ★.
- **Wildcards** ★ (`search.wildcards`, on by default): `*` = any characters, `?` = one character (`FR-*-2026`, `Dup?nt`).
- **Exclusion** ★ (`search.exclude`, on by default): a term starting with `-` or `!` removes the values it matches (`Paris; -North`, `-web` alone = everything except Web).

**Input** (card `input`): one-line box (`input.height`, 24 to 64 px, 34 by default) with a magnifier, a clear (×) button (`input.showClear`) and a placeholder (`input.placeholder`; empty = "Search in <field>…" / "Search all fields…"); or **several lines** ★ (`input.multiline`, `input.rows` visible lines, 4 by default) to paste a list, applied with Ctrl + Enter or the Filter button. Pasting a column copied from Excel into the one-line box turns line breaks into `; `. `input.applyOn` = `typing` (default, `input.delay` 400 ms after the last key) or `enter` (Enter or the "Filter" button, `input.button`; "Press Enter to filter" under the box, button highlighted while the text is not applied).

**Several fields** (card `fields`): `fields.mode` = `pick` (default: **chips** under the box pick the column searched, ← → on the keyboard; the typed text is applied again when the chip changes) or `all` ★ (no chips: a row is kept when **any** column matches; with several terms, each term may be found in a different column; exclusions apply to every column). In `pick` mode, the "All fields" chip ★ (`fields.allChip`, on by default; label `fields.allLabel`) does the same search across all columns; `fields.start` = chip selected on open (1 = first column, default; 0 = All fields).

**Suggestions** (card `suggest`): a list under the box for the term being typed (values that start with it first), matching part highlighted (`suggest.highlight`), column name shown when searching all fields, `suggest.max` (8 by default). ↓ ↑ Enter or click: the value replaces the term (quoted if needed) and filters. Esc closes the list.

**Results** (card `results`): information line under the box (`results.info`): "12 value(s) found · 3 terms · 2 not found: X, Y" (full list in the tooltip), warnings ("Search limited to the first N rows loaded", "Invalid regular expression": box in red, nothing sent). Header (card `header`): title (field names joined with " · " when empty), count "12 values" (or "n rows" across all fields) then "3 of 12" once filtered (`header.showCount`), "Clear" button (`header.showClear`). `results.noMatch` = `empty` (default: the report shows nothing, like Power BI) or `ignore` (no filter, the line says so). `results.blankLabel` = label of blank values ("(Blank)" when empty).

### Free vs premium (★)

- Every feature works without a key and nothing is ever blocked. Free features never show a watermark, and the visual inserted with its default settings never shows one. The watermark appears only when a premium feature is **actually used**.
- Shared Style card (the same in every Plume visual): the styles `none`, `minimal` and `blackWhite`, "Follow report theme" and all custom colors are **free**; every other `style.preset`, the extra palettes and `style.themeJson` are **premium**.
- Premium features of Text Plume: **several terms** (two terms or more in the text, including a pasted list; `input.multiline` itself only triggers the watermark with several terms), **wildcards** (a term that contains `*` or `?` while `search.wildcards` is on), **exclusion** (a `-term` / `!term` while `search.exclude` is on), **regular expressions** (`search.match` = `regex` with some text typed), **search all fields** (`fields.mode` = `all`, or the "All fields" chip selected, with 2 fields or more), **3 to 6 columns** in Fields to search. One term with `contains`, `starts`, `ends`, `exact` or `words`, on 1 or 2 columns with chips, is free.
- Without a valid key, a premium feature in use shows **"Plume Visuals · Premium preview"** (French « Plume Visuals · Aperçu premium »): a badge with an "Unlock →" link in edit mode, a tiled pattern across the visual in reading mode (the box stays usable), until a key is pasted in **Format › Plume Studio License › License key** (`license.key`), the first card of the Format pane. The landing page never shows the watermark.
- Accepted keys: `PLUM1.` keys covering `text-slicer` or the whole catalog, checked offline (Ed25519). Licenses last one year (one-time payment, no automatic renewal), per slicer: 19 € personal, 49 € SME, 149 € enterprise per year, or the full catalog pack.

### Expected data shape

| Fields to search (`fields`, 1 to 6 columns) | Dynamic format (`format`, optional) |
|---|---|
| `Orders[Order]` (FR-1042-2026…), or `Orders[Customer]` then `Orders[City]` for chips | measures named `card.setting` |

- **Fields to search** (`fields`, grouping, required): real columns, not measures. One row per combination of the columns is enough (the visual groups identical values); one row per order works too.
- **Dynamic format** (`format`, measures): measures named `card.setting` (e.g. `input.placeholder`, `header.title`) drive Format pane options with DAX.
- No measure is needed and there is **no Tooltips well**.

### Filter sent to the report

- **One column, at most 2 terms, `contains` / `starts` / `exact`, wildcards only at the start or end of a term, case ignored** → an `AdvancedFilter` (`Contains`, `StartsWith`, `Is`, and `DoesNotContain`, `DoesNotStartWith`, `IsNot` for exclusions; `And` / `Or`). No row limit: the condition holds beyond the loaded rows. Power BI compares ignoring case but **respecting accents**, so with `results.method` = `auto` (default) the condition is sent only when it gives exactly the same values as the visual's accent-insensitive search; otherwise the list below.
- **Every other case on one column** (accents that change the result, wildcards in the middle, `?`, `ends`, `words`, `regex`, more than 2 terms, number / date / boolean column, `search.caseSensitive`) → a `BasicFilter` `In` with the matching values found in the loaded rows ("Search limited to the first N rows loaded" when the data is truncated).
- **All fields at once** → a `TupleFilter` `In` with the matching combinations of the columns (OR across columns), limited to the loaded rows.
- **Nothing matches** → the condition itself, or a filter that keeps nothing (`x = v AND x ≠ v`); `results.noMatch` = `ignore` sends no filter.
- `results.method` = `condition` forces the condition whenever it is possible (even if Power BI then finds slightly fewer values because of accents); `values` always sends the list.
- **Restoring**: the typed text, the selected chip and a signature of the filter are saved in the hidden `state` object (`text`, `field`, `sig`, properties with `filterState`, so **bookmarks keep them**). When the signature matches, the text comes back exactly as typed; otherwise it is rebuilt from the filter (condition → terms such as `lyon; -x`; list → values joined with `; `, compared literally until the next edit; tuples → "Restored filter (n values)"). A bookmark without a filter empties the box. A filter of the visual it cannot read is removed once.
- **Sync slicers**: `supportsSynchronizingFilterState`. Power BI turns off slicer sync for a visual with more than one field, so with 2 columns or more the slicer is not synced.

### Interactions and accessibility

- The box keeps the focus and the caret while the report updates. Keyboard: ↓ ↑ in the suggestions, Enter picks a suggestion or applies the text (Ctrl + Enter on several lines), Esc closes the suggestions, ← → move between chips.
- ARIA combobox (`aria-expanded`, `aria-activedescendant`), chips as a `radiogroup`, screen-reader announcements ("n result(s)", "Search cleared"). High contrast supported.
- Cross-filtering: other slicers and visuals filter the values offered (suggestions, counts); the visual is not filtered by its own filter. No highlighting.
- Power BI context menu. Read-only (input disabled) on dashboard tiles. FR/EN (`texts.language`).

### Format pane

Card order: `license` (always first), `style`, `header`, `search`, `input`, `fields`, `suggest`, `results`, `container` (frame), `texts`. `general.filter` is where Power BI stores the filter and `state` holds the typed text: never write them by hand.

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names (several projections in `fields` for chips), `objects` keys are the option IDs.

```json
{
  "visual": {
    "visualType": "plumeTextSlicer2FFF2CD495324564B38C02E87A8C23B5",
    "query": { "queryState": {
      "fields": { "projections": [
        { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Orders" } }, "Property": "Customer" } }, "queryRef": "Orders.Customer", "nativeQueryRef": "Customer" },
        { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Orders" } }, "Property": "City" } }, "queryRef": "Orders.City", "nativeQueryRef": "City" } ] }
    } },
    "objects": {
      "search":  [ { "properties": { "match": { "expr": { "Literal": { "Value": "'starts'" } } } } } ],
      "input":   [ { "properties": { "applyOn": { "expr": { "Literal": { "Value": "'enter'" } } },
                                     "placeholder": { "expr": { "Literal": { "Value": "'Customer or city…'" } } } } } ],
      "fields":  [ { "properties": { "allChip": { "expr": { "Literal": { "Value": "false" } } } } } ],
      "suggest": [ { "properties": { "max": { "expr": { "Literal": { "Value": "12D" } } } } } ]
    }
  }
}
```

### Styles and theme JSON

Same Style card as every Plume visual (`style.preset`, `style.themeJson`, palettes, custom colors: background, text, secondary text, lines, accent); see the theme JSON tutorial https://plumevisuals.com/ai/tutorials/en/themes-json.md. The accent colors the box border when focused, the Filter button while the text is not applied, the outline of the suggestion selected with the keyboard and the highlight of the matching part.

### Common pitfalls

- The report is empty and the line reads "No value matches": the selected chip is not the column that holds the text, or a typo; `results.noMatch` = `ignore` keeps the report whole.
- Nothing happens while typing: `input.applyOn` = `enter`; press Enter or click Filter.
- "Rosch" does not find "Rösch": `search.ignoreAccents` was turned off.
- "Search limited to the first N rows loaded": the search goes through the list of values on a model with more than 100,000 rows; a single-term `contains` / `starts` / `exact` search on one text column has no limit.
- Sync slicers has no effect: the visual has 2 columns or more (Power BI limitation).
- Searching for a literal `*` or `?`, or a value containing `;`: put the term in double quotes.
- Watermark visible: several terms, a wildcard, an exclusion, a regular expression, all fields at once, 3 columns or more, or a premium style, 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)

Numeric or date operators in the box (`>600`, `4-5`, `2025`: use Range Plume, Period Plume or Date Picker Plume), a field prefix in the text (`city:paris`), search history, a button that turns the whole list into an exclusion, a preselected text on open, ticking values in a list (use Basic Slicer Plume or Bar Slicer Plume), a Tooltips well, drawing outside the visual's frame, cross-report filtering.

## Text Plume: data fields

- `fields` Fields to search / Champs à rechercher (column, 6 max): One or several columns (same table or related tables). With several columns, choose the column to search under the box, or search all of them at once.
- `searchAlso` Also search in / Rechercher aussi dans (column, 2 max): Optional columns searched too (e.g. postal code); the filter still applies to the field (e.g. city)
- `preselect` Preselection / Présélection (measure, 1 max): Optional measure returning the value(s) selected when the report opens, e.g. "Paris;Lyon" or "2026-01-01;2026-03-31"
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Text Plume: Format pane options (96)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: true / false. Text, background, accent and data colors come from the Power BI report theme.
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorTrack` Bar track / Fond des barres: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`
- `style.fontSize` Text size / Taille du texte: number, default `12`; values: 8 to 28
- `style.density` Density / Densité: dropdown, default `normal`; values: `compact` Compact; `normal` Normal; `comfortable` Comfortable
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Header / En-tête (`header`)
- `header.show` Show / Afficher: toggle, default `true`; values: true / false
- `header.title` Text / Texte: text, default (empty). Leave empty to use the field name.
- `header.fontSize` Size / Taille: number, default `14`; values: 7 to 36
- `header.bold` Bold / Gras: toggle, default `true`; values: true / false
- `header.italic` Italic / Italique: toggle, default `false`; values: true / false
- `header.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `header.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `header.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `header.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `header.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false. A long title goes on two lines instead of being cut.
- `header.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `header.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `header.divider` = `true`
- `header.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `header.divider` = `true`
- `header.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `header.divider` = `true`
- `header.showCount` Show value / selection count / Afficher le nombre de valeurs / sélection: toggle, default `true`; values: true / false
- `header.showClear` "Clear" button / Bouton « Effacer »: toggle, default `true`; values: true / false
- `header.clearLabel` Clear button label / Libellé du bouton Effacer: text, default (empty). Visible when `header.showClear` = `true`

### Search / Recherche (`search`)
- `search.match` Matching / Correspondance: dropdown, default `contains`; values: `contains` Contains; `starts` Starts with; `ends` Ends with; `exact` Is exactly; `words` Word start; `regex` Regular expression ★. How each term is compared with the values. Case is ignored, like everywhere in Power BI.
- `search.wildcards` Wildcards * and ? ★ / Jokers * et ? ★ ★: toggle, default `true`; values: true / false. * = any characters, ? = one character (e.g. FR-*-2026, Dup?nt). Put a term in "quotes" to search a literal * or ?.
- `search.ignoreAccents` Ignore accents (é = e) / Ignorer les accents (é = e): toggle, default `true`; values: true / false
- `search.loose` Hyphens, spaces and apostrophes alike / Tirets, espaces et apostrophes équivalents: toggle, default `true`; values: true / false. "Saint Emilion" finds "Saint-Émilion", "l'Isle" finds "l’Isle". The filter is then sent as a list of values when a Power BI condition would not give the same result.
- `search.caseSensitive` Match case / Respecter la casse: toggle, default `false`; values: true / false. Distinguishes "Paris" from "PARIS". The filter is then always sent as a list of values.
- `search.exclude` Exclude with "-" or "!" (-test, !test) ★ / Exclure avec « - » ou « ! » (-test, !test) ★ ★: toggle, default `true`; values: true / false. A term starting with - or ! removes the values that match it (e.g. Paris; -Nord; !Sud).
- `search.minChars` Minimum characters / Caractères minimum: number, default `1`; values: 1 to 10

### Input / Saisie (`input`)
- `input.placeholder` Placeholder / Texte indicatif: text, default (empty). Leave empty for "Search in <field>…".
- `input.multiline` Multiple lines (paste a list) ★ / Plusieurs lignes (coller une liste) ★ ★: toggle, default `false`; values: true / false. A text box to paste or type a list: one value per line or separated by ; (a column copied from Excel works).
- `input.rows` Visible lines / Lignes visibles: number, default `4`; values: 2 to 20. Visible when `input.multiline` = `true`
- `input.separator` Term separator / Séparateur des termes: dropdown, default `auto`; values: `auto` ; or line break; `semicolon` Semicolon (;); `newline` Line break; `comma` Comma (,) or line break; `none` None (whole text). Several terms = several searches (a list ★). A term in "quotes" keeps its separators.
- `input.combine` Several terms / Plusieurs termes: dropdown, default `any`; values: `any` Any of them (OR); `all` All of them (AND)
- `input.applyOn` Filter / Filtrer: dropdown, default `typing`; values: `typing` As you type; `enter` With Enter or the button. With several lines, Ctrl + Enter filters.
- `input.delay` Delay after typing (ms) / Délai après la frappe (ms): number, default `400`; values: 0 to 3000. Visible when `input.applyOn` = `typing`
- `input.button` "Filter" button / Bouton « Filtrer »: toggle, default `true`; values: true / false. Shown when filtering with Enter, or with several lines.
- `input.showClear` Clear (×) button / Croix d'effacement: toggle, default `true`; values: true / false
- `input.height` Box height (px) / Hauteur de la zone (px): number, default `34`; values: 24 to 64. Visible when `input.multiline` = `false`

### Fields / Champs (`fields`)
- `fields.mode` With several fields / Avec plusieurs champs: dropdown, default `pick`; values: `pick` Pick the field (chips under the box); `all` Search all fields ★. Up to 2 fields free, 3 to 6 fields ★. Searching all fields at once keeps the rows where any field matches.
- `fields.allChip` "All fields" chip ★ / Puce « Tous les champs » ★ ★: toggle, default `true`; values: true / false. Visible when `fields.mode` = `pick`
- `fields.allLabel` "All fields" label / Libellé « Tous les champs »: text, default (empty). Visible when `fields.mode` = `pick`
- `fields.start` Field picked on open (0 = all) / Champ choisi à l'ouverture (0 = tous): number, default `1`; values: 0 to 6. Visible when `fields.mode` = `pick`
- `fields.alsoShow` "Also search in" value in suggestions / Valeur du champ « Rechercher aussi dans » dans les suggestions: toggle, default `true`; values: true / false. Drop for example the postal code in "Also search in": typing 33 finds the cities of Gironde, and the filter applies to the city.

### Suggestions (`suggest`)
- `suggest.show` Show / Afficher: toggle, default `true`; values: true / false
- `suggest.max` Maximum count / Nombre maximum: number, default `8`; values: 1 to 30
- `suggest.highlight` Highlight matches / Surligner le texte trouvé: toggle, default `true`; values: true / false

### Results / Résultats (`results`)
- `results.info` Information line / Ligne d'information: toggle, default `true`; values: true / false. Under the box: number of values found, terms not found, warnings.
- `results.noMatch` When nothing matches / Si rien ne correspond: dropdown, default `empty`; values: `empty` Show nothing (like Power BI); `ignore` Do not filter
- `results.method` Filter sent / Filtre envoyé: dropdown, default `auto`; values: `auto` Automatic; `condition` Condition (contains, starts with…); `values` List of matching values. Automatic: a Power BI condition when it gives exactly the same result (no row limit), otherwise the list of matching values.
- `results.blankLabel` Blank label / Libellé des vides: text, default (empty)

### Preselection / Présélection (`preselect`)
- `preselect.when` Apply / Appliquer: dropdown, default `session`; values: `session` Once per session; `always` Reapply on every display. Drop in "Preselection" a measure that returns a value or a list ("Paris;Lyon"): the slicer selects it when the report opens. Premium feature ★.
- `preselect.force` Force / Forcer: toggle, default `false`; values: true / false. Replaces an existing selection: saved in the report, recalled by a bookmark or by persistent filters. Otherwise it is kept.
- `preselect.separator` Value separator / Séparateur des valeurs: text, default `;`
- `preselect.warn` Report values not found (edit mode) / Signaler les valeurs introuvables (mode édition): toggle, default `true`; values: true / false

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.transparent` Transparent background / Fond transparent: toggle, default `false`; values: true / false. The visual lets what is behind it show through (useful for a dropdown placed over another visual).
- `container.border` Border / Bordure: toggle, default `true`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `10`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Table Plume

- The Power BI table, redesigned: sort and resize with the mouse, search, frozen first column, bars, icons and pills per column.
- Slug `table` · version 1.6.0.0 · GUID (`visualType`) `plumeTable9B3E6C1F4A8D4E2B9C7F05A3D8E1B6C2` · page https://plumevisuals.com/en/visuals/table

### What the visual does

Table Plume is a Power BI custom visual that replaces the native table with a grid formatted column by column. Columns and measures are dropped in one well and shown in that order. Users click a header to sort (numbers descending first, text A → Z, then the reverse, then the model order; natural sort, so "Lot 2" before "Lot 10"), drag a header edge to resize (double-click = automatic width), and search the whole table (accent-insensitive). The first column and the headers stay frozen while scrolling, and a total row stays visible at the bottom (or at the top). Each column has its own alignment, units, decimals, prefix, suffix, colors, width and total, plus premium conditional formatting: data bars, background or text color scales, ▲ ● ▼ icons and colored pills. Web URL columns become clickable links (opened by Power BI). Beyond 300 rows only visible rows are drawn. Since version 1.2.0.0, three premium features: **angled column headers** (-90° to 90°, like Excel's text orientation), **collapsible column groups** (columns given the same group name share a header with a + / − button) and **row groups** (title rows for the values of the first 1 to 5 columns, detail rows indented below). Since version 1.3.0.0, premium **auto-scroll**: rows that do not fit scroll by themselves (for a report page tooltip or a wall display). Since version 1.5.0.0, premium **sparklines**: a field dropped in the optional **Sparkline axis** well (a date or a number: Month, Date, Year) turns each measure into a small line or column chart per row, next to its value or alone; column groups are separated by vertical lines. The visual makes no network request.

**New in version 1.6.0.0 (30/10/2026):** Free native-parity additions: new **Cell elements** card (background and font color scales or rules, icons, web URLs, data bars per column), **base64 images** (also split into chunks), Power BI **tooltips** on cells (Tooltips field, report page tooltips), default column width, row height, line thickness; column header settings moved to the **Column headers** card (`header.*` → `columnHeaders.*`).

### 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 (`style.customColors` and the colors under it) are **free**; every other `style.preset`, the other gradient palettes (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium** (watermark without a key). See "Styles and theme JSON" below.
- Using a premium feature without a valid key shows **"Plume Visuals · Premium preview"** (French: « Plume Visuals · Aperçu premium ») in the footer of the visual, with an "Unlock →" link to the pricing page. It disappears once a key is pasted in **Format › Plume Studio License › License key** (`license.key`; French: « Licence Plume Studio › Clé de licence »), the **first card** of the Format pane.
- Premium features of Table Plume:
  - `columnFormat.cf` = `dataBar` ("Data bars ★"), `colorScale` ("Background color scale ★"), `textScale` ("Text color scale ★"), `icons` ("Icons (▲ ● ▼) ★") or `pill` ("Colored pill ★"), for all columns or for any single column. `none` and `negative` ("Colored negatives") are free;
  - `columnHeaders.rotation` other than 0 ("Text angle (°) ★", angled headers), `colGroups.show` ("Collapsible groups ★"), `rowGroups.levels` other than 0 ("Group by the first columns ★") and `autoScroll.show` ("Auto-scroll ★"), all off by default;
  - sparklines: a field in **Sparkline axis** with at least one numeric measure whose `columnFormat.spark` is `line` ("Line ★", the default) or `bar` ("Columns ★"); `spark` = `none` shows the value only and stays free;
- In the Format pane, every premium option and premium list value has " ★" appended to its label and carries the description "Premium feature: usable for free with a « Premium preview » watermark…". The generated tables below star the same options.
- Accepted keys: only keys starting with `PLUM1.` shown in the buyer's account on plumevisuals.com. They are checked offline (Ed25519 signature) and must cover `table` 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". `license.showOwner` displays "Licensed to <holder>".
- Licenses last one year (one-time payment, no automatic renewal, key accepted for 30 more days, reminders 30 and 7 days before the end), for this visual: 39 € personal, 99 € SME, 299 € enterprise per year, or the catalog packs (199 € / 399 € / 1,199 € per year; tiers by number of users, designers and viewers included: personal 1–10, SME 11–200, enterprise more than 200). Renewing gives a new key to paste instead of the old one.
- Status: Available. Version 1.5.1.0 is the one delivered: download on plumevisuals.com (`.pbiviz` file) and AppSource (published, Microsoft certification passed, live since 18/10/2026). Version 1.5.2.0 (fix for angled headers crossing the column group lines, 13/10/2026) is in the code but not delivered yet. The License card starts with a read-only line "Get a license: plumevisuals.com" (`license.buy`, never read by the visual).

### Expected data shape

A **table** data view: one row per distinct combination of the grouping columns, with the measures evaluated for that row (exactly like the native table).

| Columns (`columns`): Product | Category | Revenue | Growth 2025 | Margin rate |
|---|---|---|---|---|
| Arc lamp | Lighting | 412 300 | +6.2% | 52.1% |
| Linen sofa | Furniture | 388 950 | −3.4% | 33.8% |

- **Columns** (`columns`, label "Columns" / « Colonnes », columns and measures, any number, required): display order = well order. Numbers are right-aligned and use the field's format string (dates use theirs too). A column whose data category is **Web URL** is rendered as a link.
- **Sparkline axis** (`sparkAxis`, « Axe des mini-graphiques », one grouping field, optional, premium when sparklines are shown): a date or a number (Month, Date, Year). See "Sparklines" below.
- **Dynamic format** (`format`, « Format dynamique », measures, optional): formatting measures named `card.setting` (see below). They never become columns.
- Volume: 30,000 rows per data window; more are fetched automatically up to 100,000 rows. Virtual scrolling beyond 300 rows.
- Totals are computed per column: `columnFormat.total` = `auto` uses the total provided by Power BI when there is one, otherwise the sum of the displayed measure values, and **nothing for columns whose format contains %**. `sum`, `avg`, `min`, `max`, `count` are computed by the visual on the displayed rows (the rows matching the search when a search is active); `none` hides it.

### DAX recipes

```dax
Revenue = SUM ( Sales[Amount] )
Gross margin = SUM ( Sales[Margin] )
Margin rate = DIVIDE ( [Gross margin], [Revenue] )            // format as Percentage
Orders = COUNTROWS ( Sales )
Average basket = DIVIDE ( [Revenue], [Orders] )                // set its Total to none
Growth 2025 =
DIVIDE ( CALCULATE ( [Revenue], Sales[Year] = "2025" ), CALCULATE ( [Revenue], Sales[Year] = "2024" ) ) - 1
```

Give ratios a percentage format string so the automatic total skips them, or set `columnFormat.total` explicitly for that column.

### Groups and angled headers ★ (since 1.2.0.0)

- **Angled headers** (`columnHeaders.rotation`, -90 to 90, 0 = unchanged): 45 slants headers upward, 90 is vertical (read bottom to top), negative angles slant downward. With `columnHeaders.wrap`, a slanted header continues on the next line once it reaches `columnHeaders.rotLength` px (balanced lines, breaks after a space, "-" or "/", 4 lines at most then "…"); without it, one line cut by "…". Each column only needs the width of its header's foot; texts overflow above the neighboring columns without being cut. `columnHeaders.rotFirst` also slants the first column. Sorting, mouse resizing and the frozen header row keep working.
- **Collapsible column groups**: turn on `colGroups.show`, then give columns a group name in **Column formatting › Group** (`columnFormat.group`, per column; "›" for a subgroup: `Sales › 2025`). Neighboring columns with the same name share a group header with a + / − button. `columnFormat.groupKeep` keeps a column visible when its group is collapsed (for example a total); a collapsed group with no kept column becomes one narrow collapsed column named after the group. `colGroups.startCollapsed` collapses every group at start; `colGroups.remember` saves the state in the report in edit mode (hidden `state.colGroups`), kept in memory in reading mode. Since 1.5.0.0: `colGroups.separators` (on by default) draws a vertical line between groups (lighter between subgroups) and a collapsed group that keeps columns shows "+N" (hidden columns) next to its name.
- **Row groups**: `rowGroups.levels` = 1 to 5 groups the rows by the first 1 to 5 columns: one title row per value (the value alone across the full width, a rule to the end), sub-groups for the next columns, detail rows indented below. The grouping columns are no longer shown as columns; the first remaining column header carries their names ("Quarter › Product"). Options: `indent`, `icons` (+ / −), `startCollapsed`, `remember` (`state.rowGroups`), `count` (row count in the title), `rule`, `bold`, `shade`, `background`, `color`. Groups follow the model order, sorting applies inside each group, a search opens the groups of the matching rows, clicking a title selects all its rows (cross-filter), double-click or → / ← expands or collapses, and the toolbar gets Expand all / Collapse all. There are no subtotals per row group (use Matrix Plume): the total row covers all rows.

### Sparklines ★ (since 1.5.0.0)

- Drop a date or a number in **Sparkline axis** (`sparkAxis`, one field). Power BI then sends one row per combination of the grouping columns **and** axis point; Table Plume merges the rows of each item (same values in the non-measure columns) and keeps, for each measure, its series along the axis. Dates and numbers are sorted ascending; text axis values keep the received order (prefer a date or a month number).
- Per measure, in **Column formatting** (shown only with an axis, on measures): `spark` = `line` (default, "Line ★"), `bar` ("Columns ★") or `none` ("None (value only)"); `sparkValue` (default on; off = the sparkline alone across the column); `sparkPos` = `left` (sparkline left of the value, default) or `right`; `agg` = the value shown for the row: `auto` (default: **sum** when the sum of all points equals the total provided by Power BI, otherwise the **last value**, which is always exact; never a sum of rates), `sum`, `avg`, `last`, `first`, `min`, `max`. The header tooltip says which one is used ("Revenue: sum over Month"). Without a Power BI total, `auto` columns that are not sums show no total in the total row.
- Card **Sparklines** (`sparklines`, shown with an axis): `width` (minimum width, px, default 90), `color` (empty = style accent), `lineWidth`, `area` (area under the line), `last` (highlight the last value: dot or full-opacity column), `minMax` (minimum and maximum points in the unfavorable / favorable colors), `negColor` (negative columns), `sameScale` (same vertical scale for every row; off = each sparkline uses its full height), `zero` (line axis from zero).
- Hovering a sparkline shows each point ("Jan 2025: €10,000"; a summary beyond 36 points). Lines break at empty points. Clicking a row selects all its points (cross-filters the item). Row groups, column groups, sorting (by the row value), search, totals and auto-scroll work as without an axis.
- Typical use: products with 12 or 36 months of revenue as lines, orders as columns, margin rate with its last month.

### Auto-scroll ★ (since 1.3.0.0)

- Card **Auto-scroll** (`autoScroll`): `show` (off by default, premium), `speed` (rows per second, 0.1 to 20, default 1), `loop` (back to the top after the bottom, default on; off = stops at the bottom), `pause` (seconds at the top and at the bottom, default 2), `hoverPause` (pause while the mouse is over the visual, default on).
- It only moves when the rows do not fit (vertical scrollbar); nothing moves otherwise. Any user action (wheel, click, keyboard, touch, dragging the scrollbar) pauses it for about 4 seconds, then it resumes from there. It works with virtual scrolling, row groups and the frozen header and total row.
- Typical use: a Table Plume on a **report page tooltip** page, so a long list scrolls while the tooltip is shown; or a wall display. Reading mode and edit mode alike.

### Interactions with the report

- Click a row = select it (cross-filters the other visuals), Ctrl + click = add to the selection, Esc clears. Context menu on rows.
- Keyboard: ↑ ↓, Page Up / Page Down, Home / End to move, Enter to select, Enter on a focused header to sort. ARIA grid roles; high contrast uses the host colors and underlines the selection.
- Search (`toolbar.search`) and sorting only change what the table displays; they never filter the report. The row count reads "12 rows" or "3 of 12 rows" while searching.
- Other visuals cross-filter Table Plume (it does not support highlighting). Landing page when no field is set.
- Widths dragged with the mouse are saved in the report in edit mode (hidden object `state.widths`).

### Dynamic formats

- **No fx button**: Power BI does not offer conditional formatting of Format pane options to table / matrix visuals (Table Plume, Matrix Plume, KPI Plume). Everything goes through the **Dynamic format** well (role `format`, label « Format dynamique »).
- Drop a measure in it and rename it for this visual (right-click › Rename for this visual) `card.setting`, for example `grid.density`, `title.text`, `totals.show`, `style.preset`. Case, accents and the separator are ignored (`Grid Density` = `grid.density`). It wins over the fixed setting, the style and the JSON theme.
- For the dynamic card **Column formatting**, only the "All columns" level is driven (`columnFormat.cf`, `columnFormat.units`…); a value set in the pane for one specific column stays first.
- The measure is evaluated for each row: the visual keeps the common value, otherwise the first row's. Wrap it in `CALCULATE ( …, ALLSELECTED () )` to get one value for the whole visual.
- Examples: `IF ( COUNTROWS ( ALLSELECTED ( Sales[Product] ) ) > 12, "compact", "normal" )` renamed `grid.density`; `"Products · " & FORMAT ( CALCULATE ( [Revenue], ALLSELECTED () ), "#,0" )` renamed `title.text`.
- A measure in this well that is never blank can bring back empty rows when the table has no other measure; rows where all the table's measures are blank are removed otherwise.
- Driving a setting with DAX is free; a ★ value set by DAX still shows the watermark without a key.

### Format pane: how to read the tables below

- Each option has an ID `card.option` (for example `grid.density`). The card is the capabilities.json **object name**, the option is the **property name**.
- Card order: `license` (always first), `style` (Style card shared by every Plume visual: `preset`, `themeJson`, `followTheme`, `reverse`, then custom colors with `palette`, font, background, radius, animations), `columnFormat` (dynamic card "Column formatting": a list at the top, "Apply settings to", picks "All columns" or one column), then `grid`, `columnHeaders` (column headers), `cells` (values), `firstCol`, `totals`, `toolbar`, then `title`, `source`, `container` and `texts`. Format pane in version 1.6.0.0 (30/10/2026), top to bottom: `license`, `style`, `columnFormat`, `cellElements`, `grid`, `cells`, `columnHeaders`, `totals`, `rowGroups`, `firstCol`, `colGroups`, `sparklines`, `images`, `toolbar`, `autoScroll`, `tooltip`, `title`, `source`, `container`, `texts`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- In `columnFormat`, per-column options appear only when relevant: units, decimals, prefix, suffix, conditional formatting and total for numeric columns; `barColor` / `barOnly` for data bars; `scale` for color scales and pills (`lowColor` / `highColor` when `scale` = `custom`); `iconMode` / `posColor` for icons.
- Labels follow the language of Power BI Desktop; `texts.language` can force French or English inside the visual.
- "Visible when" means the option only appears when another option has one of the listed values.

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. Literal syntax: booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes, colors wrapped in `solid.color`. Per-column settings are entries of `columnFormat` with a `selector` on the field's `queryRef`; an entry without selector is the "All columns" level. A Dynamic format measure is renamed with `displayName` in its projection.

```json
{
  "visualType": "plumeTable9B3E6C1F4A8D4E2B9C7F05A3D8E1B6C2",
  "query": {
    "queryState": {
      "columns": { "projections": [
        { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Product" } }, "queryRef": "Sales.Product", "nativeQueryRef": "Product" },
        { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Revenue" } }, "queryRef": "Sales.Revenue", "nativeQueryRef": "Revenue" },
        { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Growth 2025" } }, "queryRef": "Sales.Growth 2025", "nativeQueryRef": "Growth 2025" },
        { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Average basket" } }, "queryRef": "Sales.Average basket", "nativeQueryRef": "Average basket" } ] },
      "format": { "projections": [
        { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Table density" } }, "queryRef": "Sales.Table density", "nativeQueryRef": "Table density", "displayName": "grid.density" } ] }
    }
  },
  "objects": {
    "grid":    [ { "properties": { "banding": { "expr": { "Literal": { "Value": "true" } } } } } ],
    "totals":  [ { "properties": { "show": { "expr": { "Literal": { "Value": "true" } } },
                                   "position": { "expr": { "Literal": { "Value": "'bottom'" } } } } } ],
    "toolbar": [ { "properties": { "show": { "expr": { "Literal": { "Value": "true" } } } } } ],
    "header":  [ { "properties": { "fontSize": { "expr": { "Literal": { "Value": "11D" } } } } } ],
    "columnFormat": [
      { "properties": { "cf": { "expr": { "Literal": { "Value": "'dataBar'" } } },
                        "barColor": { "solid": { "color": { "expr": { "Literal": { "Value": "'#b8462a'" } } } } } },
        "selector": { "metadata": "Sales.Revenue" } },
      { "properties": { "cf": { "expr": { "Literal": { "Value": "'negative'" } } } }, "selector": { "metadata": "Sales.Growth 2025" } },
      { "properties": { "total": { "expr": { "Literal": { "Value": "'none'" } } } }, "selector": { "metadata": "Sales.Average basket" } } ],
    "license": [ { "properties": { "key": { "expr": { "Literal": { "Value": "'PLUM1.…'" } } } } } ]
  }
}
```

The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from the `.pbiviz` file). Do not write the hidden `state.widths` property by hand.

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`.
- `style.themeJson` (Format › Style › Theme JSON ★) takes a JSON theme as plain text. Format v2: an object with an optional `extends` (a style ID above) and optional groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`; the v1 flat format (`style`, `palette`, `accent`, `background`…) is still read. Every field is optional. Colors are `#RRGGBB` (`#RGB` and `#RRGGBBAA` accepted, opacity ignored). Unknown fields and values outside the allowed lists are ignored, out-of-range numbers are clamped. Invalid JSON shows "Invalid theme JSON: ignored" in edit mode and the visual keeps its look.
- Full field list with allowed values, examples and troubleshooting: tutorial https://plumevisuals.com/ai/tutorials/en/themes-json.md (French: https://plumevisuals.com/ai/tutorials/fr/themes-json.md). The same JSON can be pasted in every Plume visual of a page.
- Priority (the last one wins): visual defaults → `style.preset` → `style.themeJson` → `style.palette` (if not "Style or theme palette") → `style.followTheme` → custom colors → options set by hand in the other cards → DAX formats (fx button, "Dynamic format" field) → Windows high contrast.

### Common pitfalls

- Empty total for a column: its format contains % (automatic total skipped). Set `columnFormat.total` for that column if a calculation over the displayed rows is acceptable.
- Meaningless total (an average basket summed): set `columnFormat.total` = `none` for that column.
- Conditional formatting missing for a column: it only exists for numeric columns; check the column picked in "Apply settings to".
- No search box: `toolbar.show` is off by default.
- Watermark visible: a ★ conditional formatting, angled headers, column groups, row groups, auto-scroll, a ★ style or palette, or a Theme JSON is set without a valid key.
- Auto-scroll on but nothing moves: every row already fits in the visual (no vertical scrollbar), the mouse is over the visual (`autoScroll.hoverPause`), or the bottom was reached with `autoScroll.loop` off.
- Group names typed in Column formatting › Group do nothing: `colGroups.show` is off (Column groups card).
- A grouping column disappeared with row groups on: it is shown as the group title rows, and its name is in the first column header.
- A per-column setting ignored by a Dynamic format measure: the pane value set for that specific column wins over the "All columns" level.

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

Subtotals per row group, drill-down on a hierarchy field or values on rows (use Matrix Plume), an fx button on any option, conditional formatting driven by another field or a measure per cell, images or image URLs in cells, sparklines in cells, editing or write-back of cells, pagination, export from the visual itself, Power BI tooltips per cell, highlighting from other visuals.

## Table Plume: data fields

- `columns` Columns / Colonnes (GroupingOrMeasure, several max): 
- `sparkAxis` Sparkline axis / Axe des mini-graphiques (column, 1 max): A date or a number (Month, Date, Year…): measures are drawn along it as sparklines
- `cellFields` Cell elements fields / Champs des éléments de cellule (GroupingOrMeasure, several max): Not displayed: measures or columns that drive the cell elements (color, icon, link) of the displayed columns
- `tooltips` Tooltips / Info-bulles (measure, several max): Not displayed: shown in the tooltip of each row or cell
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Table Plume: Format pane options (213)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Column formatting / Mise en forme des colonnes (`columnFormat`, one entry per item with a selector)
- `columnFormat.align` Alignment / Alignement: dropdown, default `auto`; values: `auto` Automatic (numbers right); `left` Left; `center` Center; `right` Right
- `columnFormat.units` Display units / Unités d'affichage: dropdown, default `none`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `columnFormat.decimals` Decimals (-1 = field format) / Décimales (-1 = format du champ): number, default `-1`; values: -1 to 6
- `columnFormat.prefix` Prefix / Préfixe: text, default (empty)
- `columnFormat.suffix` Suffix / Suffixe: text, default (empty)
- `columnFormat.cf` Conditional formatting / Mise en forme conditionnelle: dropdown, default `none`; values: `none` None; `negative` Colored negatives; `dataBar` Data bars ★; `colorScale` Background color scale ★; `textScale` Text color scale ★; `icons` Icons (▲ ● ▼) ★; `pill` Colored pill ★. Quick formatting of a column (★). Free, like in the native table: Cell elements card (gradient, rules, a measure giving the color or an icon).
- `columnFormat.barColor` Bar color (empty = accent) / Couleur des barres (vide = accent): color, default (empty); values: hex color
- `columnFormat.barOnly` Bar only (no value) / Barre seule (sans valeur): toggle, default `false`; values: true / false
- `columnFormat.scale` Scale colors / Couleurs du dégradé: dropdown, default `accent`; values: `accent` Background → style accent; `style` Style palette; `greenRed` Green → red; `redGreen` Red → green; `custom` Custom
- `columnFormat.scaleType` Color scale type / Échelle du dégradé: dropdown, default `linear`; values: `linear` Linear; `log` Logarithmic ★; `quantile` Quantiles (rank) ★. Linear: proportional to the value. Logarithmic: spreads small values when a few large ones crush the rest. Quantiles: each shade covers as many cells (rank of the value).
- `columnFormat.lowColor` Low color / Couleur basse: color, default `#F7F4EF`; values: hex color
- `columnFormat.highColor` High color / Couleur haute: color, default `#B8462A`; values: hex color
- `columnFormat.negColor` Negative color / Couleur des négatifs: color, default `#C0392B`; values: hex color
- `columnFormat.posColor` Positive color (icons) / Couleur des positifs (icônes): color, default `#2E7D4F`; values: hex color
- `columnFormat.iconMode` Icon rule / Règle des icônes: dropdown, default `sign`; values: `sign` Sign (positive / zero / negative); `terciles` Thirds of the values (high / mid / low)
- `columnFormat.width` Width (px, 0 = auto) / Largeur (px, 0 = auto): number, default `0`; values: 0 to 800
- `columnFormat.spark` Sparkline / Mini-graphique: dropdown, default `line`; values: `none` None (value only); `line` Line ★; `bar` Columns ★. With a field in “Sparkline axis” (Month, Date…): each row's value along the axis, as a line or a column chart.
- `columnFormat.sparkValue` Value next to the sparkline / Valeur à côté du mini-graphique: toggle, default `true`; values: true / false. Off: the sparkline alone, across the whole column width.
- `columnFormat.sparkPos` Sparkline position / Position du mini-graphique: dropdown, default `left`; values: `left` Left of the value; `right` Right of the value
- `columnFormat.agg` Row value / Valeur de la ligne: dropdown, default `auto`; values: `auto` Automatic (sum when it is right, otherwise last value); `sum` Sum; `avg` Average; `last` Last value; `first` First value; `min` Minimum; `max` Maximum. With an axis, Power BI sends one value per axis point: the value shown is computed from them. Automatic: sum when Power BI confirms the measure adds up, otherwise last value (always exact). A sum or an average of ratios (rates, average basket) is approximate.
- `columnFormat.group` Group / Groupe: text, default (empty). Neighboring columns with the same group name share a header with a + / − button. Use "›" for a subgroup: Sales › 2025.
- `columnFormat.groupKeep` Stays visible when the group is collapsed / Reste visible quand le groupe est réduit: toggle, default `false`; values: true / false
- `columnFormat.bold` Bold / Gras: toggle, default `false`; values: true / false
- `columnFormat.fontColor` Text color (empty = values) / Couleur du texte (vide = valeurs): color, default (empty); values: hex color
- `columnFormat.background` Background color (empty = none) / Couleur d'arrière-plan (vide = aucune): color, default (empty); values: hex color
- `columnFormat.applyHeader` Apply to header too / Appliquer aussi à l'en-tête: toggle, default `false`; values: true / false. Text color, background, bold and alignment of the column on its header too (like "Specific column › Apply to header" in the native table).
- `columnFormat.applyTotal` Apply to total too / Appliquer aussi au total: toggle, default `false`; values: true / false
- `columnFormat.image` Images: dropdown, default `auto`; values: `auto` Automatic (data:image…); `on` Always (raw base64, SVG); `part` Chunk of the previous column's image; `off` Never (text). Automatic: a data:image/… value (or an Image URL column holding base64) becomes an image. Always: also raw base64 and SVG text. Chunk: this column continues the previous column's image (text joined, column hidden), for images longer than 32,766 characters.
- `columnFormat.total` Total: dropdown, default `auto`; values: `auto` Automatic (sum, except percentages); `sum` Sum; `avg` Average; `min` Minimum; `max` Maximum; `count` Count; `none` None

### Cell elements / Éléments de cellule (`cellElements`, one entry per item with a selector)
- `cellElements.bgMode` Background color / Couleur d'arrière-plan: dropdown, default `none`; values: `none` None; `gradient` Gradient; `rules` Rules; `field` Field value. Like conditional formatting in the native table: gradient, rules, or a measure that returns the color (#RRGGBB, rgb(), CSS name).
- `cellElements.bgField` Based on field / Selon le champ: dropdown, default (empty). The column itself, another displayed column, or a field of the "Cell elements fields" role (not displayed).
- `cellElements.bgLow` Minimum color (empty = style) / Couleur minimale (vide = style): color, default (empty); values: hex color
- `cellElements.bgMid` Center color (empty = none) / Couleur centrale (vide = aucune): color, default (empty); values: hex color
- `cellElements.bgHigh` Maximum color (empty = style) / Couleur maximale (vide = style): color, default (empty); values: hex color
- `cellElements.bgMin` Minimum (empty = lowest value) / Minimum (vide = valeur la plus basse): text, default (empty). A number (0), a percentage of the range (10%) or a percentile (p10).
- `cellElements.bgMax` Maximum (empty = highest value) / Maximum (vide = valeur la plus haute): text, default (empty). A number (100), a percentage of the range (90%) or a percentile (p90).
- `cellElements.bgRules` Rules / Règles: textarea, default (empty). One rule per line: condition(s), then ":" and the color. E.g. ">= 100 : #2E7D4F", ">= 50 and < 100 : orange", "< 50 : red", "blank : #CCCCCC", "else : gray". A % = share of the range (min → max), like "Percent" in Power BI: ">= 80% : green". The first matching rule wins.
- `cellElements.fontMode` Font color / Couleur de police: dropdown, default `none`; values: `none` None; `gradient` Gradient; `rules` Rules; `field` Field value. Like conditional formatting in the native table: gradient, rules, or a measure that returns the color (#RRGGBB, rgb(), CSS name).
- `cellElements.fontField` Based on field / Selon le champ: dropdown, default (empty). The column itself, another displayed column, or a field of the "Cell elements fields" role (not displayed).
- `cellElements.fontLow` Minimum color (empty = style) / Couleur minimale (vide = style): color, default (empty); values: hex color
- `cellElements.fontMid` Center color (empty = none) / Couleur centrale (vide = aucune): color, default (empty); values: hex color
- `cellElements.fontHigh` Maximum color (empty = style) / Couleur maximale (vide = style): color, default (empty); values: hex color
- `cellElements.fontMin` Minimum (empty = lowest value) / Minimum (vide = valeur la plus basse): text, default (empty). A number (0), a percentage of the range (10%) or a percentile (p10).
- `cellElements.fontMax` Maximum (empty = highest value) / Maximum (vide = valeur la plus haute): text, default (empty). A number (100), a percentage of the range (90%) or a percentile (p90).
- `cellElements.fontRules` Rules / Règles: textarea, default (empty). One rule per line: condition(s), then ":" and the color. E.g. ">= 100 : #2E7D4F", ">= 50 and < 100 : orange", "< 50 : red", "blank : #CCCCCC", "else : gray". A % = share of the range (min → max), like "Percent" in Power BI: ">= 80% : green". The first matching rule wins.
- `cellElements.scale` Gradient scale / Échelle des dégradés: dropdown, default `linear`; values: `linear` Linear; `log` Logarithmic ★; `quantile` Quantiles (rank) ★
- `cellElements.iconMode` Icons / Icônes: dropdown, default `none`; values: `none` None; `rules` Rules; `field` Field value. Rules: a marker set (green / amber / red dots, arrows…) by value; without rules, thirds of the range. Field value: a measure returning an icon name (green, amber, red, up, down, check, warning…), an emoji, or an SVG / base64 image ★.
- `cellElements.iconField` Based on field / Selon le champ: dropdown, default (empty)
- `cellElements.iconSet` Icon set / Jeu d'icônes: dropdown, default `traffic`; values: `traffic` Green / amber / red dots; `arrows` Arrows; `triangles` Triangles; `symbols` Symbols (✓ ! ✗); `flags` Flags; `shapes` Shapes (circle, diamond, triangle); `stars` Stars
- `cellElements.iconRules` Icon rules / Règles des icônes: textarea, default (empty). One rule per line, then ":" and the icon: high / mid / low (of the chosen set) or a name (green, amber, red, up, down, flat, check, warning, cross, star…). E.g. ">= 0.1 : high", ">= 0 : mid", "else : low". Empty: thirds of the range.
- `cellElements.iconPos` Icon layout / Disposition de l'icône: dropdown, default `left`; values: `left` Left of the value; `right` Right of the value; `only` Icon only
- `cellElements.iconAlign` Icon vertical alignment / Alignement vertical de l'icône: dropdown, default `middle`; values: `top` Top; `middle` Middle; `bottom` Bottom
- `cellElements.iconSize` Icon size (px, 0 = text size) ★ / Taille de l'icône (px, 0 = taille du texte) ★ ★: number, default `0`; values: 0 to 64
- `cellElements.urlMode` Web URL / URL web: dropdown, default `none`; values: `none` None; `field` Field value. The value becomes a link to the address given by the field (https only, opened by Power BI).
- `cellElements.urlField` Based on field / Selon le champ: dropdown, default (empty)
- `cellElements.applyValues` Apply to values / Appliquer aux valeurs: toggle, default `true`; values: true / false
- `cellElements.applyTotals` Apply to total / Appliquer au total: toggle, default `false`; values: true / false

### Grid / Grille (`grid`)
- `grid.density` Density / Densité: dropdown, default `normal`; values: `compact` Compact; `normal` Normal; `comfortable` Comfortable
- `grid.fit` Stretch columns to the visual width / Étirer les colonnes à la largeur du visuel: toggle, default `true`; values: true / false. Like "Grow to fit" in the native table. Off: each column is as wide as its content.
- `grid.defaultWidth` Default column width (px, 0 = fit to content) / Largeur par défaut des colonnes (px, 0 = selon le contenu): number, default `0`; values: 0 to 800. Like "Fixed width" in the native table: the same width for every column, except those set in Column formatting › Width or with the mouse.
- `grid.rowHeight` Minimum row height (px, 0 = automatic) / Hauteur minimale des lignes (px, 0 = automatique): number, default `0`; values: 0 to 300. Taller rows (images, icons, wall displays). Text stays vertically centered.
- `grid.rowLines` Lines between rows / Traits entre les lignes: toggle, default `true`; values: true / false
- `grid.colLines` Lines between columns / Traits entre les colonnes: toggle, default `false`; values: true / false
- `grid.lineColor` Line color (empty = style grid) / Couleur des traits (vide = grille du style): color, default (empty); values: hex color
- `grid.lineWidth` Line width (px) / Épaisseur des traits (px): number, default `1`; values: 1 to 6
- `grid.banding` Banded rows / Lignes alternées: toggle, default `false`; values: true / false
- `grid.bandColor` Banded row background (empty = automatic) / Fond des lignes alternées (vide = automatique): color, default (empty); values: hex color. Visible when `grid.banding` = `true`
- `grid.bandText` Banded row text (empty = values text) / Texte des lignes alternées (vide = texte des valeurs): color, default (empty); values: hex color. Visible when `grid.banding` = `true`
- `grid.hover` Highlight hovered row / Surligner la ligne survolée: toggle, default `true`; values: true / false

### Values / Valeurs (`cells`)
- `cells.fontSize` Size / Taille: number, default `12`; values: 7 to 30
- `cells.color` Color (empty = style text) / Couleur (vide = texte du style): color, default (empty); values: hex color
- `cells.background` Background color (empty = none) / Couleur d'arrière-plan (vide = aucune): color, default (empty); values: hex color
- `cells.bold` Bold / Gras: toggle, default `false`; values: true / false
- `cells.italic` Italic / Italique: toggle, default `false`; values: true / false
- `cells.wrap` Text wrap / Retour automatique à la ligne: toggle, default `false`; values: true / false
- `cells.blank` Text for blank cells / Texte des cellules vides: text, default (empty)
- `cells.selColor` Selected rows background (empty = light accent) / Fond des lignes sélectionnées (vide = accent pâle): color, default (empty); values: hex color
- `cells.urlIcon` Link icon instead of web addresses / Icône de lien à la place des adresses web: toggle, default `false`; values: true / false. Like "URL icon › Values" in the native table: a URL column (Web URL data category) or a cell elements link shows a clickable icon.

### Column headers / En-têtes de colonnes (`columnHeaders`)
- `columnHeaders.show` Show / Afficher: toggle, default `true`; values: true / false
- `columnHeaders.fontSize` Size / Taille: number, default `12`; values: 7 to 30
- `columnHeaders.bold` Bold / Gras: toggle, default `true`; values: true / false
- `columnHeaders.italic` Italic / Italique: toggle, default `false`; values: true / false
- `columnHeaders.caps` Small caps / Petites majuscules: toggle, default `false`; values: true / false
- `columnHeaders.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `columnHeaders.background` Background color (empty = none) / Couleur d'arrière-plan (vide = aucune): color, default (empty); values: hex color
- `columnHeaders.align` Alignment / Alignement: dropdown, default `auto`; values: `auto` Same as the column (numbers right); `left` Left; `center` Center; `right` Right
- `columnHeaders.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `columnHeaders.rotation` Text angle (°) ★ / Inclinaison du texte (°) ★ ★: slider, default `0`; values: -90 to 90. 0: horizontal. 45: slanted upward, like Excel. 90: vertical, read from bottom to top. Negative angles slant downward (-90: read from top to bottom). Long headers take little width.
- `columnHeaders.rotLength` Maximum length of a slanted line (px) / Longueur maximale d'une ligne inclinée (px): number, default `120`; values: 40 to 400. Visible when `columnHeaders.rotation` = . With "Text wrap", a longer header continues on the next line (4 lines at most); without it, it is cut with "…".
- `columnHeaders.rotFirst` Also slant the first column / Incliner aussi la première colonne: toggle, default `false`; values: true / false. Visible when `columnHeaders.rotation` = 
- `columnHeaders.underline` Rule under headers (text color) / Trait sous les en-têtes (couleur du texte): toggle, default `true`; values: true / false
- `columnHeaders.sortable` Sort by clicking a header / Trier en cliquant sur un en-tête: toggle, default `true`; values: true / false. Click: descending (numbers) or A to Z (text), again: the reverse, a third time: model order. Power BI's own sort (… › Sort by) also works.
- `columnHeaders.resizable` Resize with the mouse / Largeur ajustable à la souris: toggle, default `true`; values: true / false. Drag the edge of a header. Double-click resets the width.
- `columnHeaders.urlIcon` Link icon in URL column headers / Icône de lien dans les en-têtes des colonnes d'URL: toggle, default `false`; values: true / false. Like "URL icon › Headers" in the native table.

### Totals / Totaux (`totals`)
- `totals.show` Show / Afficher: toggle, default `false`; values: true / false
- `totals.label` Label / Libellé: text, default (empty)
- `totals.position` Position: dropdown, default `bottom`; values: `bottom` Bottom (always visible); `top` Top, under the headers
- `totals.bold` Bold / Gras: toggle, default `true`; values: true / false
- `totals.italic` Italic / Italique: toggle, default `false`; values: true / false
- `totals.background` Background color (empty = automatic) / Couleur d'arrière-plan (vide = automatique): color, default (empty); values: hex color
- `totals.color` Text color (empty = text) / Couleur du texte (vide = texte): color, default (empty); values: hex color

### Row groups / Groupes de lignes (`rowGroups`)
- `rowGroups.levels` Group by the first columns ★ / Grouper par les premières colonnes ★ ★: number, default `0`; values: 0 to 5. 0: no groups. 1: a title row for each value of the first column, its rows below and indented. 2: subgroups by the second column, and so on. Grouping columns are no longer shown as columns.
- `rowGroups.indent` Indent per level (px) / Retrait par niveau (px): number, default `16`; values: 0 to 60. Visible when `rowGroups.levels` = 
- `rowGroups.icons` + / − buttons (expand, collapse) / Boutons + / − (développer, réduire): toggle, default `true`; values: true / false. Visible when `rowGroups.levels` = 
- `rowGroups.startCollapsed` Groups collapsed at start / Groupes réduits au départ: toggle, default `false`; values: true / false. Visible when `rowGroups.levels` = 
- `rowGroups.remember` Save the state in the report (edit mode) / Mémoriser l'état dans le rapport (mode édition): toggle, default `true`; values: true / false. Visible when `rowGroups.levels` = 
- `rowGroups.count` Row count in the title / Nombre de lignes dans le titre: toggle, default `false`; values: true / false. Visible when `rowGroups.levels` = 
- `rowGroups.rule` Rule after the title / Trait après le titre: toggle, default `true`; values: true / false. Visible when `rowGroups.levels` = 
- `rowGroups.bold` Bold titles / Titres en gras: toggle, default `true`; values: true / false. Visible when `rowGroups.levels` = 
- `rowGroups.shade` Shade title rows / Teinter les lignes de titre: toggle, default `true`; values: true / false. Visible when `rowGroups.levels` = 
- `rowGroups.background` Title background (empty = automatic) / Fond des titres (vide = automatique): color, default (empty); values: hex color. Visible when `rowGroups.levels` = 
- `rowGroups.color` Title color (empty = text) / Couleur des titres (vide = texte): color, default (empty); values: hex color. Visible when `rowGroups.levels` = 

### First column / Première colonne (`firstCol`)
- `firstCol.frozen` Frozen when scrolling horizontally / Figée au défilement horizontal: toggle, default `true`; values: true / false
- `firstCol.bold` Bold / Gras: toggle, default `false`; values: true / false
- `firstCol.rowNumbers` Row numbers / Numéros de ligne: toggle, default `false`; values: true / false

### Column groups / Groupes de colonnes (`colGroups`)
- `colGroups.show` Collapsible groups ★ / Groupes repliables ★ ★: toggle, default `false`; values: true / false. Give columns a group name in Column formatting › Group ("›" for a subgroup): a group header with a + / − button appears above them.
- `colGroups.startCollapsed` Groups collapsed at start / Groupes réduits au départ: toggle, default `false`; values: true / false
- `colGroups.remember` Save the state in the report (edit mode) / Mémoriser l'état dans le rapport (mode édition): toggle, default `true`; values: true / false
- `colGroups.separators` Lines between groups / Traits entre les groupes: toggle, default `true`; values: true / false. Strong vertical line between two column groups (lighter between subgroups), in the header and down every row.

### Sparklines / Mini-graphiques (`sparklines`)
- `sparklines.width` Minimum width (px) / Largeur minimale (px): number, default `90`; values: 30 to 400
- `sparklines.color` Color (empty = style accent) / Couleur (vide = accent du style): color, default (empty); values: hex color
- `sparklines.lineWidth` Line width / Épaisseur des courbes: number, default `1.5`; values: 0.5 to 4
- `sparklines.area` Area under the line / Aire sous la courbe: toggle, default `false`; values: true / false
- `sparklines.last` Highlight the last value / Mettre en avant la dernière valeur: toggle, default `true`; values: true / false
- `sparklines.minMax` Minimum and maximum points / Points minimum et maximum: toggle, default `false`; values: true / false. Minimum in the unfavorable color, maximum in the favorable color (style colors).
- `sparklines.negColor` Negative columns (empty = unfavorable) / Barres négatives (vide = défavorable): color, default (empty); values: hex color
- `sparklines.sameScale` Same scale for every row / Même échelle pour toutes les lignes: toggle, default `false`; values: true / false. Off: each sparkline uses its full height (read the shape). On: rows can be compared with each other.
- `sparklines.zero` Axis from zero (lines) / Axe depuis zéro (courbes): toggle, default `false`; values: true / false

### Images (`images`)
- `images.size` Size / Dimension: dropdown, default `fixed`; values: `fixed` Fixed (same box for every image); `auto` Variable (each image's proportions)
- `images.height` Height (px) / Hauteur (px): number, default `28`; values: 8 to 400. Fixed: box height. Variable: maximum height.
- `images.width` Width (px, 0 = same as height) / Largeur (px, 0 = comme la hauteur): number, default `0`; values: 0 to 800. Fixed: box width (0: square). Variable: maximum width (0: no limit).
- `images.fit` Fit / Ajustement: dropdown, default `contain`; values: `contain` Contain (whole image); `cover` Crop (fill the box); `fill` Stretch. Visible when `images.size` = `fixed`
- `images.align` Alignment / Alignement: dropdown, default `auto`; values: `auto` Same as the column; `left` Left; `center` Center; `right` Right
- `images.invalid` Value that is not an image / Valeur qui n'est pas une image: dropdown, default `blank`; values: `blank` Blank cell; `text` Original text. A web address is never loaded (embedded images only: base64 or data URI).

### Toolbar / Barre d'outils (`toolbar`)
- `toolbar.show` Show / Afficher: toggle, default `false`; values: true / false. Search box, row count and (with row groups) expand all / collapse all above the table.
- `toolbar.search` Search in the table / Recherche dans le tableau: toggle, default `true`; values: true / false
- `toolbar.placeholder` Placeholder / Texte indicatif: text, default (empty)
- `toolbar.count` Row count / Nombre de lignes: toggle, default `true`; values: true / false

### Auto-scroll / Défilement automatique (`autoScroll`)
- `autoScroll.show` Auto-scroll ★ / Défilement automatique ★ ★: toggle, default `false`; values: true / false. Scrolls the rows by itself when they do not fit in the visual (vertical scrollbar): ideal in a report page tooltip or on a wall display.
- `autoScroll.speed` Speed (rows per second) / Vitesse (lignes par seconde): number, default `1`; values: 0.1 to 20. Visible when `autoScroll.show` = `true`
- `autoScroll.loop` Loop (back to the top at the end) / Boucler (revenir en haut à la fin): toggle, default `true`; values: true / false. Visible when `autoScroll.show` = `true`
- `autoScroll.pause` Pause at the top and bottom (s) / Pause en haut et en bas (s): number, default `2`; values: 0 to 30. Visible when `autoScroll.show` = `true`
- `autoScroll.hoverPause` Pause on mouse hover / Pause au survol de la souris: toggle, default `true`; values: true / false. Visible when `autoScroll.show` = `true`

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).
- `tooltip.rowLabels` Repeat the row's text columns / Rappeler les colonnes de texte de la ligne: toggle, default `true`; values: true / false. A cell's tooltip starts with the text columns of its row (product, category…), then the hovered value and the "Tooltips" fields.

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `false`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Matrix Plume

- A matrix that expands in place, stepped or tabular, with Power BI's real subtotals and a heatmap.
- Slug `matrix` · version 1.7.0.0 · GUID (`visualType`) `plumeMatrix2D6A9F3C8B1E4D7A9E5C04B8F2A6D3E1` · page https://plumevisuals.com/en/visuals/matrix

### What the visual does

Matrix Plume is a Power BI custom visual that replaces the native matrix: rows on one or more levels (region › city, category › product), optional columns (years, months) and one or more measures. Groups expand and collapse in place (+ / − buttons, double-click on a row, ← → on the keyboard, "Expand all / Collapse all"), in a **stepped** layout (one indented column) or a **tabular** one (one column per level). Subtotals and grand totals are the ones **computed by Power BI**, so they are correct for averages and ratios; they sit on the group row or in a "Total" row below the group. Column headers stack on several merged, frozen levels (year, then measures). Clicking a value column header sorts every level by that column. A search box finds rows while keeping their parents. Each measure has its own formatting, with premium heatmap (background color scale), text color scale, data bars, icons and pills. Since version 1.2.0.0, two more premium features: **angled column headers** on the last header level (-90° to 90°) and **collapsible column groups** (+ / − on the groups of the Columns field, which keep their Power BI subtotals when collapsed, and on named groups of measures). Since version 1.3.0.0, two more premium options: the **grand total column on the left** (right after the row headers, frozen while scrolling horizontally) and **auto-scroll** (rows that do not fit scroll by themselves). Since version 1.5.0.0, column groups are separated by vertical lines (`colGroups.separators`, on by default) and the fit-to-width layout leaves room for the vertical scrollbar. Since version 1.6.0.0, premium **sparklines**: one "Trend" column per measure showing how each row evolves across the matrix columns (line or columns). Since version 1.6.1.0, angled headers never cross the line of a column group. The visual makes no network request.

**New in version 1.7.0.0 (30/10/2026):** Free native-parity additions: new **Cell elements** card, **base64 images** in values and in row / column headers (Images card), log ★ or quantile ★ color scales, color scale per level on group rows and subtotals, Power BI tooltips and report page tooltips; column header settings moved to **Column headers** (`header.*` → `columnHeaders.*`).

### 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 (`style.customColors` and the colors under it) are **free**; every other `style.preset`, the other gradient palettes (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium** (watermark without a key). See "Styles and theme JSON" below.
- Using a premium feature without a valid key shows **"Plume Visuals · Premium preview"** (French: « Plume Visuals · Aperçu premium ») in the footer of the visual, with an "Unlock →" link to the pricing page. It disappears once a key is pasted in **Format › Plume Studio License › License key** (`license.key`; French: « Licence Plume Studio › Clé de licence »), the **first card** of the Format pane.
- Premium features of Matrix Plume:
  - `columnFormat.cf` = `colorScale` ("Background color scale ★", the heatmap), `textScale` ("Text color scale ★"), `dataBar` ("Data bars ★"), `icons` ("Icons (▲ ● ▼) ★") or `pill` ("Colored pill ★"), for all measures or one measure. `none` and `negative` ("Colored negatives") are free;
  - `columnHeaders.rotation` other than 0 ("Text angle (°) ★", angled headers), `colGroups.show` ("Collapsible groups ★"), `subTotals.grandColPos` = `left` ("Left (after the row headers, frozen) ★"), `autoScroll.show` ("Auto-scroll ★") and `sparklines.show` (card "Sparklines ★"), all off by default;
- Premium options and list values have " ★" appended to their label and the description "Premium feature: usable for free with a « Premium preview » watermark…".
- Accepted keys: only keys starting with `PLUM1.` shown in the buyer's account on plumevisuals.com, checked offline (Ed25519 signature), covering `matrix` 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". `license.showOwner` displays "Licensed to <holder>".
- Licenses last one year (one-time payment, no automatic renewal, key accepted for 30 more days, reminders 30 and 7 days before the end), for this visual: 39 € personal, 99 € SME, 299 € enterprise per year, or the catalog packs (199 € / 399 € / 1,199 € per year; tiers by number of users, designers and viewers included: personal 1–10, SME 11–200, enterprise more than 200).
- Status: Available, version 1.6.1.0, installed from the `.pbiviz` file or from AppSource (published, Microsoft certification passed, live since 18/10/2026). The License card starts with a read-only line "Get a license: plumevisuals.com" (`license.buy`, never read by the visual).

### Expected data shape

A **matrix** data view, like the native matrix: a row hierarchy, an optional column hierarchy, and measures evaluated at every intersection, including subtotals and totals returned by Power BI.

| Rows (`rows`) | Columns (`columns`): 2024 · Revenue | 2024 · Margin rate | 2025 · Revenue | 2025 · Margin rate |
|---|---|---|---|---|
| North West (group) | 512 000 | 44.1% | 548 300 | 43.2% |
| · Manchester | 301 200 | 45.0% | 322 900 | 43.9% |

- **Rows** (`rows`, label "Rows" / « Lignes », columns, one or more levels): the row hierarchy. Required for groups (measures alone give a single row).
- **Columns** (`columns`, « Colonnes », columns, optional): the column hierarchy; headers are merged per level, then one header per measure.
- **Values** (`values`, « Valeurs », measures, one or more).
- **Dynamic format** (`format`, « Format dynamique », measures, optional): formatting measures named `card.setting`; they never become value columns.
- Volume: 30,000 rows per data window (more fetched automatically).
- Subtotals: `subTotals.rowSubtotals`, `subTotals.rowSubtotalsType` (`Top` = on the group row, `Bottom` = "Total" row below the group) and `subTotals.columnSubtotals` are Power BI's own subtotal properties: Power BI computes those cells. `subTotals.grandRow` / `subTotals.grandCol` only show when row / column subtotals are on.

### DAX recipes

```dax
Revenue = SUM ( Sales[Amount] )
Gross margin = SUM ( Sales[Margin] )
Margin rate = DIVIDE ( [Gross margin], [Revenue] )        // correct on group rows and totals

// Share of the parent level (here: city within its region)
Share of region =
DIVIDE ( [Revenue], CALCULATE ( [Revenue], ALLSELECTED ( Sales[City] ) ) )
```

Ratios must be measures: a calculated column would be summed in subtotals.

### Column groups and angled headers ★ (since 1.2.0.0)

- **Collapsible column groups** (`colGroups.show`): a + / − button on every group header. Two kinds of groups: the levels of the **Columns** field (Year › Quarter, or a year above several measures), and **named groups of measures** typed in Column formatting › Group (`columnFormat.group`, "›" for a subgroup), inserted above the measure name under each column.
- A collapsed group of the Columns field is replaced by its **Power BI subtotals** (the "Total 2024" level disappears: the column is simply named "2024"), so column subtotals must be on (`subTotals.columnSubtotals`). A collapsed named group keeps its measures marked `columnFormat.groupKeep`. Otherwise the group becomes one narrow collapsed column named after it (tinted, empty cells, tooltip "n hidden columns"). The outermost collapsed group wins; you can sort by the column of a collapsed group.
- `colGroups.startCollapsed` collapses every group at start; `colGroups.remember` saves the state in the report in edit mode (hidden `state.colGroups`), kept in memory in reading mode. Clicking a year header cross-filters on that node.
- **Angled headers** (`columnHeaders.rotation`, -90 to 90, 0 = unchanged) apply to the headers of the last level (above the values); upper levels (years) and the corner stay horizontal. `columnHeaders.wrap` breaks long headers into balanced lines at `columnHeaders.rotLength` px (4 lines at most), otherwise one line cut by "…". Headers stay frozen while scrolling.

### Grand total column on the left ★ and auto-scroll ★ (since 1.3.0.0)

- **Subtotals › Grand total column position** (`subTotals.grandColPos`): `right` (default, after all columns, like the native matrix) or `left` (premium): the grand total column(s), one per measure under the "Total" header, move right after the row headers and stay **frozen while scrolling horizontally**, with a separator line. They are frozen as long as row headers plus total take at most 75 % of the visual width; otherwise they are simply placed on the left. The option only shows (and only has an effect) when a field is in Columns, `subTotals.columnSubtotals` and `subTotals.grandCol` are on.
- Card **Auto-scroll** (`autoScroll`): `show` (premium, off by default), `speed` (rows per second, 0.1 to 20), `loop`, `pause` (seconds at the top and bottom), `hoverPause`. Rows that do not fit scroll by themselves; nothing moves when everything fits; any user action pauses it for about 4 seconds. Typical use: a matrix on a report page tooltip or a wall display.

### Sparklines ★ (since 1.6.0.0)

- Card **Sparklines ★** (`sparklines`): `show` (premium, off by default), `kind` (`line` or `bar`), `position` (`end`: after the columns, or `start`: right after the row headers), `title` (header text, default "Trend"), `width` (minimum width in px), `color` (empty = style accent), `lineWidth`, `area` (area under the line), `last` (highlight the last value), `minMax` (minimum and maximum points in the unfavorable / favorable colors), `negColor` (negative bars), `sameScale` (one scale for all rows), `zero` (line axis from zero).
- One Trend column per measure; each row (and the grand total row) gets a small chart drawn from the values of the **Columns** field, at its deepest level, even when the column groups are collapsed (years collapsed: the line still follows every month). Without a Columns field (or with only measures in columns), nothing is drawn and no watermark appears.
- Hovering a sparkline shows a tooltip with the column labels and values; clicking it selects the row (cross-filter), like clicking the row header.

### Interactions with the report

- Click a row header = select that node (cross-filters other visuals); click a cell = select the row × column intersection (the cell is highlighted); click a column group header = select that column member. Ctrl + click adds to the selection. Context menu.
- Keyboard: ↑ ↓ to move, ← → to collapse or expand, Enter to select. ARIA `treegrid` role, levels and expanded state announced; high contrast supported.
- Expanding, sorting and searching (`toolbar.search`) only change the display, never the report filters.
- With `expand.remember` on, the expanded groups are saved in the report in edit mode (hidden `state.expanded`, together with `state.widths`). Changing `expand.startLevel` resets that saved state.
- Other visuals cross-filter Matrix Plume (it does not support highlighting).

### Dynamic formats

- **No fx button**: Power BI does not offer conditional formatting of Format pane options to table / matrix visuals (Table Plume, Matrix Plume, KPI Plume). Everything goes through the **Dynamic format** well (role `format`).
- Drop a measure in it and rename it for this visual `card.setting`, e.g. `expand.startLevel`, `rowHeaders.layout`, `title.text`, `style.preset`. Case, accents and the separator are ignored. It wins over the fixed setting, the style and the JSON theme.
- Matrix Plume reads the value of the **grand total** (root of the rows). Examples: `IF ( HASONEVALUE ( Sales[Region] ), 1, 0 )` renamed `expand.startLevel` (open cities when a slicer keeps one region); `IF ( ISFILTERED ( Sales[Category] ), "tabular", "stepped" )` renamed `rowHeaders.layout`.
- For the dynamic card **Column formatting**, only the "All columns" level is driven (`columnFormat.cf`, `columnFormat.units`…); a value set in the pane for one specific measure stays first.
- Not drivable: `subTotals.rowSubtotals`, `subTotals.rowSubtotalsType`, `subTotals.columnSubtotals` (read by Power BI itself) and the hidden `state` object.
- Driving a setting with DAX is free; a ★ value set by DAX still shows the watermark without a key.

### Format pane: how to read the tables below

- Each option has an ID `card.option` (for example `rowHeaders.layout`). The card is the capabilities.json **object name**, the option is the **property name**.
- Card order: `license` (always first), `style` (shared Style card), `columnFormat` (dynamic card "Column formatting": a list at the top, "Apply settings to", picks "All columns" or one measure; no per-measure total here), then `grid`, `rowHeaders`, `columnHeaders` (column headers), `cells` (values), `expand`, `subTotals`, `toolbar`, then `title`, `source`, `container` and `texts`. Format pane in version 1.7.0.0 (30/10/2026), top to bottom: `license`, `style`, `columnFormat`, `cellElements`, `grid`, `cells`, `columnHeaders`, `rowHeaders`, `subTotals`, `expand`, `colGroups`, `sparklines`, `images`, `toolbar`, `autoScroll`, `tooltip`, `title`, `source`, `container`, `texts`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- Per-measure options appear only when relevant: `barColor` / `barOnly` for data bars, `scale` for color scales and pills (`lowColor` / `highColor` when `scale` = `custom`), `iconMode` / `posColor` for icons.
- Labels follow the language of Power BI Desktop; `texts.language` can force French or English inside the visual.
- "Visible when" means the option only appears when another option has one of the listed values (e.g. `rowHeaders.indent` only for `stepped`).

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. Literal syntax: booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes, colors wrapped in `solid.color`. Per-measure settings are entries of `columnFormat` with a `selector` on the measure's `queryRef`.

```json
{
  "visualType": "plumeMatrix2D6A9F3C8B1E4D7A9E5C04B8F2A6D3E1",
  "query": {
    "queryState": {
      "rows": { "projections": [
        { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Region" } }, "queryRef": "Sales.Region", "nativeQueryRef": "Region" },
        { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "City" } }, "queryRef": "Sales.City", "nativeQueryRef": "City" } ] },
      "columns": { "projections": [
        { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Year" } }, "queryRef": "Sales.Year", "nativeQueryRef": "Year" } ] },
      "values": { "projections": [
        { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Revenue" } }, "queryRef": "Sales.Revenue", "nativeQueryRef": "Revenue" },
        { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Margin rate" } }, "queryRef": "Sales.Margin rate", "nativeQueryRef": "Margin rate" } ] }
    }
  },
  "objects": {
    "rowHeaders": [ { "properties": { "layout": { "expr": { "Literal": { "Value": "'stepped'" } } },
                                      "indent": { "expr": { "Literal": { "Value": "20D" } } } } } ],
    "expand":     [ { "properties": { "startLevel": { "expr": { "Literal": { "Value": "1D" } } } } } ],
    "subTotals":  [ { "properties": { "rowSubtotalsType": { "expr": { "Literal": { "Value": "'Bottom'" } } } } } ],
    "toolbar":    [ { "properties": { "search": { "expr": { "Literal": { "Value": "true" } } } } } ],
    "columnFormat": [
      { "properties": { "cf": { "expr": { "Literal": { "Value": "'colorScale'" } } },
                        "scale": { "expr": { "Literal": { "Value": "'custom'" } } },
                        "lowColor": { "solid": { "color": { "expr": { "Literal": { "Value": "'#f7f4ef'" } } } } },
                        "highColor": { "solid": { "color": { "expr": { "Literal": { "Value": "'#b8462a'" } } } } } },
        "selector": { "metadata": "Sales.Revenue" } } ],
    "license": [ { "properties": { "key": { "expr": { "Literal": { "Value": "'PLUM1.…'" } } } } } ]
  }
}
```

The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from the `.pbiviz` file). Do not write the hidden `state` properties by hand.

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`.
- `style.themeJson` (Format › Style › Theme JSON ★) takes a JSON theme as plain text. Format v2: an object with an optional `extends` (a style ID above) and optional groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`; the v1 flat format (`style`, `palette`, `accent`, `background`…) is still read. Every field is optional. Colors are `#RRGGBB` (`#RGB` and `#RRGGBBAA` accepted, opacity ignored). Unknown fields and values outside the allowed lists are ignored, out-of-range numbers are clamped. Invalid JSON shows "Invalid theme JSON: ignored" in edit mode and the visual keeps its look.
- Full field list with allowed values, examples and troubleshooting: tutorial https://plumevisuals.com/ai/tutorials/en/themes-json.md (French: https://plumevisuals.com/ai/tutorials/fr/themes-json.md). The same JSON can be pasted in every Plume visual of a page.
- Priority (the last one wins): visual defaults → `style.preset` → `style.themeJson` → `style.palette` (if not "Style or theme palette") → `style.followTheme` → custom colors → options set by hand in the other cards → DAX formats (fx button, "Dynamic format" field) → Windows high contrast.

### Common pitfalls

- The matrix ignores `expand.startLevel`: `expand.remember` kept a state saved in edit mode with the same start level. Change the level or turn `expand.remember` off.
- No grand total row: `subTotals.grandRow` is only used when `subTotals.rowSubtotals` is on.
- A ratio summed in subtotals: it is a calculated column; use a measure.
- Heatmap on the wrong measure: the `columnFormat` entry has no selector (applies to all measures) or the wrong `queryRef`.
- Watermark visible: a ★ conditional formatting, angled headers, column groups, the total column on the left, auto-scroll, a ★ style or palette, or a Theme JSON is set without a valid key.
- "Grand total column position" missing from the pane: there is no field in Columns, or column subtotals / the grand total column are off.
- Total on the left scrolls away instead of staying frozen: row headers plus total take more than 75 % of the visual width (narrow the row headers with `rowHeaders.maxWidth` or widen the visual).
- A collapsed year shows an empty narrow column instead of its total: column subtotals are off (`subTotals.columnSubtotals`).
- Search finds nothing: `toolbar.search` is off by default (`toolbar.show` is on).

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

An fx button on any option, conditional formatting driven by another field or a separate rules measure, per-level custom subtotal formulas (Power BI computes them), values shown on rows instead of columns, drill-down / drill-through buttons of the native matrix, images in cells, sparklines driven by a separate axis field (they always follow the Columns field), editing or write-back, export from the visual itself, Power BI tooltips per cell, highlighting from other visuals.

## Matrix Plume: data fields

- `rows` Rows / Lignes (column, several max): 
- `columns` Columns / Colonnes (column, several max): 
- `values` Values / Valeurs (measure, several max): 
- `cellFields` Cell elements fields / Champs des éléments de cellule (measure, several max): Not displayed: measures or columns that drive the cell elements (color, icon, link) of the displayed columns
- `tooltips` Tooltips / Info-bulles (measure, several max): Not displayed: shown in the tooltip of each row or cell
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Matrix Plume: Format pane options (217)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Column formatting / Mise en forme des colonnes (`columnFormat`, one entry per item with a selector)
- `columnFormat.align` Alignment / Alignement: dropdown, default `auto`; values: `auto` Automatic (numbers right); `left` Left; `center` Center; `right` Right
- `columnFormat.units` Display units / Unités d'affichage: dropdown, default `none`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `columnFormat.decimals` Decimals (-1 = field format) / Décimales (-1 = format du champ): number, default `-1`; values: -1 to 6
- `columnFormat.prefix` Prefix / Préfixe: text, default (empty)
- `columnFormat.suffix` Suffix / Suffixe: text, default (empty)
- `columnFormat.cf` Conditional formatting / Mise en forme conditionnelle: dropdown, default `none`; values: `none` None; `negative` Colored negatives; `dataBar` Data bars ★; `colorScale` Background color scale ★; `textScale` Text color scale ★; `icons` Icons (▲ ● ▼) ★; `pill` Colored pill ★. Quick formatting of a column (★). Free, like in the native table: Cell elements card (gradient, rules, a measure giving the color or an icon).
- `columnFormat.barColor` Bar color (empty = accent) / Couleur des barres (vide = accent): color, default (empty); values: hex color
- `columnFormat.barOnly` Bar only (no value) / Barre seule (sans valeur): toggle, default `false`; values: true / false
- `columnFormat.scale` Scale colors / Couleurs du dégradé: dropdown, default `accent`; values: `accent` Background → style accent; `style` Style palette; `greenRed` Green → red; `redGreen` Red → green; `custom` Custom
- `columnFormat.scaleType` Color scale type / Échelle du dégradé: dropdown, default `linear`; values: `linear` Linear; `log` Logarithmic ★; `quantile` Quantiles (rank) ★. Linear: proportional to the value. Logarithmic: spreads small values when a few large ones crush the rest. Quantiles: each shade covers as many cells (rank of the value).
- `columnFormat.cfGroups` Group rows and totals / Lignes de groupe et totaux: dropdown, default `none`; values: `none` Detail only; `level` Scale per level (groups included). By default, conditional formatting only colors detail cells. "Scale per level" also colors group rows (subtotals), each level with its own scale (regions together, cities together).
- `columnFormat.lowColor` Low color / Couleur basse: color, default `#F7F4EF`; values: hex color
- `columnFormat.highColor` High color / Couleur haute: color, default `#B8462A`; values: hex color
- `columnFormat.negColor` Negative color / Couleur des négatifs: color, default `#C0392B`; values: hex color
- `columnFormat.posColor` Positive color (icons) / Couleur des positifs (icônes): color, default `#2E7D4F`; values: hex color
- `columnFormat.iconMode` Icon rule / Règle des icônes: dropdown, default `sign`; values: `sign` Sign (positive / zero / negative); `terciles` Thirds of the values (high / mid / low)
- `columnFormat.width` Width (px, 0 = auto) / Largeur (px, 0 = auto): number, default `0`; values: 0 to 800
- `columnFormat.group` Group / Groupe: text, default (empty). Neighboring columns with the same group name share a header with a + / − button. Use "›" for a subgroup: Sales › 2025.
- `columnFormat.groupKeep` Stays visible when the group is collapsed / Reste visible quand le groupe est réduit: toggle, default `false`; values: true / false
- `columnFormat.bold` Bold / Gras: toggle, default `false`; values: true / false
- `columnFormat.fontColor` Text color (empty = values) / Couleur du texte (vide = valeurs): color, default (empty); values: hex color
- `columnFormat.background` Background color (empty = none) / Couleur d'arrière-plan (vide = aucune): color, default (empty); values: hex color
- `columnFormat.applyHeader` Apply to header too / Appliquer aussi à l'en-tête: toggle, default `false`; values: true / false. Text color, background, bold and alignment of the column on its header too (like "Specific column › Apply to header" in the native table).
- `columnFormat.applyTotal` Apply to total too / Appliquer aussi au total: toggle, default `false`; values: true / false
- `columnFormat.image` Images: dropdown, default `auto`; values: `auto` Automatic (data:image…); `on` Always (raw base64, SVG); `part` Chunk of the previous column's image; `off` Never (text). Automatic: a data:image/… value (or an Image URL column holding base64) becomes an image. Always: also raw base64 and SVG text. Chunk: this column continues the previous column's image (text joined, column hidden), for images longer than 32,766 characters.

### Cell elements / Éléments de cellule (`cellElements`, one entry per item with a selector)
- `cellElements.bgMode` Background color / Couleur d'arrière-plan: dropdown, default `none`; values: `none` None; `gradient` Gradient; `rules` Rules; `field` Field value. Like conditional formatting in the native table: gradient, rules, or a measure that returns the color (#RRGGBB, rgb(), CSS name).
- `cellElements.bgField` Based on field / Selon le champ: dropdown, default (empty). The column itself, another displayed column, or a field of the "Cell elements fields" role (not displayed).
- `cellElements.bgLow` Minimum color (empty = style) / Couleur minimale (vide = style): color, default (empty); values: hex color
- `cellElements.bgMid` Center color (empty = none) / Couleur centrale (vide = aucune): color, default (empty); values: hex color
- `cellElements.bgHigh` Maximum color (empty = style) / Couleur maximale (vide = style): color, default (empty); values: hex color
- `cellElements.bgMin` Minimum (empty = lowest value) / Minimum (vide = valeur la plus basse): text, default (empty). A number (0), a percentage of the range (10%) or a percentile (p10).
- `cellElements.bgMax` Maximum (empty = highest value) / Maximum (vide = valeur la plus haute): text, default (empty). A number (100), a percentage of the range (90%) or a percentile (p90).
- `cellElements.bgRules` Rules / Règles: textarea, default (empty). One rule per line: condition(s), then ":" and the color. E.g. ">= 100 : #2E7D4F", ">= 50 and < 100 : orange", "< 50 : red", "blank : #CCCCCC", "else : gray". A % = share of the range (min → max), like "Percent" in Power BI: ">= 80% : green". The first matching rule wins.
- `cellElements.fontMode` Font color / Couleur de police: dropdown, default `none`; values: `none` None; `gradient` Gradient; `rules` Rules; `field` Field value. Like conditional formatting in the native table: gradient, rules, or a measure that returns the color (#RRGGBB, rgb(), CSS name).
- `cellElements.fontField` Based on field / Selon le champ: dropdown, default (empty). The column itself, another displayed column, or a field of the "Cell elements fields" role (not displayed).
- `cellElements.fontLow` Minimum color (empty = style) / Couleur minimale (vide = style): color, default (empty); values: hex color
- `cellElements.fontMid` Center color (empty = none) / Couleur centrale (vide = aucune): color, default (empty); values: hex color
- `cellElements.fontHigh` Maximum color (empty = style) / Couleur maximale (vide = style): color, default (empty); values: hex color
- `cellElements.fontMin` Minimum (empty = lowest value) / Minimum (vide = valeur la plus basse): text, default (empty). A number (0), a percentage of the range (10%) or a percentile (p10).
- `cellElements.fontMax` Maximum (empty = highest value) / Maximum (vide = valeur la plus haute): text, default (empty). A number (100), a percentage of the range (90%) or a percentile (p90).
- `cellElements.fontRules` Rules / Règles: textarea, default (empty). One rule per line: condition(s), then ":" and the color. E.g. ">= 100 : #2E7D4F", ">= 50 and < 100 : orange", "< 50 : red", "blank : #CCCCCC", "else : gray". A % = share of the range (min → max), like "Percent" in Power BI: ">= 80% : green". The first matching rule wins.
- `cellElements.scale` Gradient scale / Échelle des dégradés: dropdown, default `linear`; values: `linear` Linear; `log` Logarithmic ★; `quantile` Quantiles (rank) ★
- `cellElements.iconMode` Icons / Icônes: dropdown, default `none`; values: `none` None; `rules` Rules; `field` Field value. Rules: a marker set (green / amber / red dots, arrows…) by value; without rules, thirds of the range. Field value: a measure returning an icon name (green, amber, red, up, down, check, warning…), an emoji, or an SVG / base64 image ★.
- `cellElements.iconField` Based on field / Selon le champ: dropdown, default (empty)
- `cellElements.iconSet` Icon set / Jeu d'icônes: dropdown, default `traffic`; values: `traffic` Green / amber / red dots; `arrows` Arrows; `triangles` Triangles; `symbols` Symbols (✓ ! ✗); `flags` Flags; `shapes` Shapes (circle, diamond, triangle); `stars` Stars
- `cellElements.iconRules` Icon rules / Règles des icônes: textarea, default (empty). One rule per line, then ":" and the icon: high / mid / low (of the chosen set) or a name (green, amber, red, up, down, flat, check, warning, cross, star…). E.g. ">= 0.1 : high", ">= 0 : mid", "else : low". Empty: thirds of the range.
- `cellElements.iconPos` Icon layout / Disposition de l'icône: dropdown, default `left`; values: `left` Left of the value; `right` Right of the value; `only` Icon only
- `cellElements.iconAlign` Icon vertical alignment / Alignement vertical de l'icône: dropdown, default `middle`; values: `top` Top; `middle` Middle; `bottom` Bottom
- `cellElements.iconSize` Icon size (px, 0 = text size) ★ / Taille de l'icône (px, 0 = taille du texte) ★ ★: number, default `0`; values: 0 to 64
- `cellElements.urlMode` Web URL / URL web: dropdown, default `none`; values: `none` None; `field` Field value. The value becomes a link to the address given by the field (https only, opened by Power BI).
- `cellElements.urlField` Based on field / Selon le champ: dropdown, default (empty)
- `cellElements.applyValues` Apply to values / Appliquer aux valeurs: toggle, default `true`; values: true / false
- `cellElements.applyTotals` Apply to totals and subtotals / Appliquer aux totaux et sous-totaux: toggle, default `false`; values: true / false

### Grid / Grille (`grid`)
- `grid.density` Density / Densité: dropdown, default `normal`; values: `compact` Compact; `normal` Normal; `comfortable` Comfortable
- `grid.fit` Stretch columns to the visual width / Étirer les colonnes à la largeur du visuel: toggle, default `true`; values: true / false. Like "Grow to fit" in the native table. Off: each column is as wide as its content.
- `grid.defaultWidth` Default column width (px, 0 = fit to content) / Largeur par défaut des colonnes (px, 0 = selon le contenu): number, default `0`; values: 0 to 800. Like "Fixed width" in the native table: the same width for every column, except those set in Column formatting › Width or with the mouse.
- `grid.rowHeight` Minimum row height (px, 0 = automatic) / Hauteur minimale des lignes (px, 0 = automatique): number, default `0`; values: 0 to 300. Taller rows (images, icons, wall displays). Text stays vertically centered.
- `grid.rowLines` Lines between rows / Traits entre les lignes: toggle, default `true`; values: true / false
- `grid.colLines` Lines between columns / Traits entre les colonnes: toggle, default `false`; values: true / false
- `grid.lineColor` Line color (empty = style grid) / Couleur des traits (vide = grille du style): color, default (empty); values: hex color
- `grid.lineWidth` Line width (px) / Épaisseur des traits (px): number, default `1`; values: 1 to 6
- `grid.banding` Banded rows / Lignes alternées: toggle, default `false`; values: true / false
- `grid.bandColor` Banded row background (empty = automatic) / Fond des lignes alternées (vide = automatique): color, default (empty); values: hex color. Visible when `grid.banding` = `true`
- `grid.bandText` Banded row text (empty = values text) / Texte des lignes alternées (vide = texte des valeurs): color, default (empty); values: hex color. Visible when `grid.banding` = `true`
- `grid.hover` Highlight hovered row / Surligner la ligne survolée: toggle, default `true`; values: true / false

### Values / Valeurs (`cells`)
- `cells.fontSize` Size / Taille: number, default `12`; values: 7 to 30
- `cells.color` Color (empty = style text) / Couleur (vide = texte du style): color, default (empty); values: hex color
- `cells.background` Background color (empty = none) / Couleur d'arrière-plan (vide = aucune): color, default (empty); values: hex color
- `cells.bold` Bold / Gras: toggle, default `false`; values: true / false
- `cells.italic` Italic / Italique: toggle, default `false`; values: true / false
- `cells.wrap` Text wrap / Retour automatique à la ligne: toggle, default `false`; values: true / false
- `cells.blank` Text for blank cells / Texte des cellules vides: text, default (empty)
- `cells.selColor` Selected rows background (empty = light accent) / Fond des lignes sélectionnées (vide = accent pâle): color, default (empty); values: hex color
- `cells.urlIcon` Link icon instead of web addresses / Icône de lien à la place des adresses web: toggle, default `false`; values: true / false. Like "URL icon › Values" in the native table: a URL column (Web URL data category) or a cell elements link shows a clickable icon.

### Column headers / En-têtes de colonnes (`columnHeaders`)
- `columnHeaders.show` Show / Afficher: toggle, default `true`; values: true / false
- `columnHeaders.fontSize` Size / Taille: number, default `12`; values: 7 to 30
- `columnHeaders.bold` Bold / Gras: toggle, default `true`; values: true / false
- `columnHeaders.italic` Italic / Italique: toggle, default `false`; values: true / false
- `columnHeaders.caps` Small caps / Petites majuscules: toggle, default `false`; values: true / false
- `columnHeaders.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `columnHeaders.background` Background color (empty = none) / Couleur d'arrière-plan (vide = aucune): color, default (empty); values: hex color
- `columnHeaders.align` Alignment / Alignement: dropdown, default `auto`; values: `auto` Same as the column (numbers right); `left` Left; `center` Center; `right` Right
- `columnHeaders.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `columnHeaders.rotation` Text angle (°) ★ / Inclinaison du texte (°) ★ ★: slider, default `0`; values: -90 to 90. 0: horizontal. 45: slanted upward, like Excel. 90: vertical, read from bottom to top. Negative angles slant downward (-90: read from top to bottom). Long headers take little width.
- `columnHeaders.rotLength` Maximum length of a slanted line (px) / Longueur maximale d'une ligne inclinée (px): number, default `120`; values: 40 to 400. Visible when `columnHeaders.rotation` = . With "Text wrap", a longer header continues on the next line (4 lines at most); without it, it is cut with "…".
- `columnHeaders.underline` Rule under headers (text color) / Trait sous les en-têtes (couleur du texte): toggle, default `true`; values: true / false
- `columnHeaders.sortable` Sort by clicking a header / Trier en cliquant sur un en-tête: toggle, default `true`; values: true / false. Click: descending (numbers) or A to Z (text), again: the reverse, a third time: model order. Power BI's own sort (… › Sort by) also works.
- `columnHeaders.resizable` Resize with the mouse / Largeur ajustable à la souris: toggle, default `true`; values: true / false. Drag the edge of a header. Double-click resets the width.
- `columnHeaders.urlIcon` Link icon in URL column headers / Icône de lien dans les en-têtes des colonnes d'URL: toggle, default `false`; values: true / false. Like "URL icon › Headers" in the native table.

### Row headers / En-têtes de lignes (`rowHeaders`)
- `rowHeaders.layout` Layout / Disposition: dropdown, default `stepped`; values: `stepped` Stepped (one indented column); `tabular` Tabular (one column per level)
- `rowHeaders.indent` Indent per level (px) / Décalage par niveau (px): number, default `16`; values: 0 to 60. Visible when `rowHeaders.layout` = `stepped`
- `rowHeaders.icons` + / − buttons / Boutons + / −: toggle, default `true`; values: true / false
- `rowHeaders.boldParents` Bold groups / Groupes en gras: toggle, default `true`; values: true / false
- `rowHeaders.shade` Shade group rows / Teinter les lignes de groupe: toggle, default `true`; values: true / false
- `rowHeaders.fontSize` Size / Taille: number, default `12`; values: 7 to 30
- `rowHeaders.italic` Italic / Italique: toggle, default `false`; values: true / false
- `rowHeaders.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `rowHeaders.background` Background color (empty = none) / Couleur d'arrière-plan (vide = aucune): color, default (empty); values: hex color
- `rowHeaders.wrap` Text wrap / Retour automatique à la ligne: toggle, default `false`; values: true / false
- `rowHeaders.iconColor` + / − button color (empty = secondary text) / Couleur des boutons + / − (vide = texte secondaire): color, default (empty); values: hex color. Visible when `rowHeaders.icons` = `true`
- `rowHeaders.iconSize` + / − button size (px) / Taille des boutons + / − (px): number, default `13`; values: 8 to 28. Visible when `rowHeaders.icons` = `true`
- `rowHeaders.maxWidth` Maximum width (% of the visual) / Largeur maximale (% du visuel): number, default `40`; values: 10 to 80

### Subtotals / Sous-totaux (`subTotals`)
- `subTotals.rowSubtotals` Row subtotals / Sous-totaux des lignes: toggle, default `true`; values: true / false
- `subTotals.rowSubtotalsType` Position: dropdown, default `Top`; values: `Top` On the group row; `Bottom` "Total" row below the group. Visible when `subTotals.rowSubtotals` = `true`
- `subTotals.columnSubtotals` Column subtotals / Sous-totaux des colonnes: toggle, default `true`; values: true / false
- `subTotals.grandRow` Grand total row / Ligne de total général: toggle, default `true`; values: true / false. Visible when `subTotals.rowSubtotals` = `true`
- `subTotals.grandCol` Grand total column / Colonne de total général: toggle, default `true`; values: true / false. Visible when `subTotals.columnSubtotals` = `true`
- `subTotals.grandColPos` Grand total column position / Position de la colonne de total: dropdown, default `right`; values: `right` Right (after all columns); `left` Left (after the row headers, frozen) ★. Visible when `subTotals.columnSubtotals` = `true`
- `subTotals.label` Total label / Libellé du total: text, default (empty)
- `subTotals.background` Totals background (empty = automatic) / Arrière-plan des totaux (vide = automatique): color, default (empty); values: hex color
- `subTotals.color` Totals text (empty = text) / Texte des totaux (vide = texte): color, default (empty); values: hex color
- `subTotals.bold` Bold totals / Totaux en gras: toggle, default `true`; values: true / false

### Expand and collapse / Développer et réduire (`expand`)
- `expand.startLevel` Levels expanded at start / Niveaux développés au départ: number, default `1`; values: 0 to 10. 0: only the first level is shown. 1: its children are shown too…
- `expand.remember` Save the state in the report (edit mode) / Mémoriser l'état dans le rapport (mode édition): toggle, default `true`; values: true / false

### Column groups / Groupes de colonnes (`colGroups`)
- `colGroups.show` Collapsible groups ★ / Groupes repliables ★ ★: toggle, default `false`; values: true / false. + / − button on group headers (multi-level "Columns" field, or groups named in Column formatting › Group). A collapsed group keeps its subtotal when there is one.
- `colGroups.startCollapsed` Groups collapsed at start / Groupes réduits au départ: toggle, default `false`; values: true / false
- `colGroups.remember` Save the state in the report (edit mode) / Mémoriser l'état dans le rapport (mode édition): toggle, default `true`; values: true / false
- `colGroups.separators` Lines between groups / Traits entre les groupes: toggle, default `true`; values: true / false. Strong vertical line between two column groups (lighter between subgroups), in the header and down every row.

### Sparklines ★ / Mini-graphiques ★ (`sparklines`)
- `sparklines.show` Show / Afficher: toggle, default `false`; values: true / false. Adds, for each measure, a column that draws the row along the matrix columns (years, months…): each row's trend at a glance. A field in "Columns" is needed.
- `sparklines.kind` Type: dropdown, default `line`; values: `line` Line; `bar` Columns
- `sparklines.position` Position: dropdown, default `end`; values: `end` After the columns; `start` After the row headers
- `sparklines.title` Header / En-tête: text, default (empty). With several measures, each measure's name is added.
- `sparklines.width` Minimum width (px) / Largeur minimale (px): number, default `90`; values: 30 to 400
- `sparklines.color` Color (empty = style accent) / Couleur (vide = accent du style): color, default (empty); values: hex color
- `sparklines.lineWidth` Line width / Épaisseur des courbes: number, default `1.5`; values: 0.5 to 4
- `sparklines.area` Area under the line / Aire sous la courbe: toggle, default `false`; values: true / false
- `sparklines.last` Highlight the last value / Mettre en avant la dernière valeur: toggle, default `true`; values: true / false
- `sparklines.minMax` Minimum and maximum points / Points minimum et maximum: toggle, default `false`; values: true / false. Minimum in the unfavorable color, maximum in the favorable color (style colors).
- `sparklines.negColor` Negative columns (empty = unfavorable) / Barres négatives (vide = défavorable): color, default (empty); values: hex color
- `sparklines.sameScale` Same scale for every row / Même échelle pour toutes les lignes: toggle, default `false`; values: true / false. Off: each sparkline uses its full height (read the shape). On: rows can be compared with each other.
- `sparklines.zero` Axis from zero (lines) / Axe depuis zéro (courbes): toggle, default `false`; values: true / false

### Images (`images`)
- `images.size` Size / Dimension: dropdown, default `fixed`; values: `fixed` Fixed (same box for every image); `auto` Variable (each image's proportions)
- `images.height` Height (px) / Hauteur (px): number, default `28`; values: 8 to 400. Fixed: box height. Variable: maximum height.
- `images.width` Width (px, 0 = same as height) / Largeur (px, 0 = comme la hauteur): number, default `0`; values: 0 to 800. Fixed: box width (0: square). Variable: maximum width (0: no limit).
- `images.fit` Fit / Ajustement: dropdown, default `contain`; values: `contain` Contain (whole image); `cover` Crop (fill the box); `fill` Stretch. Visible when `images.size` = `fixed`
- `images.align` Alignment / Alignement: dropdown, default `auto`; values: `auto` Same as the column; `left` Left; `center` Center; `right` Right
- `images.invalid` Value that is not an image / Valeur qui n'est pas une image: dropdown, default `blank`; values: `blank` Blank cell; `text` Original text. A web address is never loaded (embedded images only: base64 or data URI).
- `images.headers` Images in row and column headers / Images dans les en-têtes de lignes et de colonnes: toggle, default `true`; values: true / false. A data:image/… value of the "Rows" or "Columns" field (flag, logo) is shown as an image; screen readers still read its text.

### Toolbar / Barre d'outils (`toolbar`)
- `toolbar.show` Show / Afficher: toggle, default `true`; values: true / false. Expand all / collapse all buttons and search above the matrix.
- `toolbar.buttons` Expand all / Collapse all / Tout développer / Tout réduire: toggle, default `true`; values: true / false
- `toolbar.search` Search in rows / Recherche dans les lignes: toggle, default `false`; values: true / false
- `toolbar.placeholder` Placeholder / Texte indicatif: text, default (empty)

### Auto-scroll / Défilement automatique (`autoScroll`)
- `autoScroll.show` Auto-scroll ★ / Défilement automatique ★ ★: toggle, default `false`; values: true / false. Scrolls the rows by itself when they do not fit in the visual (vertical scrollbar): ideal in a report page tooltip or on a wall display.
- `autoScroll.speed` Speed (rows per second) / Vitesse (lignes par seconde): number, default `1`; values: 0.1 to 20. Visible when `autoScroll.show` = `true`
- `autoScroll.loop` Loop (back to the top at the end) / Boucler (revenir en haut à la fin): toggle, default `true`; values: true / false. Visible when `autoScroll.show` = `true`
- `autoScroll.pause` Pause at the top and bottom (s) / Pause en haut et en bas (s): number, default `2`; values: 0 to 30. Visible when `autoScroll.show` = `true`
- `autoScroll.hoverPause` Pause on mouse hover / Pause au survol de la souris: toggle, default `true`; values: true / false. Visible when `autoScroll.show` = `true`

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).
- `tooltip.rowLabels` Repeat the row and the column / Rappeler la ligne et la colonne: toggle, default `true`; values: true / false. A cell's tooltip starts with its row and column headers (Region, City, Year…), then the value and the "Tooltips" fields.

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `false`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Bar Plume

- Power BI's 5 bar charts in one visual, with small multiples, custom series order, stacked and clustered columns and variance arrows.
- Slug `bar-chart` · version 1.4.0.0 · GUID (`visualType`) `plumeBarChart3A7E15C29B4D4F6A8E21D0C5B9F3A7E4` · page https://plumevisuals.com/en/visuals/bar-chart

### What the visual does

Bar Plume (formerly Plume Bar) is a Power BI custom visual (base range, version 1.4.0.0, installed from the `.pbiviz` file; AppSource submission in progress) that covers Power BI's five bar charts in one visual: clustered, stacked and 100% stacked, as bars (`layout.orientation` = `horizontal`) or columns (`vertical`); with `auto` it picks horizontal bars when category names are long or numerous. It adds overlapped bars, small multiples (Small multiples field), drill-down on a hierarchy (several fields in Category, Power BI drill buttons), several measures with a Legend, a custom series order, per-series settings, fixed or maximum bar width, gaps between segments, ribbons between stacks, scrolling (`bars.scrollStart` = `end` starts on the last categories), labels with the share of the category and a detail line (Label detail field), positive and negative totals, a target marker per bar or stack, Top N with "Others", and in premium stacked-and-clustered and diverging layouts, the actual total of 100% bars, variance arrows between columns, error bars, a trend line and reference lines. Bars glide from their old value to the new one (400 ms, `style.animate`).

**New in version 1.4.0.0 (30/10/2026):** Format pane reorganized (new **Layout** card with orientation, series type and shape; new **Gridlines** card); free native-parity additions: **zoom slider**, value axis "Round the range", category-axis gridlines, scale kept under filters (`valAxis.min` / `valAxis.max` from a "Dynamic format" measure); premium **bar chart race** (Play axis ★ field, re-sort at every frame, Top N per frame, stable colors, base64 images).

### 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 (`style.customColors` and the colors under it) are **free**; every other `style.preset`, the other gradient palettes (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium** (watermark without a key). See "Styles and theme JSON" below.
- Using a premium feature without a valid key shows **"Plume Visuals · Premium preview"** (French: « Plume Visuals · Aperçu premium ») in the footer of the visual, with an "Unlock →" link to the pricing page. It disappears once a key is pasted in **Format › Plume Studio License › License key** (`license.key`; French: « Licence Plume Studio › Clé de licence »), the **first card** of the Format pane.
- Premium features of Bar Plume (the watermark appears only when they actually apply):
  - `layout.type` = `stackedClustered` ("Stacked and clustered ★") or `diverging` ("Diverging (centered on zero) ★");
  - `labels.totals100` ("Total at the end of 100% bars ★", 100% stacked only);
  - the **Variance arrows ★** card (`variance.show`, `variance.mode` = `consecutive` / `firstLast` / `series`);
  - the **Error bars ★** and **Trend line ★** cards of the Analytics pane (`errorBars.show`, `trend.show`);
  - `smallMultiples.scale` = `independent` ("Independent per panel ★"), only when a field is in Small multiples;
  - `sort.topN` ("Top N ★"), with `sort.n`, `sort.others`, `sort.othersLabel`;
  - `target.variance` = `pct` ("In % ★") or `abs` ("In value ★"), only when a field is in Target;
  - `layout.shape` = `lollipop` ("Lollipop (stem and dot) ★") or `pill` ("Pill (rounded ends) ★");
  - `dataColors.mode` = `gradient` ("Gradient by value ★") or `highlight` ("Highlight one bar ★");
  - the **Reference lines ★** card of the Analytics pane (`reference.show1/2/3`, `reference.band`);
- Premium options and list values carry " ★" in their label and the description "Premium feature: usable for free with a « Premium preview » watermark…".
- Accepted keys: only keys starting with `PLUM1.` shown in the buyer's account on plumevisuals.com, checked offline (Ed25519 signature), covering `bar-chart` 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". `license.showOwner` displays "Licensed to <holder>".
- Licenses last one year (one-time payment, no automatic renewal, key accepted for 30 more days, reminders 30 and 7 days before the end). Prices per year: 39 € personal, 99 € SME, 299 € enterprise, or a catalog pack (199 € / 399 € / 1,199 € per year; tiers by number of users, designers and viewers included: personal 1–10, SME 11–200, enterprise more than 200). Renewing gives a new key to paste instead of the old one.

### Expected data shape

The visual reads **one row per category** (and per series value when Legend is used), with the measures evaluated for that row.

| Category (`category`) | Values (`values`) | Target (`target`) |
|---|---|---|
| Île-de-France | 1 412 300 | 1 350 000 |
| Bretagne | 388 950 | 420 000 |
| … | … | … |

- **Category** (`category`, label "Category" / « Axe (catégories) », grouping, up to 6 fields): one bar per value. Several fields form a hierarchy explored with Power BI's drill buttons; after "Expand all down one level", labels are concatenated ("2024 Furniture", `catAxis.concatenate` = true) or the upper level is written under the columns (false).
- **Legend (series)** (`series`, « Légende (séries) », grouping, one field, optional): one series per value (channel, year…). Unlike native charts, **a Legend can be combined with several measures**: one series per value and measure ("Store · Revenue"), each measure in a shade of the series color; with `layout.type` = `stackedClustered`, one stack per measure.
- **Values** (`values`, « Valeurs », measures, several allowed): one series per measure.
- **Small multiples** (`multiples`, « Petits multiples », grouping, one field, optional): one panel per value, in a grid (`smallMultiples.columns`, 0 = automatic); shared value axis by default, axes on outer panels only; totals, Top N, targets and analytics are kept in every panel. A click selects the category in that panel.
- **Target** (`target`, « Objectif », one measure, optional): a marker per bar (or per stack). With a Legend, the measure is evaluated per series; with `stacked` layout the stack target is the sum of the series targets. The tooltip always adds the target and the variance in % when a target exists.
- **Label detail** (`labelDetail`, « Détail des étiquettes », one measure, optional): shown under the value (`labels.detailPos` = `below`), next to it (`inline`) or instead of it (`only`) when data labels are on.
- **Lower bound / Upper bound (error bars)** (`errorLow`, `errorHigh`, one measure each, optional): bounds of the error bars ★ (`errorBars.source` = `fields` for values, `relative` for ± deltas; `percent` needs no field).
- **Tooltips** (`tooltips`, « Infobulles », measures, optional) and **Dynamic format** (`format`, « Format dynamique », measures, see below).
- Volume: up to 10,000 rows (category × small multiple) and 60 series (top-N data reduction of Power BI). Beyond the room, bars scroll.
- Values are taken as they come: Top N and "Others" are computed on the categories received, and "Others" is the **sum** of the remaining categories per series.

### DAX recipes

```dax
Revenue = SUM ( Sales[Amount] )
Gross margin = SUM ( Sales[Margin] )

// Target from a disconnected table Targets[Region], Targets[Annual target]
Target =
CALCULATE ( SUM ( Targets[Annual target] ), TREATAS ( VALUES ( Sales[Region] ), Targets[Region] ) )
    * MAX ( 1, DISTINCTCOUNT ( Sales[Year] ) )

// Year-over-year change, usable in Tooltips or for a dynamic title
Growth 2025 = DIVIDE ( CALCULATE ( [Revenue], Sales[Year] = "2025" ), CALCULATE ( [Revenue], Sales[Year] = "2024" ) ) - 1
```

For a "lower is better" metric (costs, lead times), set `target.lowerIsBetter` = true: the colors of the variance swap meaning, the sign stays mathematical.

### Interactions with the report

- Click a bar = select (cross-filters other visuals), Ctrl + click = add, click on the background = clear. Clicking the "Others" bar selects every grouped category. Legend click selects a whole series (`legend.interactive`), legend hover highlights it.
- Supports **highlighting** from other visuals: the highlighted part is drawn solid, the rest faded.
- Keyboard: Tab to the chart, arrow keys / Home / End to move between bars, Enter or Space to select (Ctrl / Shift to add), Esc to clear. Screen-reader announcements, ARIA labels.
- Context menu, Power BI tooltips (report-page tooltips too), landing page when no field is set, read-only on dashboards, high contrast (series told apart by fill), reduced motion respected. No network request.

### Dynamic formats

- **fx button** (Power BI conditional formatting) on every color and every text of the Format pane: *Field value*, *Rules*, *Gradient*. With `dataColors.mode` = `category`, each category color has its own fx button (rules color each bar like native visuals).
- **Dynamic format** field (role `format`, several measures): a measure renamed for this visual as `card.setting` (right-click › Rename for this visual) drives **any** setting: sizes, toggles, lists, fonts, colors, texts. It wins over the fixed value, the style and an fx rule; its measures are never drawn. Names ignore case, accents and separator (`Title Color` = `title.color`).
- Value used for a global setting: the common value of all bars, else the total, else the first bar. Wrap with `CALCULATE ( …, ALLSELECTED () )` for a whole-visual value. Unknown names and unusable values are reported in edit mode and ignored.
- Examples: `title.text` = `"Revenue by region · 2025 vs 2024: " & FORMAT ( CALCULATE ( [Growth 2025], ALLSELECTED () ), "+0.0 %;-0.0 %" )`; `title.color` = `IF ( CALCULATE ( [Growth 2025], ALLSELECTED () ) >= 0, "#2E7D4F", "#C0392B" )`; `sort.n` = `SELECTEDVALUE ( 'Product count'[Product count], 6 )` (a numeric range parameter). A ★ setting driven by DAX stays ★.

### Format pane: how to read the tables below

- Each option has an ID `card.option` (for example `layout.orientation`). The card is the capabilities.json **object name**, the option is the **property name**.
- Card order: `license` (always first), `style` (shared Style card: `preset`, `themeJson`, `followTheme`, `reverse`, then custom colors with `palette`, font, background, radius, animations), `dataColors` (dynamic card "Data colors": mode, then one color per series or per category, stored with its selector), `bars`, `seriesFormat` (dynamic card "Per-series settings": "Apply settings to" All series or one series; labels, label position and color, opacity, relative width when overlapped, stack when stacked and clustered, side when diverging), `sort` ("Sort and order": categories, then series order `sort.seriesBy` = `model` / `nameAsc` / `nameDesc` / `totalDesc` / `totalAsc` / `custom` with `sort.seriesNames` = "Web; Store", `sort.seriesReverse`), `target`, `variance`, `labels`, `catAxis`, `valAxis`, `legend`, `smallMultiples`, `interaction`, then `title`, `source`, `container`, `texts`. The `reference` ("Reference lines ★"), `errorBars` ("Error bars ★") and `trend` ("Trend line ★") cards are in the **Analytics** pane. Format pane in version 1.4.0.0 (30/10/2026), top to bottom: `license`, `style`, `layout`, `dataColors`, `seriesFormat`, `bars`, `labels`, `catAxis`, `valAxis`, `gridlines`, `legend`, `sort`, `target`, `variance`, `zoom`, `smallMultiples`, `play`, `race`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`; Analytics pane: `reference`, `errorBars`, `trend`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- Labels follow the language of Power BI Desktop; `texts.language` can force French or English inside the visual. "Visible when" means the option only appears when another option has one of the listed values (e.g. `sort.n` only when `sort.topN` = true, `target.goodColor` only when `target.variance` ≠ `none`).

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. Literal syntax: booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes, colors wrapped in `solid.color`. A per-series color uses an entry with a `selector`.

```json
{
  "visualType": "plumeBarChart3A7E15C29B4D4F6A8E21D0C5B9F3A7E4",
  "query": {
    "queryState": {
      "category": { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Region" } }, "queryRef": "Sales.Region", "nativeQueryRef": "Region" } ] },
      "values":   { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Revenue" } }, "queryRef": "Sales.Revenue", "nativeQueryRef": "Revenue" } ] },
      "target":   { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Target" } }, "queryRef": "Sales.Target", "nativeQueryRef": "Target" } ] },
      "format":   { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Dynamic title" } }, "queryRef": "Sales.Dynamic title", "nativeQueryRef": "Dynamic title", "displayName": "title.text" } ] }
    }
  },
  "objects": {
    "bars":       [ { "properties": { "orientation": { "expr": { "Literal": { "Value": "'vertical'" } } } } } ],
    "target":     [ { "properties": { "marker": { "expr": { "Literal": { "Value": "'line'" } } },
                                       "variance": { "expr": { "Literal": { "Value": "'pct'" } } } } } ],
    "labels":     [ { "properties": { "show": { "expr": { "Literal": { "Value": "true" } } },
                                       "decimals": { "expr": { "Literal": { "Value": "0D" } } } } } ],
    "catAxis":    [ { "properties": { "labelMode": { "expr": { "Literal": { "Value": "'rotate45'" } } } } } ],
    "dataColors": [ { "properties": { "fill": { "solid": { "color": { "expr": { "Literal": { "Value": "'#b8462a'" } } } } } },
                      "selector": { "metadata": "Sales.Revenue" } } ],
    "license":    [ { "properties": { "key": { "expr": { "Literal": { "Value": "'PLUM1.…'" } } } } } ]
  }
}
```

Top N: `"sort": [ { "properties": { "topN": { "expr": { "Literal": { "Value": "true" } } }, "n": { "expr": { "Literal": { "Value": "6D" } } } } } ]`. The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from the `.pbiviz` file).

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`.
- `style.themeJson` (Format › Style › Theme JSON ★) takes a JSON theme as plain text. Format v2: an object with an optional `extends` (a style ID above) and optional groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`; the v1 flat format (`style`, `palette`, `accent`, `background`…) is still read. Every field is optional. Colors are `#RRGGBB` (`#RGB` and `#RRGGBBAA` accepted, opacity ignored). Unknown fields and values outside the allowed lists are ignored, out-of-range numbers are clamped. Invalid JSON shows "Invalid theme JSON: ignored" in edit mode and the visual keeps its look.
- Full field list with allowed values, examples and troubleshooting: tutorial https://plumevisuals.com/ai/tutorials/en/themes-json.md (French: https://plumevisuals.com/ai/tutorials/fr/themes-json.md). The same JSON can be pasted in every Plume visual of a page.
- Priority (the last one wins): visual defaults → `style.preset` → `style.themeJson` → `style.palette` (if not "Style or theme palette") → `style.followTheme` → custom colors → options set by hand in the other cards → DAX formats (fx button, "Dynamic format" field) → Windows high contrast.

### Common pitfalls

- Five native charts: clustered / stacked / 100% stacked = `layout.type` (`clustered`, `stacked`, `stacked100`), bars or columns = `layout.orientation`.
- Unwanted scrollbar: bars are thinner than `bars.minSize` (lower it) or `bars.widthMode` = `fixed` with a large `bars.barPx`. Small multiples scroll when a panel would be lower than `smallMultiples.minHeight`.
- No target marker: Target well empty, or the measure is blank for those categories (no relationship, misspelled keys).
- Variance to target computed on the first measure when several are clustered, on the stack total when stacked. Variance arrows compare category totals (`consecutive`, `firstLast`) or the first two series (`series`).
- "Others" shows a meaningless figure for a ratio or an average: "Others" is a sum. Turn off `sort.others` for non-additive measures.
- Months sorted by value: set `sort.by` = `data` (model order) with a sort-by column in the model, or `labelAsc` with `sort.natural` for codes like "M2" / "M10".
- `labels.totals` only exists for `stacked` and `stackedClustered`, `labels.totals100` for `stacked100`; `bars.groupGap` for `clustered` and `stackedClustered` (negative = partial overlap); `bars.ribbons` for `stacked` and `stacked100`.
- Labels of small stacked segments disappear when the text does not fit: turn on `labels.overflow`, or hide them on purpose with `labels.minShare`.
- Watermark visible: a ★ option is applied (see the list above) without a valid key.
- A measure in the Dynamic format field that is never blank can bring back categories without data: return BLANK when the main measure is blank.

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

Combo bar + line chart, secondary value axis, waterfall or bridge (use Waterfall Plume), continuous date axis and zoom slider (bars scroll instead), dynamic Top N by another measure than the bar value, "Others" as an average, per-bar images or icons, data-driven bar width, export of the data from the visual, play axis or animation over time, forecast (use Line Plume).

## Bar Plume: data fields

- `category` Category / Axe (catégories) (column, 6 max): 
- `series` Legend (series) / Légende (séries) (column, 1 max): 
- `values` Values / Valeurs (measure, several max): 
- `multiples` Small multiples / Petits multiples (column, 1 max): 
- `target` Target / Objectif (measure, 1 max): 
- `labelDetail` Label detail / Détail des étiquettes (measure, 1 max): 
- `errorLow` Lower bound (error bars) / Borne basse (barres d'erreur) (measure, 1 max): 
- `errorHigh` Upper bound (error bars) / Borne haute (barres d'erreur) (measure, 1 max): 
- `tooltips` Tooltips / Infobulles (measure, several max): 
- `play` Play axis ★ / Axe de lecture ★ ★ (column, 1 max): A date, a year or an ordered category: the visual moves from one value to the next (play button)
- `image` Image (base64) ★ ★ (measure, 1 max): Text measure or column: an image (data URI or base64) per category, shown in the bar chart race.
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Bar Plume: Format pane options (288)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Layout / Disposition (`layout`)
- `layout.orientation` Orientation: dropdown, default `auto`; values: `auto` Automatic (based on room); `vertical` Columns (vertical); `horizontal` Bars (horizontal). Automatic: horizontal bars when category names are long or numerous.
- `layout.type` Series / Séries: dropdown, default `clustered`; values: `clustered` Clustered (side by side); `stacked` Stacked; `stacked100` 100% stacked; `overlap` Overlapped; `stackedClustered` Stacked and clustered ★; `diverging` Diverging (centered on zero) ★. Stacked and clustered: one stack per measure (with a legend) or per "Stack" chosen series by series. Diverging: agreement scales (Likert), side of each series in "Per-series settings".
- `layout.divergingPct` As % of the category / En % de la catégorie: toggle, default `true`; values: true / false. Visible when `layout.type` = `diverging`
- `layout.shape` Shape / Forme: dropdown, default `bar`; values: `bar` Bar; `lollipop` Lollipop (stem and dot) ★; `pill` Pill (rounded ends) ★

### Data colors / Couleurs des données (`dataColors`, one entry per item with a selector)
- `dataColors.mode` Coloring / Coloration: dropdown, default `auto`; values: `auto` Palette (one color per series); `single` Single color; `category` One color per category; `gradient` Gradient by value ★; `highlight` Highlight one bar ★
- `dataColors.single` Color / Couleur: color, default (empty); values: hex color
- `dataColors.fill` Color / Couleur: color, default (empty); values: hex color
- `dataColors.negative` Negative values (empty = same color) / Valeurs négatives (vide = même couleur): color, default (empty); values: hex color
- `dataColors.highlightWhat` Highlighted bar / Barre mise en avant: dropdown, default `max`; values: `max` Largest; `min` Smallest; `first` First; `last` Last; `name` Named category
- `dataColors.highlightName` Category name / Nom de la catégorie: text, default (empty)
- `dataColors.highlightColor` Highlight color (empty = accent) / Couleur mise en avant (vide = accent): color, default (empty); values: hex color
- `dataColors.othersColor` Other bars color (empty = style gray) / Couleur des autres barres (vide = gris du style): color, default (empty); values: hex color

### Per-series settings / Réglages par série (`seriesFormat`, one entry per item with a selector)
- `seriesFormat.labels` Data labels / Étiquettes de données: dropdown, default `inherit`; values: `inherit` Same as the Labels card; `on` Shown; `off` Hidden
- `seriesFormat.labelPos` Label position / Position des étiquettes: dropdown, default `inherit`; values: `inherit` Same as the Labels card; `auto` Automatic; `outsideEnd` Outside end; `insideEnd` Inside end; `center` Center; `insideBase` Inside base
- `seriesFormat.labelColor` Label color (empty = Labels card) / Couleur des étiquettes (vide = carte Étiquettes): color, default (empty); values: hex color
- `seriesFormat.opacity` Opacity (%, 0 = Bars card) / Opacité (%, 0 = carte Barres): number, default `0`; values: 0 to 100
- `seriesFormat.width` Relative width (%, 0 = automatic) / Largeur relative (%, 0 = automatique): number, default `0`; values: 0 to 100. Overlapped: width of the series relative to the room (a thin bar in front of a wide one).
- `seriesFormat.stack` Stack (stacked and clustered) / Pile (empilées et groupées): dropdown, default `auto`; values: `auto` Automatic (one per measure); `1` Stack 1; `2` Stack 2; `3` Stack 3; `4` Stack 4; `5` Stack 5; `6` Stack 6
- `seriesFormat.side` Side (diverging) / Côté (divergentes): dropdown, default `auto`; values: `auto` Automatic (first half on the left); `left` Negative (left / bottom); `right` Positive (right / top); `neutral` Neutral (across zero)

### Bars / Barres (`bars`)
- `bars.widthMode` Bar width / Largeur des barres: dropdown, default `relative`; values: `relative` Relative to the room; `fixed` Fixed (px)
- `bars.thickness` Bar thickness (%) / Épaisseur des barres (%): number, default `70`; values: 10 to 100. Visible when `bars.widthMode` = `relative`
- `bars.maxPx` Maximum width (px, 0 = no limit) / Largeur maximale (px, 0 = sans limite): number, default `0`; values: 0 to 400. Visible when `bars.widthMode` = `relative`
- `bars.barPx` Width (px) / Largeur (px): number, default `24`; values: 2 to 300. Visible when `bars.widthMode` = `fixed`
- `bars.groupGap` Gap between series (%) / Écart entre séries (%): number, default `6`; values: -50 to 50. Visible when `layout.type` = `clustered` or `stackedClustered`. Negative: bars of the same group partly overlap.
- `bars.segmentGap` Gap between segments (px) / Espace entre les segments (px): number, default `0`; values: 0 to 12. Visible when `layout.type` = `stacked` or `stacked100` or `stackedClustered` or `diverging`
- `bars.outerPad` Outer padding (% of a category) / Marge aux extrémités (% d'une catégorie): number, default `0`; values: 0 to 100
- `bars.radius` End rounding / Arrondi du bout: number, default `2`; values: 0 to 20
- `bars.dotSize` Dot size / Taille du point: number, default `10`; values: 4 to 30. Visible when `layout.shape` = `lollipop`
- `bars.minSize` Minimum thickness before scrolling (px) / Épaisseur minimale avant défilement (px): number, default `16`; values: 6 to 80
- `bars.scrollStart` Initial scroll position / Défilement au départ: dropdown, default `start`; values: `start` Start; `end` End (last categories)
- `bars.opacity` Opacity (%) / Opacité (%): number, default `100`; values: 10 to 100
- `bars.border` Outline / Contour: toggle, default `false`; values: true / false
- `bars.borderColor` Outline color (empty = style stroke) / Couleur du contour (vide = contour du style): color, default (empty); values: hex color. Visible when `bars.border` = `true`
- `bars.overlapOrder` Drawing order / Ordre de dessin: dropdown, default `largestBehind`; values: `largestBehind` Largest behind; `series` Series order
- `bars.overlapNarrow` Following series narrower / Séries suivantes plus fines: toggle, default `false`; values: true / false. Each series is narrower than the previous one: actual inside plan, this year inside last year.
- `bars.track` Track behind bars / Rail derrière les barres: toggle, default `false`; values: true / false. A light bar up to the maximum, behind each bar.
- `bars.ribbons` Ribbons between stacks / Rubans entre les piles: toggle, default `false`; values: true / false. Visible when `layout.type` = `stacked` or `stacked100`. Links each series from one stack to the next, like Power BI ribbons.
- `bars.ribbonOpacity` Ribbon opacity (%) / Opacité des rubans (%): number, default `25`; values: 5 to 90. Visible when `layout.type` = `stacked` or `stacked100`

### Data labels / Étiquettes de données (`labels`)
- `labels.show` Show / Afficher: toggle, default `false`; values: true / false
- `labels.content` Content / Contenu: dropdown, default `value`; values: `value` Value; `percent` Share (of the stack, else of the total); `percentCat` Share of the category; `percentTotal` Share of the grand total; `valuePercent` Value and share; `valuePercentCat` Value and share of the category; `category` Category; `series` Series; `categoryValue` Category and value; `seriesValue` Series and value
- `labels.position` Position: dropdown, default `auto`; values: `auto` Automatic; `outsideEnd` Outside end; `insideEnd` Inside end; `center` Center; `insideBase` Inside base
- `labels.minShare` Hide below (% of the category) / Masquer sous (% de la catégorie): number, default `0`; values: 0 to 50. Labels of segments smaller than this share of their category are hidden (0 = all).
- `labels.overflow` Overflow text / Laisser déborder le texte: toggle, default `false`; values: true / false. Stacked: the label of a segment that is too short is shown anyway (otherwise it is hidden).
- `labels.detailPos` "Label detail" field / Champ « Détail des étiquettes »: dropdown, default `below`; values: `below` On a second line; `inline` Next to the value; `only` Instead of the value
- `labels.orientation` Text orientation / Orientation du texte: dropdown, default `horizontal`; values: `horizontal` Horizontal; `vertical` Vertical (columns)
- `labels.background` Label background / Fond des étiquettes: toggle, default `false`; values: true / false
- `labels.bgColor` Background color (empty = visual background) / Couleur du fond (vide = fond du visuel): color, default (empty); values: hex color. Visible when `labels.background` = `true`
- `labels.bgOpacity` Background opacity (%) / Opacité du fond (%): number, default `85`; values: 5 to 100. Visible when `labels.background` = `true`
- `labels.fontSize` Size / Taille: number, default `10`; values: 6 to 24
- `labels.color` Color (empty = automatic) / Couleur (vide = automatique): color, default (empty); values: hex color. Automatic: readable color depending on the background (inside bars: white or dark).
- `labels.bold` Bold / Gras: toggle, default `false`; values: true / false
- `labels.halo` Text halo / Halo autour du texte: toggle, default `true`; values: true / false
- `labels.declutter` Hide overlapping labels / Masquer les étiquettes qui se chevauchent: toggle, default `true`; values: true / false
- `labels.totals` Total at the end of stacks / Total au bout des piles: toggle, default `true`; values: true / false. Visible when `layout.type` = `stacked` or `stackedClustered`
- `labels.totalsSplit` Positive and negative apart / Positifs et négatifs séparés: toggle, default `false`; values: true / false. Visible when `layout.type` = `stacked` or `stackedClustered`. With negative values: one total at each end of the stack instead of the net total.
- `labels.totals100` Total at the end of 100% bars ★ / Total au bout des barres 100 % ★ ★: toggle, default `false`; values: true / false. Visible when `layout.type` = `stacked100`. The actual total of each category (as a value), at the end of the 100% bar.
- `labels.totalsBold` Bold totals / Totaux en gras: toggle, default `true`; values: true / false
- `labels.totalsColor` Totals color (empty = text) / Couleur des totaux (vide = texte): color, default (empty); values: hex color
- `labels.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `labels.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `labels.prefix` Prefix / Préfixe: text, default (empty)
- `labels.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)

### Category axis / Axe des catégories (`catAxis`)
- `catAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `catAxis.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `catAxis.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `catAxis.labelMode` Long labels / Étiquettes longues: dropdown, default `auto`; values: `auto` Automatic; `wrap` Two lines; `rotate45` Tilted (45°); `rotate90` Vertical; `truncate` Truncated (…)
- `catAxis.maxSize` Maximum room (% of the visual) / Place maximale (% du visuel): number, default `30`; values: 10 to 60
- `catAxis.line` Axis line / Trait de l'axe: toggle, default `true`; values: true / false
- `catAxis.allLabels` Show every label / Afficher toutes les étiquettes: toggle, default `false`; values: true / false. No label is skipped, even when categories are tight.
- `catAxis.concatenate` Concatenate labels / Concaténer les niveaux: toggle, default `true`; values: true / false. Expanded hierarchy ("Expand all down one level"): off, the upper level is written under the columns, once per group.
- `catAxis.showTitle` Show / Afficher: toggle, default `false`; values: true / false
- `catAxis.titleText` Text / Texte: text, default (empty). Visible when `catAxis.showTitle` = `true`

### Value axis / Axe des valeurs (`valAxis`)
- `valAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `valAxis.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `valAxis.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `valAxis.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `valAxis.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `valAxis.prefix` Prefix / Préfixe: text, default (empty)
- `valAxis.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)
- `valAxis.line` Axis line / Trait de l'axe: toggle, default `false`; values: true / false
- `valAxis.scale` Scale / Échelle: dropdown, default `linear`; values: `linear` Linear; `log` Logarithmic
- `valAxis.min` Minimum: text, default (empty)
- `valAxis.max` Maximum: text, default (empty)
- `valAxis.zero` Always include zero / Toujours inclure zéro: toggle, default `true`; values: true / false. Visible when `valAxis.scale` = `linear`
- `valAxis.ticks` Number of ticks (approx.) / Nombre de graduations (environ): number, default `5`; values: 2 to 20
- `valAxis.invert` Invert axis / Inverser l'axe: toggle, default `false`; values: true / false
- `valAxis.round` Round range / Arrondir la plage: toggle, default `true`; values: true / false. Computed bounds rounded to a round tick. Off: the axis stops at the extreme values.
- `valAxis.showTitle` Show / Afficher: toggle, default `false`; values: true / false
- `valAxis.titleText` Text / Texte: text, default (empty). Visible when `valAxis.showTitle` = `true`

### Gridlines / Quadrillage (`gridlines`)
- `gridlines.valShow` Show / Afficher: toggle, default `true`; values: true / false
- `gridlines.valColor` Color (empty = style grid) / Couleur (vide = grille du style): color, default (empty); values: hex color
- `gridlines.valWidth` Width / Épaisseur: number, default `1`; values: 0.5 to 6
- `gridlines.valStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `gridlines.zeroLine` Zero line / Ligne du zéro: toggle, default `true`; values: true / false
- `gridlines.catShow` Show / Afficher: toggle, default `false`; values: true / false
- `gridlines.catColor` Color (empty = style grid) / Couleur (vide = grille du style): color, default (empty); values: hex color
- `gridlines.catWidth` Width / Épaisseur: number, default `1`; values: 0.5 to 6
- `gridlines.catStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted

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

### Sort / Tri (`sort`)
- `sort.by` Sort by / Trier par: dropdown, default `valueDesc`; values: `valueDesc` Value, descending; `valueAsc` Value, ascending; `labelAsc` Category A → Z; `labelDesc` Category Z → A; `seriesDesc` One series' value, descending; `seriesAsc` One series' value, ascending; `data` Model order. Model order keeps the order of the field (dates, months, sort-by column).
- `sort.bySeries` Series name / Nom de la série: text, default (empty). Visible when `sort.by` = `seriesDesc` or `seriesAsc`
- `sort.natural` Natural sort (2 before 10) / Tri naturel (2 avant 10): toggle, default `true`; values: true / false
- `sort.topN` Top N ★ ★: toggle, default `false`; values: true / false
- `sort.n` N: number, default `10`; values: 1 to 500. Visible when `sort.topN` = `true`
- `sort.others` Group the rest into "Others" / Regrouper le reste dans « Autres »: toggle, default `true`; values: true / false. Visible when `sort.topN` = `true`. "Others" is the sum of the remaining categories. Clicking it selects them.
- `sort.othersLabel` "Others" label / Libellé « Autres »: text, default (empty). Visible when `sort.topN` = `true`
- `sort.seriesBy` Series order / Ordre des séries: dropdown, default `model`; values: `model` Model order; `nameAsc` Name A → Z; `nameDesc` Name Z → A; `totalDesc` Total, descending; `totalAsc` Total, ascending; `custom` Custom. Order of stacks, groups and legend. Colors stay with their series.
- `sort.seriesNames` Names in order (separated by ;) / Noms dans l'ordre (séparés par ;): text, default (empty). Visible when `sort.seriesBy` = `custom`. Series missing from the list follow, in model order.
- `sort.seriesReverse` Reverse order / Inverser l'ordre: toggle, default `false`; values: true / false
- `sort.legendReverse` Legend in the visual order of stacks / Légende dans l'ordre visuel des piles: toggle, default `false`; values: true / false. Stacked columns: the legend follows the top-to-bottom order of the segments.

### Target / Objectif (`target`)
- `target.marker` Marker / Repère: dropdown, default `line`; values: `line` Line; `dot` Dot; `ghost` Ghost bar. Drawn when a field is placed in "Target".
- `target.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `target.width` Width / Épaisseur: number, default `2`; values: 1 to 6
- `target.variance` Variance to target / Écart à l'objectif: dropdown, default `none`; values: `none` None; `pct` In % ★; `abs` In value ★
- `target.goodColor` Color when reached / Couleur si atteint: color, default `#2E7D4F`; values: hex color. Visible when `target.variance` = `pct` or `abs`
- `target.badColor` Color when missed / Couleur si non atteint: color, default `#C0392B`; values: hex color. Visible when `target.variance` = `pct` or `abs`
- `target.lowerIsBetter` Lower is better / Plus bas = mieux: toggle, default `false`; values: true / false. Visible when `target.variance` = `pct` or `abs`

### Variance arrows ★ / Écarts entre colonnes ★ (`variance`)
- `variance.show` Show ★ / Afficher ★ ★: toggle, default `false`; values: true / false
- `variance.mode` Compare / Comparer: dropdown, default `consecutive`; values: `consecutive` Each category to the previous one; `firstLast` The last category to the first one; `series` 2nd series to the 1st, within each group. Compared values: the category total (the value with a single series).
- `variance.display` Show the variance / Afficher l'écart: dropdown, default `pct`; values: `pct` In %; `abs` In value; `both` In value and %
- `variance.goodColor` Increase color / Couleur des hausses: color, default `#2E7D4F`; values: hex color
- `variance.badColor` Decrease color / Couleur des baisses: color, default `#C0392B`; values: hex color
- `variance.lowerIsBetter` Decrease is good / Baisse = bonne nouvelle: toggle, default `false`; values: true / false
- `variance.fontSize` Text size / Taille du texte: number, default `9`; values: 6 to 20

### Zoom (`zoom`)
- `zoom.show` Zoom slider / Curseur de zoom: toggle, default `false`; values: true / false. Two-handle slider below the axis: choose the visible range (drag, keyboard). The position is not saved in the report.
- `zoom.labels` Slider labels / Étiquettes du curseur: toggle, default `true`; values: true / false
- `zoom.height` Height (px) / Hauteur (px): number, default `22`; values: 14 to 48

### Small multiples / Petits multiples (`smallMultiples`)
- `smallMultiples.columns` Columns (0 = automatic) / Colonnes (0 = automatique): number, default `0`; values: 0 to 12
- `smallMultiples.minHeight` Minimum panel height (px) / Hauteur minimale d'un panneau (px): number, default `80`; values: 40 to 600. Below that, the grid scrolls vertically.
- `smallMultiples.gap` Spacing (px) / Espacement (px): number, default `14`; values: 0 to 60
- `smallMultiples.scale` Value axis / Axe des valeurs: dropdown, default `shared`; values: `shared` Shared by all panels; `independent` Independent per panel ★
- `smallMultiples.outerAxes` Axes on outer panels only / Axes sur les bords seulement: toggle, default `true`; values: true / false. Visible when `smallMultiples.scale` = `shared`
- `smallMultiples.border` Panel border / Cadre des panneaux: toggle, default `false`; values: true / false
- `smallMultiples.titleShow` Title of each panel / Titre de chaque panneau: toggle, default `true`; values: true / false
- `smallMultiples.titleSize` Text size / Taille du texte: number, default `10`; values: 6 to 24. Visible when `smallMultiples.titleShow` = `true`
- `smallMultiples.titleColor` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color. Visible when `smallMultiples.titleShow` = `true`
- `smallMultiples.titleAlign` Alignment / Alignement: dropdown, default `left`; values: `left` Start; `center` Center. Visible when `smallMultiples.titleShow` = `true`
- `smallMultiples.titleTotal` Total in the title / Total dans le titre: toggle, default `false`; values: true / false. Visible when `smallMultiples.titleShow` = `true`

### Playback ★ / Lecture ★ (`play`)
- `play.start` Frame shown on opening / Image affichée à l'ouverture: dropdown, default `first`; values: `last` The last one (most recent); `first` The first one
- `play.speed` Duration of a frame (ms) / Durée d'une image (ms): number, default `900`; values: 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, default `false`; values: true / false
- `play.autoPlay` Play automatically on opening / Lecture automatique à l'ouverture: toggle, default `false`; values: 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, default `true`; values: true / false. Values, positions and colors move smoothly from one frame to the next.
- `play.controls` Play bar / Barre de lecture: toggle, default `true`; values: true / false
- `play.position` Bar position / Position de la barre: dropdown, default `bottom`; values: `bottom` Bottom; `top` Top. Visible when `play.controls` = `true`
- `play.ticks` Tick marks / Graduations: dropdown, default `auto`; values: `auto` Automatic; `all` Every frame; `none` None. Visible when `play.controls` = `true`
- `play.tickLabels` Tick labels / Étiquettes des graduations: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.stepButtons` Start and end buttons / Boutons début et fin: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.speedButton` Speed button / Bouton de vitesse: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.showLabel` Current value in large type / Valeur en cours en grand: toggle, default `true`; values: true / false
- `play.labelSize` Large value size / Taille de la valeur en grand: number, default `44`; values: 12 to 160. Visible when `play.showLabel` = `true`
- `play.labelPosition` Large value position / Position de la valeur en grand: dropdown, default `bottomRight`; values: `bottomRight` Bottom right; `topRight` Top right; `topLeft` Top left; `bottomLeft` Bottom left; `center` Center. Visible when `play.showLabel` = `true`

### Bar chart race ★ / Course de barres ★ (`race`)
- `race.order` Bar order / Ordre des barres: dropdown, default `rank`; values: `rank` Ranking at each frame (re-sort); `fixed` Fixed order (Sort card). Ranking: bars swap places when a category overtakes another.
- `race.topN` Bars shown (Top N of each frame) / Barres affichées (Top N de chaque image): number, default `10`; values: 1 to 60
- `race.scale` Value scale / Échelle des valeurs: dropdown, default `frame`; values: `frame` Fitted to each frame; `all` Shared by all frames
- `race.interpolate` In-between values during the transition / Valeurs intermédiaires pendant la transition: toggle, default `true`; values: true / false. Bars and labels count from one value to the next (otherwise they jump to the new value).
- `race.values` Values at the end of bars / Valeurs au bout des barres: toggle, default `true`; values: true / false. Number format: Data labels card (units, decimals, prefix, suffix).
- `race.names` Category names / Noms des catégories: dropdown, default `axis`; values: `axis` On the axis; `inside` Inside the bar; `end` At the end of the bar
- `race.images` Category images / Images des catégories: toggle, default `true`; values: true / false. "Image (base64)" field: one image per category (data URI or base64; web addresses refused).
- `race.imageShape` Image shape / Forme de l'image: dropdown, default `circle`; values: `circle` Circle; `square` Rounded square. Visible when `race.images` = `true`
- `race.total` Frame total under the large value / Total de l'image sous la valeur en grand: toggle, default `false`; values: true / false

### Reference lines ★ / Lignes de référence ★ (`reference`, Analytics pane)
- `reference.show1` Show / Afficher: toggle, default `false`; values: true / false
- `reference.kind1` Value / Valeur: dropdown, default `average`; values: `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile; `measure` "Target" field (average)
- `reference.value1` Constant value / Valeur constante: number, default `0`. Visible when `reference.kind1` = `constant`
- `reference.pct1` Percentile / Centile: number, default `90`; values: 1 to 99. Visible when `reference.kind1` = `percentile`
- `reference.label1` Label / Libellé: text, default (empty)
- `reference.showValue1` Show the value / Afficher la valeur: toggle, default `true`; values: true / false
- `reference.color1` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.style1` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `reference.width1` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `reference.labelPos1` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None
- `reference.show2` Show / Afficher: toggle, default `false`; values: true / false
- `reference.kind2` Value / Valeur: dropdown, default `constant`; values: `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile; `measure` "Target" field (average)
- `reference.value2` Constant value / Valeur constante: number, default `0`. Visible when `reference.kind2` = `constant`
- `reference.pct2` Percentile / Centile: number, default `90`; values: 1 to 99. Visible when `reference.kind2` = `percentile`
- `reference.label2` Label / Libellé: text, default (empty)
- `reference.showValue2` Show the value / Afficher la valeur: toggle, default `true`; values: true / false
- `reference.color2` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.style2` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `reference.width2` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `reference.labelPos2` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None
- `reference.show3` Show / Afficher: toggle, default `false`; values: true / false
- `reference.kind3` Value / Valeur: dropdown, default `median`; values: `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile; `measure` "Target" field (average)
- `reference.value3` Constant value / Valeur constante: number, default `0`. Visible when `reference.kind3` = `constant`
- `reference.pct3` Percentile / Centile: number, default `90`; values: 1 to 99. Visible when `reference.kind3` = `percentile`
- `reference.label3` Label / Libellé: text, default (empty)
- `reference.showValue3` Show the value / Afficher la valeur: toggle, default `true`; values: true / false
- `reference.color3` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.style3` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `reference.width3` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `reference.labelPos3` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None
- `reference.band` Show / Afficher: toggle, default `false`; values: true / false
- `reference.bandFrom` From / De: number, default `0`
- `reference.bandTo` To / À: number, default `0`
- `reference.bandLabel` Label / Libellé: text, default (empty)
- `reference.bandColor` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.bandOpacity` Opacity (%) / Opacité (%): number, default `12`; values: 2 to 60

### Error bars ★ / Barres d'erreur ★ (`errorBars`, Analytics pane)
- `errorBars.show` Show ★ / Afficher ★ ★: toggle, default `false`; values: true / false
- `errorBars.source` Bounds / Bornes: dropdown, default `fields`; values: `fields` Lower / Upper bound fields (values); `relative` Lower / Upper bound fields (± deltas); `percent` Percentage of the value. Stacked: on the stack total. With a single delta field, it is used on both sides.
- `errorBars.pct` Percentage (±) / Pourcentage (±): number, default `10`; values: 0 to 100. Visible when `errorBars.source` = `percent`
- `errorBars.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `errorBars.width` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `errorBars.cap` Cap width (px) / Largeur des taquets (px): number, default `8`; values: 0 to 40
- `errorBars.band` Shaded band instead of whiskers / Bande ombrée plutôt que des traits: toggle, default `false`; values: true / false

### Trend ★ / Tendance ★ (`trend`, Analytics pane)
- `trend.show` Show ★ / Afficher ★ ★: toggle, default `false`; values: true / false
- `trend.on` Computed on / Calculée sur: dropdown, default `total`; values: `total` Category totals; `series` Each series (clustered, overlapped)
- `trend.color` Color (empty = text or series) / Couleur (vide = texte ou série): color, default (empty); values: hex color
- `trend.style` Line style / Style du trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `trend.width` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `trend.label` Slope at the end of the line / Pente en fin de ligne: toggle, default `false`; values: true / false

### Interactions (`interaction`)
- `interaction.hover` Highlight on hover / Mettre en avant au survol: toggle, default `true`; values: true / false
- `interaction.dim` Dimmed items opacity (%) / Opacité des éléments estompés (%): number, default `25`; values: 5 to 80

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Line Plume

- Lines and areas on a real time axis, with trends, forecasts and annotations that follow the data.
- Slug `line-chart` · version 1.5.0.0 · GUID (`visualType`) `plumeLineChart5C1B8E47D2A04E9F9B36C7A2E1D5F084` · page https://plumevisuals.com/en/visuals/line-chart

### What the visual does

Line Plume (formerly Plume Line) is a Power BI custom visual (base range, version 1.5.0.0, installed from the `.pbiviz` file; AppSource submission in preparation) that draws line and area charts on a real time axis: dates are spaced by their real gap with calendar ticks (years, quarters, months, weeks, days, hours); numbers and categories work too. Straight, smooth (monotone, no overshoot) or step lines, solid or stacked areas, missing values (break, connect, zero), markers, a secondary Y axis (secondary series dashed, also with a Legend since 1.3.0.0) and a vertical hover guide that lists every series of the date in one tooltip. Premium adds **annotations attached to points** (x value + series) that follow the line when data or filters change, end-of-line labels, one highlighted series, gradient areas, and since 1.3.0.0 an Analytics pane with **trends and forecasts** (linear, polynomial, exponential, logarithmic, power, Holt, seasonal Holt-Winters, with an 80 % or 95 % forecast interval, projected periods and equation / R²), a **moving average**, **horizontal lines** (constants, statistics, free list, measures) and **vertical lines** (today, dates, shaded periods, event measure), plus a dashed **future part**, **threshold colors** and a shaded **area between two series** in Format › Lines. Since 1.4.0.0, a **Per-series settings** card sets these options series by series. Everything is computed inside the visual. New data draws from left to right; the same points glide.

**New in version 1.5.0.0 (30/10/2026):** Format pane reorganized (new **Gridlines** card); free native-parity additions: **small multiples** (shared or independent Y axis), **combo chart** (Per-series settings › Type = Columns), 100% stacked areas, **zoom slider**, error bars, date tick spacing, "Round the range", series name from a measure; premium **several highlighted series ★**.

### 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 (`style.customColors` and the colors under it) are **free**; every other `style.preset`, the other gradient palettes (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium** (watermark without a key). See "Styles and theme JSON" below.
- Using a premium feature without a valid key shows **"Plume Visuals · Premium preview"** (French: « Plume Visuals · Aperçu premium ») in the footer, with an "Unlock →" link to the pricing page. It disappears once a key is pasted in **Format › Plume Studio License › License key** (`license.key`; French: « Licence Plume Studio › Clé de licence »), the **first card** of the Format pane.
- Premium features of Line Plume (the watermark appears only when they actually apply):
  - the **Annotations ★** card: watermark when `annotations.show` is on (default) **and** at least one annotation exists (a valid line in `annotations.list`, or a non-blank value of the Annotations (text) measure);
  - the **End-of-line labels ★** card (`endLabels.show`), except when the free **Minimal** style turns them on by itself and they are left as they are (since 1.3.1.0); turned on by hand, or tuned under Minimal (`endLabels.content`, `fontSize`, `colorBy`, `hideLegend`), they are ★;
  - `dataColors.mode` = `highlight` ("Highlight one series ★");
  - `lines.area` = `gradient` ("Gradient ★");
  - the Analytics pane: **Horizontal lines ★** (`reference.*`, the `reference.list` free list, the role **Horizontal lines (measures)** `refY`), **Vertical lines ★** (`vlines.today`, `vlines.list`, the role **Vertical lines (events)** `events`), **Moving average ★** (`movingAvg.show`), **Trend and forecast ★** (`trend.show`);
  - Format › Lines: **future part dashed ★** (`lines.futureShow`), **threshold colors ★** (`lines.thrShow`), **area between two series ★** (`lines.betweenShow`);
- Accepted keys: only keys starting with `PLUM1.` from the buyer's account on plumevisuals.com, checked offline (Ed25519 signature), covering `line-chart` 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". `license.showOwner` displays "Licensed to <holder>".
- Licenses last one year (one-time payment, no automatic renewal, key accepted for 30 more days, reminders 30 and 7 days before the end). Prices per year: 39 € personal, 99 € SME, 299 € enterprise, or a catalog pack (199 € / 399 € / 1,199 € per year; tiers by number of users, designers and viewers included: personal 1–10, SME 11–200, enterprise more than 200).

### Expected data shape

The visual reads **one row per x value** (and per series when Legend is used), with the measures evaluated for that row.

| X axis (`axis`) | Legend (`series`) | Y axis values (`values`) | Annotations (text) (`annotations`) |
|---|---|---|---|
| 2024-10-01 | Web | 48 210 | New website |
| 2024-11-01 | Web | 61 930 | |
| … | … | … | … |

- **X axis** (`axis`, label "X axis" / « Axe X », grouping, one field): a date column (use the field itself, not the Date Hierarchy), a number column (years as whole numbers) or any category. `xAxis.type` forces `continuous` or `categorical`.
- **Legend (series)** (`series`, « Légende (séries) », optional): one line per value. **With a Legend, Y axis values accepts one measure and Secondary Y axis values one measure** (one dashed line per series on the secondary axis, since 1.3.0.0).
- **Y axis values** (`values`, « Valeurs (axe Y) », measures): one line per measure without Legend.
- **Secondary Y axis values** (`values2`, « Valeurs (axe Y secondaire) », measures, optional): drawn dashed against `y2Axis`.
- **Annotations (text)** (`annotations`, « Annotations (texte) », one text measure, optional ★): one annotation per non-blank value, attached to the first main line of its group. With a Legend the measure is evaluated **per series**, so a measure that ignores the series annotates every line.
- **Horizontal lines (measures) ★** (`refY`, « Lignes horizontales (mesures) ★ », measures, optional): one line per measure, flat if the measure has the same value everywhere (target, What-if parameter), stepped if it changes along the X axis (monthly target); with a Legend, one line per series in its color; value shown in the tooltip.
- **Vertical lines (events) ★** (`events`, « Lignes verticales (événements) ★ », one measure, optional): a text measure (a line where it is not blank, labelled with the text), a date measure (a line at that date) or a 1/0 flag (a line where it is not 0).
- **Tooltips** (`tooltips`) and **Dynamic format** (`format`, see below).
- Volume: 30,000 x values per data window, more fetched automatically up to 100,000; beyond, a warning icon "Only the first n rows are loaded". Up to 60 series.

### Annotations: list syntax (`annotations.list`)

One line per annotation, `x | text` or `x | series | text`; lines starting with `#` or `//` are comments.

```text
## Comment
2023-11 | Web | Black Friday: Web record
2023-12-01 | Store | Christmas in store
2025-03-15 | Mid-March
```

- **x**: a date (`2024-06-01`, `2024-06`, `2024`, `2024-06-01T14:30`, `15/06/2024` with a day-first locale, `06/15/2024` in en-US), a number or a category as displayed. A date or number not in the data snaps to the nearest point inside the axis range; outside it, the annotation is hidden.
- **series**: optional; legend label, case and accents ignored. Empty: the first line that has a value at x.
- **text**: up to 4 wrapped lines. Escape a vertical bar as `\|`, a value starting with `#` or `//` as `\#…` / `\//…`.
- Unplaceable lines (unknown series, unreadable x) are reported at the bottom in edit mode only: "Annotation ignored (series or x not found): …". A filtered-out x is not an error.
- In edit mode (`annotations.editOnChart`), hovering shows an **"Annotate"** button: click a point, type, Enter (Esc cancels); the visual writes the line into the list. Drag to move (offsets saved in the hidden object `annotState.offsets`), double-click to edit, × to delete. Annotations from the measure can be dragged but not edited or deleted. Keyboard: Tab, "Annotate" (Enter), ← → date, ↑ ↓ line, Enter to type.

### Per-series settings (since 1.4.0.0)

Format › **Per-series settings** (`seriesFormat`, French « Réglages par série »), list **"Apply settings to"**: *All series*, then each series (each measure without a Legend; each Legend value with a Legend; with a Legend the secondary-axis measure is one entry). Priority: the series' own value, else *All series*, else the regular card (`inherit` = "Same as the … card").

- Free: `lineStyle` (`inherit`, `solid`, `dashed`, `dotted`), `width` (0 = Lines card), `shape` (`linear`, `smooth`, `step`), `markers`, `labels` (`on` / `off`), `area` (`none`, `solid`), `reference` (series counted in the computed horizontal lines).
- ★: `area` = `gradient`, `future` = `on` with its own `futureDate` (empty = the Lines card date, else today) and `futureStyle`, `threshold` = `on`, `between` = `first` / `second` (the two series of the area between two series, no names to type), `endLabel` = `on`, `trend` = `on` (a trend for this series with the Trend and forecast card settings, even when that card is off), `movingAvg` = `on`. `off` removes the feature from a series.
- One series only: `off` on All series, then `on` on that series. Example: CA solid and Marge brute dashed after July 2025 = Marge brute › Future part dashed: Yes, Starting from: 2025-07.
- In PBIP, per-series values are stored with the series selector (`"selector": { "metadata": "Sales.Revenue" }` for a measure, a data selector for a Legend value), All series without selector.

### Analytics pane (★, since 1.3.0.0)

- **Trend and forecast** (`trend.*`): `trend.kind` = `linear`, `poly` (`trend.degree` 2 to 6), `exp`, `log`, `power` (least squares), `holt` (Holt exponential smoothing, `trend.damped`), `holtWinters` (`trend.season`: 0 = automatic, 12 for months, 4 for quarters, 7 for days, 52 for weeks; needs two full seasons, else Holt). `trend.window` = 0 (all points) or the last N points; `trend.applyTo` = all series, primary axis or named series (`trend.names`, separated by `;`), one trend per series, Legend included. `trend.horizon` = 0 to 500 periods projected after the last point (months, quarters and years follow the calendar; also on a category axis: "+1, +2…" slots, or dates if categories are dates); the X axis is extended. `trend.interval` = `none`, `80`, `95` (Student prediction interval for regressions, approximate error variance at h steps for smoothing), `trend.bandOpacity`. `trend.projStyle`, `trend.endValue`, `trend.equation` (equation and R², x = period number), `trend.legend`. Hovering the projected zone shows the period, each series' forecast and the interval.
- **Moving average** (`movingAvg.*`): `period` 2 to 400 points, `method` = `simple`, `weighted`, `exponential` (α = 2 / (N + 1)), `align` = trailing or centered, `partial` (start with an incomplete window), `applyTo` / `names`, `dimSource` (opacity of the original line, 40 % by default), `legend`. Blank values are skipped. Independent from the trend (both can show).
- **Horizontal lines** (`reference.*`): 3 lines (`kindN` = constant, average, median, min, max, percentile), a band (`band`, `bandFrom`, `bandTo`), and the free list `reference.list`, one per line: `1200 | Target | #2E7D4F`, `260 000 | Record | accent | dotted`, `800..1000 | Target zone`, `y2: 30 % | Margin target` (secondary axis). Colors: `#RRGGBB`, `accent`, `favorable`, `défavorable` / `unfavorable`; styles `solid`, `dashed`, `dotted` (French `plein`, `tirets`, `pointillés`).
- **Vertical lines** (`vlines.*`): `vlines.today` (+ `todayLabel`), and the list `vlines.list`: `2024-03-15 | Launch | #B8462A | solid`, `2024-07..2024-08 | Summer` (shaded period from the start of July to the end of August), `today | Today`, `Q3 2024 | Acquisition` (category as displayed). Dates: `2024-03-15`, `2024-03`, `2024`, `15/03/2024` (`03/15/2024` in en-US). A date outside the axis is ignored; an unreadable line is reported at the bottom in edit mode only ("Horizontal line ignored" / "Vertical line ignored").
- Format › Lines: **future part** (`futureShow`, from `today` or `futureDate`, `futureStyle`): the line after that date is dashed, same series, no extra legend entry; **threshold** (`thrShow`, `thrSource` = fixed `thrValue` or the first horizontal line, `thrAbove` / `thrBelow` colors): the line, its area and markers change color at the exact crossing, the area goes from the line to the threshold; **area between two series** (`betweenShow`, `betweenA`, `betweenB`, `betweenUp`, `betweenDown`, `betweenOpacity`).

### DAX recipes

```dax
Revenue = SUM ( Sales[Amount] )
Margin rate = DIVIDE ( SUM ( Sales[Margin] ), [Revenue] )   // good candidate for the secondary axis

// Annotations (text) from a disconnected table Events[Month], Events[Text]
Event =
VAR m = MAX ( Sales[Month] )
RETURN CONCATENATEX ( FILTER ( Events, Events[Month] = m ), Events[Text], " · " )

// Horizontal lines (measures): a flat target, or a monthly target (stepped line)
Target = 40000
Monthly target = AVERAGEX ( VALUES ( Sales[Month] ), [Revenue] ) * 1.08

// Vertical lines (events): text where something happened, blank elsewhere
Milestone = SWITCH ( MAX ( Sales[Month] ), DATE ( 2024, 9, 1 ), "New website", BLANK () )

// With a Legend: annotate one series only
Event (Web only) = IF ( SELECTEDVALUE ( Sales[Channel] ) = "Web", [Event] )
```

### Interactions with the report

- Hover: vertical guide (`interaction.crosshair`) and one tooltip with every series at that x. Click = nearest point (cross-filters other visuals), Ctrl + click = add, click on the legend selects a whole series, legend hover highlights it.
- Keyboard: ← → move through x values (values are announced), Enter selects the x value, Esc clears.
- Line Plume is cross-filtered by other visuals (it does not render highlighting). Context menu, report-page tooltips, landing page, read-only on dashboards, high contrast (series told apart by solid, dashed and dotted strokes), reduced motion. No network request.

### Dynamic formats

- **fx button** on every color and text of the Format pane (*Field value*, *Rules*, *Gradient*), including `annotations.list` and `annotations.color`.
- **Dynamic format** field (role `format`): a measure renamed for this visual as `card.setting` drives **any** setting (sizes, toggles, lists, fonts, colors, texts); it wins over the fixed value, the style and an fx rule, and is never drawn. Names ignore case, accents and separator.
- Value used for a global setting: common value of all rows, else the total, else the first row; use `CALCULATE ( …, ALLSELECTED () )` for a whole-visual value.
- Examples: `annotations.list` = `CONCATENATEX ( Notes, FORMAT ( Notes[Month], "yyyy-MM" ) & " | " & Notes[Channel] & " | " & Notes[Text], UNICHAR ( 10 ) )` (line breaks are kept; the measure then overrides the typed list, so the "Annotate" button edits are not used); `lines.interpolation` = `"smooth"`; `title.subtitle` from a measure. A ★ setting driven by DAX stays ★.

### Format pane: how to read the tables below

- Each option has an ID `card.option` (object name + property name in capabilities.json).
- Card order: `license`, `style`, `dataColors` (dynamic "Data colors": mode, then one color per series stored with its selector), `lines`, `endLabels` (★), `labels`, `annotations` (★), `xAxis`, `yAxis`, `y2Axis` (shown only with secondary values), `legend`, `interaction`, then `title`, `source`, `container`, `texts`. `reference` (horizontal lines), `vlines` (vertical lines), `movingAvg` and `trend` are in the **Analytics** pane. Format pane in version 1.5.0.0 (30/10/2026), top to bottom: `license`, `style`, `dataColors`, `lines`, `seriesFormat`, `endLabels`, `labels`, `xAxis`, `yAxis`, `y2Axis`, `gridlines`, `legend`, `annotations`, `zoom`, `smallMultiples`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`; Analytics pane: `reference`, `vlines`, `errorBars`, `movingAvg`, `trend`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- `xAxis.dateFormat` is shown only for a time axis, `xAxis.labelMode` only for categories. Labels follow the Power BI Desktop language; `texts.language` can force French or English.

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are data role names, `objects` keys are option IDs. Literals: `true` / `false`, numbers with `D`, strings in single quotes (line breaks as `\n` in JSON), colors in `solid.color`.

```json
{
  "visualType": "plumeLineChart5C1B8E47D2A04E9F9B36C7A2E1D5F084",
  "query": {
    "queryState": {
      "axis":   { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Month" } }, "queryRef": "Sales.Month", "nativeQueryRef": "Month" } ] },
      "series": { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Channel" } }, "queryRef": "Sales.Channel", "nativeQueryRef": "Channel" } ] },
      "values": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Revenue" } }, "queryRef": "Sales.Revenue", "nativeQueryRef": "Revenue" } ] }
    }
  },
  "objects": {
    "lines":       [ { "properties": { "interpolation": { "expr": { "Literal": { "Value": "'smooth'" } } },
                                        "width": { "expr": { "Literal": { "Value": "2.5D" } } } } } ],
    "annotations": [ { "properties": { "list": { "expr": { "Literal": { "Value": "'2023-11 | Web | Black Friday: Web record\n2024-05 | Web | Mother''s Day campaign'" } } },
                                        "style": { "expr": { "Literal": { "Value": "'filled'" } } },
                                        "content": { "expr": { "Literal": { "Value": "'textValue'" } } } } } ],
    "xAxis":       [ { "properties": { "dateFormat": { "expr": { "Literal": { "Value": "'MMM yyyy'" } } } } } ],
    "license":     [ { "properties": { "key": { "expr": { "Literal": { "Value": "'PLUM1.…'" } } } } } ]
  }
}
```

A per-line color without Legend: `"dataColors": [ { "properties": { "fill": { "solid": { "color": { "expr": { "Literal": { "Value": "'#b8462a'" } } } } } }, "selector": { "metadata": "Sales.Revenue" } } ]`. Never write `annotState` by hand. The custom visual package must also be embedded in the report.

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`.
- `style.themeJson` (Format › Style › Theme JSON ★) takes a JSON theme as plain text. Format v2: an object with an optional `extends` (a style ID above) and optional groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`; the v1 flat format (`style`, `palette`, `accent`, `background`…) is still read. Every field is optional. Colors are `#RRGGBB` (`#RGB` and `#RRGGBBAA` accepted, opacity ignored). Unknown fields and values outside the allowed lists are ignored, out-of-range numbers are clamped. Invalid JSON shows "Invalid theme JSON: ignored" in edit mode and the visual keeps its look.
- Full field list with allowed values, examples and troubleshooting: tutorial https://plumevisuals.com/ai/tutorials/en/themes-json.md (French: https://plumevisuals.com/ai/tutorials/fr/themes-json.md). The same JSON can be pasted in every Plume visual of a page.
- Priority (the last one wins): visual defaults → `style.preset` → `style.themeJson` → `style.palette` (if not "Style or theme palette") → `style.followTheme` → custom colors → options set by hand in the other cards → DAX formats (fx button, "Dynamic format" field) → Windows high contrast.

### Common pitfalls

- Only years on the axis: the Date Hierarchy was dropped; use the date field itself.
- Same annotation repeated on each line: the Annotations (text) measure ignores the series (see DAX recipes).
- Annotation missing: x outside the current axis range, unknown series name, or `annotations.show` off. Check the edit-mode message at the bottom.
- `15/03/2025` read as month/day: dates in the list follow the number locale; ISO `2025-03-15` always works.
- Only one measure accepted in Y axis values: a Legend is set (one measure on each axis at most).
- Settings ignored for one series: the series has its own value in Per-series settings (it wins over the cards).
- No forecast drawn: `trend.horizon` is 0, or Holt-Winters has less than two full seasons (it falls back to Holt), or the series has fewer than 3 points.
- Log scale hides points: values ≤ 0 are ignored on a logarithmic axis.
- Watermark visible: annotations exist, end labels turned on or tuned by hand, highlight, gradient area, horizontal or vertical lines, moving average, trend, future part, threshold, area between series, or a ★ style, palette or theme JSON is used without a valid key. The free Minimal style alone never shows it.

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

Bars or columns combined with lines (use Bar Plume for bars), ARIMA / Prophet or forecasts computed outside the visual, forecasts of the secondary axis driven by another measure, more than one secondary axis, a different trend type per series, small multiples, drill-down inside the visual, play axis / time animation, annotation images or links, free-floating annotations not attached to a point, annotations on the secondary axis series from the measure, zoom slider, export of annotations.

## Line Plume: data fields

- `axis` X axis / Axe X (column, 1 max): 
- `series` Legend (series) / Légende (séries) (column, 1 max): 
- `multiples` Small multiples / Petits multiples (column, 1 max): 
- `values` Y axis values / Valeurs (axe Y) (measure, several max): 
- `values2` Secondary Y axis values / Valeurs (axe Y secondaire) (measure, several max): 
- `refY` Reference lines (measures) ★ / Lignes de référence (mesures) ★ ★ (measure, several max): One horizontal line per measure (target, what-if parameter); a measure that varies along the X axis is drawn as steps.
- `events` Vertical lines (events) ★ / Lignes verticales (événements) ★ ★ (measure, 1 max): Text measure: a vertical line at each x where it is not empty, labeled with its text. Date measure: a vertical line at that date.
- `annotations` Annotations (text) ★ / Annotations (texte) ★ ★ (measure, 1 max): Optional text measure: each non-empty value is shown as an annotation on the point of the line (x and series).
- `errorLow` Lower bound (error bars) / Borne basse (barres d'erreur) (measure, 1 max): 
- `errorHigh` Upper bound (error bars) / Borne haute (barres d'erreur) (measure, 1 max): 
- `seriesName` Series name (measure) / Nom de la série (mesure) (measure, 1 max): Text measure: renames each series of the legend (or the first series without a legend), e.g. "Sales " & [Year].
- `tooltips` Tooltips / Infobulles (measure, several max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Line Plume: Format pane options (325)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Data colors / Couleurs des données (`dataColors`, one entry per item with a selector)
- `dataColors.mode` Coloring / Coloration: dropdown, default `auto`; values: `auto` Palette (one color per series); `single` Single color; `highlight` Highlight series ★
- `dataColors.single` Color / Couleur: color, default (empty); values: hex color
- `dataColors.fill` Color / Couleur: color, default (empty); values: hex color
- `dataColors.highlightWhat` Highlighted series / Séries mises en avant: dropdown, default `last`; values: `last` Highest at the end; `first` First ones; `name` Named series
- `dataColors.highlightN` Number of series / Nombre de séries: number, default `1`; values: 1 to 12. Highest at the end or first ones: how many series are highlighted.
- `dataColors.highlightName` Series names (separated by ;) / Noms des séries (séparés par ;): text, default (empty). One or more series: "North; South". Each keeps its palette color (empty highlight color) or takes the highlight color.
- `dataColors.highlightColor` Highlight color (empty = accent, or palette if several) / Couleur mise en avant (vide = accent, ou palette si plusieurs): color, default (empty); values: hex color
- `dataColors.othersColor` Other series color (empty = style gray) / Couleur des autres séries (vide = gris du style): color, default (empty); values: hex color

### Lines / Courbes (`lines`)
- `lines.width` Width / Épaisseur: number, default `2`; values: 0.5 to 8
- `lines.interpolation` Shape / Forme: dropdown, default `linear`; values: `linear` Straight; `smooth` Smooth; `step` Step
- `lines.style` Line style / Style du trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `lines.missing` Missing values / Valeurs manquantes: dropdown, default `gap`; values: `gap` Break the line; `connect` Connect points; `zero` Treat as zero
- `lines.markers` Markers / Marqueurs: dropdown, default `auto`; values: `auto` Automatic (few points); `none` None; `all` All points; `last` Last point; `ends` First and last; `minmax` Minimum and maximum
- `lines.markerSize` Size / Taille: number, default `6`; values: 2 to 20. Visible when `lines.markers` = `auto` or `all` or `last` or `ends` or `minmax`
- `lines.markerShape` Shape / Forme: dropdown, default `circle`; values: `circle` Circle; `square` Square; `diamond` Diamond; `triangle` Triangle. Visible when `lines.markers` = `auto` or `all` or `last` or `ends` or `minmax`
- `lines.markerHollow` Hollow markers / Marqueurs creux: toggle, default `false`; values: true / false. Visible when `lines.markers` = `auto` or `all` or `last` or `ends` or `minmax`
- `lines.area` Fill under the line / Remplissage sous la courbe: dropdown, default `none`; values: `none` None; `solid` Solid; `gradient` Gradient ★
- `lines.areaOpacity` Opacity (%) / Opacité (%): number, default `18`; values: 2 to 90. Visible when `lines.area` = `solid` or `gradient`
- `lines.areaSeries` Filled series / Séries remplies: dropdown, default `primary`; values: `primary` Primary Y axis; `all` All (secondary axis included); `named` Named series. Visible when `lines.area` = `solid` or `gradient`
- `lines.areaNames` Series names (separated by ;) / Noms des séries (séparés par ;): text, default (empty). Visible when `lines.area` = `solid` or `gradient`
- `lines.areaColor` Color (empty = series color) / Couleur (vide = celle de la série): color, default (empty); values: hex color. Visible when `lines.area` = `solid` or `gradient`
- `lines.stacked` Stacked series / Séries empilées: toggle, default `false`; values: true / false. Each series is drawn on top of the previous one (stacked area).
- `lines.percent` 100% stacked / Empilées à 100 %: toggle, default `false`; values: true / false. Visible when `lines.stacked` = `true`. Each series as a share of the total of the date (100% stacked area, like the native visual).
- `lines.futureShow` Show / Afficher: toggle, default `false`; values: true / false. The same line turns dashed after a date: actuals then forecast, with no second series and no duplicate legend entry.
- `lines.futureFrom` Starting from / À partir de: dropdown, default `today`; values: `today` Today; `date` A date or a value
- `lines.futureDate` Date or value / Date ou valeur: text, default (empty). Visible when `lines.futureFrom` = `date`
- `lines.futureStyle` Line style / Style du trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `lines.thrShow` Show / Afficher: toggle, default `false`; values: true / false. The line (and its area) changes color exactly where it crosses the threshold.
- `lines.thrSource` Threshold / Seuil: dropdown, default `value`; values: `value` Fixed value; `reference` First reference line
- `lines.thrValue` Value / Valeur: number, default `0`. Visible when `lines.thrSource` = `value`
- `lines.thrAbove` Color above / Couleur au-dessus: color, default `#2E7D4F`; values: hex color
- `lines.thrBelow` Color below / Couleur en dessous: color, default `#C0392B`; values: hex color
- `lines.betweenShow` Show / Afficher: toggle, default `false`; values: true / false. Shades the gap between two lines (actual and budget, minimum and maximum…): one color when the first is above, another when it falls below.
- `lines.betweenA` First series (empty = 1st) / Première série (vide = la 1re): text, default (empty)
- `lines.betweenB` Second series (empty = 2nd) / Seconde série (vide = la 2e): text, default (empty)
- `lines.betweenUp` Color when the first is above / Couleur quand la première est au-dessus: color, default `#2E7D4F`; values: hex color
- `lines.betweenDown` Color when the first is below / Couleur quand la première est en dessous: color, default `#C0392B`; values: hex color
- `lines.betweenOpacity` Opacity (%) / Opacité (%): number, default `22`; values: 2 to 90

### Per-series settings / Réglages par série (`seriesFormat`, one entry per item with a selector)
- `seriesFormat.name` Display name (empty = field name) / Nom affiché (vide = nom du champ): text, default (empty). Renames the series in the legend, labels and tooltips. The "Series name (measure)" field computes it in DAX.
- `seriesFormat.kind` Type: dropdown, default `inherit`; values: `inherit` Line; `column` Columns (combo chart). Columns: the series is drawn as columns under the lines, on its axis (primary or secondary), like the native combo chart.
- `seriesFormat.lineStyle` Line style / Style de trait: dropdown, default `inherit`; values: `inherit` Same as the Lines card; `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `seriesFormat.width` Width (0 = Lines card) / Épaisseur (0 = carte Courbes): number, default `0`; values: 0 to 8
- `seriesFormat.shape` Shape / Forme: dropdown, default `inherit`; values: `inherit` Same as the Lines card; `linear` Straight; `smooth` Smooth; `step` Step
- `seriesFormat.markers` Markers / Marqueurs: dropdown, default `inherit`; values: `inherit` Same as the Lines card; `none` None; `all` All points; `last` Last point; `ends` First and last; `minmax` Minimum and maximum
- `seriesFormat.labels` Data labels / Étiquettes de données: dropdown, default `inherit`; values: `inherit` Same as the Labels card; `on` Shown; `off` Hidden
- `seriesFormat.area` Fill under the line / Remplissage sous la courbe: dropdown, default `inherit`; values: `inherit` Same as the Lines card; `none` None; `solid` Solid; `gradient` Gradient ★
- `seriesFormat.future` Future part dashed / Partie future en pointillés: dropdown, default `inherit`; values: `inherit` Same as the Lines card; `on` Yes ★; `off` No. Yes: the line changes style from the date below (empty = the one of the Lines card, otherwise today). One series solid, the other dashed after July 2025, for instance.
- `seriesFormat.futureDate` Starting from (date or value) / À partir de (date ou valeur): text, default (empty)
- `seriesFormat.futureStyle` Future part line style / Trait de la partie future: dropdown, default `inherit`; values: `inherit` Same as the Lines card; `dashed` Dashed; `dotted` Dotted; `solid` Solid
- `seriesFormat.threshold` Color by threshold / Couleur selon le seuil: dropdown, default `inherit`; values: `inherit` Same as the Lines card; `on` Yes ★; `off` No
- `seriesFormat.between` Area between two series / Aire entre deux séries: dropdown, default `inherit`; values: `inherit` Same as the Lines card; `first` First series of the area ★; `second` Second series of the area ★. Pick the first and second series here instead of typing their names in the Lines card.
- `seriesFormat.endLabel` End-of-line label / Étiquette en bout de courbe: dropdown, default `inherit`; values: `inherit` Same as the End-of-line labels card; `on` Yes ★; `off` No
- `seriesFormat.trend` Trend / Tendance: dropdown, default `inherit`; values: `inherit` Same as the Analytics pane; `on` Yes ★; `off` No. Yes: a trend for this series, with the settings of the Trend card of the Analytics pane, even when the card is off. For a single series: "No" on All series, then "Yes" on that series.
- `seriesFormat.movingAvg` Moving average / Moyenne mobile: dropdown, default `inherit`; values: `inherit` Same as the Analytics pane; `on` Yes ★; `off` No
- `seriesFormat.reference` Counted in computed lines / Comptée dans les lignes calculées: dropdown, default `inherit`; values: `inherit` Same as the Analytics pane (primary axis); `on` Yes; `off` No. Computed reference lines of the Analytics pane (average, median, minimum, maximum, percentile): series taken into account.

### End-of-line labels ★ / Étiquettes en bout de courbe ★ (`endLabels`)
- `endLabels.show` Show / Afficher: toggle, default `false`; values: true / false. Names the series directly at the end of each line, instead of a legend.
- `endLabels.content` Content / Contenu: dropdown, default `nameValue`; values: `name` Series name; `value` Last value; `nameValue` Name and last value
- `endLabels.fontSize` Text size / Taille du texte: number, default `10`; values: 6 to 24
- `endLabels.colorBy` Color / Couleur: dropdown, default `series`; values: `series` Series color; `text` Text
- `endLabels.hideLegend` Hide the legend / Masquer la légende: toggle, default `true`; values: true / false

### Data labels / Étiquettes de données (`labels`)
- `labels.show` Show / Afficher: toggle, default `false`; values: true / false
- `labels.position` Position: dropdown, default `auto`; values: `auto` Automatic; `above` Above; `below` Below
- `labels.which` Labeled points / Points étiquetés: dropdown, default `all`; values: `all` All (no overlap); `last` Last point; `ends` First and last; `minmax` Minimum and maximum
- `labels.fontSize` Size / Taille: number, default `10`; values: 6 to 24
- `labels.color` Color (empty = automatic) / Couleur (vide = automatique): color, default (empty); values: hex color. Automatic: readable color depending on the background (inside bars: white or dark).
- `labels.bold` Bold / Gras: toggle, default `false`; values: true / false
- `labels.halo` Text halo / Halo autour du texte: toggle, default `true`; values: true / false
- `labels.declutter` Hide overlapping labels / Masquer les étiquettes qui se chevauchent: toggle, default `true`; values: true / false
- `labels.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `labels.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `labels.prefix` Prefix / Préfixe: text, default (empty)
- `labels.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)

### X axis / Axe X (`xAxis`)
- `xAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `xAxis.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `xAxis.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `xAxis.labelMode` Long labels / Étiquettes longues: dropdown, default `auto`; values: `auto` Automatic; `wrap` Two lines; `rotate45` Tilted (45°); `rotate90` Vertical; `truncate` Truncated (…)
- `xAxis.maxSize` Maximum room (% of the visual) / Place maximale (% du visuel): number, default `30`; values: 10 to 60
- `xAxis.line` Axis line / Trait de l'axe: toggle, default `true`; values: true / false
- `xAxis.type` Axis type / Type d'axe: dropdown, default `auto`; values: `auto` Automatic; `continuous` Continuous; `categorical` Categorical. Continuous: dates and numbers are spaced by their real gap.
- `xAxis.dateFormat` Date format / Format des dates: text, default (empty)
- `xAxis.tickUnit` Date ticks / Graduations des dates: dropdown, default `auto`; values: `auto` Automatic; `year` Years; `quarter` Quarters; `month` Months; `week` Weeks; `day` Days. Continuous date axis: one tick per chosen unit. Two neighboring ticks never show the same label.
- `xAxis.tickEvery` Every N units / Toutes les N unités: number, default `1`; values: 1 to 100. Visible when `xAxis.tickUnit` = `year` or `quarter` or `month` or `week` or `day`
- `xAxis.showTitle` Show / Afficher: toggle, default `false`; values: true / false
- `xAxis.titleText` Text / Texte: text, default (empty). Visible when `xAxis.showTitle` = `true`

### Y axis / Axe Y (`yAxis`)
- `yAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `yAxis.position` Position: dropdown, default `left`; values: `left` Left; `right` Right
- `yAxis.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `yAxis.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `yAxis.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `yAxis.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `yAxis.prefix` Prefix / Préfixe: text, default (empty)
- `yAxis.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)
- `yAxis.line` Axis line / Trait de l'axe: toggle, default `false`; values: true / false
- `yAxis.scale` Scale / Échelle: dropdown, default `linear`; values: `linear` Linear; `log` Logarithmic
- `yAxis.min` Minimum: text, default (empty)
- `yAxis.max` Maximum: text, default (empty)
- `yAxis.zero` Always include zero / Toujours inclure zéro: toggle, default `false`; values: true / false. Visible when `yAxis.scale` = `linear`
- `yAxis.ticks` Number of ticks (approx.) / Nombre de graduations (environ): number, default `5`; values: 2 to 20
- `yAxis.invert` Invert axis / Inverser l'axe: toggle, default `false`; values: true / false
- `yAxis.round` Round range / Arrondir la plage: toggle, default `true`; values: true / false. Computed bounds rounded to a round tick. Off: the axis stops at the extreme values.
- `yAxis.showTitle` Show / Afficher: toggle, default `false`; values: true / false
- `yAxis.titleText` Text / Texte: text, default (empty). Visible when `yAxis.showTitle` = `true`

### Secondary Y axis / Axe Y secondaire (`y2Axis`)
- `y2Axis.show` Show / Afficher: toggle, default `true`; values: true / false
- `y2Axis.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `y2Axis.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `y2Axis.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `y2Axis.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `y2Axis.prefix` Prefix / Préfixe: text, default (empty)
- `y2Axis.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)
- `y2Axis.line` Axis line / Trait de l'axe: toggle, default `false`; values: true / false
- `y2Axis.scale` Scale / Échelle: dropdown, default `linear`; values: `linear` Linear; `log` Logarithmic
- `y2Axis.min` Minimum: text, default (empty)
- `y2Axis.max` Maximum: text, default (empty)
- `y2Axis.zero` Always include zero / Toujours inclure zéro: toggle, default `false`; values: true / false. Visible when `y2Axis.scale` = `linear`
- `y2Axis.ticks` Number of ticks (approx.) / Nombre de graduations (environ): number, default `5`; values: 2 to 20
- `y2Axis.invert` Invert axis / Inverser l'axe: toggle, default `false`; values: true / false
- `y2Axis.round` Round range / Arrondir la plage: toggle, default `true`; values: true / false. Computed bounds rounded to a round tick. Off: the axis stops at the extreme values.
- `y2Axis.showTitle` Show / Afficher: toggle, default `false`; values: true / false
- `y2Axis.titleText` Text / Texte: text, default (empty). Visible when `y2Axis.showTitle` = `true`

### Gridlines / Quadrillage (`gridlines`)
- `gridlines.hShow` Show / Afficher: toggle, default `true`; values: true / false
- `gridlines.hColor` Color (empty = style grid) / Couleur (vide = grille du style): color, default (empty); values: hex color
- `gridlines.hWidth` Width / Épaisseur: number, default `1`; values: 0.5 to 6
- `gridlines.hStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `gridlines.zeroLine` Zero line / Ligne du zéro: toggle, default `true`; values: true / false
- `gridlines.vShow` Show / Afficher: toggle, default `false`; values: true / false
- `gridlines.vColor` Color (empty = style grid) / Couleur (vide = grille du style): color, default (empty); values: hex color
- `gridlines.vWidth` Width / Épaisseur: number, default `1`; values: 0.5 to 6
- `gridlines.vStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted

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

### Annotations ★ (`annotations`)
- `annotations.show` Show / Afficher: toggle, default `true`; values: true / false
- `annotations.list` Annotations (one per line) / Annotations (une par ligne): textarea, default (empty). One line per annotation: "x | text" or "x | series | text". x: date (2024-06-01, 2024-06, 06/15/2024), number or category as displayed. The annotation stays attached to that point of the line. In edit mode, the chart's "Annotate" button fills this list.
- `annotations.content` Displayed content / Contenu affiché: dropdown, default `text`; values: `text` Text; `textValue` Text and value; `textXValue` Text, x and value
- `annotations.editOnChart` "Annotate" button (edit mode) / Bouton « Annoter » (mode édition): toggle, default `true`; values: true / false. In edit mode, an "Annotate" button appears when hovering the chart: then click a point of the line to annotate it. Annotations can be dragged, edited with a double-click and removed with ×.
- `annotations.style` Style: dropdown, default `bubble`; values: `bubble` Bubble; `filled` Filled label; `plain` Text only
- `annotations.color` Color (empty = series color) / Couleur (vide = celle de la série): color, default (empty); values: hex color
- `annotations.fontSize` Text size / Taille du texte: number, default `10`; values: 7 to 24
- `annotations.bold` Bold / Gras: toggle, default `false`; values: true / false
- `annotations.maxWidth` Maximum width (px) / Largeur maximale (px): number, default `160`; values: 60 to 400
- `annotations.marker` Marker on the point / Repère sur le point: toggle, default `true`; values: true / false
- `annotations.connector` Connector / Trait vers le point: dropdown, default `line`; values: `line` Line; `none` None
- `annotations.connectorStyle` Line style / Style du trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `annotations.connector` = `line`
- `annotations.position` Default position / Position par défaut: dropdown, default `auto`; values: `auto` Automatic (no overlap); `above` Above; `below` Below; `right` Right; `left` Left. Position of annotations that have not been dragged.
- `annotations.distance` Distance from the point (px) / Distance au point (px): number, default `26`; values: 6 to 160

### Zoom (`zoom`)
- `zoom.show` Zoom slider / Curseur de zoom: toggle, default `false`; values: true / false. Two-handle slider below the axis: choose the visible range (drag, keyboard). The position is not saved in the report.
- `zoom.labels` Slider labels / Étiquettes du curseur: toggle, default `true`; values: true / false
- `zoom.height` Height (px) / Hauteur (px): number, default `22`; values: 14 to 48

### Small multiples / Petits multiples (`smallMultiples`)
- `smallMultiples.columns` Columns (0 = automatic) / Colonnes (0 = automatique): number, default `0`; values: 0 to 12
- `smallMultiples.minHeight` Minimum panel height (px) / Hauteur minimale d'un panneau (px): number, default `100`; values: 40 to 600. Below that, the grid scrolls vertically.
- `smallMultiples.gap` Spacing (px) / Espacement (px): number, default `14`; values: 0 to 60
- `smallMultiples.scale` Y axis / Axe Y: dropdown, default `shared`; values: `shared` Shared by all panels; `independent` Independent per panel
- `smallMultiples.border` Panel border / Cadre des panneaux: toggle, default `false`; values: true / false
- `smallMultiples.titleShow` Show / Afficher: toggle, default `true`; values: true / false
- `smallMultiples.titleSize` Size / Taille: number, default `10`; values: 6 to 24
- `smallMultiples.titleColor` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `smallMultiples.titleAlign` Alignment / Alignement: dropdown, default `left`; values: `left` Start; `center` Center

### Reference lines ★ / Lignes de référence ★ (`reference`, Analytics pane)
- `reference.show1` Show / Afficher: toggle, default `false`; values: true / false
- `reference.kind1` Value / Valeur: dropdown, default `average`; values: `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile
- `reference.value1` Constant value / Valeur constante: number, default `0`. Visible when `reference.kind1` = `constant`
- `reference.pct1` Percentile / Centile: number, default `90`; values: 1 to 99. Visible when `reference.kind1` = `percentile`
- `reference.label1` Label / Libellé: text, default (empty)
- `reference.showValue1` Show the value / Afficher la valeur: toggle, default `true`; values: true / false
- `reference.color1` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.style1` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `reference.width1` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `reference.labelPos1` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None
- `reference.show2` Show / Afficher: toggle, default `false`; values: true / false
- `reference.kind2` Value / Valeur: dropdown, default `constant`; values: `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile
- `reference.value2` Constant value / Valeur constante: number, default `0`. Visible when `reference.kind2` = `constant`
- `reference.pct2` Percentile / Centile: number, default `90`; values: 1 to 99. Visible when `reference.kind2` = `percentile`
- `reference.label2` Label / Libellé: text, default (empty)
- `reference.showValue2` Show the value / Afficher la valeur: toggle, default `true`; values: true / false
- `reference.color2` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.style2` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `reference.width2` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `reference.labelPos2` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None
- `reference.show3` Show / Afficher: toggle, default `false`; values: true / false
- `reference.kind3` Value / Valeur: dropdown, default `median`; values: `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile
- `reference.value3` Constant value / Valeur constante: number, default `0`. Visible when `reference.kind3` = `constant`
- `reference.pct3` Percentile / Centile: number, default `90`; values: 1 to 99. Visible when `reference.kind3` = `percentile`
- `reference.label3` Label / Libellé: text, default (empty)
- `reference.showValue3` Show the value / Afficher la valeur: toggle, default `true`; values: true / false
- `reference.color3` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.style3` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `reference.width3` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `reference.labelPos3` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None
- `reference.list` Lines (one per line) / Lignes (une par ligne): textarea, default (empty). "value | label | color | style": as many lines as needed. "a..b | label | color" shades a band. Prefix "y2:" for the secondary axis (y2: 0.3 | Target margin). Color #RRGGBB and style (solid, dashed, dotted) are optional.
- `reference.mShape` Shape / Forme: dropdown, default `auto`; values: `auto` Automatic; `flat` Horizontal (last value); `step` Steps along the X axis; `line` Straight, along the X axis. Measures dropped in the "Reference lines (measures)" field. Automatic: horizontal when the measure has the same value everywhere (target, what-if parameter), steps otherwise (monthly target). With a legend, one line per series, in its color.
- `reference.mColor` Color (empty = accent or series) / Couleur (vide = accent ou série): color, default (empty); values: hex color
- `reference.mStyle` Line style / Style du trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `reference.mWidth` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `reference.mLabel` Label / Libellé: dropdown, default `nameValue`; values: `nameValue` Name and value; `name` Name; `value` Value; `none` None
- `reference.band` Show / Afficher: toggle, default `false`; values: true / false
- `reference.bandFrom` From / De: number, default `0`
- `reference.bandTo` To / À: number, default `0`
- `reference.bandLabel` Label / Libellé: text, default (empty)
- `reference.bandColor` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.bandOpacity` Opacity (%) / Opacité (%): number, default `12`; values: 2 to 60

### Vertical lines ★ / Lignes verticales ★ (`vlines`, Analytics pane)
- `vlines.today` Show / Afficher: toggle, default `false`; values: true / false. Vertical line at today's date (date axis, or categories that are dates).
- `vlines.todayLabel` Label / Libellé: text, default (empty)
- `vlines.todayColor` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `vlines.list` Lines and periods (one per line) / Lignes et périodes (une par ligne): textarea, default (empty). "x | label | color | style": x = date (2024-03-15, 2024-03, 03/15/2024, today), number or category as displayed. "x1..x2 | label | color" shades a period. Optional color #RRGGBB, style: solid, dashed or dotted. Measures in the "Vertical lines (events)" field add their own lines.
- `vlines.color` Color (empty = muted text) / Couleur (vide = texte atténué): color, default (empty); values: hex color
- `vlines.style` Line style / Style du trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `vlines.width` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `vlines.labelPos` Labels / Libellés: dropdown, default `top`; values: `top` Top; `bottom` Bottom; `none` None
- `vlines.labelOrient` Text direction / Sens du texte: dropdown, default `horizontal`; values: `horizontal` Horizontal; `vertical` Along the line. Visible when `vlines.labelPos` = `top` or `bottom`
- `vlines.fontSize` Text size / Taille du texte: number, default `9`; values: 6 to 20
- `vlines.bandOpacity` Periods opacity (%) / Opacité des périodes (%): number, default `10`; values: 2 to 60

### Error bars / Barres d'erreur (`errorBars`, Analytics pane)
- `errorBars.show` Show / Afficher: toggle, default `false`; values: true / false
- `errorBars.source` Bounds / Bornes: dropdown, default `fields`; values: `fields` Lower / Upper bound fields (values); `relative` Lower / Upper bound fields (± deltas); `percent` Percentage of the value. With a single delta field, it is used on both sides. Primary and secondary axis series.
- `errorBars.pct` Percentage (±) / Pourcentage (±): number, default `10`; values: 0 to 100. Visible when `errorBars.source` = `percent`
- `errorBars.shape` Shape / Forme: dropdown, default `bar`; values: `bar` Whiskers; `band` Shaded band
- `errorBars.color` Color (empty = series color) / Couleur (vide = celle de la série): color, default (empty); values: hex color
- `errorBars.width` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `errorBars.cap` Cap width (px) / Largeur des taquets (px): number, default `6`; values: 0 to 40. Visible when `errorBars.shape` = `bar`
- `errorBars.opacity` Band opacity (%) / Opacité de la bande (%): number, default `18`; values: 2 to 80. Visible when `errorBars.shape` = `band`

### Moving average ★ / Moyenne mobile ★ (`movingAvg`, Analytics pane)
- `movingAvg.show` Show / Afficher: toggle, default `false`; values: true / false. Moving average of each series, on top of the line (and of any trend).
- `movingAvg.period` Number of points / Nombre de points: number, default `3`; values: 2 to 400. Window size, in axis points (3 = three months on a monthly axis, 7 = one week on a daily axis).
- `movingAvg.method` Average / Moyenne: dropdown, default `simple`; values: `simple` Simple; `weighted` Weighted (recent points count more); `exponential` Exponential
- `movingAvg.align` Window / Fenêtre: dropdown, default `trailing`; values: `trailing` Previous points (trailing); `centered` Centered on the point. Visible when `movingAvg.method` = `simple` or `weighted`
- `movingAvg.partial` From the first points / Dès les premiers points: toggle, default `false`; values: true / false. Also compute on an incomplete window at the start (otherwise the average starts at the N-th point).
- `movingAvg.applyTo` Series / Séries: dropdown, default `all`; values: `all` All; `primary` Primary Y axis; `named` Named series
- `movingAvg.names` Series names (separated by ;) / Noms des séries (séparés par ;): text, default (empty). Visible when `movingAvg.applyTo` = `named`
- `movingAvg.color` Color (empty = series color) / Couleur (vide = celle de la série): color, default (empty); values: hex color
- `movingAvg.style` Line style / Style du trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `movingAvg.width` Width / Épaisseur: number, default `2.5`; values: 0.5 to 8
- `movingAvg.dimSource` Original line opacity (%) / Opacité de la courbe d'origine (%): number, default `40`; values: 5 to 100. 100 = original line unchanged; lower, the moving average stands out.
- `movingAvg.legend` In the legend / Dans la légende: toggle, default `false`; values: true / false

### Trend ★ / Tendance ★ (`trend`, Analytics pane)
- `trend.show` Show / Afficher: toggle, default `false`; values: true / false. Trend of each series, optionally extended into the future with a forecast interval.
- `trend.kind` Type: dropdown, default `linear`; values: `linear` Linear; `poly` Polynomial; `exp` Exponential; `log` Logarithmic ★; `power` Power ★; `holt` Exponential smoothing (Holt); `holtWinters` Seasonal (Holt-Winters)
- `trend.degree` Order / Degré: number, default `2`; values: 2 to 6. Visible when `trend.kind` = `poly`
- `trend.season` Season in periods (0 = automatic) / Saison en périodes (0 = automatique): number, default `0`; values: 0 to 400. Visible when `trend.kind` = `holtWinters`. Automatic: 12 for months, 4 for quarters, 7 for days, 52 for weeks. At least two full seasons are needed.
- `trend.damped` Damped trend / Tendance amortie: toggle, default `false`; values: true / false. Visible when `trend.kind` = `holt` or `holtWinters`. The slope flattens along the forecast (conservative forecasts).
- `trend.window` Fit on the last N points (0 = all) / Calcul sur les N derniers points (0 = tous): number, default `0`; values: 0 to 100000
- `trend.applyTo` Series / Séries: dropdown, default `all`; values: `all` All; `primary` Primary Y axis; `named` Named series
- `trend.names` Series names (separated by ;) / Noms des séries (séparés par ;): text, default (empty). Visible when `trend.applyTo` = `named`
- `trend.horizon` Forecast periods / Périodes projetées: number, default `0`; values: 0 to 500. Number of axis steps added after the last point (months, quarters, days, categories…). 0 = no forecast.
- `trend.interval` Forecast interval / Intervalle de prévision: dropdown, default `80`; values: `none` None; `80` 80%; `95` 95%
- `trend.bandOpacity` Interval opacity (%) / Opacité de l'intervalle (%): number, default `14`; values: 2 to 60. Visible when `trend.interval` = `80` or `95`
- `trend.projStyle` Forecast line style / Style de la projection: dropdown, default `dotted`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `trend.endValue` Value at the end of the forecast / Valeur en fin de projection: toggle, default `true`; values: true / false
- `trend.color` Color (empty = series color) / Couleur (vide = celle de la série): color, default (empty); values: hex color
- `trend.style` Line style / Style du trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `trend.width` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `trend.equation` Equation and R² / Équation et R²: toggle, default `false`; values: true / false. x = period number (1 = first point of the axis).
- `trend.legend` In the legend / Dans la légende: toggle, default `false`; values: true / false

### Interactions (`interaction`)
- `interaction.hover` Highlight on hover / Mettre en avant au survol: toggle, default `true`; values: true / false
- `interaction.dim` Dimmed items opacity (%) / Opacité des éléments estompés (%): number, default `25`; values: 5 to 80
- `interaction.crosshair` Vertical guide on hover / Repère vertical au survol: toggle, default `true`; values: true / false. Shows every series at the hovered date in one tooltip.

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Scatter Plume

- Scatter and bubble charts that move through time: play axis, zoom, lasso, quadrants, trends, density and images.
- Slug `scatter-chart` · version 1.4.0.0 · GUID (`visualType`) `plumeScatterChart7F2D4A91C6E34B0D8A5E13F9B2C6D7A1` · page https://plumevisuals.com/en/visuals/scatter-chart

### What the visual does

Scatter Plume is a Power BI custom visual (base range, version 1.4.0.0, installed from the `.pbiviz` file; AppSource submission in progress) that draws scatter and bubble charts: one point per value of Details, positioned by two measures (X, Y), with an optional third measure for the bubble area and a Legend for one color (or shape) per series. It covers the native scatter chart and adds what users ask for on the forums: a **play axis** (play button, slider, loop, trails of the selected bubbles), zoom sliders and Shift + drag zoom, rectangle or **lasso** selection, up to **100,000 points** (native: 10,000), jitter for overlapping points, a text label per point (Label field), a color per point (Color field), reference measures (Reference X / Y fields) and readable dates everywhere (play axis, tooltips, Details, Legend, small multiple titles, date axes). Premium adds named and tinted quadrants with point counts, trend models (linear, polynomial, exponential, logarithmic, power) with equation and a 95% band, symmetry shading and ratio line, confidence ellipses, automatic clusters (k-means), small multiples, highlighted points, **density** (hexagons, squares, circles, a continuous surface or contour lines), density trails and density around the selection, marginal distributions, connected points and an **image inside each point** (embedded base64 only). Points glide to their new position when filters change or the play axis moves.

**New in version 1.4.0.0 (30/10/2026):** Format pane reorganized (new **Gridlines** card); free native-parity additions: cross and plus markers, hollow points, label background, "Round the range", axis min / max from a measure (scale kept under filters), **drill-down** of a hierarchy in Details; premium **y = a·x + b lines ★** (Analytics pane).

### Free vs premium (★)

- Every feature works without a key and nothing is ever blocked. Free features never show a watermark, and the default settings use no premium feature.
- 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 (`style.customColors` and the colors under it) are **free**; every other `style.preset`, the other gradient palettes (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium** (watermark without a key). See "Styles and theme JSON" below.
- Using a premium feature without a valid key shows **"Plume Visuals · Premium preview"** (French: « Plume Visuals · Aperçu premium ») in the footer, with an "Unlock →" link to the pricing page. It disappears once a key is pasted in **Format › Plume Studio License › License key** (`license.key`; French: « Licence Plume Studio › Clé de licence »), the **first card** of the Format pane.
- Premium features of Scatter Plume (the watermark appears only when they actually apply):
  - fields **Small multiples ★** (`multiples`), **Highlight ★** (`highlight`) and **Image ★** (`image`) when filled; a **number** in the Color field (gradient);
  - the **Quadrants ★** card (`quadrants.show`);
  - `dataColors.mode` = `gradient` ("Gradient by a value ★", `dataColors.gradientBy` = `y`, `x`, `size` or `field`);
  - `points.connect` ("Connect the points of each series ★");
  - `play.trails` = `all` ("All points ★"), `play.trailMode` = `density` or `both` ("Density ★", "Lines and density ★");
  - `highlight.names` ("Highlighted points ★");
  - the **Density ★** (`density.show`) and **Marginal distributions ★** (`marginals.show`) cards;
  - `interaction.selDensity` = `series` or `selected` ("Density around the selection");
  - the Analytics pane cards **Reference lines ★** (`reference.show1/2/3`, `reference.band`), **Trend ★** (`trend.show`), **Symmetry and ratio ★** (`symmetry.show`, `symmetry.ratio`), **Confidence ellipses ★** (`ellipses.show`) and **Automatic clusters ★** (`clusters.show`).
- Premium options and list values carry " ★" in their label.
- Accepted keys: only keys starting with `PLUM1.` from the buyer's account on plumevisuals.com, checked offline (Ed25519 signature), covering `scatter-chart` 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". `license.showOwner` displays "Licensed to <holder>".
- Licenses last one year (one-time payment, no automatic renewal, key accepted for 30 more days, reminders 30 and 7 days before the end). Prices per year: 39 € personal, 99 € SME, 299 € enterprise, or a catalog pack (199 € / 399 € / 1,199 € per year; tiers by number of users, designers and viewers included: personal 1–10, SME 11–200, enterprise more than 200). Renewing gives a new key to paste instead of the old one.

### Expected data shape

The visual reads **one row per Details value** (per Details × Legend × Play axis × Small multiples value when those fields are used), with the measures evaluated for that row.

| Details (`details`) | Legend (`legend`) | Play axis (`play`) | X axis (`x`) | Y axis (`y`) | Size (`size`) |
|---|---|---|---|---|---|
| Linen sofa | Furniture | Jan 2025 | 412 | 0.34 | 366 680 |
| Cedar candle | Decor | Jan 2025 | 1 105 | 0.61 | 24 310 |
| … | … | … | … | … | … |

- **Details (one point each)** (`details`, « Détails (un point par valeur) », grouping, one field): one point per value. Without it, one point per series.
- **Legend (series)** (`legend`, « Légende (séries) », grouping, one field, optional): one color per value, and one shape per value with `points.shape` = `series`.
- **X axis** (`x`, « Axe X ») and **Y axis** (`y`, « Axe Y »): one measure each. A row with a blank X or Y is not drawn. A date measure gives a date axis (ticks by granularity).
- **Size** (`size`, « Taille », one measure, optional): bubble **area** proportional to the value, between `points.minSize` and `points.maxSize`, scaled like Power BI (`points.sizeScale` = `auto`, `magnitude`, `range`). Without it, `points.size` is used.
- **Play axis** (`play`, « Axe de lecture », grouping, one field, optional): a date, a month, a year or an ordered category. The points move from one value to the next; axes stay fixed during playback. Dates (including the ISO UTC strings Power BI Desktop sends, such as "2025-03-31T22:00:00.000Z") are read as local dates, sorted as dates and written with the column's format string when it is precise ("mmm yyyy" → "Apr 2025"), otherwise by granularity (first days of months → "April 2025", January 1st → "2025").
- **Small multiples ★** (`multiples`, grouping, one field, optional): one small scatter chart per value (36 at most), same axes for all.
- **Label (text)** (`labelText`, « Étiquette (texte) », one measure, optional): text always written next to each point; blank = no label for that point.
- **Image ★** (`image`, one measure, optional): an embedded image drawn in a disc inside each point. Accepted: `data:image/(png|jpeg|gif|webp|bmp|svg+xml);base64,…` or raw base64 recognized by its signature (PNG, JPEG, GIF, WebP, SVG). An `http(s)` address is **never loaded** (certified visuals make no network request): the point is drawn normally and, in edit mode only, a message explains that only embedded images are shown. Images are not drawn beyond 5,000 points (canvas mode).
- **Color** (`colorBy`, « Couleur », one measure, optional): a color per point (`#RRGGBB`, `#RGB`, CSS names such as `red`), free; a **number** gives a gradient ★ (`dataColors.gradientBy` = `field`).
- **Highlight ★** (`highlight`, one measure, optional): not blank and not 0 = the point stands out (`highlight.color`), the others turn gray (`highlight.othersGray`, `highlight.othersOpacity`).
- **Reference X / Reference Y** (`refX`, `refY`, one measure each, optional): a target or benchmark used by reference lines ★ (`reference.kindN` = `measure`) and quadrant splits ★ (`quadrants.xMode` / `yMode` = `measure`); the line label is the measure name.
- **Tooltips** (`tooltips`) and **Dynamic format** (`format`, see below).
- Volume: windows of 10,000 rows then `fetchMoreData` up to **100,000 points** (a warning beyond that), and 60 Legend values. Above 3,000 points one event listener for the whole cloud; above **5,000 points** the points are drawn on a canvas (hover, click, right-click and rectangle selection kept; no per-point keyboard navigation, no transition, no images).
- Axes, labels and tooltips reuse the format string of each measure (set percentages in the model).

### DAX recipes

```dax
Revenue = SUM ( Sales[Amount] )
Orders = COUNTROWS ( Sales )
Gross margin = SUM ( Sales[Margin] )
Margin rate = DIVIDE ( [Gross margin], [Revenue] )
Average basket = DIVIDE ( [Revenue], [Orders] )

// Label field: text only for the best sellers
Top label = IF ( [Revenue] > 50000, "Top" )

// Color field: a color per point (free)
Margin color = IF ( [Margin rate] > 0.5, "#2E7D4F", "#C0392B" )

// Image field ★: a flag stored as raw base64 in Countries[Flag base64] (Power Query: Binary.ToText ( <file>, BinaryEncoding.Base64 ))
Flag = "data:image/svg+xml;base64," & SELECTEDVALUE ( Countries[Flag base64] )

// Reference Y field: a margin target from a parameter
Margin target = SELECTEDVALUE ( 'Margin threshold'[Margin threshold], 0.45 )
```

Quadrant splits `average` and `median` are computed on the **displayed points** (each point counts once, all series together), not weighted by Size. Use `constant` for a business threshold, in the unit of the measure (0.45 for 45%), or `measure` with the Reference X / Y field.

### Interactions with the report

- Draw a rectangle (`interaction.brush`) or a lasso (`interaction.brushShape` = `lasso`) to select every point inside it (Ctrl to add); click a point, Ctrl + click to add, click the background to clear. Selections cross-filter other visuals. Legend click selects a whole series or cluster (`legend.interactive`), hover highlights it (`interaction.hover`, `interaction.dim`).
- Play axis: selecting a bubble selects that item on every frame (the report is filtered on the item, not on the month); its trail shows its path in chronological order (`play.trails`).
- Zoom: sliders on X and Y (`zoom.x`, `zoom.y`), Shift + drag zooms into a rectangle (`zoom.rect`), double-click or the ⟲ button returns to the full view. The mouse wheel does not zoom (it scrolls the report page).
- Keyboard: Tab to the chart, arrow keys / Home / End to move between points, Enter or Space to select, Esc to clear. Screen-reader announcements, including the current play-axis frame.
- Scatter Plume is cross-filtered by other visuals (it does not render highlighting). Context menu everywhere (points, background, empty plot, axes, legend, play bar), report-page tooltips, landing page, read-only on dashboards, high contrast (one shape per series forced, no tints), reduced motion (no transition, no auto-play). No network request.

### Dynamic formats

- **fx button** on every color and text of the Format pane (*Field value*, *Rules*, *Gradient*), for example `quadrants.colorTR` or `quadrants.lineColor`.
- **Dynamic format** field (role `format`): a measure renamed for this visual as `card.setting` (right-click › Rename for this visual) drives **any** setting: sizes, toggles, lists, fonts, colors, texts. It wins over the fixed value, the style and an fx rule; its measures are never drawn. Names ignore case, accents and separator.
- Value used for a global setting: total when Power BI provides it, else the common value of all points, else the first point; wrap with `CALCULATE ( …, ALLSELECTED () )` for a whole-visual value.
- Examples: `trend.model` = `"poly2"`; `play.speed` = `300`; `density.shape` = `"contour"`; `quadrants.yValue` = a threshold measure (with `quadrants.yMode` = `constant`); `labels.n` = `SELECTEDVALUE ( 'Label count'[Label count], 8 )`. A ★ setting driven by DAX stays ★.

### Format pane: how to read the tables below

- Each option has an ID `card.option` (object name + property name in capabilities.json).
- Card order: `license`, `style`, `dataColors` (dynamic "Data colors": mode, gradient value, then one color per series stored with its selector), `points` (shape, sizes, size scaling, opacity, outline, keep bubbles inside, jitter; Images ★: `imageMinSize`, `imageBorder`, `imageBorderWidth`; Connect points ★), `labels`, `quadrants` (★), `xAxis`, `yAxis`, `legend`, `play` (play axis: start frame, speed, loop, auto-play, play bar, background value, trails, trail style), `zoom`, `smallMultiples` (★), `highlight` (★), `density` (★: `shape` = `hex` / `square` / `circle` / `continuous` / `contour`, `mode` = `under` / `replace`, `radius` for cells, `bandwidth` for continuous and contour (0 = automatic, Scott's rule), `levels` for contour lines, `colorMode`, `opacity`), `marginals` (★), `interaction` (hover, rectangle or lasso, density around the selection), then `title`, `source`, `container`, `texts`. `reference`, `trend`, `symmetry`, `ellipses` and `clusters` are in the **Analytics** pane. Format pane in version 1.4.0.0 (30/10/2026), top to bottom: `license`, `style`, `dataColors`, `points`, `labels`, `quadrants`, `xAxis`, `yAxis`, `gridlines`, `legend`, `play`, `zoom`, `smallMultiples`, `highlight`, `density`, `marginals`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`; Analytics pane: `reference`, `trend`, `symmetry`, `slopes`, `ellipses`, `clusters`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- "Visible when": `quadrants.xValue` only when `quadrants.xMode` = `constant`, `labels.n` only when `labels.which` = `top`, `xAxis.zero` only on a linear scale, `density.radius` only for hexagons, squares and circles, `density.bandwidth` only for continuous and contour, `density.levels` only for contour, `interaction.brushShape` only when `interaction.brush` is on. `interaction.selDensity` is hidden when the Play axis field is filled (use `play.trailMode` instead). Labels follow the Power BI Desktop language; `texts.language` can force French or English.

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are data role names, `objects` keys are option IDs. Literals: `true` / `false`, numbers with `D`, strings and enumeration values in single quotes, colors in `solid.color`.

```json
{
  "visualType": "plumeScatterChart7F2D4A91C6E34B0D8A5E13F9B2C6D7A1",
  "query": {
    "queryState": {
      "details": { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Product" } }, "queryRef": "Sales.Product", "nativeQueryRef": "Product" } ] },
      "play":    { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Month" } }, "queryRef": "Sales.Month", "nativeQueryRef": "Month" } ] },
      "x":       { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Orders" } }, "queryRef": "Sales.Orders", "nativeQueryRef": "Orders" } ] },
      "y":       { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Margin rate" } }, "queryRef": "Sales.Margin rate", "nativeQueryRef": "Margin rate" } ] },
      "size":    { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Revenue" } }, "queryRef": "Sales.Revenue", "nativeQueryRef": "Revenue" } ] }
    }
  },
  "objects": {
    "quadrants":  [ { "properties": { "show": { "expr": { "Literal": { "Value": "true" } } },
                                       "yMode": { "expr": { "Literal": { "Value": "'constant'" } } },
                                       "yValue": { "expr": { "Literal": { "Value": "0.45D" } } },
                                       "topRight": { "expr": { "Literal": { "Value": "'Drivers'" } } },
                                       "bottomLeft": { "expr": { "Literal": { "Value": "'To review'" } } } } } ],
    "play":       [ { "properties": { "speed": { "expr": { "Literal": { "Value": "600D" } } },
                                       "loop": { "expr": { "Literal": { "Value": "true" } } } } } ],
    "density":    [ { "properties": { "show": { "expr": { "Literal": { "Value": "true" } } },
                                       "shape": { "expr": { "Literal": { "Value": "'continuous'" } } } } } ],
    "labels":     [ { "properties": { "show": { "expr": { "Literal": { "Value": "true" } } },
                                       "n": { "expr": { "Literal": { "Value": "6D" } } } } } ],
    "dataColors": [ { "properties": { "fill": { "solid": { "color": { "expr": { "Literal": { "Value": "'#b8462a'" } } } } } },
                      "selector": { "metadata": "Sales.Margin rate" } } ],
    "license":    [ { "properties": { "key": { "expr": { "Literal": { "Value": "'PLUM1.…'" } } } } } ]
  }
}
```

Without Legend, the single series color is stored on the Y measure (`"selector": { "metadata": "Sales.Margin rate" }`). For readable play-axis labels, give the date column an explicit format string (`mmm yyyy` for months, `yyyy` for years). The custom visual package must also be embedded in the report.

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`.
- `style.themeJson` (Format › Style › Theme JSON ★) takes a JSON theme as plain text. Format v2: an object with an optional `extends` (a style ID above) and optional groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`; the v1 flat format (`style`, `palette`, `accent`, `background`…) is still read. Every field is optional. Colors are `#RRGGBB` (`#RGB` and `#RRGGBBAA` accepted, opacity ignored). Unknown fields and values outside the allowed lists are ignored, out-of-range numbers are clamped. Invalid JSON shows "Invalid theme JSON: ignored" in edit mode and the visual keeps its look.
- Full field list with allowed values, examples and troubleshooting: tutorial https://plumevisuals.com/ai/tutorials/en/themes-json.md (French: https://plumevisuals.com/ai/tutorials/fr/themes-json.md). The same JSON can be pasted in every Plume visual of a page.
- Priority (the last one wins): visual defaults → `style.preset` → `style.themeJson` → `style.palette` (if not "Style or theme palette") → `style.followTheme` → custom colors → options set by hand in the other cards → DAX formats (fx button, "Dynamic format" field) → Windows high contrast.

### Common pitfalls

- Only one point: Details is empty.
- Missing points: blank X or Y, or values ≤ 0 on a logarithmic axis.
- Play axis shows "2025-03-31T22:00:00.000Z" or months in the wrong order: that was version 1.3.0.0; update to 1.3.1.0. For "Apr 2025", give the column the format string `mmm yyyy`.
- The trail zigzags: it links the positions of one item in chronological order; the zigzag is the real month-to-month change. Several selected items = one trail each.
- Image field shows nothing: the measure returns a web address (never loaded), or more than 5,000 points are drawn (canvas). Convert images to base64 (Power Query `Binary.ToText`, or a text column) and build a `data:image/…;base64,` string.
- Fixed split has no effect: the value is in the measure's unit (0.45, not 45, for a percentage).
- The tinted quadrant is always the top-right one **on screen**; with `yAxis.invert` or `xAxis.invert` it is no longer the "high/high" one. Rename quadrants accordingly, or use `quadrants.tintAll`.
- Average split looks wrong: it is unweighted, over displayed points only (filters change it).
- Same product drawn several times: it belongs to several Legend values (e.g. Legend = Channel).
- Density around the selection does not appear: the Play axis field is filled (use `play.trailMode`), or nothing is selected.
- Watermark visible: a ★ option or field is used (see the list above) without a valid key.

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

Images loaded from a web address (URLs are ignored by design), mouse-wheel zoom, categorical X axis (dot plot: use Bar Plume), drill-down on Details, LOESS or moving-average trend, outlier detection, more or fewer than four quadrants, 3D scatter, data-driven point shape (other than one shape per Legend value), different axes per small multiple, zoom sliders or marginal distributions in small multiples mode, export of the data from the visual, video export of the animation (PDF and subscriptions show the current frame).

## Scatter Plume: data fields

- `details` Details (one point each) / Détails (un point par valeur) (column, 4 max): 
- `legend` Legend (series) / Légende (séries) (column, 1 max): 
- `x` X axis / Axe X (measure, 1 max): 
- `y` Y axis / Axe Y (measure, 1 max): 
- `size` Size / Taille (measure, 1 max): 
- `play` Play axis / Axe de lecture (column, 1 max): A date, a year or an ordered category: the points move from one value to the next (play button)
- `multiples` Small multiples ★ / Petits multiples ★ ★ (column, 1 max): One small scatter chart per value, sharing the same axes
- `labelText` Label (text) / Étiquette (texte) (measure, 1 max): Text written next to each point; blank = no label for that point
- `image` Image ★ ★ (measure, 1 max): An embedded image per point (data:image/…;base64 or raw base64); web addresses are never loaded
- `colorBy` Color / Couleur (measure, 1 max): A color (#RRGGBB, red…) per point, or a number for a gradient ★
- `highlight` Highlight ★ / Mise en avant ★ ★ (measure, 1 max): Not blank and not 0: the point stands out, the others turn gray
- `refX` Reference X / Référence X (measure, 1 max): Target or benchmark on the X axis: reference lines and quadrant splits ★
- `refY` Reference Y / Référence Y (measure, 1 max): Target or benchmark on the Y axis: reference lines and quadrant splits ★
- `tooltips` Tooltips / Infobulles (measure, several max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Scatter Plume: Format pane options (323)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Data colors / Couleurs des données (`dataColors`, one entry per item with a selector)
- `dataColors.mode` Coloring / Coloration: dropdown, default `auto`; values: `auto` Palette (one color per series); `single` Single color; `gradient` Gradient by a value ★
- `dataColors.single` Color / Couleur: color, default (empty); values: hex color
- `dataColors.fill` Color / Couleur: color, default (empty); values: hex color
- `dataColors.gradientBy` Gradient value / Valeur du dégradé: dropdown, default `y`; values: `y` Y axis; `x` X axis; `size` Size; `field` “Color” field

### Points (`points`)
- `points.shape` Shape / Forme: dropdown, default `circle`; values: `circle` Circle; `square` Square; `diamond` Diamond; `triangle` Triangle; `cross` Cross (x); `plus` Plus (+); `series` One shape per series. One shape per series helps when colors are hard to tell apart.
- `points.size` Size (without a Size field) / Taille (sans champ Taille): number, default `8`; values: 2 to 40
- `points.minSize` Smallest bubble / Bulle la plus petite: number, default `5`; values: 2 to 40
- `points.maxSize` Largest bubble / Bulle la plus grande: number, default `36`; values: 6 to 120
- `points.sizeScale` Size scaling / Échelle des tailles: dropdown, default `auto`; values: `auto` Automatic; `magnitude` Magnitude (0 = smallest); `range` Data range (min → max). Automatic: magnitude when all sizes have the same sign, data range otherwise (like Power BI).
- `points.opacity` Opacity (%) / Opacité (%): number, default `80`; values: 10 to 100
- `points.fill` Fill points / Remplir les points: toggle, default `true`; values: true / false. Off: hollow markers (only their outline, in the point color), like “Fill point” in Power BI.
- `points.outline` Outline / Contour: toggle, default `true`; values: true / false
- `points.outlineColor` Outline color (empty = background) / Couleur du contour (vide = fond): color, default (empty); values: hex color. Visible when `points.outline` = `true`
- `points.outlineWidth` Outline width / Épaisseur du contour: number, default `1`; values: 0.5 to 6. Visible when `points.outline` = `true`
- `points.autoFit` Keep bubbles inside the plot / Bulles entières dans le cadre: toggle, default `true`; values: true / false. Widens the axes so that bubbles near the edges are not cut (when minimum and maximum are automatic).
- `points.jitter` Jitter overlapping points (px) / Dispersion des points superposés (px): number, default `0`; values: 0 to 20. Moves each point by a small fixed offset so that identical points can be seen and clicked. 0 = exact positions.
- `points.imageMinSize` Minimum size of a point with an image (px) / Taille minimale d'un point avec image (px): number, default `22`; values: 8 to 120. Points that carry an image (“Image” field) are drawn at least this large so the image stays legible.
- `points.imageBorder` Border in the series color / Bordure de la couleur de la série: toggle, default `true`; values: true / false
- `points.imageBorderWidth` Border width / Épaisseur de la bordure: number, default `1.5`; values: 0.5 to 6. Visible when `points.imageBorder` = `true`
- `points.connect` Connect the points of each series ★ / Relier les points de chaque série ★ ★: toggle, default `false`; values: true / false. A line joins the points of a series in the order of the Details field (a year, a month…): a trajectory.
- `points.connectWidth` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `points.connectStyle` Line style / Style du trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `points.connectArrows` Arrow on the last point / Flèche sur le dernier point: toggle, default `true`; values: true / false

### Data labels / Étiquettes de données (`labels`)
- `labels.show` Show / Afficher: toggle, default `false`; values: true / false
- `labels.content` Content / Contenu: dropdown, default `category`; values: `category` Detail (point name); `categoryY` Name and Y value; `xy` X and Y values; `y` Y value
- `labels.which` Labeled points / Points étiquetés: dropdown, default `top`; values: `top` Largest (N); `all` All (no overlap); `selected` Selected. Points with a text in the “Label (text)” field are always labeled with that text.
- `labels.n` N: number, default `10`; values: 1 to 200. Visible when `labels.which` = `top`
- `labels.italic` Italic / Italique: toggle, default `false`; values: true / false
- `labels.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false. A colored box behind each label, like the native “Background” of category labels.
- `labels.bgColor` Background color (empty = background) / Couleur de l'arrière-plan (vide = fond): color, default (empty); values: hex color. Visible when `labels.bgShow` = `true`
- `labels.bgTransparency` Background transparency (%) / Transparence de l'arrière-plan (%): slider, default `15`; values: 0 to 100. Visible when `labels.bgShow` = `true`
- `labels.fontSize` Size / Taille: number, default `10`; values: 6 to 24
- `labels.color` Color (empty = automatic) / Couleur (vide = automatique): color, default (empty); values: hex color. Automatic: readable color depending on the background (inside bars: white or dark).
- `labels.bold` Bold / Gras: toggle, default `false`; values: true / false
- `labels.halo` Text halo / Halo autour du texte: toggle, default `true`; values: true / false
- `labels.declutter` Hide overlapping labels / Masquer les étiquettes qui se chevauchent: toggle, default `true`; values: true / false
- `labels.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `labels.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `labels.prefix` Prefix / Préfixe: text, default (empty)
- `labels.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)

### Quadrants ★ (`quadrants`)
- `quadrants.show` Show ★ / Afficher ★ ★: toggle, default `false`; values: true / false
- `quadrants.xMode` Vertical split / Séparation verticale: dropdown, default `average`; values: `average` Average of X; `median` Median of X; `constant` Fixed value; `measure` “Reference X” field
- `quadrants.xValue` X value / Valeur X: number, default `0`. Visible when `quadrants.xMode` = `constant`
- `quadrants.yMode` Horizontal split / Séparation horizontale: dropdown, default `average`; values: `average` Average of Y; `median` Median of Y; `constant` Fixed value; `measure` “Reference Y” field
- `quadrants.yValue` Y value / Valeur Y: number, default `0`. Visible when `quadrants.yMode` = `constant`
- `quadrants.lineColor` Split color (empty = secondary) / Couleur des séparations (vide = secondaire): color, default (empty); values: hex color
- `quadrants.lineStyle` Line style / Style du trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `quadrants.tint` Tint the top-right quadrant / Teinter le quadrant en haut à droite: toggle, default `true`; values: true / false
- `quadrants.tintAll` Tint all four quadrants / Teinter les quatre quadrants: toggle, default `false`; values: true / false
- `quadrants.colorTR` Top right (empty = accent) / En haut à droite (vide = accent): color, default (empty); values: hex color
- `quadrants.colorTL` Top left (empty = automatic) / En haut à gauche (vide = automatique): color, default (empty); values: hex color. Visible when `quadrants.tintAll` = `true`
- `quadrants.colorBL` Bottom left (empty = unfavorable) / En bas à gauche (vide = défavorable): color, default (empty); values: hex color. Visible when `quadrants.tintAll` = `true`
- `quadrants.colorBR` Bottom right (empty = automatic) / En bas à droite (vide = automatique): color, default (empty); values: hex color. Visible when `quadrants.tintAll` = `true`
- `quadrants.tintOpacity` Tint opacity (%) / Opacité de la teinte (%): number, default `7`; values: 2 to 40
- `quadrants.colorPoints` Color points by quadrant / Colorer les points selon leur quadrant: toggle, default `false`; values: true / false
- `quadrants.topLeft` Top left / En haut à gauche: text, default (empty)
- `quadrants.topRight` Top right / En haut à droite: text, default (empty)
- `quadrants.bottomLeft` Bottom left / En bas à gauche: text, default (empty)
- `quadrants.bottomRight` Bottom right / En bas à droite: text, default (empty)
- `quadrants.namesSize` Text size / Taille du texte: number, default `9`; values: 6 to 20
- `quadrants.counts` Point count / Nombre de points: dropdown, default `none`; values: `none` None; `count` Count; `percent` Percentage; `both` Count and percentage

### X axis / Axe X (`xAxis`)
- `xAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `xAxis.position` Position: dropdown, default `bottom`; values: `bottom` Bottom; `top` Top
- `xAxis.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `xAxis.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `xAxis.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `xAxis.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `xAxis.prefix` Prefix / Préfixe: text, default (empty)
- `xAxis.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)
- `xAxis.line` Axis line / Trait de l'axe: toggle, default `false`; values: true / false
- `xAxis.scale` Scale / Échelle: dropdown, default `linear`; values: `linear` Linear; `log` Logarithmic
- `xAxis.min` Minimum: text, default (empty)
- `xAxis.max` Maximum: text, default (empty)
- `xAxis.zero` Always include zero / Toujours inclure zéro: toggle, default `false`; values: true / false. Visible when `xAxis.scale` = `linear`
- `xAxis.ticks` Number of ticks (approx.) / Nombre de graduations (environ): number, default `5`; values: 2 to 20
- `xAxis.invert` Invert axis / Inverser l'axe: toggle, default `false`; values: true / false
- `xAxis.round` Round range / Arrondir la plage: toggle, default `true`; values: true / false. Computed bounds rounded to a round tick. Off: the axis stops at the extreme values.
- `xAxis.showTitle` Show / Afficher: toggle, default `false`; values: true / false
- `xAxis.titleText` Text / Texte: text, default (empty). Visible when `xAxis.showTitle` = `true`

### Y axis / Axe Y (`yAxis`)
- `yAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `yAxis.position` Position: dropdown, default `left`; values: `left` Left; `right` Right
- `yAxis.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `yAxis.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `yAxis.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `yAxis.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `yAxis.prefix` Prefix / Préfixe: text, default (empty)
- `yAxis.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)
- `yAxis.line` Axis line / Trait de l'axe: toggle, default `false`; values: true / false
- `yAxis.scale` Scale / Échelle: dropdown, default `linear`; values: `linear` Linear; `log` Logarithmic
- `yAxis.min` Minimum: text, default (empty)
- `yAxis.max` Maximum: text, default (empty)
- `yAxis.zero` Always include zero / Toujours inclure zéro: toggle, default `false`; values: true / false. Visible when `yAxis.scale` = `linear`
- `yAxis.ticks` Number of ticks (approx.) / Nombre de graduations (environ): number, default `5`; values: 2 to 20
- `yAxis.invert` Invert axis / Inverser l'axe: toggle, default `false`; values: true / false
- `yAxis.round` Round range / Arrondir la plage: toggle, default `true`; values: true / false. Computed bounds rounded to a round tick. Off: the axis stops at the extreme values.
- `yAxis.showTitle` Show / Afficher: toggle, default `false`; values: true / false
- `yAxis.titleText` Text / Texte: text, default (empty). Visible when `yAxis.showTitle` = `true`

### Gridlines / Quadrillage (`gridlines`)
- `gridlines.hShow` Show / Afficher: toggle, default `true`; values: true / false
- `gridlines.hColor` Color (empty = style grid) / Couleur (vide = grille du style): color, default (empty); values: hex color
- `gridlines.hWidth` Width / Épaisseur: number, default `1`; values: 0.5 to 6
- `gridlines.hStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `gridlines.zeroLine` Zero line / Ligne du zéro: toggle, default `true`; values: true / false
- `gridlines.vShow` Show / Afficher: toggle, default `false`; values: true / false
- `gridlines.vColor` Color (empty = style grid) / Couleur (vide = grille du style): color, default (empty); values: hex color
- `gridlines.vWidth` Width / Épaisseur: number, default `1`; values: 0.5 to 6
- `gridlines.vStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `gridlines.plotColor` Background color (empty = none) / Couleur d'arrière-plan (vide = aucune): color, default (empty); values: hex color
- `gridlines.plotTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100

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

### Highlight ★ / Mise en avant ★ (`highlight`)
- `highlight.names` Highlighted points ★ / Points mis en avant ★ ★: textarea, default (empty). Names of the Details field (case and accents ignored). The “Highlight” field does the same with a measure.
- `highlight.color` Color (empty = point color) / Couleur (vide = couleur du point): color, default (empty); values: hex color
- `highlight.othersGray` Other points in gray / Autres points en gris: toggle, default `true`; values: true / false
- `highlight.othersOpacity` Other points opacity (%) / Opacité des autres points (%): number, default `35`; values: 5 to 100
- `highlight.labels` Label highlighted points / Étiqueter les points mis en avant: toggle, default `true`; values: true / false

### Zoom (`zoom`)
- `zoom.x` X axis zoom slider / Curseur de zoom de l'axe X: toggle, default `false`; values: true / false
- `zoom.y` Y axis zoom slider / Curseur de zoom de l'axe Y: toggle, default `false`; values: true / false
- `zoom.rect` Shift + drag: zoom into a rectangle / Maj + glisser : zoomer sur un rectangle: toggle, default `true`; values: true / false. Double-click the chart, or the ⟲ button, to zoom out.

### Density ★ / Densité ★ (`density`)
- `density.show` Show ★ / Afficher ★ ★: toggle, default `false`; values: true / false. Shows where the points concentrate: cells colored by the number of points, or a smooth heat map.
- `density.shape` Shape / Forme: dropdown, default `hex`; values: `hex` Hexagons; `square` Squares; `circle` Circles (size by count); `continuous` Continuous (smooth gradient); `contour` Contour lines
- `density.mode` Points: dropdown, default `under`; values: `under` Density under the points; `replace` Density instead of the points
- `density.radius` Cell size (px) / Taille des cases (px): number, default `12`; values: 4 to 40. Visible when `density.shape` = `hex` or `square` or `circle`
- `density.bandwidth` Smoothing (px, 0 = automatic) / Lissage (px, 0 = automatique): number, default `0`; values: 0 to 120. Visible when `density.shape` = `continuous` or `contour`. Radius of the smoothing kernel. Automatic: computed from the spread and the number of points.
- `density.levels` Number of contour lines / Nombre de lignes de niveau: number, default `6`; values: 2 to 15. Visible when `density.shape` = `contour`
- `density.colorMode` Colors / Couleurs: dropdown, default `gradient`; values: `gradient` Style gradient; `single` One color
- `density.color` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color. Visible when `density.colorMode` = `single`
- `density.opacity` Opacity (%) / Opacité (%): number, default `75`; values: 10 to 100

### Marginal distributions ★ / Distributions en marge ★ (`marginals`)
- `marginals.show` Show ★ / Afficher ★ ★: toggle, default `false`; values: true / false. Distribution of X above the chart and of Y on its right.
- `marginals.kind` Type: dropdown, default `histogram`; values: `histogram` Histogram; `box` Box plot
- `marginals.bins` Number of bins / Nombre de classes: number, default `20`; values: 5 to 60. Visible when `marginals.kind` = `histogram`
- `marginals.bySeries` One per series / Une par série: toggle, default `true`; values: true / false
- `marginals.size` Height (px) / Hauteur (px): number, default `44`; values: 20 to 160

### Small multiples ★ / Petits multiples ★ (`smallMultiples`)
- `smallMultiples.columns` Columns (0 = automatic) / Colonnes (0 = automatique): number, default `0`; values: 0 to 12
- `smallMultiples.minHeight` Minimum chart height (px) / Hauteur minimale d'un graphique (px): number, default `120`; values: 60 to 600
- `smallMultiples.gap` Spacing (px) / Espacement (px): number, default `12`; values: 0 to 60
- `smallMultiples.titleSize` Title size / Taille des titres: number, default `10`; values: 6 to 24
- `smallMultiples.border` Frame around each chart / Cadre autour de chaque graphique: toggle, default `false`; values: true / false

### Playback / Lecture (`play`)
- `play.start` Frame shown on opening / Image affichée à l'ouverture: dropdown, default `last`; values: `last` The last one (most recent); `first` The first one
- `play.speed` Duration of a frame (ms) / Durée d'une image (ms): number, default `1000`; values: 200 to 5000
- `play.loop` Loop / Lecture en boucle: toggle, default `false`; values: true / false
- `play.autoPlay` Play automatically on opening / Lecture automatique à l'ouverture: toggle, default `false`; values: true / false. Not when the system asks to reduce motion.
- `play.controls` Play bar / Barre de lecture: toggle, default `true`; values: true / false
- `play.showLabel` Current value in the background / Valeur en cours en fond: toggle, default `true`; values: true / false
- `play.labelSize` Background value size / Taille de la valeur en fond: number, default `44`; values: 12 to 160. Visible when `play.showLabel` = `true`
- `play.trails` Trails / Traînées: dropdown, default `selected`; values: `selected` Selected points; `none` None; `all` All points ★. The path of a point from the first frame to the current one.
- `play.trailMode` Trail style / Forme des traînées: dropdown, default `lines`; values: `lines` Lines; `density` Density ★; `both` Lines and density ★. Density: a heat map of every position of the point over all frames, drawn under the points (one per series when several points are selected).

### Interactions (`interaction`)
- `interaction.hover` Highlight on hover / Mettre en avant au survol: toggle, default `true`; values: true / false
- `interaction.dim` Dimmed items opacity (%) / Opacité des éléments estompés (%): number, default `25`; values: 5 to 80
- `interaction.brush` Select by drawing a rectangle / Sélection en traçant un rectangle: toggle, default `true`; values: true / false. Drag on the chart to select every point inside the rectangle (Ctrl to add).
- `interaction.brushShape` Selection shape / Forme de la sélection: dropdown, default `rectangle`; values: `rectangle` Rectangle; `lasso` Lasso (freehand). Visible when `interaction.brush` = `true`
- `interaction.selDensity` Density around the selection / Densité autour de la sélection: dropdown, default `none`; values: `none` None; `series` Points of the same series ★; `selected` Selected points ★. When points are selected, a heat map of their series (or of the selected points) is drawn under the cloud. With a play axis, see Playback › Trail style.

### Reference lines ★ / Lignes de référence ★ (`reference`, Analytics pane)
- `reference.show1` Show / Afficher: toggle, default `false`; values: true / false
- `reference.axis1` Axis / Axe: dropdown, default `y`; values: `y` Y axis (horizontal); `x` X axis (vertical)
- `reference.kind1` Value / Valeur: dropdown, default `average`; values: `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile; `measure` “Reference X” or “Reference Y” field
- `reference.value1` Constant value / Valeur constante: number, default `0`. Visible when `reference.kind1` = `constant`
- `reference.pct1` Percentile / Centile: number, default `90`; values: 1 to 99. Visible when `reference.kind1` = `percentile`
- `reference.label1` Label / Libellé: text, default (empty)
- `reference.showValue1` Show the value / Afficher la valeur: toggle, default `true`; values: true / false
- `reference.color1` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.style1` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `reference.width1` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `reference.labelPos1` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None
- `reference.show2` Show / Afficher: toggle, default `false`; values: true / false
- `reference.axis2` Axis / Axe: dropdown, default `y`; values: `y` Y axis (horizontal); `x` X axis (vertical)
- `reference.kind2` Value / Valeur: dropdown, default `constant`; values: `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile; `measure` “Reference X” or “Reference Y” field
- `reference.value2` Constant value / Valeur constante: number, default `0`. Visible when `reference.kind2` = `constant`
- `reference.pct2` Percentile / Centile: number, default `90`; values: 1 to 99. Visible when `reference.kind2` = `percentile`
- `reference.label2` Label / Libellé: text, default (empty)
- `reference.showValue2` Show the value / Afficher la valeur: toggle, default `true`; values: true / false
- `reference.color2` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.style2` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `reference.width2` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `reference.labelPos2` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None
- `reference.show3` Show / Afficher: toggle, default `false`; values: true / false
- `reference.axis3` Axis / Axe: dropdown, default `y`; values: `y` Y axis (horizontal); `x` X axis (vertical)
- `reference.kind3` Value / Valeur: dropdown, default `median`; values: `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile; `measure` “Reference X” or “Reference Y” field
- `reference.value3` Constant value / Valeur constante: number, default `0`. Visible when `reference.kind3` = `constant`
- `reference.pct3` Percentile / Centile: number, default `90`; values: 1 to 99. Visible when `reference.kind3` = `percentile`
- `reference.label3` Label / Libellé: text, default (empty)
- `reference.showValue3` Show the value / Afficher la valeur: toggle, default `true`; values: true / false
- `reference.color3` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.style3` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `reference.width3` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `reference.labelPos3` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None
- `reference.band` Show / Afficher: toggle, default `false`; values: true / false
- `reference.bandAxis` Axis / Axe: dropdown, default `y`; values: `y` Y axis; `x` X axis
- `reference.bandFrom` From / De: number, default `0`
- `reference.bandTo` To / À: number, default `0`
- `reference.bandLabel` Label / Libellé: text, default (empty)
- `reference.bandColor` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.bandOpacity` Opacity (%) / Opacité (%): number, default `12`; values: 2 to 60

### Trend ★ / Tendance ★ (`trend`, Analytics pane)
- `trend.show` Show / Afficher: toggle, default `false`; values: true / false. Regression line or curve (least squares).
- `trend.model` Model / Modèle: dropdown, default `linear`; values: `linear` Linear; `poly2` Polynomial (degree 2); `poly3` Polynomial (degree 3); `exp` Exponential; `log` Logarithmic; `power` Power
- `trend.perSeries` One trend per series / Une tendance par série: toggle, default `false`; values: true / false
- `trend.showR2` Show R² / Afficher le R²: toggle, default `true`; values: true / false
- `trend.showEquation` Show the equation / Afficher l'équation: toggle, default `false`; values: true / false
- `trend.band` 95% band / Bande à 95 %: dropdown, default `none`; values: `none` None; `mean` Confidence (the curve); `prediction` Prediction (the points)
- `trend.bandOpacity` Band opacity (%) / Opacité de la bande (%): number, default `14`; values: 3 to 60
- `trend.color` Color (empty = text or series) / Couleur (vide = texte ou série): color, default (empty); values: hex color
- `trend.style` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `trend.width` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6

### Symmetry and ratio ★ / Symétrie et ratio ★ (`symmetry`, Analytics pane)
- `symmetry.show` Show / Afficher: toggle, default `false`; values: true / false. Shades the areas where Y is above and below X, around the y = x diagonal.
- `symmetry.colorAbove` Color where Y > X (empty = favorable) / Couleur où Y > X (vide = favorable): color, default (empty); values: hex color
- `symmetry.colorBelow` Color where Y < X (empty = unfavorable) / Couleur où Y < X (vide = défavorable): color, default (empty); values: hex color
- `symmetry.opacity` Opacity (%) / Opacité (%): number, default `8`; values: 2 to 40
- `symmetry.labelAbove` Text where Y > X / Texte où Y > X: text, default (empty)
- `symmetry.labelBelow` Text where Y < X / Texte où Y < X: text, default (empty)
- `symmetry.diagonal` y = x diagonal / Diagonale y = x: toggle, default `true`; values: true / false
- `symmetry.ratio` Show / Afficher: toggle, default `false`; values: true / false. A line from the origin whose slope is the overall ratio Y ÷ X (like Power BI), or a fixed slope.
- `symmetry.ratioMode` Slope / Pente: dropdown, default `total`; values: `total` Total Y ÷ total X; `constant` Fixed value
- `symmetry.ratioValue` Fixed slope / Pente fixe: number, default `1`. Visible when `symmetry.ratioMode` = `constant`
- `symmetry.ratioColor` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `symmetry.ratioStyle` Line style / Style du trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `symmetry.ratioLabel` Show the slope / Afficher la pente: toggle, default `true`; values: true / false

### Slope lines y = a·x ★ / Droites y = a·x ★ (`slopes`, Analytics pane)
- `slopes.show1` Show / Afficher: toggle, default `false`; values: true / false
- `slopes.a1` Slope a (y = a·x + b) / Pente a (y = a·x + b): number, default `0.03`. E.g. 0.05 for a 5% yield: Y = 5% of X. Can be driven by a measure (Dynamic format field: slopes.a1).
- `slopes.b1` Intercept b / Ordonnée à l'origine b: number, default `0`
- `slopes.label1` Label / Libellé: text, default (empty)
- `slopes.color1` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `slopes.style1` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `slopes.width1` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `slopes.labelPos1` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None
- `slopes.show2` Show / Afficher: toggle, default `false`; values: true / false
- `slopes.a2` Slope a (y = a·x + b) / Pente a (y = a·x + b): number, default `0.05`. E.g. 0.05 for a 5% yield: Y = 5% of X. Can be driven by a measure (Dynamic format field: slopes.a2).
- `slopes.b2` Intercept b / Ordonnée à l'origine b: number, default `0`
- `slopes.label2` Label / Libellé: text, default (empty)
- `slopes.color2` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `slopes.style2` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `slopes.width2` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `slopes.labelPos2` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None
- `slopes.show3` Show / Afficher: toggle, default `false`; values: true / false
- `slopes.a3` Slope a (y = a·x + b) / Pente a (y = a·x + b): number, default `0.07`. E.g. 0.05 for a 5% yield: Y = 5% of X. Can be driven by a measure (Dynamic format field: slopes.a3).
- `slopes.b3` Intercept b / Ordonnée à l'origine b: number, default `0`
- `slopes.label3` Label / Libellé: text, default (empty)
- `slopes.color3` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `slopes.style3` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `slopes.width3` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `slopes.labelPos3` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None

### Confidence ellipses ★ / Ellipses de confiance ★ (`ellipses`, Analytics pane)
- `ellipses.show` Show / Afficher: toggle, default `false`; values: true / false. The area that holds most of the points of each series (normal distribution).
- `ellipses.level` Level / Niveau: dropdown, default `95`; values: `68` 68%; `90` 90%; `95` 95%; `99` 99%
- `ellipses.bySeries` One per series (or per group) / Une par série (ou par groupe): toggle, default `true`; values: true / false
- `ellipses.fillOpacity` Fill opacity (%) / Opacité du remplissage (%): number, default `8`; values: 0 to 50
- `ellipses.style` Line style / Style du trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted

### Automatic clusters ★ / Groupes automatiques ★ (`clusters`, Analytics pane)
- `clusters.show` Show / Afficher: toggle, default `false`; values: true / false. Groups points that are close to each other (k-means) and colors each group.
- `clusters.k` Number of clusters (0 = automatic) / Nombre de groupes (0 = automatique): number, default `0`; values: 0 to 10
- `clusters.normalize` Put X and Y on the same scale / Mettre X et Y à la même échelle: toggle, default `true`; values: true / false. Recommended when X and Y have different units (orders and euros).
- `clusters.centers` Mark the centers / Marquer les centres: toggle, default `true`; values: true / false
- `clusters.prefix` Cluster name / Nom des groupes: text, default (empty)

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# KPI Plume

- KPI cards that flip: value, comparison, target, trend, icon, and on the back the definition and the figures you choose.
- Slug `kpi-card` · version 1.4.0.0 · GUID (`visualType`) `plumeKpiCardC478BD14F72F4580AC1F80652CEB51D7` · page https://plumevisuals.com/en/visuals/kpi-card

### What the visual does

KPI Plume (formerly Plume KPI) is a Power BI custom visual (base range, version 1.4.0.0, installed from the `.pbiviz` file; AppSource submission in progress) that draws KPI cards: one card per measure, or, with a category field, one card per region / product / team (optionally plus a "Total" card). Cards always fit in the visual with no scroll bar (`layout.overflow` = `fit`, default; `scroll` keeps the minimum sizes and scrolls). Each card shows a title, an icon (134 built-in Lucide icons in 11 themes, chosen per KPI in `kpiFormat.icon` or picked automatically from the measure name: revenue → €, orders → cart, rate → %, customers → people…; or given by a text measure in the Icon field), an optional ↗ link button (`kpiFormat.link`), the value with automatic units per number (1.5M, 171K, 451), a comparison (change in % or value, ▲▼ arrows, badge, "vs …" label, neutral zone, good / bad / neutral colors), a target (a field, or a value typed per KPI in `kpiFormat.targetValue`; progress bar or text; ring and bullet ★), an optional second comparison ★ (Comparison 2 field) and a trend sparkline (line, area, smooth area; columns and step ★) placed at the bottom, in the background or on the right. The signature feature: cards **flip** (on hover, on click, or on the ↻ icon) to show their back: an information text with **bold**, line breaks and placeholders, plus key figures chosen KPI by KPI in the dynamic card "Back of the card: content per KPI" (`backItems`: comparison, change, comparison 2, target, achievement, period, last period, min, max, average, tooltip fields, and up to 8 measures of the "Back of the card: figures" field shown only on the back). At rest a card is drawn flat (no 3D transform) so its text stays sharp; 3D is only used during the flip. Trend-axis dates sent by Power BI Desktop as ISO text are read as dates ("Dec 2025 vs Nov 2025"; `sparkline.dateFormat` overrides the period format). The visual makes no network request.

**New in version 1.4.0.0 (30/10/2026):** Format pane reorganized (`compare` → `comparison`, `trend` → `sparkline`); free native-parity additions: **Title** and **Note** text-measure fields per KPI, **Reference labels** fields and card, accent bar on the right with its own color, KPI title position and italics, distance to target, date of the last period.

### 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 (`style.customColors` and the colors under it) are **free**; every other `style.preset`, the other gradient palettes (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium** (watermark without a key). See "Styles and theme JSON" below.
- Using a premium feature without a valid key shows **"Plume Visuals · Premium preview"** (French: « Plume Visuals · Aperçu premium ») in the footer of the visual, with an "Unlock →" link to the pricing page. It disappears once a key is pasted in **Format › Plume Studio License › License key** (`license.key`; French: « Licence Plume Studio › Clé de licence »), the **first card** of the Format pane.
- Premium features of KPI Plume:
  - `card.shape` = `circle`, `leaf`, `chamfer` ("Cut corners ★") or `ticket`;
  - `layout.arrange` = `heroLeft` / `heroTop` ("First one large, on the left / on top ★", size in `layout.heroSize`);
  - `target.style` = `ring` or `bullet`: counts only when a Target field is present and `target.show` is on;
  - `sparkline.type` = `columns` or `step`: counts only with a Trend axis field and `sparkline.show` on;
  - `flip.animation` = `slide`, `door`, `curtain`, `zoom`, `cube`, and `flip.easing` = `bounce`: count only when `flip.trigger` is not `none`;
  - the **Comparison 2** field (`reference2`): counts when it is filled and `comparison.show` and `comparison.show2` are on;
  - `comparison.statusFrom` = `both` ("Target and comparison (green, amber, red) ★").
- Free in 1.3: per-KPI icons, the Icon field, fixed target and field numbers per KPI, the back content per KPI and the "Back of the card: figures" field, the link per card, `layout.hideBlank`, `layout.overflow`, `comparison.statusFrom` = `compare` / `compare2` / `target` (thresholds with `comparison.warnFrom`, amber `comparison.warnColor`).
- 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 `kpi-card` 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, key accepted for 30 more days, reminders 30 and 7 days before the end), for this visual: 39 € personal, 99 € SME, 299 € enterprise per year, or the catalog packs (199 € / 399 € / 1,199 € per year; tiers by number of users, designers and viewers included: personal 1–10, SME 11–200, enterprise more than 200). Version 1.3.2.0, available on plumevisuals.com (`.pbiviz` file); AppSource submission in progress.

### Expected data shape

A **matrix** data view: trend periods on rows, category members on columns, measures in cells, plus the grand total that Power BI computes (hidden `subTotals` object, kept on).

- **Values (one KPI per measure)** (`values`, « Valeurs (un KPI par mesure) », measures, required): one card per measure.
- **Comparison (previous year…)** (`reference`, « Comparaison (année précédente…) », measures): compared with the value **of the same rank** (1st with 1st…), or the field number set per KPI in `kpiFormat.refField` (0 = same rank, -1 = none).
- **Comparison 2 (budget…)** ★ (`reference2`, « Comparaison 2 (budget…) », measures, same rank): second change under the first one (label `kpiFormat.refLabel2`).
- **Target** (`target`, « Objectif », measures): target of the KPI of the same rank, or the field number set in `kpiFormat.targetField`; `kpiFormat.targetValue` (non-zero) types a fixed target for one KPI instead.
- **Trend axis (date)** (`trend`, « Axe de tendance (date) », one column): month, week, year… draws the sparkline (data window of 2,000 periods).
- **One KPI per… (category)** (`category`, « Un KPI par… (catégorie) », one column): repeats the KPIs for each member.
- **Back of the card (text)** (`backText`, « Dos de la carte (texte) », measures): text measure shown on the back of the KPI of the same rank (a definition, a comment).
- **Back of the card: figures** (`backFields`, « Dos de la carte : chiffres », up to 8 measures): label + value rows shown only on the back, with the measure's own format; switched on or off per KPI with `backItems.f1` … `backItems.f8`.
- **Icon (text measure)** (`icon`, « Icône (mesure texte) », measures, same rank): an icon key (`trendUp`) or Lucide name (`trending-up`), an emoji or short symbol, or an inline image `data:image/svg+xml…` (also png, jpeg, gif, webp). Web addresses are never loaded.
- **Tooltips** (`tooltips`, « Infobulles », measures) and **Dynamic format** (`format`, « Format dynamique », measures named `card.setting`).

| Month (`trend`) | Revenue (`values`) | Target (`target`) |
|---|---|---|
| 2025-10-01 | 118 400 | 110 000 |
| 2025-11-01 | 151 900 | 110 000 |
| Total | 1 512 000 | 1 320 000 |

- With a trend axis, `value.aggregate` = `total` (default) shows the **total row computed by Power BI** (exact for rates and averages); if no total is available it falls back to the last period. Other values: `last`, `first`, `avg`, `max`, `min` of the periods.
- `comparison.source` = `auto` uses the Comparison field when filled, otherwise the previous period of the trend axis. With `previous` / `first`, the change compares the **last period** with the previous / first one (label like "Dec 2025 vs Nov 2025"), even when the displayed value is the total.
- Status (`comparison.statusFrom`): `auto` (default) = good / bad from the sign of the change (`kpiFormat.lowerIsBetter` reverses it, `comparison.neutral` = neutral band in %), without a comparison from the target being reached; `compare` / `compare2` = from one change; `target` = good from 100 %, warning (amber) from `comparison.warnFrom` % (default 90), bad below; `both` ★ = good when the target is reached, warning when only a comparison is favorable, bad otherwise. Each change badge keeps the color of its own direction.

### DAX recipes

```dax
Revenue = SUM ( Sales[Amount] )
Orders = COUNTROWS ( Sales )
Average basket = DIVIDE ( [Revenue], [Orders] )
Margin rate = DIVIDE ( SUM ( Sales[Margin] ), [Revenue] )
Target = 110000 * DISTINCTCOUNT ( Sales[Month] )

// Comparison field: needs a marked date table; take the trend axis from that table too
Revenue LY = CALCULATE ( [Revenue], SAMEPERIODLASTYEAR ( 'Calendar'[Date] ) )

// Back of the card (text)
Revenue back = "Top region: " & MAXX ( TOPN ( 1, VALUES ( Sales[Region] ), [Revenue] ), Sales[Region] )
```

Back text placeholders (`kpiFormat.backText`): `{name}`, `{value}`, `{ref}`, `{delta}`, `{deltaPct}`, `{ref2}`, `{delta2}`, `{deltaPct2}`, `{target}`, `{progress}`, `{min}`, `{max}`, `{avg}` are formatted values; `{first}`, `{last}`, `{period}` are period labels. `**…**` = bold; a line break or a literal `\n` = new paragraph. `kpiFormat.note` (note under the value) accepts `{value}`, `{ref}`, `{delta}`, `{target}`, `{progress}`, `{period}`. Back text priority: the text set for that measure, then the Back of the card measure, then the "All KPIs" text. `backItems.textAfter` puts it after the figures; `back.figLayout` (`auto` / `columns` / `stacked`) and `back.fit` (shrink to 75 % before scrolling, no visible scroll bar) keep the back readable.

### Interactions with the report

- With One KPI per…, clicking a card cross-filters the report (`interaction.select`), other cards are dimmed (`interaction.dim`), clicking the background clears. When `flip.trigger` = `click`, a click flips and **Ctrl + click** filters.
- Power BI tooltips on cards (value, comparison, change, target, tooltip fields) when `tooltip.show` is on and `flip.trigger` is not `hover`; per-period tooltip on the sparkline (`tooltip.periodTip`). Context menu on each card.
- Keyboard: Tab to reach the cards, ← → to move, Enter or Space flips, Esc flips back. The back is announced to screen readers. Reduced motion makes flips and the counter instant. High contrast uses host colors. Never flips on a dashboard tile. `flip.preview` shows the back in edit mode to format it.

### Dynamic formats

- **No fx button**: Power BI does not offer conditional formatting of Format pane options to table / matrix visuals (Table Plume, Matrix Plume, KPI Plume). Everything goes through the **Dynamic format** well (role `format`).
- Rename each measure for this visual `card.setting`, e.g. `flip.trigger`, `layout.arrange`, `title.text`, `kpiFormat.backText`. Case, accents and the separator are ignored. It wins over the fixed setting, the style and the JSON theme.
- KPI Plume reads the **grand total** value. Examples: `"Data as of " & FORMAT ( MAX ( Sales[Month] ), "mmmm yyyy" )` renamed `kpiFormat.backText`; `IF ( ISFILTERED ( Sales[Region] ), "none", "click" )` renamed `flip.trigger`.
- For the dynamic card **Per-KPI settings**, only the "All KPIs" level is driven (`kpiFormat.color`, `kpiFormat.backText`…); a value set for one specific measure in the pane stays first.
- Driving a setting with DAX is free; a ★ value set by DAX still shows the watermark without a key.

### Format pane: how to read the tables below

- Each option has an ID `card.option` (for example `flip.trigger`). The card is the capabilities.json **object name**, the option is the **property name**. Note that the visual has a Format card named `card` ("Card"), so its options read `card.shape`, `card.colorBy`…
- Card order: `license` (always first), `style` (shared Style card), `kpiFormat` (dynamic card "Per-KPI settings": a list at the top, "Apply settings to", picks "All KPIs" or one measure), then `layout`, `card`, `kpiTitle`, `value`, `icon`, `comparison`, `target`, `trend`, `flip`, `back`, `backItems` (dynamic card "Back of the card: content per KPI", same "Apply settings to" list, only when `flip.trigger` is not `none`), `interaction`, then `title`, `source`, `container` and `texts`. Format pane in version 1.4.0.0 (30/10/2026), top to bottom: `license`, `style`, `kpiFormat`, `backItems`, `layout`, `card`, `kpiTitle`, `value`, `refLabels`, `icon`, `comparison`, `target`, `sparkline`, `flip`, `back`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- Labels follow the language of Power BI Desktop; `texts.language` can force French or English inside the visual.
- "Visible when" means the option only appears when another option has one of the listed values (most `flip` options only when `flip.trigger` is not `none`).

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. Literal syntax: booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes (double an apostrophe inside), colors wrapped in `solid.color`. Per-KPI settings are entries of `kpiFormat` with a `selector` on the measure's `queryRef`.

```json
{
  "visualType": "plumeKpiCardC478BD14F72F4580AC1F80652CEB51D7",
  "query": {
    "queryState": {
      "values": { "projections": [
        { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Revenue" } }, "queryRef": "Sales.Revenue", "nativeQueryRef": "Revenue" },
        { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Margin rate" } }, "queryRef": "Sales.Margin rate", "nativeQueryRef": "Margin rate" } ] },
      "target": { "projections": [
        { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Target" } }, "queryRef": "Sales.Target", "nativeQueryRef": "Target" } ] },
      "trend": { "projections": [
        { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Month" } }, "queryRef": "Sales.Month", "nativeQueryRef": "Month" } ] }
    }
  },
  "objects": {
    "layout":  [ { "properties": { "arrange": { "expr": { "Literal": { "Value": "'row'" } } } } } ],
    "card":    [ { "properties": { "colorBy": { "expr": { "Literal": { "Value": "'status'" } } },
                                   "statusBar": { "expr": { "Literal": { "Value": "'left'" } } } } } ],
    "trend":   [ { "properties": { "type": { "expr": { "Literal": { "Value": "'line'" } } } } } ],
    "flip":    [ { "properties": { "trigger": { "expr": { "Literal": { "Value": "'hover'" } } },
                                   "animation": { "expr": { "Literal": { "Value": "'fade'" } } },
                                   "duration": { "expr": { "Literal": { "Value": "400D" } } } } } ],
    "kpiFormat": [
      { "properties": { "backText": { "expr": { "Literal": { "Value": "'**Revenue** for the period: {value}.\\nBest month: {max}.'" } } },
                        "color": { "solid": { "color": { "expr": { "Literal": { "Value": "'#b8462a'" } } } } } },
        "selector": { "metadata": "Sales.Revenue" } },
      { "properties": { "icon": { "expr": { "Literal": { "Value": "'percent'" } } },
                        "decimals": { "expr": { "Literal": { "Value": "1D" } } } },
        "selector": { "metadata": "Sales.Margin rate" } } ],
    "license": [ { "properties": { "key": { "expr": { "Literal": { "Value": "'PLUM1.…'" } } } } } ]
  }
}
```

The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from the `.pbiviz` file). Do not turn off the hidden `subTotals` properties: the period total comes from them.

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`.
- `style.themeJson` (Format › Style › Theme JSON ★) takes a JSON theme as plain text. Format v2: an object with an optional `extends` (a style ID above) and optional groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`; the v1 flat format (`style`, `palette`, `accent`, `background`…) is still read. Every field is optional. Colors are `#RRGGBB` (`#RGB` and `#RRGGBBAA` accepted, opacity ignored). Unknown fields and values outside the allowed lists are ignored, out-of-range numbers are clamped. Invalid JSON shows "Invalid theme JSON: ignored" in edit mode and the visual keeps its look.
- Full field list with allowed values, examples and troubleshooting: tutorial https://plumevisuals.com/ai/tutorials/en/themes-json.md (French: https://plumevisuals.com/ai/tutorials/fr/themes-json.md). The same JSON can be pasted in every Plume visual of a page.
- Priority (the last one wins): visual defaults → `style.preset` → `style.themeJson` → `style.palette` (if not "Style or theme palette") → `style.followTheme` → custom colors → options set by hand in the other cards → DAX formats (fx button, "Dynamic format" field) → Windows high contrast.

### Common pitfalls

- Target or comparison on the wrong card: pairing is by rank; keep the same order in Values, Comparison, Target and Back of the card, or set `kpiFormat.targetField` / `kpiFormat.refField` for that KPI, or type a fixed target (`kpiFormat.targetValue`).
- The change does not match the displayed value: with `comparison.source` = `auto` and no Comparison field, it compares the last two periods of the trend axis. Add a last-year measure.
- `Revenue LY` blank or wrong: time intelligence on a date table, but the trend axis comes from the fact table; take both from the date table.
- A click flips instead of filtering: `flip.trigger` = `click`; use Ctrl + click, or `hover` / `icon` (with `hover`, cards show no Power BI tooltip: the back replaces it).
- Watermark visible: a ★ shape, layout, target style, trend type, animation or easing, a filled Comparison 2 field, the "Target and comparison" status, or a ★ style / palette / Theme JSON, without a valid key.
- Choosing the icon of one card: Per-KPI settings, pick the measure in "Apply settings to", then Icon (the list reads "Theme · Icon").

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

An fx button on any option, a needle gauge or speedometer, more than one target per KPI, a third comparison, a forecast on the sparkline, icons or images loaded from a web address (only built-in icons, symbols / emoji, or `data:image/…` from the Icon field), page navigation or drillthrough on click (only the context menu and the ↗ link), drill-down on the trend, a play / animation over time, write-back of targets, dynamic Top N of categories, highlighting from other visuals.

## KPI Plume: data fields

- `values` Values (one KPI per measure) / Valeurs (un KPI par mesure) (measure, several max): Each measure is one KPI card.
- `reference` Comparison (previous year…) / Comparaison (année précédente…) (measure, several max): Compared with the value of the same rank (1st with 1st…).
- `reference2` Comparison 2 (budget…) / Comparaison 2 (budget…) (measure, several max): Second comparison of the KPI of the same rank, shown under the first one.
- `target` Target / Objectif (measure, several max): Goal of the KPI of the same rank: progress bar or ring.
- `trend` Trend axis (date) / Axe de tendance (date) (column, 1 max): Draws the sparkline (month, week, year…).
- `category` One KPI per… (category) / Un KPI par… (catégorie) (column, 1 max): Repeats the KPIs for each value of the field (region, product…).
- `backText` Back of the card (text) / Dos de la carte (texte) (measure, several max): Text measure shown on the back of the KPI of the same rank (a definition, a comment…).
- `backFields` Back of the card: figures / Dos de la carte : chiffres (measure, several max): Measures shown only on the back (label and value). Choose them per KPI in “Back of the card: content per KPI”.
- `icon` Icon (text measure) / Icône (mesure texte) (measure, several max): Icon name (trending-up, euro…), emoji or SVG image (data:image/svg+xml…) for the KPI of the same rank, for instance per category.
- `titles` Title (text measure) / Titre (mesure texte) (measure, several max): Title of the KPI of the same rank, computed by DAX (for instance “Sales” & the selected year). Replaces Per-KPI settings › Title.
- `notes` Note (text measure) / Note (mesure texte) (measure, several max): Note under the value of the KPI of the same rank, computed by DAX. Placeholders such as {delta} are filled.
- `refLabels` Reference labels / Libellés de référence (measure, several max): Measures shown under the value (label and value), like the reference labels of the native card.
- `refDetails` Reference labels: details / Libellés de référence : détails (measure, several max): Detail written under the reference label of the same rank (text or number).
- `tooltips` Tooltips / Infobulles (measure, several max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## KPI Plume: Format pane options (228)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Per-KPI settings / Réglages par KPI (`kpiFormat`, one entry per item with a selector)
- `kpiFormat.title` Title (empty = measure name) / Titre (vide = nom de la mesure): text, default (empty)
- `kpiFormat.note` Note under the value / Note sous la valeur: text, default (empty). Short text such as “Year to date”. Placeholders: {value}, {ref}, {delta}, {target}, {progress}, {period}.
- `kpiFormat.icon` Icon / Icône: dropdown, default `auto`; values: `auto` Automatic (from the name); `none` None; `euro` Finance · Euro; `dollar` Finance · Dollar; `pound` Finance · Pound sterling; `coins` Finance · Coins; `banknote` Finance · Banknote; `wallet` Finance · Wallet; `piggyBank` Finance · Piggy bank (savings); `creditCard` Finance · Credit card; `receipt` Finance · Receipt; `landmark` Finance · Bank; `handCoins` Finance · Payment; `calculator` Finance · Calculator; `percent` Finance · Percent; `badgePercent` Finance · Discount; `cart` Sales · Cart; `bag` Sales · Shopping bag; `store` Sales · Store; `tag` Sales · Tag (price); `ticket` Sales · Ticket; `handshake` Sales · Handshake (deals); `briefcase` Sales · Briefcase; `gift` Sales · Gift; `megaphone` Sales · Megaphone (marketing); `users` People · People; `user` People · Person; `userPlus` People · New customer; `userCheck` People · Verified customer; `userMinus` People · Lost customer; `contact` People · Contact; `baby` People · Baby; `smile` People · Smile (satisfaction); `frown` People · Frown; `thumbsUp` People · Thumbs up; `messages` People · Messages; `target` Performance · Target; `trendUp` Performance · Rise; `trendDown` Performance · Fall; `bars` Performance · Column chart; `barsH` Performance · Bar chart; `line` Performance · Line chart; `pie` Performance · Pie chart; `gauge` Performance · Gauge; `activity` Performance · Activity; `award` Performance · Award; `trophy` Performance · Trophy; `medal` Performance · Medal; `flag` Performance · Flag (milestone); `rocket` Performance · Rocket (launch); `star` Performance · Star; `zapFast` Performance · Speedometer; `layers` Performance · Layers; `sigma` Performance · Sum; `clock` Time · Clock; `timer` Time · Timer; `hourglass` Time · Hourglass; `calendar` Time · Calendar; `calendarCheck` Time · Calendar check; `calendarDays` Time · Days; `history` Time · History; `truck` Operations · Truck (delivery); `box` Operations · Box (stock); `packageCheck` Operations · Package delivered; `boxes` Operations · Boxes; `warehouse` Operations · Warehouse; `factory` Operations · Factory; `wrench` Operations · Wrench (maintenance); `settings` Operations · Settings; `hardHat` Operations · Hard hat; `forklift` Operations · Forklift; `ship` Operations · Ship; `plane` Operations · Plane; `car` Operations · Car; `route` Operations · Route; `fuel` Operations · Fuel; `clipboard` Operations · Checklist; `check` Status · Check; `checkPlain` Status · Tick; `circleX` Status · Rejected; `alert` Status · Alert; `alertCircle` Status · Warning; `info` Status · Information; `shield` Status · Shield; `shieldCheck` Status · Security; `lock` Status · Lock; `bell` Status · Bell; `bug` Status · Bug; `eye` Status · Eye (views); `leaf` Energy and environment · Leaf; `sprout` Energy and environment · Sprout; `recycle` Energy and environment · Recycle; `bolt` Energy and environment · Bolt (energy); `battery` Energy and environment · Battery; `plug` Energy and environment · Plug; `sun` Energy and environment · Sun; `cloud` Energy and environment · Cloud; `cloudRain` Energy and environment · Rain; `wind` Energy and environment · Wind; `flame` Energy and environment · Flame; `drop` Energy and environment · Drop (water); `waves` Energy and environment · Waves; `thermometer` Energy and environment · Thermometer; `trees` Energy and environment · Trees; `globe` Energy and environment · Globe; `heart` Health and education · Heart; `heartPulse` Health and education · Heart pulse; `stethoscope` Health and education · Stethoscope; `pill` Health and education · Pill; `hospital` Health and education · Hospital; `graduation` Health and education · Graduation; `book` Health and education · Book; `school` Health and education · School; `dumbbell` Health and education · Dumbbell (sport); `utensils` Health and education · Utensils (meals); `coffee` Health and education · Coffee; `phone` Digital · Phone; `mail` Digital · Mail; `message` Digital · Message; `click` Digital · Click; `monitor` Digital · Monitor; `smartphone` Digital · Smartphone; `server` Digital · Server; `database` Digital · Database; `wifi` Digital · Wi-Fi; `download` Digital · Download; `upload` Digital · Upload; `share` Digital · Share; `search` Digital · Search; `link` Digital · Link; `fileText` Digital · Document; `home` Places · House; `building` Places · Building; `mapPin` Places · Location; `map` Places · Map; `hotel` Places · Hotel. Choose “All KPIs” or one measure in “Apply settings to” above, then its icon (134 Lucide icons, by theme).
- `kpiFormat.symbol` Or symbol / emoji (replaces the icon) / Ou symbole / emoji (remplace l'icône): text, default (empty)
- `kpiFormat.color` KPI color (empty = “Card” card) / Couleur du KPI (vide = carte « Carte »): color, default (empty); values: hex color
- `kpiFormat.units` Display units / Unités d'affichage: dropdown, default `fit`; values: `fit` Automatic (full value when it fits); `auto` Abbreviated (K, M, bn); `none` None; `k` Thousands; `m` Millions; `b` Billions. Automatic: the full value with the format of the measure when it fits in the card, otherwise abbreviated (1.5M).
- `kpiFormat.decimals` Decimals (-1 = automatic) / Décimales (-1 = automatique): number, default `-1`; values: -1 to 6
- `kpiFormat.prefix` Prefix / Préfixe: text, default (empty)
- `kpiFormat.suffix` Suffix / Suffixe: text, default (empty)
- `kpiFormat.lowerIsBetter` Lower is better / Plus bas = mieux: toggle, default `false`; values: true / false. A decrease is shown in the “good” color (costs, delays, incidents…).
- `kpiFormat.refLabel` Comparison label / Libellé de la comparaison: text, default (empty). Empty: “vs” + name of the comparison measure (or of the previous period).
- `kpiFormat.refLabel2` Comparison 2 label / Libellé de la comparaison 2: text, default (empty). Second comparison (“Comparison 2” field). Empty: “vs” + name of the measure.
- `kpiFormat.targetValue` Fixed target (0 = “Target” field) / Objectif fixe (0 = champ « Objectif »): number, default `0`. A target typed here for this KPI, without a measure. It replaces the “Target” field.
- `kpiFormat.targetField` “Target” field number (0 = same rank, -1 = none) / N° du champ « Objectif » (0 = même rang, -1 = aucun): number, default `0`; values: -1 to 30. By default the 1st target goes with the 1st value, the 2nd with the 2nd… Type 2 to use the 2nd measure of “Target” for this KPI.
- `kpiFormat.refField` “Comparison” field number (0 = same rank, -1 = none) / N° du champ « Comparaison » (0 = même rang, -1 = aucun): number, default `0`; values: -1 to 30
- `kpiFormat.link` Link (web address) / Lien (adresse web): text, default (empty). Adds a ↗ button to the card that opens this address (https:// or mailto: only; Power BI opens secure links only). Power BI asks for confirmation.
- `kpiFormat.backText` Back of the card text / Texte du dos de la carte: textarea, default (empty). Shown when the card flips (a definition, for instance). **bold**, line breaks and placeholders: {name}, {value}, {ref}, {delta}, {deltaPct}, {ref2}, {delta2}, {deltaPct2}, {target}, {progress}, {min}, {max}, {avg}, {first}, {last}, {period}.

### Back of the card: content per KPI / Dos de la carte : contenu par KPI (`backItems`, one entry per item with a selector)
- `backItems.text` Text (Per-KPI settings or “Back of the card” field) / Texte (Réglages par KPI ou champ « Dos de la carte »): toggle, default `true`; values: true / false
- `backItems.textAfter` Text after the figures / Texte après les chiffres: toggle, default `false`; values: true / false
- `backItems.ref` Comparison value / Valeur de comparaison: toggle, default `true`; values: true / false
- `backItems.delta` Change / Écart: toggle, default `true`; values: true / false
- `backItems.ref2` Comparison 2 and change / Comparaison 2 et écart: toggle, default `true`; values: true / false
- `backItems.target` Target / Objectif: toggle, default `true`; values: true / false
- `backItems.progress` Target achievement / Atteinte de l'objectif: toggle, default `true`; values: true / false
- `backItems.period` Period / Période: toggle, default `true`; values: true / false
- `backItems.last` Last period / Dernière période: toggle, default `true`; values: true / false
- `backItems.min` Minimum: toggle, default `true`; values: true / false
- `backItems.max` Maximum: toggle, default `true`; values: true / false
- `backItems.avg` Average / Moyenne: toggle, default `true`; values: true / false
- `backItems.tooltips` “Tooltips” fields / Champs « Infobulles »: toggle, default `true`; values: true / false
- `backItems.f1` Back figure 1 / Chiffre 1 du dos: toggle, default `true`; values: true / false
- `backItems.f2` Back figure 2 / Chiffre 2 du dos: toggle, default `true`; values: true / false
- `backItems.f3` Back figure 3 / Chiffre 3 du dos: toggle, default `true`; values: true / false
- `backItems.f4` Back figure 4 / Chiffre 4 du dos: toggle, default `true`; values: true / false
- `backItems.f5` Back figure 5 / Chiffre 5 du dos: toggle, default `true`; values: true / false
- `backItems.f6` Back figure 6 / Chiffre 6 du dos: toggle, default `true`; values: true / false
- `backItems.f7` Back figure 7 / Chiffre 7 du dos: toggle, default `true`; values: true / false
- `backItems.f8` Back figure 8 / Chiffre 8 du dos: toggle, default `true`; values: true / false

### Layout / Disposition (`layout`)
- `layout.arrange` Arrangement / Agencement: dropdown, default `auto`; values: `auto` Automatic grid; `row` One row; `column` One column; `grid` Grid (number of columns); `heroLeft` First one large, on the left ★; `heroTop` First one large, on top ★. Automatic: the number of columns that gives the best card proportions.
- `layout.columns` Number of columns / Nombre de colonnes: number, default `3`; values: 1 to 12. Visible when `layout.arrange` = `grid`
- `layout.heroSize` First KPI size (%) / Taille du premier KPI (%): number, default `45`; values: 20 to 80. Visible when `layout.arrange` = `heroLeft` or `heroTop`
- `layout.gap` Gap between cards / Espace entre les cartes: number, default `12`; values: 0 to 60
- `layout.overflow` When the cards do not fit / Quand les cartes ne tiennent pas: dropdown, default `fit`; values: `fit` Shrink them (never a scroll bar); `scroll` Keep the minimum sizes and scroll. Shrink: every card stays visible, the minimum sizes only choose the number of columns.
- `layout.minWidth` Minimum card width (px) / Largeur minimale d'une carte (px): number, default `150`; values: 60 to 800. Below this size, the cards wrap (and scroll if “Keep the minimum sizes” is chosen).
- `layout.minHeight` Minimum card height (px) / Hauteur minimale d'une carte (px): number, default `96`; values: 40 to 600
- `layout.lastRow` Incomplete last row / Dernière ligne incomplète: dropdown, default `left`; values: `left` Aligned left; `center` Centered; `stretch` Stretched
- `layout.order` KPI order / Ordre des KPI: dropdown, default `data`; values: `data` Field order; `valueDesc` Value, descending; `valueAsc` Value, ascending; `deltaDesc` Best change first; `nameAsc` Name A → Z
- `layout.hideBlank` Hide blank KPIs / Masquer les KPI vides: toggle, default `false`; values: true / false. A card whose value is blank is not drawn (for instance a region without sales).
- `layout.totalCard` “Total” card (with “One KPI per…”) / Carte « Total » (avec « Un KPI par… »): toggle, default `false`; values: true / false. Adds a card with the total over all categories, first.
- `layout.totalLabel` Total label / Libellé du total: text, default (empty). Visible when `layout.totalCard` = `true`

### Card / Carte (`card`)
- `card.shape` Shape / Forme: dropdown, default `rounded`; values: `rect` Rectangle; `rounded` Rounded corners (Frame › Rounded corners); `pill` Pill; `circle` Circle ★; `leaf` Leaf (two rounded corners) ★; `chamfer` Cut corners ★; `ticket` Ticket (notches) ★; `underline` Underlined (no fill); `none` None (text only)
- `card.fill` Fill (empty = automatic) / Fond (vide = automatique): color, default (empty); values: hex color. Automatic: the style background, slightly raised on dark backgrounds.
- `card.fillOpacity` Fill opacity (%) / Opacité du fond (%): number, default `100`; values: 0 to 100
- `card.tint` KPI color tint in the fill (%) / Teinte de la couleur du KPI dans le fond (%): number, default `0`; values: 0 to 40
- `card.border` Border / Bordure: toggle, default `true`; values: true / false
- `card.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `card.border` = `true`
- `card.borderWidth` Width / Épaisseur: number, default `1`; values: 0.5 to 6. Visible when `card.border` = `true`
- `card.shadow` Soft shadow / Ombre douce: toggle, default `false`; values: true / false
- `card.colorBy` KPI color / Couleur des KPI: dropdown, default `accent`; values: `accent` Style accent (same for all); `palette` One color per KPI (palette); `status` By status (good / bad). Used by the icon, the sparkline and the status bar.
- `card.statusBar` Accent bar (status) / Barre d'accent (état): dropdown, default `none`; values: `none` None; `left` Left; `top` Top; `right` Right; `bottom` Bottom. Colored by the status of the card (good, warning, bad), otherwise the KPI color.
- `card.statusWidth` Accent bar width / Épaisseur de la barre d'accent: number, default `4`; values: 1 to 16. Visible when `card.statusBar` = `left` or `top` or `right` or `bottom`
- `card.accentColor` Bar color (empty = status or KPI) / Couleur de la barre (vide = état ou KPI): color, default (empty); values: hex color. Visible when `card.statusBar` = `left` or `top` or `right` or `bottom`
- `card.layout` Content layout / Disposition du contenu: dropdown, default `stack`; values: `stack` Stacked (title, value, details); `center` Centered; `split` Value left, trend right
- `card.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right. Visible when `card.layout` = `stack` or `split`
- `card.vAlign` Vertical position / Position verticale: dropdown, default `top`; values: `top` Top; `middle` Middle; `bottom` Bottom
- `card.padding` Inner padding / Marge intérieure: number, default `14`; values: 0 to 48
- `card.hover` Hover effect / Effet au survol: dropdown, default `lift`; values: `none` None; `lift` Lift; `outline` Accent outline; `glow` Glow

### KPI titles / Titre des KPI (`kpiTitle`)
- `kpiTitle.show` Show / Afficher: toggle, default `true`; values: true / false
- `kpiTitle.fontSize` Size / Taille: number, default `12`; values: 7 to 32
- `kpiTitle.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `kpiTitle.bold` Bold / Gras: toggle, default `false`; values: true / false
- `kpiTitle.italic` Italic / Italique: toggle, default `false`; values: true / false
- `kpiTitle.caps` Small caps / Petites majuscules: toggle, default `false`; values: true / false
- `kpiTitle.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false. On a narrow card the title wraps (up to three lines) and gets slightly smaller before being cut.
- `kpiTitle.position` Position: dropdown, default `above`; values: `above` Above the value; `below` Below the value. Below the value: like the category label of the native card.

### Value / Valeur (`value`)
- `value.autoSize` Automatic size / Taille automatique: toggle, default `true`; values: true / false. The value fills the room left in the card, up to the maximum size.
- `value.fontSize` Size (maximum if automatic) / Taille (maximale si automatique): number, default `36`; values: 10 to 160
- `value.weight` Weight / Graisse: dropdown, default `600`; values: `400` Regular; `600` Semibold; `700` Bold
- `value.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `value.statusColor` Color by status (good / bad) / Couleur selon l'état (bon / mauvais): toggle, default `false`; values: true / false
- `value.aggregate` Displayed value (with a trend axis) / Valeur affichée (avec un axe de tendance): dropdown, default `total`; values: `total` Period total (computed by the measure); `last` Last period; `first` First period; `avg` Average of the periods; `max` Maximum; `min` Minimum. Total: the measure evaluated over the whole filter context (exact for ratios and averages).
- `value.countUp` Animated counter / Compteur animé: toggle, default `true`; values: true / false. The value counts up when data changes (respects Style › Animations).
- `value.blank` Text when blank / Texte si vide: text, default (empty)

### Reference labels / Libellés de référence (`refLabels`)
- `refLabels.show` Show / Afficher: toggle, default `true`; values: true / false. Shown when measures are placed in “Reference labels” (label = measure name, value with its format; “Details” under it).
- `refLabels.pairing` KPIs concerned / KPI concernés: dropdown, default `all`; values: `all` Every label on each KPI; `rank` By rank (1st label with the 1st KPI…)
- `refLabels.max` Maximum per card / Nombre maximal par carte: number, default `3`; values: 1 to 8
- `refLabels.position` Position: dropdown, default `below`; values: `below` Below the value; `bottom` Bottom of the card
- `refLabels.arrange` Arrangement / Agencement: dropdown, default `row`; values: `row` Side by side; `column` Stacked
- `refLabels.divider` Divider / Séparateur: toggle, default `true`; values: true / false
- `refLabels.background` Background / Arrière-plan: toggle, default `false`; values: true / false
- `refLabels.bgColor` Background color (empty = KPI tint) / Couleur de l'arrière-plan (vide = teinte du KPI): color, default (empty); values: hex color. Visible when `refLabels.background` = `true`
- `refLabels.titleSize` Label size / Taille du libellé: number, default `10`; values: 7 to 24
- `refLabels.titleColor` Label color (empty = secondary text) / Couleur du libellé (vide = texte secondaire): color, default (empty); values: hex color
- `refLabels.valueSize` Value size / Taille de la valeur: number, default `13`; values: 7 to 32
- `refLabels.valueColor` Value color (empty = text) / Couleur de la valeur (vide = texte): color, default (empty); values: hex color
- `refLabels.detailSize` Details size / Taille des détails: number, default `10`; values: 7 to 24

### Icon / Icône (`icon`)
- `icon.show` Show / Afficher: toggle, default `true`; values: true / false. The icon of each KPI is chosen in Per-KPI settings › Icon, or by a text measure in the “Icon” field.
- `icon.position` Position: dropdown, default `topRight`; values: `topRight` Top right; `topLeft` Before the title; `left` Left of the value; `above` Above (centered); `background` Watermark
- `icon.style` Icon background / Fond de l'icône: dropdown, default `circle`; values: `plain` None; `circle` Round badge; `square` Square badge; `ring` Ring; `solid` Solid badge
- `icon.size` Size / Taille: number, default `30`; values: 12 to 96
- `icon.color` Color (empty = KPI color) / Couleur (vide = couleur du KPI): color, default (empty); values: hex color

### Comparison / Comparaison (`comparison`)
- `comparison.show` Show / Afficher: toggle, default `true`; values: true / false
- `comparison.source` Compare with / Comparer à: dropdown, default `auto`; values: `auto` Automatic; `reference` “Comparison” field; `previous` Previous period (trend axis); `first` First period (trend axis). Automatic: the “Comparison” field if present, otherwise the previous period of the trend axis.
- `comparison.mode` Display / Afficher: dropdown, default `pct`; values: `pct` Change in %; `abs` Change in value; `both` Change in value and %; `ref` Comparison value
- `comparison.arrow` Arrow / Flèche: dropdown, default `triangle`; values: `triangle` ▲ ▼; `arrow` ↑ ↓; `chevron` ⌃ ⌄; `none` None
- `comparison.badge` As a badge / En pastille: toggle, default `true`; values: true / false
- `comparison.showLabel` Label (“vs …”) / Libellé (« vs … »): toggle, default `true`; values: true / false
- `comparison.fontSize` Size / Taille: number, default `12`; values: 7 to 30
- `comparison.neutral` Neutral zone (± %) / Zone neutre (± %): number, default `0`; values: 0 to 50. A change smaller than this percentage is shown in the neutral color.
- `comparison.show2` Comparison 2 (“Comparison 2” field) / Comparaison 2 (champ « Comparaison 2 »): toggle, default `true`; values: true / false. A second change under the first one, for instance vs budget and vs last year.
- `comparison.statusFrom` Card status (good, warning, bad) / État de la carte (bon, alerte, mauvais): dropdown, default `auto`; values: `auto` Automatic (comparison, otherwise target); `compare` Comparison; `compare2` Comparison 2; `target` Target (thresholds); `both` Target and comparison (green, amber, red) ★. Colors the status bar, the value and the cards “by status”. Target and comparison: good when the target is reached, warning when only the comparison is favorable, bad otherwise.
- `comparison.warnFrom` Warning from (% of target) / Alerte à partir de (% de l'objectif): number, default `90`; values: 0 to 100. Visible when `comparison.statusFrom` = `target`. With “Target”: good from 100 %, warning from this percentage, bad below. 0 = no warning level.
- `comparison.goodColor` “Good” color / Couleur « bon »: color, default `#2E7D4F`; values: hex color
- `comparison.warnColor` “Warning” color / Couleur « alerte »: color, default `#C77C02`; values: hex color. Visible when `comparison.statusFrom` = `target` or `both`
- `comparison.badColor` “Bad” color / Couleur « mauvais »: color, default `#C0392B`; values: hex color
- `comparison.neutralColor` Neutral color (empty = secondary text) / Couleur neutre (vide = texte secondaire): color, default (empty); values: hex color

### Target / Objectif (`target`)
- `target.show` Show / Afficher: toggle, default `true`; values: true / false. Drawn when a field is placed in “Target”.
- `target.style` Shape / Forme: dropdown, default `bar`; values: `bar` Progress bar; `ring` Ring ★; `bullet` Bullet (bar and marker) ★; `text` Text only
- `target.thickness` Thickness / Épaisseur: number, default `6`; values: 2 to 24
- `target.showPct` Percentage reached / Pourcentage atteint: toggle, default `true`; values: true / false
- `target.label` Label / Libellé: text, default (empty)
- `target.distance` Distance to target / Distance à l'objectif: dropdown, default `none`; values: `none` Hidden; `pct` In %; `abs` As a value; `both` Value and %. Like the native KPI: “▲ +5.2% vs Target”, colored good / bad (“Lower is better” respected).
- `target.color` Color (empty = KPI color, “good” when reached) / Couleur (vide = couleur du KPI, « bon » si atteint): color, default (empty); values: hex color
- `target.trackColor` Track color (empty = grid) / Couleur du rail (vide = grille): color, default (empty); values: hex color

### Sparkline / Courbe de tendance (`sparkline`)
- `sparkline.show` Show / Afficher: toggle, default `true`; values: true / false. Drawn when a field is placed in “Trend axis”.
- `sparkline.dateFormat` Period format (empty = automatic) / Format des périodes (vide = automatique): text, default (empty). Dates of the trend axis in the comparison label, the back and the tooltips. Automatic: month and year for monthly dates (Dec 2025), the year for yearly dates. Examples: mmm yy, dd/mm/yyyy.
- `sparkline.type` Type: dropdown, default `area`; values: `line` Line; `area` Area; `smooth` Smooth area; `columns` Columns ★; `step` Step ★
- `sparkline.position` Position: dropdown, default `bottom`; values: `bottom` Bottom of the card; `background` Card background; `right` Right
- `sparkline.height` Height (% of the card) / Hauteur (% de la carte): number, default `32`; values: 10 to 70
- `sparkline.color` Color (empty = KPI color) / Couleur (vide = couleur du KPI): color, default (empty); values: hex color
- `sparkline.width` Line width / Épaisseur du trait: number, default `1.5`; values: 0.5 to 5
- `sparkline.opacity` Area opacity (%) / Opacité de l'aire (%): number, default `22`; values: 0 to 100
- `sparkline.lastDot` Dot on the last value / Point sur la dernière valeur: toggle, default `true`; values: true / false
- `sparkline.minMax` Minimum and maximum markers / Repères minimum et maximum: toggle, default `false`; values: true / false
- `sparkline.refLine` Target line / Ligne de l'objectif: toggle, default `false`; values: true / false. Horizontal line at the target value (per period: target ÷ number of periods when “Displayed value” is the total).
- `sparkline.zero` Start at zero / Partir de zéro: toggle, default `false`; values: true / false
- `sparkline.showDate` Date of the last period / Date de la dernière période: toggle, default `false`; values: true / false. Writes the last period of the trend axis under the value (like the “Date” option of the native KPI).

### Flip / Retournement (`flip`)
- `flip.trigger` Flip the card / Retourner la carte: dropdown, default `click`; values: `none` Never; `hover` On hover; `click` On click; `icon` On click on the ↻ icon. The back shows the information text (Per-KPI settings or “Back of the card” field) and key figures (card “Back of the card: content per KPI”). Keyboard: Enter.
- `flip.animation` Animation: dropdown, default `flipX`; values: `flipX` Horizontal flip; `flipY` Vertical flip; `fade` Fade; `slide` Sliding panel ★; `door` Door (swing) ★; `curtain` Curtain ★; `zoom` Zoom ★; `cube` Cube ★. Visible when `flip.trigger` = `hover` or `click` or `icon`
- `flip.direction` Direction / Sens: dropdown, default `left`; values: `left` To the left; `right` To the right; `up` Upwards; `down` Downwards. Visible when `flip.trigger` = `hover` or `click` or `icon`
- `flip.duration` Duration (ms) / Durée (ms): number, default `600`; values: 100 to 3000. Visible when `flip.trigger` = `hover` or `click` or `icon`
- `flip.easing` Motion / Mouvement: dropdown, default `smooth`; values: `smooth` Smooth; `easeInOut` Ease in and out; `linear` Linear; `bounce` Bounce ★. Visible when `flip.trigger` = `hover` or `click` or `icon`
- `flip.autoBack` Flip back after (s, 0 = never) / Revenir seule après (s, 0 = jamais): number, default `0`; values: 0 to 120. Visible when `flip.trigger` = `click` or `icon`
- `flip.single` One flipped card at a time / Une seule carte retournée à la fois: toggle, default `true`; values: true / false. Visible when `flip.trigger` = `click` or `icon`
- `flip.hint` ↻ indicator on the cards / Indicateur ↻ sur les cartes: toggle, default `true`; values: true / false. Visible when `flip.trigger` = `hover` or `click` or `icon`
- `flip.preview` Show the back (preview in edit mode) / Montrer le dos (aperçu en mode édition): toggle, default `false`; values: true / false. Visible when `flip.trigger` = `hover` or `click` or `icon`. Shows every back while you format them. Ignored in reading view.

### Back of the card / Dos de la carte (`back`)
- `back.content` Content / Contenu: dropdown, default `both`; values: `both` Text and key figures; `text` Text only (figures if no text); `figures` Key figures only
- `back.figures` Key figures / Chiffres clés: dropdown, default `all`; values: `all` All available; `compare` Comparison and target; `trend` Trend (min, max, average). Visible when `back.content` = `both` or `figures`
- `back.figLayout` Figures layout / Disposition des chiffres: dropdown, default `auto`; values: `auto` Automatic (two columns, stacked when the card is narrow); `columns` Label left, value right; `stacked` Value under the label. Visible when `back.content` = `both` or `figures`
- `back.fit` Shrink the text to fit / Réduire le texte pour tout afficher: toggle, default `true`; values: true / false. The text gets smaller (down to 75 %) before the back scrolls.
- `back.showTitle` Repeat the title / Rappeler le titre: toggle, default `true`; values: true / false
- `back.fontSize` Text size / Taille du texte: number, default `12`; values: 7 to 32
- `back.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center
- `back.fill` Fill (empty = KPI tint) / Fond (vide = teinte du KPI): color, default (empty); values: hex color
- `back.solid` Solid KPI color fill / Fond plein à la couleur du KPI: toggle, default `false`; values: true / false. Text in white or black for contrast.
- `back.textColor` Text color (empty = automatic) / Couleur du texte (vide = automatique): color, default (empty); values: hex color

### Interactions (`interaction`)
- `interaction.select` Click = filter the report (with “One KPI per…”) / Clic = filtrer le rapport (avec « Un KPI par… »): toggle, default `true`; values: true / false. With “Flip on click”, use Ctrl + click to select.
- `interaction.dim` Opacity of unselected cards (%) / Opacité des cartes non sélectionnées (%): number, default `35`; values: 5 to 90

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips). Not on a card that flips on hover (the back gives the details).
- `tooltip.periodTip` Tooltip per period on the sparkline / Infobulle par période sur la courbe: toggle, default `true`; values: true / false. Visible when `tooltip.show` = `true`

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Sankey Plume

- Sankey diagram: flows from a source to a destination over several levels, or customers changing segment from one year to the next.
- Slug `alluvial-shift` · version 1.4.0.0 · GUID (`visualType`) `plumeAlluvialShift7C4F119D60FF4086BE549F8CECDC03B9` · page https://plumevisuals.com/en/visuals/alluvial-shift

### What the visual does

Sankey Plume (identifier `alluvial-shift`, formerly Plume Sankey) is a Power BI custom visual (version 1.4.0.0, installed from its `.pbiviz` file; AppSource submission in progress) that draws **Sankey and alluvial charts**: amounts moving from one place to another, drawn as ribbons between columns of nodes. It has three modes, chosen by the fields:

**New in version 1.4.0.0 (30/10/2026):** Format pane reorganized (category labels in **Category labels**, `labels.*` → `categoryLabels.*`); free parity with Microsoft's Sankey: bold / italic and two-line category labels, show all labels, bold / italic flow labels, flow outline color and width.

- **Source → Destination** (`source` + `destination` roles): one flow per data row, like the Microsoft "Sankey Chart" visual. A name found in both fields is a single node, so flows chain over several levels (up to 30; beyond, a warning icon). Flows going back to an earlier column (cycles, a node to itself) are drawn as **loops under the chart**, or hidden. `layout.structure` = `twoColumns` puts every source on the left and every destination on the right instead (same name = same color on both sides).
- **Stages mode**: several fields in Categories, one column each (e.g. Acquisition channel → Region → Segment, or Segment 2024 → Segment 2025), up to 8 columns.
- **Over-time mode**: one field in Categories (the state) + Period + Individual. The visual follows each individual from one period to the next (at most 24 columns, the most recent periods), with hatched **"New"** and **"Lost"** nodes (French « Nouveaux », « Perdus ») for individuals who appear or disappear.

A category keeps the same place and color in every column. Node order: automatic (largest on top; in Source → Destination, fewer crossings with the barycenter method), by size, alphabetical, data order ("Sort by column") or **custom** (a list "Gold; Silver; Bronze", or drag a node up or down in edit mode: the order is saved in the report). Flow labels show a value, the conversion rate (% of the origin node) or a % of total. Flows can be colored by origin, destination, a neutral gray or **a measure** (Flow color field). Hovering a category or a flow traces the matching paths across every column.

**New in 1.3.0.0 (19/10/2026):** **threads ★** (`flows.render` = `threads`): with whole numbers, each unit is drawn as one thin line (a flow of 64 = 64 lines), up to 3,000 lines; **highlighted flows ★** (`flows.focusLinks`): name flows "origin > destination" or a journey "A > B > C"; **one color per highlighted name** (`flows.focusColors`); adjustable **opacity of dimmed flows** (`flows.dimOpacity`).

### 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 (`style.customColors` and the colors under it) are **free**; every other `style.preset`, the other gradient palettes (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium**. See "Styles and theme JSON" below.
- Free in Sankey Plume: the three modes, cycles as loops, two columns, every node order including custom order and dragging, flow labels, flow color by a measure, opacity (`flows.opacity`) and dimmed-flow opacity (`flows.dimOpacity`), highlight colors (`flows.focusColors`), Tooltips field, cross-highlighting, path tracing, New / Lost nodes.
- Premium features of Sankey Plume:
  - `layout.orientation` = `vertical` ("Vertical (top to bottom) ★");
  - `flows.render` = `threads` ("Threads: one line per unit ★");
  - `flows.focus` ("Highlight the category ★"): only the flows going through the named categories (separated by ;) keep their color, from the first column to the last (exact paths in stages and over-time modes; everything upstream and downstream in Source → Destination);
  - `flows.focusLinks` ("Highlight flows ★"): only the named flows keep their color, e.g. `Silver > Gold; Bronze > Silver` (also `→` or `->`, case ignored); a chain `Bronze > Silver > Gold` keeps the individuals who followed that exact journey (stages and over-time modes); in Source → Destination, the named links only;
  - `migration.retention` ("Retention rate between columns ★"), with `migration.retentionKind` = `same` (same category in the next column) or `present` (still present in the next column); it writes "78% retained" / "78% still present" between columns;
  - `flows.changesOnly` ("Emphasize category changes ★"): flows that stay in the same category are dimmed;
  - `flows.colorBy` = `gradient` ("Gradient origin → destination ★").
- Without a valid key, a premium feature in use shows, in edit mode, a "Premium preview" note in the footer; in reading view (published report), **"Plume Visuals · Premium preview"** (French « Plume Visuals · Aperçu premium ») is repeated lightly across the whole visual, without catching the mouse or the keyboard. It disappears once a key is pasted in **Format › Plume Studio License › License key** (`license.key`; French « Licence Plume Studio › Clé de licence »), 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 `alluvial-shift` 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". `license.showOwner` displays "Licensed to <holder>".
- Licenses last one year (one-time payment, no automatic renewal, key accepted for 30 more days, reminders 30 and 7 days before the end). Prices: 39 € personal, 99 € SME, 299 € enterprise per year, or the catalog pack (199 € / 399 € / 1,199 € per year; tiers by number of users, designers and viewers included: personal 1–10, SME 11–200, enterprise more than 200).

### Expected data shape

**Source → Destination: one row per flow.**

| Source (`source`) | Destination (`destination`) | Value (`value`) |
|---|---|---|
| Home | Catalog | 500 |
| Catalog | Cart | 400 |
| Cart | Catalog | 100 |

**Over time: one row per combination** of Period × Categories × Individual, with the Value measure for that row.

| Categories (`stages`) | Period (`period`) | Individual (`entity`) | Value (`value`) |
|---|---|---|---|
| Silver | 2024 | C0042 | 1 |
| Gold | 2025 | C0042 | 1 |
| Bronze | 2024 | C0107 | 1 |

- **Source** and **Destination** (`source`, `destination`, grouping, one column each). Both are needed for this mode; the other category fields are then ignored. An empty value becomes a "(Blank)" node. The value of a node is the larger of its incoming and outgoing totals.
- **Categories (one column per field)** (`stages`, « Catégories (une colonne par champ) », grouping, 1 to 8 columns). With a Period, only the first field is used (a hint says so).
- **Period (migrations over time)** (`period`, « Période (migrations dans le temps) », grouping, one column, optional). Dates and numbers are sorted; text periods keep the model order ("Sort by column"). Only the 24 most recent periods are drawn.
- **Individual (customer, product…)** (`entity`, « Individu (client, produit…) », grouping, one column). Required for flows in over-time mode: without it, only the columns are drawn and a hint asks for it. An individual in two categories of the same period counts in the larger one, with its total value.
- **Value or weight (optional)** (`value`, « Valeur ou poids (facultatif) », one measure). Without it, one individual or one row counts as 1; in stages mode and Source → Destination without Value, each combination counts as 1 (a hint suggests adding a measure). A value that changes between periods gives a flow with a different thickness at origin and destination. Negative rows are left out with the warning "Negative values ignored". Threads need whole values.
- **Flow color (measure)** (`linkColor`, « Couleur des flux (mesure) », one measure): with `flows.colorBy` = `measure`, each flow takes a color from the style's gradient palette (weighted average over the rows of the flow), with a small min → max legend.
- **Tooltips** (`tooltips`, up to 5 measures): added to the flow tooltip (sum of the rows of the flow).
- **Dynamic format** (`format`, « Format dynamique », several measures): see below; never drawn.
- Volume: 30,000 rows per data window, more fetched up to 100,000. At most 5,000 individual IDs are sent per selected flow or node.

### DAX recipes

```dax
// Value
Customer count = DISTINCTCOUNT ( Customers[Customer] )
Customer revenue = SUM ( Customers[Revenue] )
Visit count = SUM ( Journey[Visits] )

// Text period sorted correctly: build a number and use it in "Sort by column", or use a date
Quarter key = YEAR ( Customers[Date] ) * 10 + QUARTER ( Customers[Date] )
```

A missing row for an individual in a period is what makes it "Lost" (next column) or "New" (previous column). A customer who comes back after a gap counts as lost, then new.

### Interactions with the report

- Hover a category or a flow: with `interaction.trace` on (default), the share of every flow that goes through the hovered item is drawn on top, across all columns (Source → Destination: everything upstream and downstream); the rest is dimmed (`interaction.dim`).
- Click a category: cross-filter on that category in its column (Source → Destination: its flows). Click a flow: stages mode, the pair of categories; over-time mode, **the individuals of the flow** (a selection on the Individual column); Source → Destination, the source, destination pair. Ctrl, Cmd or Shift + click adds to the selection. Context menu everywhere (nodes, flows, loops, labels, headers, empty area).
- **Cross-highlighting** from other visuals (`supportsHighlight`): when Value holds a measure, the highlighted part of each flow and node is drawn darker; Power BI's "Edit interactions" can switch back to filtering.
- In edit mode, with `interaction.drag` on (default), drag a node up or down: `nodes.order` becomes `custom` and `nodes.customOrder` is filled in (saved with the report).
- Tooltips: node (column, category, value, share of the column, individuals, retained, came from other categories, new, stay, move, lost afterwards, incoming and outgoing in Source → Destination); flow (from, to, value at origin and destination, share of the origin category, share of total, cycle, flow color measure, tooltip measures). Report-page tooltips are supported.
- Keyboard: Tab to reach the chart, arrows between categories and flows, Enter to select, Esc to clear. High contrast (host colors, flows as outlines, entries, exits and loops dashed; threads are drawn as outlined ribbons), reduced motion, ARIA labels. Left-to-right (top-to-bottom in vertical) reveal when data changes.

### Dynamic formats

- **fx button** (Power BI conditional formatting) on every color and text of the Format pane: Field value, Rules, Gradient. Sankey Plume uses a categorical projection, so fx is offered (unlike Table Plume, Matrix Plume and KPI Plume).
- **"Dynamic format" well** (`format` role, French « Format dynamique »): drop measures and rename each one, for this visual, `card.setting` (case, accents and separator ignored). It drives **any** setting: sizes, toggles, lists, fonts, colors, texts. It wins over the fixed setting, the style and an fx rule. Driving a ★ setting by DAX still shows the watermark without a key.
- For a global setting, the visual keeps the total if Power BI provides it, otherwise the common value of all rows, otherwise the first one: wrap the measure in `CALCULATE ( …, ALLSELECTED () )`.

```dax
// renamed title.subtitle
Customers subtitle = "Active customers in 2025: " & FORMAT ( CALCULATE ( [Customer count], Customers[Year] = 2025, ALLSELECTED () ), "#,0" )
// renamed flows.colorBy (values: source, target, gradient, measure, neutral)
Flow coloring = SELECTEDVALUE ( Settings[Flow color], "source" )
// renamed flows.focusLinks
Upgrades = "Silver > Gold; Bronze > Silver"
```

### Format pane: option IDs

- Each option has an ID `card.option` (for example `flows.colorBy`): the card is the capabilities.json object name, the option the property name.
- Card order: `license` (always first), `style` (shared Style card), `dataColors` (`mode` = `auto` | `single`, `single`, then one `fill` per category, stored on the category), `layout`, `nodes`, `flows`, `linkLabels`, `migration`, `categoryLabels`, `headers`, `interaction`, then `title`, `source`, `container`, `texts`. Format pane in version 1.4.0.0 (30/10/2026), top to bottom: `license`, `style`, `layout`, `dataColors`, `nodes`, `flows`, `migration`, `categoryLabels`, `linkLabels`, `headers`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- `layout`: `orientation` (`horizontal` | `vertical` ★), `structure` (`chain` | `twoColumns`, Source → Destination only), `align` (`justify` = final destinations in the last column | `left` = as early as possible; visible with `chain`), `cycles` (`loop` | `hide`; visible with `chain`).
- `nodes`: `width` (3–40, 12), `padding` (0–40, 10), `order` (`auto` | `size` | `alpha` | `data` | `custom`), `customOrder` (text, visible with `custom`), `maxCategories` (2–40, 12; the rest in "Others").
- `flows`: `colorBy` (`source` | `target` | `gradient` ★ | `measure` | `neutral`), `opacity` (5–100, 45), `render` (`ribbons` | `threads` ★), `threadWidth` (0–4 px, 0 = auto; visible with `threads`), `curvature` (0–100, 50), `changesOnly` ★, `focus` ★ (text), `focusLinks` ★ (text), `focusColors` (`flow` | `distinct`), `dimOpacity` (5–100, 45: % of `opacity` for dimmed flows), `minShare` (0–20 % of total).
- `linkLabels`: `show` (off), `content` (`value` | `pctSource` | `pctTotal` | `valuePct`), `fontSize` (6–20, 9), `color`, `minThickness` (0–40 px, 0 = auto).
- `migration`: `showMissing` (on), `newLabel`, `lostLabel` (over-time mode only), `retention` ★, `retentionKind` (`same` | `present`). The card is hidden for a Source → Destination chain.
- `categoryLabels`: `show`, `content` (`name` | `nameValue` | `namePct` | `all`), `pctOf` (`column` | `first`), `fontSize` (6–24, 10), `color`, `halo`, `units` (`auto` | `none` | `k` | `m` | `b`), `decimals` (−1–6), `prefix`, `suffix`.
- `headers`: `show`, `names` (separated by ;), `fontSize`, `color`, `showTotal`.
- `interaction`: `hover`, `dim` (5–80, 25), `trace`, `drag`.
- Threads are used only when every visible flow value is a whole number and the total is at most 3,000 lines; otherwise solid ribbons are drawn with the warning "Threads unavailable".
- Labels follow the language of Power BI Desktop; `texts.language` forces French or English inside the visual.

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. Booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes, colors in `solid.color`. `displayName` on a projection is "Rename for this visual".

```json
{
  "visualType": "plumeAlluvialShift7C4F119D60FF4086BE549F8CECDC03B9",
  "query": {
    "queryState": {
      "stages": { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Customers" } }, "Property": "Segment" } }, "queryRef": "Customers.Segment", "nativeQueryRef": "Segment" } ] },
      "period": { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Customers" } }, "Property": "Year" } }, "queryRef": "Customers.Year", "nativeQueryRef": "Year" } ] },
      "entity": { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Customers" } }, "Property": "Customer" } }, "queryRef": "Customers.Customer", "nativeQueryRef": "Customer" } ] },
      "value":  { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Customers" } }, "Property": "Customer count" } }, "queryRef": "Customers.Customer count", "nativeQueryRef": "Customer count" } ] }
    }
  },
  "objects": {
    "flows":     [ { "properties": { "render": { "expr": { "Literal": { "Value": "'threads'" } } },
                                      "focusLinks": { "expr": { "Literal": { "Value": "'Silver > Gold; Bronze > Silver'" } } },
                                      "focusColors": { "expr": { "Literal": { "Value": "'distinct'" } } },
                                      "dimOpacity": { "expr": { "Literal": { "Value": "60D" } } } } } ],
    "migration": [ { "properties": { "retention": { "expr": { "Literal": { "Value": "true" } } } } } ],
    "labels":    [ { "properties": { "content": { "expr": { "Literal": { "Value": "'namePct'" } } } } } ],
    "headers":   [ { "properties": { "showTotal": { "expr": { "Literal": { "Value": "true" } } } } } ],
    "license":   [ { "properties": { "key": { "expr": { "Literal": { "Value": "'PLUM1.…'" } } } } } ]
  }
}
```

For Source → Destination, use the `source` and `destination` roles instead of `stages`, `period` and `entity`. The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from the `.pbiviz` file).

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`. Own adjustments in Sankey Plume: Minimal (thin nodes, lighter flows), Unknown Pleasures (neutral flows), Neon and Graphite (stronger flows), Newspaper (softer curves).
- `style.themeJson` (Format › Style › Theme JSON ★) takes a JSON theme as plain text. Format v2: an object with an optional `extends` (a style ID above) and optional groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`; the v1 flat format (`style`, `palette`, `accent`, `background`…) is still read. Every field is optional. Colors are `#RRGGBB` (`#RGB` and `#RRGGBBAA` accepted, opacity ignored). Unknown fields and values outside the allowed lists are ignored, out-of-range numbers are clamped. Invalid JSON shows "Invalid theme JSON: ignored" in edit mode and the visual keeps its look.
- Full field list with allowed values, examples and troubleshooting: tutorial https://plumevisuals.com/ai/tutorials/en/themes-json.md (French: https://plumevisuals.com/ai/tutorials/fr/themes-json.md). The same JSON can be pasted in every Plume visual of a page.
- Priority (the last one wins): visual defaults → `style.preset` → `style.themeJson` → `style.palette` (if not "Style or theme palette") → `style.followTheme` → custom colors → options set by hand in the other cards → DAX formats (fx button, "Dynamic format" field) → Windows high contrast.

### Common pitfalls

- Columns but no flows: Period without Individual. Add the individual column.
- Landing page with a Source field: Destination is missing (or the other way around).
- Periods out of order: a text period; set "Sort by column" or use a number or a date.
- Only one category field used: with a Period, only the first Categories field counts.
- Every flow has thickness 1: no Value (each row or combination counts as 1).
- A loop under the chart: a cycle; `layout.cycles` = `hide` to leave it out, or `layout.structure` = `twoColumns`.
- "More than 30 levels" warning: very long Source → Destination chains; filter or use two columns.
- "Threads unavailable" warning: threads with decimal values or more than 3,000 lines; use a count measure or filter.
- A name in `flows.focusLinks` stays gray: misspelled category or reversed direction ("origin > destination").
- Too many categories: `nodes.maxCategories` (default 12) groups the rest in "Others"; `flows.minShare` hides thin flows.
- "Negative values ignored" warning: credit notes or returns in Value; only positive amounts are drawn.
- Pale flows with a darker part: cross-highlighting from another visual.
- Watermark visible: vertical orientation, threads, `flows.focus`, `flows.focusLinks`, `migration.retention`, `flows.changesOnly`, `flows.colorBy` = `gradient`, a ★ style or palette, 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)

Nodes dragged freely anywhere (only up or down within their column), a logarithmic scale, a minimum node height, forcing every label to show, images in nodes, source or destination label roles, more than 8 stage columns, 24 periods or 30 levels, several state fields in over-time mode, a hierarchy drill-down, per-flow colors set by hand (use a highlight or the Flow color measure), animation playback over periods, exporting the list of individuals of a flow or an image of the chart, threads for decimal values.

## Sankey Plume: data fields

- `stages` Categories (one column per field) / Catégories (une colonne par champ) (column, 8 max): 
- `period` Period (migrations over time) / Période (migrations dans le temps) (column, 1 max): 
- `entity` Individual (customer, product…) / Individu (client, produit…) (column, 1 max): 
- `source` Source (column, 1 max): With Destination: one flow per row, from Source to Destination (classic Sankey).
- `destination` Destination (column, 1 max): With Source: one flow per row, from Source to Destination (classic Sankey).
- `value` Value or weight (optional) / Valeur ou poids (facultatif) (measure, 1 max): 
- `linkColor` Flow color (measure) / Couleur des flux (mesure) (measure, 1 max): Measure that colors each flow on the gradient palette (Format › Flows › Flow color).
- `tooltips` Tooltips / Infobulles (measure, 5 max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Sankey Plume: Format pane options (132)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Layout / Disposition (`layout`)
- `layout.orientation` Orientation: dropdown, default `horizontal`; values: `horizontal` Horizontal (left to right); `vertical` Vertical (top to bottom) ★. Vertical: columns become rows, handy for long category names and tall report pages.
- `layout.structure` Source → Destination: dropdown, default `chain`; values: `chain` Chain (one node per name, several levels); `twoColumns` Two columns (origin → destination). Chain: a name found in both Source and Destination is a single node, so flows go on over several levels. Two columns: every source on the left, every destination on the right.
- `layout.align` Node placement / Place des nœuds: dropdown, default `justify`; values: `justify` Final destinations in the last column; `left` As early as possible (left). Visible when `layout.structure` = `chain`
- `layout.cycles` Flows going backward (cycles) / Flux qui reviennent en arrière (cycles): dropdown, default `loop`; values: `loop` Loops under the chart; `hide` Hide. Visible when `layout.structure` = `chain`

### Data colors / Couleurs des données (`dataColors`, one entry per item with a selector)
- `dataColors.mode` Coloring / Coloration: dropdown, default `auto`; values: `auto` Palette (one color per category); `single` Single color
- `dataColors.single` Color / Couleur: color, default (empty); values: hex color
- `dataColors.fill` Color / Couleur: color, default (empty); values: hex color

### Categories (nodes) / Catégories (nœuds) (`nodes`)
- `nodes.width` Node width / Largeur des nœuds: number, default `12`; values: 3 to 40
- `nodes.padding` Space between nodes / Espace entre les nœuds: number, default `10`; values: 0 to 40
- `nodes.order` Category order / Ordre des catégories: dropdown, default `auto`; values: `auto` Automatic (largest on top, fewer crossings); `size` Largest on top; `alpha` Alphabetical; `data` Data order (Sort by column); `custom` Custom (list or drag the nodes). The same order is kept in every column, so a category never jumps from one place to another. Custom: type the list below, or drag a node up or down in edit mode.
- `nodes.customOrder` Custom order (separated by ;) / Ordre personnalisé (séparé par ;): text, default (empty). Visible when `nodes.order` = `custom`. Categories in this order, the others after them (largest first). Filled in automatically when you drag a node.
- `nodes.maxCategories` Categories shown at most (the rest in « Others ») / Catégories affichées au plus (le reste dans « Autres »): number, default `12`; values: 2 to 40
- `nodes.minHeight` Minimum node height (px, 0 = none) / Hauteur minimale des nœuds (px, 0 = aucune): number, default `0`; values: 0 to 40. Small categories stay visible and clickable, like « Min optimal height » of the Microsoft Sankey. Their flows keep their true thickness.

### Flows / Flux (`flows`)
- `flows.colorBy` Flow color / Couleur des flux: dropdown, default `source`; values: `source` Origin category; `target` Destination category; `gradient` Gradient origin → destination ★; `measure` By the « Flow color » field; `neutral` Neutral (gray). By the Flow color field: drop a measure (margin rate, satisfaction…) in « Flow color »; flows follow the gradient palette of the style.
- `flows.opacity` Opacity (%) / Opacité (%): number, default `45`; values: 5 to 100
- `flows.render` Flow drawing / Dessin des flux: dropdown, default `ribbons`; values: `ribbons` Solid ribbons; `threads` Threads: one line per unit ★. Threads: with whole numbers (seats, students, customers…), each unit is drawn as a thin line (64 → 64 lines). With decimals or more than 3,000 lines, solid ribbons are kept.
- `flows.threadWidth` Thread width (px, 0 = auto) / Épaisseur des fils (px, 0 = auto): number, default `0`; values: 0 to 4. Visible when `flows.render` = `threads`
- `flows.curvature` Curvature (%) / Courbure (%): number, default `50`; values: 0 to 100
- `flows.changesOnly` Emphasize category changes ★ / Faire ressortir les changements de catégorie ★ ★: toggle, default `false`; values: true / false. Flows that stay in the same category are dimmed: only migrations stand out.
- `flows.focus` Highlight the category ★ / Mettre en avant la catégorie ★ ★: text, default (empty). Only the flows going through this category keep their color, from the first column to the last (separate several names with ;). Stays on the page, in PDF exports too.
- `flows.focusLinks` Highlight flows ★ / Mettre en avant des flux ★ ★: text, default (empty). Name a flow as « origin > destination » (several separated by ;). A chain « A > B > C » follows one exact journey. The other flows step back.
- `flows.focusColors` Highlight color / Couleur des mises en avant: dropdown, default `flow`; values: `flow` Flow color; `distinct` One color per highlighted name
- `flows.dimOpacity` Dimmed flows: opacity (% of opacity) / Flux en retrait : opacité (% de l'opacité): number, default `45`; values: 5 to 100. Flows set back by a highlight or by « Emphasize category changes ».
- `flows.minShare` Hide flows below (% of total) / Masquer les flux sous (% du total): number, default `0`; values: 0 to 20
- `flows.outline` Flow outline / Contour des flux: toggle, default `false`; values: true / false
- `flows.outlineColor` Outline color (empty = flow color) / Couleur du contour (vide = couleur du flux): color, default (empty); values: hex color. Visible when `flows.outline` = `true`
- `flows.outlineWidth` Outline width / Épaisseur du contour: number, default `1`; values: 0.5 to 4. Visible when `flows.outline` = `true`

### Entries, exits and retention / Entrées, sorties et maintien (`migration`)
- `migration.showMissing` Show entries and exits / Afficher les entrées et les sorties: toggle, default `true`; values: true / false. Mode with a Period field: individuals that appear (new) or disappear (lost) from one period to the next.
- `migration.newLabel` Entries label / Libellé des entrées: text, default (empty)
- `migration.lostLabel` Exits label / Libellé des sorties: text, default (empty)
- `migration.retention` Retention rate between columns ★ / Taux de maintien entre les colonnes ★ ★: toggle, default `false`; values: true / false
- `migration.retentionKind` Retention = / Maintien =: dropdown, default `same`; values: `same` Same category in the next column; `present` Still present in the next column. Visible when `migration.retention` = `true`

### Category labels / Étiquettes des catégories (`categoryLabels`)
- `categoryLabels.show` Show / Afficher: toggle, default `true`; values: true / false
- `categoryLabels.content` Content / Contenu: dropdown, default `nameValue`; values: `name` Name; `nameValue` Name and value; `namePct` Name and % of the column; `all` Name, value and %
- `categoryLabels.pctOf` Percentage of / Pourcentage calculé sur: dropdown, default `column`; values: `column` The column total; `first` The first column total. First column: each category as a share of the starting total (a funnel: what is left at each step).
- `categoryLabels.fontSize` Text size / Taille du texte: number, default `10`; values: 6 to 24
- `categoryLabels.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `categoryLabels.halo` Text halo / Halo autour du texte: toggle, default `true`; values: true / false
- `categoryLabels.bold` Bold (name) / Gras (nom): toggle, default `true`; values: true / false
- `categoryLabels.italic` Italic / Italique: toggle, default `false`; values: true / false
- `categoryLabels.wrap` Two lines if needed / Sur deux lignes si besoin: toggle, default `true`; values: true / false. A long name goes on two lines instead of being shortened (…); in vertical layout the labels also get more room.
- `categoryLabels.force` Force display / Afficher toutes les étiquettes: toggle, default `false`; values: true / false. On: labels are written even in tight columns (they may touch). Off: a label that does not fit is left out.
- `categoryLabels.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `categoryLabels.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `categoryLabels.prefix` Prefix / Préfixe: text, default (empty)
- `categoryLabels.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)

### Flow labels / Étiquettes des flux (`linkLabels`)
- `linkLabels.show` Show / Afficher: toggle, default `false`; values: true / false
- `linkLabels.content` Content / Contenu: dropdown, default `value`; values: `value` Value; `pctSource` % of the origin node (conversion); `pctTotal` % of total; `valuePct` Value and % of the origin node
- `linkLabels.fontSize` Text size / Taille du texte: number, default `9`; values: 6 to 20
- `linkLabels.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `linkLabels.bold` Bold / Gras: toggle, default `true`; values: true / false
- `linkLabels.italic` Italic / Italique: toggle, default `false`; values: true / false
- `linkLabels.force` Force display / Afficher même sans place: toggle, default `false`; values: true / false. Off: a label is left out when the flow is too short or when it would touch another label (its value stays in the tooltip).
- `linkLabels.minThickness` Only on flows thicker than (px, 0 = auto) / Seulement sur les flux plus épais que (px, 0 = auto): number, default `0`; values: 0 to 40. Auto: a label is shown when the flow is at least as thick as the text.

### Column headers / En-têtes des colonnes (`headers`)
- `headers.show` Show / Afficher: toggle, default `true`; values: true / false
- `headers.names` Column names (separated by ;) / Noms des colonnes (séparés par ;): text, default (empty). Leave empty for the field names (stages) or the period values.
- `headers.fontSize` Text size / Taille du texte: number, default `10`; values: 6 to 24
- `headers.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `headers.showTotal` Total under the name / Total sous le nom: toggle, default `false`; values: true / false

### Interactions (`interaction`)
- `interaction.hover` Highlight on hover / Mettre en avant au survol: toggle, default `true`; values: true / false
- `interaction.dim` Dimmed items opacity (%) / Opacité des éléments estompés (%): number, default `25`; values: 5 to 80
- `interaction.trace` Trace paths on hover / Suivre les parcours au survol: toggle, default `true`; values: true / false. Hovering a category highlights, in every column, where its members come from and where they go.
- `interaction.drag` Drag nodes to reorder them (edit mode) / Glisser les nœuds pour les réordonner (mode édition): toggle, default `true`; values: true / false. In edit mode, drag a category up or down: the new order is saved with the report (Category order = Custom).

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Waterfall Plume

- Power BI's waterfall chart with the subtotals, start value and budget-to-actual bridge you were waiting for, plus a price-volume-mix bridge.
- Slug `waterfall` · version 1.4.0.0 · GUID (`visualType`) `plumeWaterfall9B3F32EBD7B24799B76C4056F6F566E2` · page https://plumevisuals.com/en/visuals/waterfall

### What the visual does

Waterfall Plume is a Power BI custom visual (version 1.4.0.0, installed from its `.pbiviz` file; AppSource submission in progress) that draws **two charts**:

**New in version 1.4.0.0 (30/10/2026):** Format pane reorganized (new **Gridlines** card); free native-parity additions: color of the "Others" bar, legend (Increase / Decrease / Total), data label position, scale kept under filters (`yAxis.min` / `yAxis.max` from a "Dynamic format" measure).

- a **classic waterfall** that matches Power BI's native waterfall chart (Category, Breakdown, Tooltips, "Maximum breakdowns" + Others, increase / decrease / total colors, axis from zero, sorting) and adds what users ask for on the forums: a **start value** (opening balance), an **end value check** with a "Gap" bar, a **budget-to-actual bridge** by category (Reference value), a hidden or renamed total, a **custom step order**, one bar per measure (an income statement made of measures), adjustable connectors (dotted, dashed, solid, color), the split of each category, and, with premium, **subtotals** at chosen positions ("Gross margin", "EBITDA"), **horizontal bars** and **grouping of small steps** into "Others (n)";
- a **price-volume-mix bridge**: it explains the change in revenue (or margin) between two periods as volume, mix and price effects, plus new products, discontinued products and other changes, computed by the visual product by product from a product field, a quantity measure and an amount measure (no DAX decomposition needed). A summary strip shows amount, quantities and average price (reference → compared, with ▲▼), and each bar's tooltip explains the effect in one sentence with its main contributor.

**Chart type** (`cascade.mode`, Format › Waterfall › Chart type): `auto` (default) = price-volume-mix bridge as soon as a measure is in **Quantity (price-volume-mix)**, waterfall otherwise; `waterfall` or `pvm` force one of them. Reports saved before 1.3.0.0 (all price-volume-mix bridges, with a quantity) open unchanged.

**Readability (1.3.1.0):** with `labels.units` = `auto`, each label gets its own unit, never larger than the chart's ("−€31.4K" next to "€1.43M"), always with at least 2 significant digits, even with forced units (never "€0M"); the same rule applies to the summary strip and the breakdown by product. Labels are placed without overlap (shifted, otherwise hidden: the value stays in the tooltip, which shows the full value in the measure's format). With `dataColors.total` empty, totals take the style's main color only if it clearly differs from increases, decreases and the background, otherwise a neutral tint of the style; in Black and white, decreases are light with a dashed border. Dates in Category, Breakdown or Period (including the ISO text sent by Power BI Desktop) are read as local dates, sorted chronologically and written in the column's format (or "April 2025", "2025" when the format is generic).

### The price-volume-mix calculation

For each product *i* sold in **both** periods (Q = quantity, P = amount ÷ quantity, index 0 = reference, 1 = compared; Qtot = total quantity of the products sold in both periods; share0(i) = Q0(i) ÷ Qtot0):

| Effect | Formula |
|---|---|
| Volume | (Qtot1 − Qtot0) × share0(i) × P0(i) |
| Mix | (Q1(i) − Qtot1 × share0(i)) × P0(i) |
| Price | Q1(i) × (P1(i) − P0(i)) |
| New | Amount1 of products with no quantity and no amount in the reference |
| Discontinued | − Amount0 of products with no quantity and no amount in the compared period |
| Other changes | Amount1 − Amount0 of the remaining products (no usable quantity: services, discounts, net returns) |

Per product, Volume + Mix + Price = Amount1 − Amount0, so the bridge lands exactly on the total change. Worked example: Candle 100 units / 1,000 → 90 / 990; Vase 50 / 1,500 → 90 / 2,520. Volume +500, Mix +600, Price −90, total +1,010 = 3,510 − 2,500. `effects.layout` = `vp` merges mix into volume; `effects.newLost` = `volume` puts new and discontinued products into volume.

### Free vs premium (★)

- Every feature works without a key and nothing is ever blocked. Free features never show a watermark, and the default settings use no premium feature (except the price-volume-mix breakdown by product, offered on click: see below).
- 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 (`style.customColors` and the colors under it) are **free**; every other `style.preset`, the other gradient palettes (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium**. See "Styles and theme JSON" below.
- Premium features of Waterfall Plume (the watermark appears only when they actually apply):
  - waterfall: `cascade.subtotals` ("Subtotals ★", when at least one entry matches a step), `cascade.subtotalEach` ("Subtotal after each category ★"), `cascade.group` = `topN` or `share` ("Keep the N largest ★", "Below a % of the total ★", only when steps are actually grouped);
  - both charts: `bars.orientation` = `horizontal` ("Bars (horizontal) ★");
  - price-volume-mix: the **Breakdown by product ★** card (`detail`): `detail.show` ("Open on bar click") is **on by default**; clicking (or pressing Enter on) a bar opens the split of that effect by product, and the watermark then appears without a key. Turn `detail.show` off to never offer it. `effects.view` = `products` ("Product (change of each product) ★"): a bridge of each product's change (top `effects.topN` + "Others").
- Premium options and list values carry " ★" in their label.
- Watermark without a valid key (CHARTE 1.9, "continuous watermark"): in edit mode, a **"Plume Visuals · Premium preview"** badge (French: « Plume Visuals · Aperçu premium ») in the footer with an "Unlock →" link to the pricing page; in reading mode (published report), "Plume Visuals · Premium preview" is repeated over the whole visual, without capturing the mouse or keyboard. It disappears once a key is pasted in **Format › Plume Studio License › License key** (`license.key`; French: « Licence Plume Studio › Clé de licence »), the **first card** of the Format pane.
- Accepted keys: only keys starting with `PLUM1.` from the buyer's account on plumevisuals.com, checked offline (Ed25519 signature), covering `waterfall` 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". `license.showOwner` displays "Licensed to <holder>".
- Licenses last one year (one-time payment, no automatic renewal, key accepted for 30 more days, reminders 30 and 7 days before the end). Prices per year: 39 € personal, 99 € SME, 299 € enterprise, or a catalog pack (199 € / 399 € / 1,199 € per year; tiers by number of users, designers and viewers included: personal 1–10, SME 11–200, enterprise more than 200). Renewing gives a new key to paste instead of the old one.

### Fields (data roles)

| Field (EN / FR) | Role | Kind | Use |
|---|---|---|---|
| Category (or Product) / Catégorie (ou Produit) | `category` | 1 column | One step per value; the product level of the price-volume-mix bridge |
| Breakdown / Répartition | `breakdown` | 1 column | Change from one category to the next (like Power BI), or split of each category |
| Period (comparison) / Période (comparaison) | `period` | 1 column | Waterfall: one total per period, categories explain the change; price-volume-mix: the two periods compared |
| Values (amount) / Valeurs (montant) | `amount` | measure (1 with a category, up to 30 without) | Step amount; revenue or margin of the price-volume-mix bridge |
| Reference value (budget, last year…) / Valeur de référence (budget, N-1…) | `amountBase` | 1 measure | Waterfall: budget-to-actual bridge; price-volume-mix without Period: reference amount |
| Start value / Valeur de départ | `startValue` | 1 measure | Start bar (opening balance) |
| End value (check) / Valeur de fin (contrôle) | `endValue` | 1 measure | Measured end bar; a "Gap" bar shows any difference with start + steps |
| Quantity (price-volume-mix) / Quantité (prix-volume-mix) | `quantity` | 1 measure | Turns on the price-volume-mix bridge (Chart type = Automatic) |
| Reference quantity (price-volume-mix) / Quantité de référence (prix-volume-mix) | `quantityBase` | 1 measure | Price-volume-mix without Period: reference quantity |
| Tooltips / Infobulles | `tooltips` | measures | Added to the tooltip of each step that matches a data row |
| Dynamic format / Format dynamique | `format` | measures | Drives any setting with DAX (see below); never drawn |

### Expected data shape

**Waterfall** (one row per step; the sign matters, a cost is negative). The fields in use decide the form:

| Fields | Form |
|---|---|
| Category + Values | Simple waterfall: one step per category, then a "Total" bar; axis from zero |
| Category + Values + Reference value | Budget-to-actual: start = reference total, one step per category = Values − Reference, end = Values total ("Difference between Revenue and Budget." in the tooltip) |
| Category + Breakdown + Values | `cascade.breakdownMode` = `change` (default, like Power BI): each category is a total and the breakdown items explain the change to the next one (top `cascade.maxBreakdowns`, default 5, + "Others (n)"); `split`: each category is split into its items |
| Category + Period + Values | One total per period, categories explain the change from one period to the next (`cascade.compare` = `all`, `firstLast` or `prevLast`) |
| Values only (several measures) | One bar per measure, then the total (income statement made of measures) |
| + Start value / End value | Start bar instead of 0 / measured end bar with a "Gap" bar if needed |

Start and End values: if the measure returns the same value for every category (an opening balance), that value is used; otherwise the sum over the categories.

```dax
Result =
DATATABLE (
    "Account", STRING, "Order", INTEGER, "Amount", DOUBLE,
    { { "Revenue", 1, 1000 }, { "Cost of sales", 2, -400 }, { "Staff costs", 3, -250 }, { "Rent", 4, -80 },
      { "Marketing", 5, -60 }, { "Other income", 6, 30 }, { "Taxes", 7, -50 } }
)
Total amount = SUM ( Result[Amount] )
// Account sorted by Order (Column tools › Sort by column) → total 190
// cascade.subtotals = "Cost of sales = Gross margin; Marketing = EBITDA" → Gross margin 600, EBITDA 210
```

**Price-volume-mix bridge** (one row per product, measures evaluated per period):

| Product (`category`) | Period (`period`) | Quantity (`quantity`) | Amount (`amount`) |
|---|---|---|---|
| Candle | 2024 | 100 | 1,000 |
| Candle | 2025 | 90 | 990 |
| Vase | 2025 | 90 | 2,520 |

- `effects.compare` = `firstLast` (default) or `prevLast`. Dates and numbers are sorted; text values keep the data order.
- Without a Period field: **Reference quantity** and **Reference value** are both required; Quantity and Values are then the compared period.
- The Product level decides what is "price" and what is "mix": at category level, a shift between products of the same category becomes a price effect. With a margin as the amount, the "price" is the unit margin.

Limits: a warning icon above 10,000 rows (products) or 60 periods. Messages: "Add a "Period" field (at least two values), or the "Reference quantity" and "Reference value" measures." (price-volume-mix without a comparison); "Quantities are zero or missing: volume, mix and price effects cannot be computed."; "Subtotals not found (unknown step name): …" (edit mode only).

### DAX recipes

```dax
Revenue = SUM ( Sales[Amount] )
Items sold = SUM ( Sales[Quantity] )
Revenue budget = SUM ( Budget[Amount] )          // Reference value of a budget-to-actual bridge

// Without a Period field: reference measures (marked date table related to Sales[Date]); filter the page on the compared year
Items sold LY = CALCULATE ( [Items sold], SAMEPERIODLASTYEAR ( 'Date'[Date] ) )
Revenue LY = CALCULATE ( [Revenue], SAMEPERIODLASTYEAR ( 'Date'[Date] ) )

// Cash flow: same value for every category = used as is
Opening cash =
VAR FirstDay = MIN ( 'Date'[Date] )
RETURN CALCULATE ( SUM ( Balances[Balance] ), Balances[Date] = FirstDay )
```

### Interactions with the report

- Waterfall: clicking a step, a total (pillar) or "Others" cross-filters the report on the category, the breakdown item or the period ("Others" selects the grouped categories); Ctrl + click adds; clicking the background clears. Context menu everywhere (bars, totals, axis labels, background, title).
- Price-volume-mix: effect bars (volume, mix, price…) are not data points; clicking them opens the breakdown by product ★ (when `detail.show` is on); in the breakdown, clicking a product cross-filters on it; × closes it. With `effects.view` = `products`, clicking a product bar selects that product; Alt + click opens its breakdown.
- Keyboard: arrows between bars, Enter to activate (open or close the breakdown), Esc to clear. Direction is always given by ▲▼ (`bars.arrows`), never by color only; high contrast uses the host colors and draws decreases dashed. Other visuals cross-filter it (no highlighting).

### Dynamic formats

- **fx button** on every color and text of the Format pane (Field value, Rules, Gradient).
- **"Dynamic format" well** (`format` role, French « Format dynamique »): drop measures and rename each one, for this visual, `card.setting`. It drives any setting (sizes, toggles, lists, fonts, colors, texts), including the 1.3 ones (`cascade.*`, `bars.orientation`, `bars.connectorStyle`, `bars.connectorColor`, `dataColors.subtotal`), and wins over the fixed setting, the style and an fx rule. With a Period field the measure is repeated in each period: the first one wins. A ★ setting driven by DAX still shows the watermark without a key.

```dax
// renamed bars.orientation: horizontal bars ★ when there are many accounts (whole-visual value thanks to ALLSELECTED)
Orientation = IF ( CALCULATE ( DISTINCTCOUNT ( Result[Account] ), ALLSELECTED () ) > 12, "horizontal", "vertical" )
// renamed dataColors.lowerIsBetter: TRUE when the amount is a cost
Costs mode = SELECTEDVALUE ( 'Analysed measure'[Is cost], FALSE () )
```

### Format pane

- Each option has an ID `card.option` (object name + property name in capabilities.json); full list with values in the reference tables.
- Card order: `license` (always first), `style`, `dataColors` (favorable, unfavorable, totals, `subtotal`, `lowerIsBetter`), `cascade` (groups: Chart type `mode`; Steps `sort`, `customOrder`, `breakdownMode`, `compare`, `maxBreakdowns`, `group`, `groupN`, `groupPct`, `othersLabel`; Start, subtotals and total `startLabel`, `showTotal`, `totalLabel`, `subtotals` ★, `subtotalEach` ★, `gapLabel`), `effects` (price-volume-mix only: `view`, `layout`, `newLost`, `compare`, `topN`, labels), `bars` (`orientation`, `width`, `connectors`, `connectorStyle`, `connectorColor`, `arrows`), `labels`, `summary`, `detail` (★, price-volume-mix only), `xAxis` (steps axis), `yAxis` (value axis), `interaction`, then `title`, `source`, `container`, `texts`. Format pane in version 1.4.0.0 (30/10/2026), top to bottom: `license`, `style`, `dataColors`, `cascade`, `effects`, `bars`, `labels`, `xAxis`, `yAxis`, `gridlines`, `legend`, `summary`, `detail`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- "Visible when": in a price-volume-mix bridge, only `cascade.mode` shows in the Waterfall card; `effects` and `detail` only in a price-volume-mix bridge. Waterfall: `breakdownMode` with Category + Breakdown; `compare` with a Breakdown as change or a Period; `maxBreakdowns` with a Breakdown or a Period; `group` only for a simple waterfall, budget-to-actual or measures; `subtotals`, `startLabel`, `showTotal`, `gapLabel` hidden with a Breakdown as change or a Period; `showTotal` hidden for budget-to-actual; `subtotalEach` only with `breakdownMode` = `split`; `customOrder` only with `sort` = `custom`. `effects.compare` only with a Period field.
- `yAxis.zero` ("Start at zero (otherwise: broken axis)"): on by default for a waterfall (like Power BI, the pane shows it on), off by default for a price-volume-mix bridge (broken axis with break marks on the totals).
- Labels follow the language of Power BI Desktop; `texts.language` forces French or English inside the visual. An empty title gives an automatic title built from the fields ("Revenue change by Channel").

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. Booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes, colors in `solid.color`.

```json
{
  "visualType": "plumeWaterfall9B3F32EBD7B24799B76C4056F6F566E2",
  "query": {
    "queryState": {
      "category": { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Result" } }, "Property": "Account" } }, "queryRef": "Result.Account", "nativeQueryRef": "Account" } ] },
      "amount":   { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Result" } }, "Property": "Total amount" } }, "queryRef": "Result.Total amount", "nativeQueryRef": "Total amount" } ] }
    }
  },
  "objects": {
    "cascade":    [ { "properties": { "subtotals": { "expr": { "Literal": { "Value": "'Cost of sales = Gross margin; Marketing = EBITDA'" } } },
                                       "totalLabel": { "expr": { "Literal": { "Value": "'Net income'" } } },
                                       "sort": { "expr": { "Literal": { "Value": "'data'" } } } } } ],
    "bars":       [ { "properties": { "connectorStyle": { "expr": { "Literal": { "Value": "'solid'" } } } } } ],
    "dataColors": [ { "properties": { "subtotal": { "solid": { "color": { "expr": { "Literal": { "Value": "'#B8952A'" } } } } } } } ],
    "license":    [ { "properties": { "key": { "expr": { "Literal": { "Value": "'PLUM1.…'" } } } } } ]
  }
}
```

For a price-volume-mix bridge, project `category` (product), `period` (year), `quantity` and `amount`, and set for example `"effects": [ { "properties": { "compare": { "expr": { "Literal": { "Value": "'prevLast'" } } } } } ]`. The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from the `.pbiviz` file).

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`.
- `style.themeJson` (Format › Style › Theme JSON ★) takes a JSON theme as plain text. Format v2: an object with an optional `extends` (a style ID above) and optional groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`; the v1 flat format (`style`, `palette`, `accent`, `background`…) is still read. Every field is optional. Colors are `#RRGGBB` (`#RGB` and `#RRGGBBAA` accepted, opacity ignored). Unknown fields and values outside the allowed lists are ignored, out-of-range numbers are clamped. Invalid JSON shows "Invalid theme JSON: ignored" in edit mode and the visual keeps its look.
- Full field list with allowed values, examples and troubleshooting: tutorial https://plumevisuals.com/ai/tutorials/en/themes-json.md (French: https://plumevisuals.com/ai/tutorials/fr/themes-json.md). The same JSON can be pasted in every Plume visual of a page.
- Priority (the last one wins): visual defaults → `style.preset` → `style.themeJson` → `style.palette` (if not "Style or theme palette") → `style.followTheme` → custom colors → options set by hand in the other cards → DAX formats (fx button, "Dynamic format" field) → Windows high contrast.

### Common pitfalls

- A price-volume-mix bridge instead of a waterfall: a measure is in Quantity; remove it or set `cascade.mode` = `waterfall`.
- Steps in alphabetical order: no "Sort by column" on the category; or use `cascade.sort` = `custom` with `cascade.customOrder` (names separated by semicolons, case-insensitive).
- A cost going up: the amount is positive in the data; flip its sign in the measure.
- No percentage in the labels: the percentage needs a start bar (start value, reference, first total); a share of the final total would be misleading. The tooltip still gives "Share of total".
- "Subtotals not found": misspelled step name in `cascade.subtotals`. A subtotal row already in the data ("Gross margin"): enter its name alone, it becomes a subtotal (running total).
- "Add a Period field…" message: the Period has one value under the current filters, or only one reference measure is set.
- Mix looks wrong: the product level is too coarse (category) or too fine (SKU with few sales). Large "Other changes": products with an amount but no quantity in one period (services, discounts, returns).
- Watermark after a click on a price-volume-mix bar: the breakdown by product ★ is on by default (`detail.show`).
- Costs: set `dataColors.lowerIsBetter` so that decreases are green.
- The visual makes no network request: data and license key stay in the report.

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

A stacked waterfall (mixed signs in one bar; use the Breakdown instead), small multiples, hierarchy drill-down (product within category), one color per category (color means favorable / unfavorable), more than two periods in one price-volume-mix bridge, a currency or exchange-rate effect, a cost-of-goods or margin-rate effect, a customer or channel mix in addition to the product mix, effects written back to the model as measures, export of the breakdown.

## Waterfall Plume: data fields

- `category` Category (or Product) / Catégorie (ou Produit) (column, 1 max): 
- `breakdown` Breakdown / Répartition (column, 1 max): 
- `period` Period (comparison) / Période (comparaison) (column, 1 max): 
- `amount` Values (amount) / Valeurs (montant) (measure, 30 max): 
- `amountBase` Reference value (budget, last year…) / Valeur de référence (budget, N-1…) (measure, 1 max): 
- `startValue` Start value / Valeur de départ (measure, 1 max): 
- `endValue` End value (check) / Valeur de fin (contrôle) (measure, 1 max): 
- `quantity` Quantity (price-volume-mix) / Quantité (prix-volume-mix) (measure, 1 max): 
- `quantityBase` Reference quantity (price-volume-mix) / Quantité de référence (prix-volume-mix) (measure, 1 max): 
- `tooltips` Tooltips / Infobulles (measure, several max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Waterfall Plume: Format pane options (167)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Data colors / Couleurs des données (`dataColors`)
- `dataColors.increase` Increase (favorable) / Augmentation (favorable): color, default `#2E7D4F`; values: hex color
- `dataColors.decrease` Decrease (unfavorable) / Diminution (défavorable): color, default `#C0392B`; values: hex color
- `dataColors.total` Total (empty = palette) / Total (vide = palette): color, default (empty); values: hex color
- `dataColors.subtotal` Subtotals (empty = total) / Sous-totaux (vide = total): color, default (empty); values: hex color. Waterfall: subtotal bars and intermediate category totals.
- `dataColors.others` Other (empty = by direction) / Autres (vide = selon le sens): color, default (empty); values: hex color. The « Others (n) » bar of grouped steps or breakdowns, like the « Other » color of the native waterfall.
- `dataColors.lowerIsBetter` A decrease is favorable (costs) / Une baisse est favorable (coûts): toggle, default `false`; values: true / false. For costs or discounts: increases are shown in the « unfavorable » color.

### Waterfall / Cascade (`cascade`)
- `cascade.mode` Chart type / Type de graphique: dropdown, default `auto`; values: `auto` Automatic (from the fields); `waterfall` Waterfall; `pvm` Price-volume-mix bridge. Automatic: price-volume-mix bridge when a Quantity is set, otherwise a classic waterfall.
- `cascade.sort` Step order / Ordre des étapes: dropdown, default `data`; values: `data` Data order (Sort axis); `valueDesc` Value, descending; `valueAsc` Value, ascending; `absDesc` Largest changes first; `nameAsc` Name A → Z; `nameDesc` Name Z → A; `custom` Custom list. Data order: the order of the model, or the one chosen with « … › Sort axis » in the visual header.
- `cascade.customOrder` Custom order / Ordre personnalisé: text, default (empty). Visible when `cascade.sort` = `custom`. Step names separated by semicolons; steps not listed follow in data order.
- `cascade.breakdownMode` With a Breakdown / Avec une Répartition: dropdown, default `change`; values: `change` Change between categories (like Power BI); `split` Split of each category. Change: each category is a total and the breakdown explains the change from one category to the next. Split: each category value is split into its breakdown items.
- `cascade.compare` Totals compared / Totaux comparés: dropdown, default `all`; values: `all` All, one after the other; `firstLast` The first and the last; `prevLast` The previous and the last
- `cascade.maxBreakdowns` Maximum breakdowns / Répartitions affichées au plus: number, default `5`; values: 1 to 50. The largest changes are shown; the others are grouped in « Other ».
- `cascade.group` Group small steps / Regrouper les petites étapes: dropdown, default `none`; values: `none` No; `topN` Keep the N largest ★; `share` Below a % of the total ★
- `cascade.groupN` Steps kept / Étapes gardées: number, default `8`; values: 1 to 50. Visible when `cascade.group` = `topN`
- `cascade.groupPct` Threshold (% of changes) / Seuil (% des écarts): number, default `2`; values: 0 to 50. Visible when `cascade.group` = `share`. Steps smaller than this share of the sum of all changes (in absolute value) are grouped.
- `cascade.othersLabel` Grouped steps label / Libellé du regroupement: text, default (empty)
- `cascade.startLabel` Start label / Libellé du départ: text, default (empty)
- `cascade.showTotal` Show total / Afficher le total: toggle, default `true`; values: true / false
- `cascade.totalLabel` Total label / Libellé du total: text, default (empty). Visible when `cascade.showTotal` = `true`
- `cascade.subtotals` Subtotals ★ / Sous-totaux ★ ★: text, default (empty). « Step = Name »: a subtotal named Name after the step. A step name alone: this step becomes a subtotal (running total). Separate entries with semicolons.
- `cascade.subtotalEach` Subtotal after each category ★ / Sous-total après chaque catégorie ★ ★: toggle, default `false`; values: true / false
- `cascade.gapLabel` Label of the gap to the end value / Libellé de l'écart avec la valeur de fin: text, default (empty)

### Effects (price-volume-mix) / Effets (prix-volume-mix) (`effects`)
- `effects.view` Break down by / Décomposer par: dropdown, default `effects`; values: `effects` Effect (volume, mix, price…); `products` Product (change of each product) ★
- `effects.layout` Effects shown / Effets affichés: dropdown, default `vmp`; values: `vmp` Volume, mix and price; `vp` Volume (mix included) and price. Visible when `effects.view` = `effects`
- `effects.newLost` New and discontinued products / Produits nouveaux et arrêtés: dropdown, default `separate`; values: `separate` Separate effects; `volume` Included in volume. Visible when `effects.view` = `effects`
- `effects.compare` With a Period field, compare / Avec un champ Période, comparer: dropdown, default `firstLast`; values: `firstLast` The first and the last period; `prevLast` The previous and the last period
- `effects.topN` Products shown (bridge by product) / Produits affichés (pont par produit): number, default `8`; values: 2 to 30. Visible when `effects.view` = `products`
- `effects.baseLabel` Reference period / Période de référence: text, default (empty)
- `effects.currentLabel` Compared period / Période comparée: text, default (empty)
- `effects.volumeName` Volume effect / Effet volume: text, default (empty)
- `effects.mixName` Mix effect / Effet mix: text, default (empty)
- `effects.priceName` Price effect / Effet prix: text, default (empty)
- `effects.newName` New products / Nouveaux produits: text, default (empty)
- `effects.lostName` Discontinued products / Produits arrêtés: text, default (empty)

### Bars / Barres (`bars`)
- `bars.orientation` Orientation: dropdown, default `vertical`; values: `vertical` Columns (vertical); `horizontal` Bars (horizontal) ★
- `bars.width` Bar width (%) / Largeur des barres (%): number, default `62`; values: 10 to 95
- `bars.connectors` Connector lines / Traits de liaison: toggle, default `true`; values: true / false
- `bars.connectorStyle` Connector style / Style des liaisons: dropdown, default `dotted`; values: `dotted` Dotted; `dashed` Dashed; `solid` Solid. Visible when `bars.connectors` = `true`
- `bars.connectorColor` Connector color (empty = secondary) / Couleur des liaisons (vide = secondaire): color, default (empty); values: hex color. Visible when `bars.connectors` = `true`
- `bars.arrows` ▲▼ arrows in labels / Flèches ▲▼ dans les étiquettes: toggle, default `true`; values: true / false. The direction is never shown by color alone.

### Data labels / Étiquettes de données (`labels`)
- `labels.show` Show / Afficher: toggle, default `true`; values: true / false
- `labels.content` Content / Contenu: dropdown, default `valuePct`; values: `valuePct` Value and % of reference; `value` Value; `pct` % of reference
- `labels.position` Position: dropdown, default `auto`; values: `auto` Outside end; `insideEnd` Inside end; `center` Inside center; `insideBase` Inside base. Inside: the label moves outside the bar when it does not fit.
- `labels.fontSize` Size / Taille: number, default `10`; values: 6 to 24
- `labels.color` Color (empty = automatic) / Couleur (vide = automatique): color, default (empty); values: hex color. Automatic: readable color depending on the background (inside bars: white or dark).
- `labels.bold` Bold / Gras: toggle, default `false`; values: true / false
- `labels.italic` Italic / Italique: toggle, default `false`; values: true / false
- `labels.halo` Text halo / Halo autour du texte: toggle, default `true`; values: true / false
- `labels.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `labels.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `labels.prefix` Prefix / Préfixe: text, default (empty)
- `labels.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)

### Category axis / Axe des catégories (`xAxis`)
- `xAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `xAxis.fontSize` Text size / Taille du texte: number, default `9`; values: 6 to 24
- `xAxis.color` Color (empty = secondary) / Couleur (vide = secondaire): color, default (empty); values: hex color
- `xAxis.line` Axis line / Trait de l'axe: toggle, default `true`; values: true / false
- `xAxis.showTitle` Axis title / Titre de l'axe: toggle, default `false`; values: true / false
- `xAxis.titleText` Title text / Texte du titre: text, default (empty). Visible when `xAxis.showTitle` = `true`

### Value axis / Axe des valeurs (`yAxis`)
- `yAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `yAxis.position` Position: dropdown, default `left`; values: `left` Left; `right` Right
- `yAxis.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `yAxis.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `yAxis.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `yAxis.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `yAxis.prefix` Prefix / Préfixe: text, default (empty)
- `yAxis.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)
- `yAxis.line` Axis line / Trait de l'axe: toggle, default `false`; values: true / false
- `yAxis.min` Minimum: text, default (empty). Empty = automatic. To keep the same scale when filtering: « Dynamic format » field, measure yAxis.min = CALCULATE ( [Measure], REMOVEFILTERS () ) (or ALL ( Table )).
- `yAxis.max` Maximum: text, default (empty). Empty = automatic. To keep the same scale when filtering: « Dynamic format » field, measure yAxis.max = CALCULATE ( [Measure], REMOVEFILTERS () ) (or ALL ( Table )).
- `yAxis.zero` Start at zero (otherwise: broken axis) / Commencer à zéro (sinon : axe coupé): toggle, default `false`; values: true / false. Off: the axis starts near the smallest bar so that small effects stay visible; total bars show a break mark.
- `yAxis.ticks` Number of ticks (approx.) / Nombre de graduations (environ): number, default `5`; values: 2 to 20
- `yAxis.showTitle` Show / Afficher: toggle, default `false`; values: true / false
- `yAxis.titleText` Text / Texte: text, default (empty). Visible when `yAxis.showTitle` = `true`

### Gridlines / Quadrillage (`gridlines`)
- `gridlines.show` Show / Afficher: toggle, default `true`; values: true / false. Horizontal with columns, vertical with horizontal bars (the gridlines turn with the chart).
- `gridlines.color` Color (empty = style grid) / Couleur (vide = grille du style): color, default (empty); values: hex color. Visible when `gridlines.show` = `true`
- `gridlines.style` Line style / Style du trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `gridlines.show` = `true`
- `gridlines.width` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `gridlines.show` = `true`
- `gridlines.zeroLine` Zero line / Ligne du zéro: toggle, default `true`; values: true / false
- `gridlines.catShow` Show / Afficher: toggle, default `false`; values: true / false
- `gridlines.catColor` Color (empty = style grid) / Couleur (vide = grille du style): color, default (empty); values: hex color. Visible when `gridlines.catShow` = `true`
- `gridlines.catStyle` Line style / Style du trait: dropdown, default `dotted`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `gridlines.catShow` = `true`
- `gridlines.catWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `gridlines.catShow` = `true`

### Legend / Légende (`legend`)
- `legend.show` Show / Afficher: toggle, default `false`; values: true / false. Increase, decrease, total (and subtotal, other): like the legend of the native waterfall chart.
- `legend.position` Position: dropdown, default `top`; values: `top` Top; `bottom` Bottom; `right` Right; `left` Left
- `legend.align` Alignment / Alignement: dropdown, default `left`; values: `left` Start; `center` Center; `right` End. Visible when `legend.position` = `top` or `bottom`
- `legend.showTitle` Legend title / Titre de la légende: toggle, default `false`; values: true / false
- `legend.titleText` Title text / Texte du titre: text, default (empty). Visible when `legend.showTitle` = `true`
- `legend.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `legend.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color

### Summary strip / Bandeau de synthèse (`summary`)
- `summary.show` Show / Afficher: toggle, default `true`; values: true / false. Amount, quantities and average price: reference → compared period.
- `summary.fontSize` Text size / Taille du texte: number, default `12`; values: 8 to 20

### Breakdown by product ★ / Détail par produit ★ (`detail`)
- `detail.show` Open on bar click / Ouvrir au clic sur une barre: toggle, default `true`; values: true / false. Click an effect: its contribution by product appears next to the bridge.
- `detail.position` Position: dropdown, default `auto`; values: `auto` Automatic; `right` Right; `bottom` Bottom
- `detail.topN` Products shown / Produits affichés: number, default `8`; values: 3 to 30

### Interactions (`interaction`)
- `interaction.hover` Highlight on hover / Mettre en avant au survol: toggle, default `true`; values: true / false
- `interaction.dim` Dimmed items opacity (%) / Opacité des éléments estompés (%): number, default `25`; values: 5 to 80

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).
- `tooltip.explain` Explanation sentence / Phrase d'explication: toggle, default `true`; values: true / false. A sentence that explains the step (change, volume, mix or price effect…), on several short lines.
- `tooltip.contributor` Main contributor / Principal contributeur: toggle, default `true`; values: true / false

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Gantt Plume

- The Gantt chart for Power BI: a task grid, a timeline you zoom from hours to years, a collapsible hierarchy, milestones and the critical path.
- Slug `gantt-chart` · version 1.3.0.0 · GUID (`visualType`) `plumeGanttChartB2FEC518BC294539ACD7EE04DBA8CFE8` · page https://plumevisuals.com/en/visuals/gantt-chart

### What the visual does

Gantt Plume is a Power BI custom visual that turns a task table into a project plan: a **task grid** on the left (owner, start, end, duration, progress, outline numbers and up to 8 extra columns) and a **timeline** on the right that the reader zooms from hours to years (toolbar, Ctrl + mouse wheel centered on the pointer) and drags to scroll. Tasks sit in a **collapsible hierarchy** of up to 6 group levels (portfolio › project › phase…), with summary bars (min / max dates, progress weighted by duration) and numeric grid columns summed per group. Milestones (4 shapes), several bars on one row (absences, machines, split tasks), weekends and holidays shaded, durations in business days, calendar days or hours, a today line or a fixed status date, a custom sort order, bar labels and colors from your fields. Premium features: **dependencies** in MS Project format with the **critical path**, **baseline versus actual** with the variance in business days, **computed status** (done, on track, at risk, late, upcoming), **bar color from a DAX measure**, **rollup of collapsed groups** (a collapsed project shows its tasks' bars and named milestones on its row), **resource view** (one row per owner, overlaps in red), **whole plan in the frame** for PDF / PowerPoint export, and date markers in the Analytics pane. Version 1.2.0.0 (name "Gantt Plume" since that version, formerly "Plume Gantt") added the Sort order and Bar label fields, the bar color measure, the rollup of collapsed groups, outline numbers, long names on two lines, month / hour / quarter / year formats and new initial positions (end of the plan, chosen date). Version 1.2.1.0 made dependency arrows always read left to right (an arrow to a successor that starts before the elbow drops onto its bar or milestone), placed bar labels after the outgoing arrow, kept right-hand labels inside "Fit" and added a Task column width setting with wrapping on up to 6 lines. The visual makes no network request.

**New in version 1.3.0.0 (30/10/2026):** Format pane reorganized (`view.*` → `layout.*`, `timeline.*` → `timeAxis.*`, row sort in **Sort**, labels in **Labels**); free parity with Microsoft's Gantt: vertical and horizontal gridlines, milestone lines, bar border, "Progress complete at", non-working day color, header background, axis start / end (fixed or `timeAxis.min` / `timeAxis.max` measures); opens framed on the whole plan.

### 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 (`style.customColors` and the colors under it) are **free**; every other `style.preset`, the other gradient palettes (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium** (watermark without a key). See "Styles and theme JSON" below.
- Using a premium feature without a valid key shows **"Plume Visuals · Premium preview"** (French: « Plume Visuals · Aperçu premium ») in the footer of the visual, with an "Unlock →" link to the pricing page. It disappears once a key is pasted in **Format › Plume Studio License › License key** (`license.key`; French: « Licence Plume Studio › Clé de licence »), the **first card** of the Format pane.
- Premium features of Gantt Plume (the watermark shows only when one of them is actually in use):
  - the **Predecessors ★** field with `dependencies.show` or `critical.show` on (cards "Dependencies ★" and "Critical path ★"); `critical.show` is off by default, `dependencies.show` on;
  - the **Baseline start ★ / Baseline end ★** fields with `baseline.show` on (card "Baseline ★");
  - the **Bar color (measure) ★** field, as soon as it returns a color for a bar;
  - `dataColors.mode` = `status` ("Computed status (late, at risk…) ★");
  - `layout.mode` = `resources` ("Resources (one row per owner) ★") and `layout.fit` ("Whole plan in the frame (PDF export) ★");
  - `rows.rollup` = `milestones` or `all` ("Collapsed group: detail on its row ★") when there are groups;
  - a date marker or the shaded period of the Analytics pane card "Date markers ★" (`markers.show1`… with a date, `markers.band` with both dates).
- Premium options and list values have " ★" appended to their label and the description "Premium feature: usable for free with a « Premium preview » watermark…".
- Accepted keys: only keys starting with `PLUM1.` shown in the buyer's account on plumevisuals.com, checked offline (Ed25519 signature), covering `gantt-chart` 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". `license.showOwner` displays "Licensed to <holder>".
- Licenses last one year (one-time payment, no automatic renewal, key accepted for 30 more days, reminders 30 and 7 days before the end), for this visual: 39 € personal, 99 € SME, 299 € enterprise per year, or the catalog packs (199 € / 399 € / 1,199 € per year; tiers by number of users, designers and viewers included: personal 1–10, SME 11–200, enterprise more than 200).
- Status: Available, version 1.2.1.0, installed from the `.pbiviz` file (AppSource submission in progress). The License card starts with a read-only line "Get a license: plumevisuals.com" (`license.buy`, never read by the visual).

### Expected data shape

A **categorical** data view: one category per task field (all text and date fields are categories, combined row by row), measures for duration, progress, bar color, tooltips and dynamic format. One row of the source table = one task (or one bar).

| ID | Project | Phase | Task | Start | Finish | Baseline start | Baseline finish | Owner | Team | Milestone | Predecessors | % complete |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| A2 | Bordeaux store | Studies | Lease signed | 2026-05-18 | 2026-05-18 | 2026-05-18 | 2026-05-18 | Hugo Lambert | Management | Yes | A1 | 1.00 |
| A3 | Bordeaux store | Studies | Building permit | 2026-05-19 | 2026-07-30 | 2026-05-19 | 2026-07-14 | Paul Martin | Works | | A2 | 1.00 |
| A6 | Bordeaux store | Works | Electrics and lighting | 2026-08-26 | 2026-09-11 | 2026-08-10 | 2026-08-25 | Karim Haddad | Works | | A4SS+18 | 1.00 |

- **Groups (project, phase…)** (`groups`, « Groupes (projet, phase…) », columns, up to 6, from the widest to the narrowest): the hierarchy; no parent-ID column is needed.
- **Task** (`task`, « Tâche », column, required).
- **Start** (`start`, « Début », column, required): a date column (choose the field itself, not its Date Hierarchy). ISO text dates with time, time zone or "Z", and `dd/mm/yyyy hh:mm:ss` are read too; dates outside 1900–2200 (e.g. 12/31/9999 for "no end") are ignored and reported in edit mode.
- **End** (`end`, « Fin », column) or **Duration (when there is no end)** (`duration`, « Durée (s'il n'y a pas de fin) », measure, added to the start in `timeAxis.durationUnit`, business days by default). A task with no end and no duration is a milestone.
- **Progress (%)** (`progress`, « Avancement (%) », measure): 0–1 or 0–100.
- **Owner / resource** (`resource`, « Responsable / ressource », column): grid column, coloring by owner, resource view.
- **Color (team, type…)** (`legend`, « Couleur (équipe, type…) », column): one color per value, chosen in Data colors and remembered per value (hidden `state.colors`).
- **Bar label** (`label`, « Étiquette », column): the text on the bar; replaces "Task and owner" when filled (`labels.content` = `field` forces it).
- **Bar color (measure) ★** (`barColor`, « Couleur des barres (mesure) ★ », measure): `#RRGGBB` or a color name; it wins over every coloring mode; a blank value keeps the usual color.
- **Milestone (yes / no)** (`milestone`, « Jalon (oui / non) », column): Yes / No, Oui / Non, True / False, 1 / 0 or "x"; any other non-empty text also makes a milestone and is shown as its type.
- **Task ID (for dependencies)** (`id`, « Identifiant (pour les dépendances) », column): referenced by Predecessors; also the "Data order (ID)" sort.
- **Sort order** (`sort`, « Ordre de tri », column): number, date or text (natural sort: "Lot 2" before "Lot 10"; ISO dates as text; blanks last); ranks tasks and groups, `sort.by` only breaks ties.
- **Predecessors ★** (`predecessors`, « Prédécesseurs ★ », column): see below.
- **Baseline start ★ / Baseline end ★** (`baselineStart`, `baselineEnd`, « Début / Fin de référence ★ », columns).
- **Grid columns** (`columns`, « Colonnes du tableau », columns, up to 8): extra grid columns, numeric ones summed on group rows when `grid.sumColumns` is on.
- **Tooltips** (`tooltips`, « Infobulles », measures) and **Dynamic format** (`format`, « Format dynamique », measures, never drawn).
- Volume: 30,000 rows per data window, more fetched automatically up to 100,000 rows; beyond, filter the page. Thousands of rows scroll virtually.

### DAX recipes

```dax
Progress = AVERAGE ( Tasks[% complete] )                   // 0–1, or 0–100

// Bar color ★: red for a task whose end has passed while it is not complete, blank = usual color
Alert color =
IF (
    MAX ( Tasks[% complete] ) < 1 && MAX ( Tasks[Finish] ) < DATE ( 2026, 10, 15 ),
    "#C0392B"
)

// Duration from a number of business days (when there is no End column)
Duration (days) = SUM ( Tasks[Days] )
```

### Dependencies and critical path ★

- **Predecessors** syntax (MS Project): IDs separated by `;` or `,`, each optionally followed by a link type and a lag: `3;5SS+2;8FF-1d` (English types FS, SS, FF, SF) or `3;5DD+2;8FF-1j` (French types FD, DD, FF, DF). No type = FS (finish → start). Lag units: days (`d`, `j`; business or calendar days following `timeAxis.durationUnit`), calendar days (`ed`, `ej`), hours (`h`), weeks (`w`, `sem`), months (`mo`, `mois`), `%` of the predecessor's duration; a decimal comma is accepted (`+1,5j`).
- The visual never moves tasks: dates always come from the data. Arrows are elbow lines; a successor that starts too early is a **conflict** (`dependencies.conflicts`, red by default, also in the tooltip). Hovering a bar highlights its whole upstream and downstream chain (`dependencies.hover`).
- **Critical path** (`critical.show`, off by default): CPM computed on the business-day calendar (weekends, `timeAxis.holidays`), network by network (independent projects each get their own critical path), total float per task (grid column "Float", `grid.colFloat`), `critical.tolerance` = maximum float in days still shown as critical. Circular links are left out of the calculation without breaking the rest.
- Edit-mode warnings: unknown predecessor (an ID absent from the Task ID field, or a task filtered off the page), unknown lag unit (counted in days), circular dependencies, critical path without the Predecessors field.

### Baseline, computed status and bar color ★

- **Baseline** (`baseline.show`, on by default once the baseline fields are filled): a gray bar under each bar (`baseline.color`), the variance in business days at the bar end (`baseline.variance`: ▲ late, ▼ early) and in the grid column "Variance" (`grid.colVariance`); `baseline.tolerance` = accepted variance in days.
- **Computed status** (`dataColors.mode` = `status`): done (progress 100 %), late (end passed and not done, hatched), at risk (expected progress, i.e. elapsed time, minus actual progress greater than `dataColors.tolerance` points, default 10, dashed), on track, upcoming; computed at `layout.statusDate` (empty = today). Without a Progress field: done once the end has passed, upcoming before the start, on track in between; a group takes the most worrying status of its tasks. Colors `dataColors.done`, `onTrack`, `risk`, `late`, `upcoming`; grid column "Status" (`grid.colStatus`). The status is always written in words and with a pill, never by color alone.
- **Bar color (measure)**: see the `barColor` field above; it wins over `dataColors.mode`.

### Collapsed groups, resource view and one-page plan ★

- `rows.rollup` ("Collapsed group: detail on its row ★"): `none` (summary bar only, default), `milestones` (task milestones with their names on a pill), `all` (task bars and milestones). Like the MS Project rollup; labels never overlap; hover and click act on the task itself.
- `layout.mode` = `resources`: one row per owner, tasks stacked in lanes, overlaps in red, task count; requires the Owner field (warning otherwise); more than 40 simultaneous tasks for one owner overlap.
- `layout.fit`: no scrolling, every row and the whole period fit in the visual, for printing, PDF / PowerPoint export and subscriptions.
- Analytics pane, card **Date markers ★** (`markers`): 3 markers (`show1`, `date1`, `label1`, `color1`, `style1` `solid` / `dashed` / `dotted`, same for 2 and 3) and one shaded period (`band`, `bandFrom`, `bandTo`, `bandLabel`, `bandColor`, `bandOpacity`). Dates as `yyyy-mm-dd`.

### Interactions with the report

- Click a bar or a row = select that task (cross-filters other visuals); Ctrl / Shift + click adds to the selection; click a legend value selects the series (`legend.interactive`); context menu; Power BI tooltips with dates, duration, progress, owner and the Tooltips measures (★ extras: status and expected progress, predecessors, successors, float, conflict, variance).
- Toolbar (`toolbar.show`): search a task (keeps its groups), scales and "Fit", expand / collapse all, "Today" button. Ctrl + wheel zooms around the pointer, dragging the background scrolls.
- Keyboard: ↑ ↓ Home End Page Up / Down to move, ← → to collapse or expand, Enter / Space to select, Esc to clear, + / − for the scale. ARIA labels for screen readers, high contrast supported, reduced motion respected.
- Saved in the report in edit mode only (persistProperties): expanded groups (hidden `state.expanded`, when `rows.remember` is on), per-value colors (`state.colors`), the grid width after dragging the splitter (`grid.width`, double-click = automatic) and the scale picked in the toolbar (`timeAxis.scale`). In reading mode these are kept in memory only.
- Other visuals cross-filter Gantt Plume (it does not support highlighting).

### Dynamic formats

- **fx button** (Power BI conditional formatting) on every color and every text of the Format pane: *Field value*, *Rules*, *Gradient*, e.g. `layout.statusDate` or `timeAxis.todayColor`.
- **Dynamic format** field (role `format`, several measures): a measure renamed for this visual as `card.setting` (right-click › Rename for this visual) drives **any** setting, e.g. `layout.statusDate`, `layout.startDate` (with `layout.startAt` = `date`), `timeAxis.scale`, `critical.show`, `rows.startLevel`. It wins over the fixed value, the style and an fx rule; its measures are never drawn. Names ignore case, accents and separator.
- Value used: the common value of all rows, else the total, else the first row. Wrap with `CALCULATE ( …, ALLSELECTED () )` for a whole-visual value. Examples: `IF ( HASONEVALUE ( Tasks[Project] ), "week", "month" )` renamed `timeAxis.scale`; `FORMAT ( MAX ( Tasks[Start] ), "yyyy-mm-dd" )` renamed `layout.startDate`.
- Driving a setting with DAX is free; a ★ value set by DAX still shows the watermark without a key.

### Format pane: how to read the tables below

- Each option has an ID `card.option` (for example `timeAxis.scale`). The card is the capabilities.json **object name**, the option is the **property name**.
- Card order: `license` (always first), `style` (shared Style card), `dataColors`, `view` (Display), `timeline`, `grid` (Task grid), `rows` (Rows and hierarchy), `bars`, `milestones`, `dependencies`, `critical`, `baseline`, `legend`, `toolbar`, `interaction`, then `title`, `source`, `container` and `texts`; `markers` is in the **Analytics** pane. `state` is hidden. Format pane in version 1.3.0.0 (30/10/2026), top to bottom: `license`, `style`, `layout`, `dataColors`, `grid`, `rows`, `bars`, `milestones`, `dependencies`, `critical`, `baseline`, `labels`, `timeAxis`, `gridlines`, `legend`, `sort`, `toolbar`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`; Analytics pane: `markers`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- Labels follow the language of Power BI Desktop; `texts.language` can force French or English inside the visual.
- "Visible when" means the option only appears when another option has one of the listed values.

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. Literal syntax: booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes, colors wrapped in `solid.color`.

```json
{
  "visualType": "plumeGanttChartB2FEC518BC294539ACD7EE04DBA8CFE8",
  "query": {
    "queryState": {
      "groups": { "projections": [
        { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Tasks" } }, "Property": "Project" } }, "queryRef": "Tasks.Project", "nativeQueryRef": "Project" },
        { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Tasks" } }, "Property": "Phase" } }, "queryRef": "Tasks.Phase", "nativeQueryRef": "Phase" } ] },
      "task": { "projections": [
        { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Tasks" } }, "Property": "Task" } }, "queryRef": "Tasks.Task", "nativeQueryRef": "Task" } ] },
      "start": { "projections": [
        { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Tasks" } }, "Property": "Start" } }, "queryRef": "Tasks.Start", "nativeQueryRef": "Start" } ] },
      "end": { "projections": [
        { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Tasks" } }, "Property": "Finish" } }, "queryRef": "Tasks.Finish", "nativeQueryRef": "Finish" } ] },
      "progress": { "projections": [
        { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Tasks" } }, "Property": "Progress" } }, "queryRef": "Tasks.Progress", "nativeQueryRef": "Progress" } ] },
      "id": { "projections": [
        { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Tasks" } }, "Property": "ID" } }, "queryRef": "Tasks.ID", "nativeQueryRef": "ID" } ] },
      "predecessors": { "projections": [
        { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Tasks" } }, "Property": "Predecessors" } }, "queryRef": "Tasks.Predecessors", "nativeQueryRef": "Predecessors" } ] }
    }
  },
  "objects": {
    "view":       [ { "properties": { "statusDate": { "expr": { "Literal": { "Value": "'2026-10-15'" } } } } } ],
    "timeline":   [ { "properties": { "scale": { "expr": { "Literal": { "Value": "'month'" } } },
                                      "holidays": { "expr": { "Literal": { "Value": "'2026-12-25; 2027-01-01'" } } } } } ],
    "rows":       [ { "properties": { "startLevel": { "expr": { "Literal": { "Value": "1D" } } } } } ],
    "dataColors": [ { "properties": { "mode": { "expr": { "Literal": { "Value": "'status'" } } } } } ],
    "critical":   [ { "properties": { "show": { "expr": { "Literal": { "Value": "true" } } } } } ],
    "license":    [ { "properties": { "key": { "expr": { "Literal": { "Value": "'PLUM1.…'" } } } } } ]
  }
}
```

The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from the `.pbiviz` file). Do not write the hidden `state` properties by hand.

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`. Gantt-specific touches: *Minimal* drops banded rows and vertical lines, *Unknown Pleasures* drops banded rows, *Neon* makes the bars glow.
- `style.themeJson` (Format › Style › Theme JSON ★) takes a JSON theme as plain text. Format v2: an object with an optional `extends` (a style ID above) and optional groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`; the v1 flat format (`style`, `palette`, `accent`, `background`…) is still read. Every field is optional. Colors are `#RRGGBB` (`#RGB` and `#RRGGBBAA` accepted, opacity ignored). Unknown fields and values outside the allowed lists are ignored, out-of-range numbers are clamped. Invalid JSON shows "Invalid theme JSON: ignored" in edit mode and the visual keeps its look.
- Full field list with allowed values, examples and troubleshooting: tutorial https://plumevisuals.com/ai/tutorials/en/themes-json.md (French: https://plumevisuals.com/ai/tutorials/fr/themes-json.md). The same JSON can be pasted in every Plume visual of a page.
- Priority (the last one wins): visual defaults → `style.preset` → `style.themeJson` → `style.palette` (if not "Style or theme palette") → `style.followTheme` → custom colors → options set by hand in the other cards → DAX formats (fx button, "Dynamic format" field) → Windows high contrast.

### Common pitfalls

- No bars and a message about a date hierarchy: the date field arrived as Power BI's "Date Hierarchy"; in the field well, pick the column itself.
- Tasks shown as milestones: no End and no Duration, or the Milestone field says yes.
- Durations look too long: `timeAxis.durationUnit` is `workdays` by default (weekends and `timeAxis.holidays` are skipped); `timeAxis.endInclusive` (on by default) counts the end date as a full day for dates without time.
- "Unknown predecessor": the ID is not in the Task ID field (IDs are matched case-insensitively), or that task is filtered off the page, which also cuts the critical path.
- No critical path: `critical.show` is off by default, or the Predecessors field is empty.
- The plan ignores `rows.startLevel`: `rows.remember` kept groups expanded by hand in edit mode; change the level or turn `rows.remember` off.
- The timeline opens on today instead of the plan: `layout.startAt` is `today` by default; use `start`, `end` or `date` with `layout.startDate`.
- Resource view empty: the Owner / resource field is missing.
- Watermark visible: dependencies or critical path with the Predecessors field, the baseline fields, the bar color measure, the computed status, the resource view, "Whole plan in the frame", a rollup of collapsed groups, a date marker, a ★ style or palette, or a Theme JSON is in use without a valid key.
- More than 100,000 rows: the visual stops loading and says so in edit mode; filter the page (project, period).

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

Moving or resizing bars with the mouse (no write-back to the source), automatic rescheduling of tasks from their dependencies (dates always come from the data), several date columns per row turned into automatic phases, export split over several pages, resource leveling, costs or earned value calculations, drill-down / drill-through buttons, highlighting from other visuals, an fx button on non-color, non-text options (use the Dynamic format field).

## Gantt Plume: data fields

- `groups` Groups (project, phase…) / Groupes (projet, phase…) (column, 6 max): One field per hierarchy level, from the widest to the narrowest
- `task` Task / Tâche (column, 1 max): 
- `start` Start / Début (column, 1 max): A date column (choose the field itself, not its date hierarchy)
- `end` End / Fin (column, 1 max): 
- `duration` Duration (when there is no end) / Durée (s'il n'y a pas de fin) (measure, 1 max): 
- `progress` Progress (%) / Avancement (%) (measure, 1 max): 
- `resource` Owner / resource / Responsable / ressource (column, 1 max): 
- `legend` Color (team, type…) / Couleur (équipe, type…) (column, 1 max): 
- `label` Bar label / Étiquette (column, 1 max): Text shown on the bar (e.g. status, phase, short note)
- `barColor` Bar color (measure) ★ / Couleur des barres (mesure) ★ ★ (measure, 1 max): A measure returning a color (#RRGGBB or a name), e.g. red when late
- `milestone` Milestone (yes / no) / Jalon (oui / non) (column, 1 max): 
- `id` Task ID (for dependencies) / Identifiant (pour les dépendances) (column, 1 max): 
- `sort` Sort order / Ordre de tri (column, 1 max): Number, date or text: tasks (and groups) are sorted by it
- `predecessors` Predecessors ★ / Prédécesseurs ★ ★ (column, 1 max): IDs separated by ; e.g. 3;5SS+2
- `baselineStart` Baseline start ★ / Début de référence ★ ★ (column, 1 max): 
- `baselineEnd` Baseline end ★ / Fin de référence ★ ★ (column, 1 max): 
- `columns` Grid columns / Colonnes du tableau (column, 8 max): 
- `tooltips` Tooltips / Infobulles (measure, several max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Gantt Plume: Format pane options (210)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Layout / Disposition (`layout`)
- `layout.mode` View / Vue: dropdown, default `tasks`; values: `tasks` Tasks (hierarchy); `resources` Resources (one row per owner) ★
- `layout.fit` Whole plan in the frame (PDF export) ★ / Tout le planning dans le cadre (export PDF) ★ ★: toggle, default `false`; values: true / false. No scrolling: every row and the whole timeline fit in the visual, for printing and PDF or PowerPoint export.
- `layout.startAt` Initial position / Position au départ: dropdown, default `start`; values: `start` Start of the plan; `today` Today (status date); `end` End of the plan; `date` Chosen date. With the automatic scale, the whole plan is framed when the visual opens.
- `layout.startDate` Initial date (yyyy-mm-dd) / Date de départ (aaaa-mm-jj): text, default (empty). Visible when `layout.startAt` = `date`. The timeline opens at this date (it can come from a DAX measure with the Dynamic format field: layout.startDate).
- `layout.statusDate` Status date (empty = today) / Date d'état (vide = aujourd'hui): text, default (empty). Date used for the today line, the computed status and the expected progress.

### Data colors / Couleurs des données (`dataColors`, one entry per item with a selector)
- `dataColors.mode` Coloring / Coloration: dropdown, default `auto`; values: `auto` Automatic (Color field, else first group); `legend` By the Color field; `group` By the first group; `resource` By owner; `single` Single color; `status` Computed status (late, at risk…) ★
- `dataColors.single` Color / Couleur: color, default (empty); values: hex color
- `dataColors.fill` Color / Couleur: color, default (empty); values: hex color
- `dataColors.summary` Summary bars (empty = text) / Barres de synthèse (vide = texte): color, default (empty); values: hex color
- `dataColors.done` Status: done / Statut : terminé: color, default `#2E7D4F`; values: hex color
- `dataColors.onTrack` Status: on track / Statut : dans les temps: color, default `#2A6F97`; values: hex color
- `dataColors.risk` Status: at risk / Statut : à risque: color, default `#B26B00`; values: hex color
- `dataColors.late` Status: late / Statut : en retard: color, default `#C0392B`; values: hex color
- `dataColors.upcoming` Status: upcoming / Statut : à venir: color, default `#7C8190`; values: hex color
- `dataColors.tolerance` “At risk” beyond (points behind) / « À risque » au-delà de (points de retard): number, default `10`; values: 0 to 50. Expected progress (elapsed time) minus actual progress, in percentage points.

### Task grid / Tableau des tâches (`grid`)
- `grid.show` Show / Afficher: toggle, default `true`; values: true / false
- `grid.width` Width (px, 0 = automatic) / Largeur (px, 0 = automatique): number, default `0`; values: 0 to 3000. Drag the separator between the grid and the timeline to change it.
- `grid.fontSize` Text size / Taille du texte: number, default `12`; values: 7 to 20
- `grid.dateFormat` Date format / Format des dates: text, default (empty)
- `grid.indent` Indent per level (px) / Retrait par niveau (px): number, default `14`; values: 4 to 40
- `grid.nameWidth` Task column width (px, 0 = automatic) / Largeur de la colonne Tâche (px, 0 = automatique): number, default `0`; values: 0 to 1200. Width of the name column. The other columns keep their width; those that no longer fit are hidden. Turn on Wrap long names to keep long names readable.
- `grid.wrap` Wrap long names / Retour à la ligne des noms longs: toggle, default `false`; values: true / false. A name that does not fit goes on several lines (its row gets taller) instead of being cut.
- `grid.wrapLines` Maximum lines / Lignes au plus: number, default `3`; values: 2 to 6. Visible when `grid.wrap` = `true`. Beyond this, the last line is cut with an ellipsis.
- `grid.sumColumns` Sum numeric columns in groups / Totaliser les colonnes numériques des groupes: toggle, default `true`; values: true / false
- `grid.headerColor` Column header color (empty = secondary text) / Couleur des en-têtes de colonnes (vide = texte secondaire): color, default (empty); values: hex color
- `grid.colWbs` No. (1, 1.1, 1.1.1…) / N° (1, 1.1, 1.1.1…): toggle, default `false`; values: true / false. Outline number of each row, as in Microsoft Project (WBS), following the displayed order.
- `grid.colResource` Owner / Responsable: toggle, default `true`; values: true / false
- `grid.colStart` Start / Début: toggle, default `true`; values: true / false
- `grid.colEnd` End / Fin: toggle, default `true`; values: true / false
- `grid.colDuration` Duration / Durée: toggle, default `false`; values: true / false
- `grid.colProgress` Progress / Avancement: toggle, default `true`; values: true / false
- `grid.colStatus` Status (computed status) / Statut (statut calculé): toggle, default `true`; values: true / false
- `grid.colFloat` Float (critical path) / Marge (chemin critique): toggle, default `true`; values: true / false
- `grid.colVariance` Variance (baseline) / Écart (planning de référence): toggle, default `true`; values: true / false

### Rows and hierarchy / Lignes et hiérarchie (`rows`)
- `rows.height` Row height (px) / Hauteur des lignes (px): number, default `28`; values: 14 to 72
- `rows.startLevel` Levels expanded at start / Niveaux développés au départ: number, default `9`; values: 0 to 9. 0: only the first level is shown. 1: its children are shown too…
- `rows.remember` Save the state in the report (edit mode) / Mémoriser l'état dans le rapport (mode édition): toggle, default `true`; values: true / false
- `rows.summary` Group summary bars / Barres de synthèse des groupes: toggle, default `true`; values: true / false
- `rows.rollup` Collapsed group: detail on its row ★ / Groupe réduit : détail sur sa ligne ★ ★: dropdown, default `none`; values: `none` Summary bar only; `milestones` Task milestones; `all` Task bars and milestones. Like the Microsoft Project rollup: a collapsed project shows its milestones (with their names) and bars on one line, to compare many projects.
- `rows.sameRow` Same task = same row (several bars) / Même tâche = même ligne (plusieurs barres): toggle, default `true`; values: true / false. Rows with the same task name in the same group share one line (absences, machines, split tasks).

### Bars / Barres (`bars`)
- `bars.height` Height (% of the row) / Hauteur (% de la ligne): number, default `58`; values: 20 to 100
- `bars.radius` Rounded corners / Coins arrondis: number, default `3`; values: 0 to 12
- `bars.progress` Progress inside the bar / Avancement dans la barre: toggle, default `true`; values: true / false
- `bars.maxProgress` Progress complete at / Avancement terminé à: dropdown, default `auto`; values: `auto` Automatic (1 or 100); `1` 1 (100%); `100` 100. Value of the Progress field that means “done”, as the Maximum completion of the Microsoft Gantt.
- `bars.borderWidth` Border width / Épaisseur de la bordure: number, default `0`; values: 0 to 4
- `bars.borderColor` Border color (empty = bar color) / Couleur de la bordure (vide = couleur de la barre): color, default (empty); values: hex color

### Milestones / Jalons (`milestones`)
- `milestones.shape` Shape / Forme: dropdown, default `diamond`; values: `diamond` Diamond; `circle` Circle; `triangle` Triangle; `square` Square
- `milestones.size` Size (px) / Taille (px): number, default `12`; values: 6 to 28
- `milestones.color` Color (empty = task color) / Couleur (vide = couleur de la tâche): color, default (empty); values: hex color
- `milestones.showDate` Date in the label / Date dans l'étiquette: toggle, default `true`; values: true / false
- `milestones.line` Vertical line / Ligne verticale: toggle, default `false`; values: true / false. A line across the whole plan at each milestone date.
- `milestones.lineColor` Line color (empty = milestone color) / Couleur de la ligne (vide = couleur du jalon): color, default (empty); values: hex color. Visible when `milestones.line` = `true`
- `milestones.lineStyle` Line style / Style du trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `milestones.line` = `true`
- `milestones.lineOpacity` Opacity (%) / Opacité (%): number, default `60`; values: 10 to 100. Visible when `milestones.line` = `true`

### Dependencies ★ / Dépendances ★ (`dependencies`)
- `dependencies.show` Show / Afficher: toggle, default `true`; values: true / false
- `dependencies.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `dependencies.width` Width / Épaisseur: number, default `1.2`; values: 0.5 to 4
- `dependencies.conflicts` Flag conflicts (successor too early) / Signaler les conflits (successeur trop tôt): toggle, default `true`; values: true / false
- `dependencies.conflictColor` Conflict color / Couleur des conflits: color, default `#C0392B`; values: hex color. Visible when `dependencies.conflicts` = `true`
- `dependencies.hover` Follow the chain on hover / Suivre la chaîne au survol: toggle, default `true`; values: true / false

### Critical path ★ / Chemin critique ★ (`critical`)
- `critical.show` Show / Afficher: toggle, default `false`; values: true / false. Computed from the dependencies: tasks whose delay delays the end of the plan.
- `critical.color` Color / Couleur: color, default `#C0392B`; values: hex color
- `critical.tolerance` Maximum float (days) / Marge maximale (jours): number, default `0`; values: 0 to 30

### Baseline ★ / Planning de référence ★ (`baseline`)
- `baseline.show` Show / Afficher: toggle, default `true`; values: true / false
- `baseline.color` Color (empty = gray) / Couleur (vide = gris): color, default (empty); values: hex color
- `baseline.variance` Variance in days at the bar end / Écart en jours en bout de barre: toggle, default `true`; values: true / false
- `baseline.tolerance` Accepted variance (days) / Écart toléré (jours): number, default `0`; values: 0 to 30

### Data labels / Étiquettes de données (`labels`)
- `labels.show` Show / Afficher: toggle, default `true`; values: true / false
- `labels.content` Content / Contenu: dropdown, default `nameResource`; values: `nameResource` Task and owner; `name` Task; `resource` Owner; `progress` Progress; `dates` Dates; `field` “Bar label” field; `none` None. When the Bar label field is filled, it replaces “Task and owner”.
- `labels.position` Position: dropdown, default `right`; values: `right` Right of the bar; `inside` Inside the bar when long enough; `left` Left of the bar
- `labels.fontSize` Size / Taille: number, default `10`; values: 6 to 18
- `labels.bold` Bold / Gras: toggle, default `false`; values: true / false
- `labels.italic` Italic / Italique: toggle, default `false`; values: true / false
- `labels.color` Color (empty = automatic) / Couleur (vide = automatique): color, default (empty); values: hex color

### Time axis / Axe du temps (`timeAxis`)
- `timeAxis.scale` Initial scale / Échelle au départ: dropdown, default `auto`; values: `auto` Automatic (whole plan, adapted ticks); `fit` Fit all; `hour` Hours; `day` Days; `week` Weeks; `month` Months; `quarter` Quarters; `year` Years. The reader can change it with the toolbar or Ctrl + mouse wheel.
- `timeAxis.weekStart` First day of the week / Premier jour de la semaine: dropdown, default `monday`; values: `monday` Monday; `sunday` Sunday
- `timeAxis.weekNumbers` Week numbers / Numéros de semaine: toggle, default `true`; values: true / false
- `timeAxis.fiscalStart` Fiscal year start (quarters, years) / Début de l'exercice (trimestres, années): dropdown, default `1`; values: `1` January; `2` February; `3` March; `4` April; `5` May; `6` June; `7` July; `8` August; `9` September; `10` October; `11` November; `12` December
- `timeAxis.min` Axis start (yyyy-mm-dd) / Début de l'axe (aaaa-mm-jj): text, default (empty). Fixed start of the timeline. Keep the same frame under a filter with a DAX measure in the Dynamic format field named timeAxis.min, e.g. CALCULATE(MIN(Tasks[Start]), REMOVEFILTERS()).
- `timeAxis.max` Axis end (yyyy-mm-dd) / Fin de l'axe (aaaa-mm-jj): text, default (empty). Fixed end of the timeline (DAX: a timeAxis.max measure).
- `timeAxis.weekends` Shade weekends / Griser les week-ends: toggle, default `true`; values: true / false
- `timeAxis.weekendColor` Days off color (empty = gray) / Couleur des jours non ouvrés (vide = grisé): color, default (empty); values: hex color. Visible when `timeAxis.weekends` = `true`
- `timeAxis.holidays` Holidays (yyyy-mm-dd; …) / Jours fériés (aaaa-mm-jj ; …): text, default (empty)
- `timeAxis.endInclusive` End date included / Date de fin incluse: toggle, default `true`; values: true / false. A task from the 3rd to the 5th lasts 3 days (dates without time).
- `timeAxis.durationUnit` Durations counted in / Durées comptées en: dropdown, default `workdays`; values: `workdays` Business days; `days` Calendar days; `hours` Hours. Also used to add the Duration field to the start date.
- `timeAxis.fontSize` Size / Taille: number, default `9`; values: 6 to 18
- `timeAxis.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `timeAxis.headerBg` Header background color / Couleur d'arrière-plan de l'en-tête: color, default (empty); values: hex color. Background of the time header and of the grid column headers (empty = none).
- `timeAxis.monthStyle` Month names / Noms des mois: dropdown, default `auto`; values: `auto` Automatic (as space allows); `long` Full (January); `short` Short (Jan); `narrow` Initial (J); `numeric` Number (01)
- `timeAxis.hourCycle` Hours / Heures: dropdown, default `auto`; values: `auto` As the language; `h24` 24-hour (14:00); `h12` 12-hour (2:00 PM). Timeline, grid dates and tooltips.
- `timeAxis.quarterFormat` Quarter format / Format des trimestres: text, default (empty). q = quarter, yyyy or yy = year (with a fiscal year: the year it ends), other Power BI date codes accepted. Empty: Q1, Q2…
- `timeAxis.yearFormat` Year format / Format des années: text, default (empty). yyyy or yy = year (with a fiscal year: the year it ends). Empty: 2026, or FY 2026-27 with a fiscal year.
- `timeAxis.todayLine` “Today” line / Ligne « aujourd'hui »: toggle, default `true`; values: true / false
- `timeAxis.todayColor` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color. Visible when `timeAxis.todayLine` = `true`
- `timeAxis.todayLabel` Line label / Texte du repère: text, default (empty). Visible when `timeAxis.todayLine` = `true`

### Gridlines / Quadrillage (`gridlines`)
- `gridlines.vertical` Vertical (ticks) / Verticales (graduations): toggle, default `true`; values: true / false
- `gridlines.verticalColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `gridlines.vertical` = `true`
- `gridlines.verticalStyle` Line style / Style du trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `gridlines.vertical` = `true`
- `gridlines.horizontal` Horizontal (between rows) / Horizontales (entre les lignes): toggle, default `false`; values: true / false
- `gridlines.horizontalColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `gridlines.horizontal` = `true`
- `gridlines.width` Width / Épaisseur: number, default `1`; values: 0.5 to 4
- `gridlines.banding` Banded rows / Lignes alternées: toggle, default `true`; values: true / false

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

### Sort / Tri (`sort`)
- `sort.by` Sort tasks by / Trier les tâches par: dropdown, default `start`; values: `start` Start date; `end` End date; `name` Name; `data` Data order (ID). Applied inside each group. Data order follows the Task ID field when there is one. With the Sort order field, this order only breaks ties.
- `sort.groupBy` Sort groups by / Trier les groupes par: dropdown, default `same`; values: `same` Same as tasks; `start` Start date; `end` End date; `name` Name; `data` Data order (ID). Projects and phases can follow their own order (e.g. by name) while tasks follow the plan.
- `sort.desc` Descending order / Ordre décroissant: toggle, default `false`; values: true / false

### Toolbar / Barre d'outils (`toolbar`)
- `toolbar.show` Show / Afficher: toggle, default `true`; values: true / false
- `toolbar.search` Search / Recherche: toggle, default `true`; values: true / false
- `toolbar.zoom` Scales and “Fit” / Échelles et « Tout voir »: toggle, default `true`; values: true / false
- `toolbar.expand` Expand / collapse all / Tout développer / réduire: toggle, default `true`; values: true / false
- `toolbar.today` “Today” button / Bouton « Aujourd'hui »: toggle, default `true`; values: true / false

### Interactions (`interaction`)
- `interaction.hover` Highlight on hover / Mettre en avant au survol: toggle, default `true`; values: true / false
- `interaction.dim` Dimmed items opacity (%) / Opacité des éléments estompés (%): number, default `25`; values: 5 to 80

### Date markers ★ / Repères de date ★ (`markers`, Analytics pane)
- `markers.show1` Show / Afficher: toggle, default `false`; values: true / false
- `markers.date1` Date (yyyy-mm-dd) / Date (aaaa-mm-jj): text, default (empty)
- `markers.label1` Label / Libellé: text, default (empty)
- `markers.color1` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `markers.style1` Line style / Style du trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `markers.show2` Show / Afficher: toggle, default `false`; values: true / false
- `markers.date2` Date (yyyy-mm-dd) / Date (aaaa-mm-jj): text, default (empty)
- `markers.label2` Label / Libellé: text, default (empty)
- `markers.color2` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `markers.style2` Line style / Style du trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `markers.show3` Show / Afficher: toggle, default `false`; values: true / false
- `markers.date3` Date (yyyy-mm-dd) / Date (aaaa-mm-jj): text, default (empty)
- `markers.label3` Label / Libellé: text, default (empty)
- `markers.color3` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `markers.style3` Line style / Style du trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `markers.band` Show / Afficher: toggle, default `false`; values: true / false
- `markers.bandFrom` From (yyyy-mm-dd) / Du (aaaa-mm-jj): text, default (empty)
- `markers.bandTo` To (yyyy-mm-dd) / Au (aaaa-mm-jj): text, default (empty)
- `markers.bandLabel` Label / Libellé: text, default (empty)
- `markers.bandColor` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `markers.bandOpacity` Opacity (%) / Opacité (%): number, default `10`; values: 2 to 60

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Candle Plume

- A real stock chart in Power BI: candles with no weekend gaps, from one minute to one year, volume, moving averages and 60+ indicators.
- Slug `candle-chart` · version 1.1.0.0 · GUID (`visualType`) `plumeCandleChart4DCBF4C29CE24C99BB068D8F6EC07CA0` · page https://plumevisuals.com/en/visuals/candle-chart

### What the visual does

Candle Plume (identifier `candle-chart`) is a Power BI custom visual (version 1.1.0.0, installed from its `.pbiviz` file; AppSource submission in progress) that draws **candlestick (OHLC) stock charts**. Power BI Desktop has no native candlestick chart (only paginated reports have one).

**New in version 1.1.0.0 (30/10/2026):** Format pane reorganized (`chartType` → `layout`, `priceAxis` → `yAxis`, gridlines in **Gridlines**, crosshair legend in **Legend**); Symbol read as a second category (no more 1,000-point limit), automatic chart type (line with the Price field only), position labels without overlap, wrapped annotations; free price-axis min / max (fixed or measures) and title.

- **No weekend gaps**: by default the time axis has one bar per step (`data.axis` = `bars`), so weekends, holidays and nights without data take no room; `time` spaces bars by real time.
- **Timeframes computed in the visual**: the granularity of the data is detected (median gap), then bars are grouped **up only** into 1m, 5m, 15m, 30m, 1H, 4H, 1D, 1W, 1M, 3M (quarter) or 1Y (open = first, high = max, low = min, close = last, volume = sum, events concatenated with their count, position state = last). Weeks start on Monday, Sunday or Saturday; quarters and years can follow a fiscal year; a market session (`data.session` = `09:00-17:30`) drops rows outside it and aligns 1H / 4H bars on its start.
- **A single price measure is enough**: the `price` role ("Price (single value)") replaces Open, High, Low and Close; the visual builds each bar (e.g. daily copper purchase prices shown as monthly candles).
- **Indicators computed on the bars received, never on the calendar** (a 5-bar average skips weekends). Range buttons (1M, 3M, 6M, YTD, 1Y, 5Y, All) and `data.displayFrom` move the window **without filtering**, so the full history warms up long averages. When history is missing, the visual shows e.g. "SMA 200: 143 / 200 bars".
- Volume pane (or overlay) with its average, legend with OHLC, change and indicator values at the hovered bar, crosshair across panes, mouse wheel zoom, drag to scroll, drag the price axis to stretch it, double-click to reset; the window and timeframe are kept after a filter.
- Several symbols with the `series` role: buttons to switch, or a comparison in % ★.
- Events from measures (`eventText`, `eventType`), click-to-add annotations ★, long / short / neutral positions ★ with result, %, duration, risk / reward, MAE / MFE, statistics panel and equity curve.

### 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 (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium**.
- Free in Candle Plume: candles, hollow candles, OHLC bars, line, area; every timeframe, session, fiscal and week setting; Price (single value); volume and its average; **SMA, EMA** (moving average shortcuts with type `sma` or `ema`) and the price indicators **hl2, hlc3, ohlc4**; the in-visual indicator manager; range buttons and Display from; events from measures; log, percent and indexed scales; series buttons; legend, crosshair, zoom; label backgrounds and "Keep room for the legend".
- Premium features of Candle Plume:
  - `layout.type` = `heikinAshi`, `baseline`, `hlc` or `lineMarkers`;
  - every other indicator: **Bollinger Bands, RSI, MACD** (shortcuts `indicators.bbShow`, `rsiShow`, `macdShow`) and 55 more (list below); moving average types `wma`, `vwma`, `rma`, `dema`, `tema`, `hma`; crossover `signals`; more than one indicator pane;
  - `annotations.list` (manual annotations, also written by the Annotate button);
  - positions: the `position` role (and `entryPrice`, `exitPrice`) or `positions.list` (also written by the Position button);
  - `data.compare` with at least two series; `navigation.navigator`.
- 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 `candle-chart` 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, key accepted for 30 more days, reminders 30 and 7 days before the end). Prices: 39 € personal, 99 € SME, 299 € enterprise per year, or the catalog pack (199 € / 399 € / 1,199 € per year; tiers by number of users: personal 1–10, SME 11–200, enterprise more than 200).

### Expected data shape

One row per bar of the source data (per date and, with several symbols, per symbol), with measures for the prices.

| Date / time (`time`) | Symbol (`series`) | Open (`open`) | High (`high`) | Low (`low`) | Close (`close`) | Volume (`volume`) |
|---|---|---|---|---|---|---|
| 2025-01-02 | PLUME | 48.10 | 48.90 | 47.80 | 48.60 | 1,210,000 |
| 2025-01-03 | PLUME | 48.60 | 49.40 | 48.20 | 49.10 | 980,000 |

- **Date / time** (`time`, « Date / heure », one column, required): a date or date-time **column**, not the automatic date hierarchy (with the hierarchy you get one bar per year). Text in YYYY-MM-DD is read as a date; any other text gives a category axis in data order, with no grouping.
- **Symbol (series)** (`series`, « Symbole (série) », one column): one series per value; buttons to switch; `data.series` forces one; `data.compare` ★ draws the others as % lines. Up to 30 series.
- **Open, High, Low, Close** (`open`, `high`, `low`, `close`, « Ouverture », « Plus haut », « Plus bas », « Clôture », one measure each). Close (or Price) is required; give all four for real candles.
- **Price (single value)** (`price`, « Prix (valeur unique) », one measure): instead of the four; one price per row (readings, ticks), the visual builds each bar.
- **Volume** (`volume`): volume pane and volume indicators (VWMA, VWAP, OBV, MFI…).
- **Lines on prices** (`overlay`, « Courbes sur les prix », up to 5 measures): target, benchmark, forecast drawn over the prices.
- **Event text** (`eventText`) and **Event type** (`eventType`, text: `buy`, `sell`, `flag`, `circle`, `star`, `diamond` or a letter): a marker on each bar where the text is not empty.
- **Position state ★** (`position`): +1 long, −1 short, 0 out of the market per bar; each change opens or closes a position. **Entry price ★**, **Exit price ★** (`entryPrice`, `exitPrice`): actual execution prices, otherwise the close.
- **Tooltips** (`tooltips`) and **Dynamic format** (`format`, see below).
- Volume of data: windows of 30,000 rows, more fetched with `fetchMoreData` up to Power BI's limit; "Data truncated from …" when Power BI stops. 100,000 minute rows render in about 2.5 s with indicators.

### DAX recipes

```dax
// One row per date and per symbol: a simple sum returns the value
Open price = SUM ( Prices[Open] )
High price = SUM ( Prices[High] )
Low price = SUM ( Prices[Low] )
Close price = SUM ( Prices[Close] )
Traded volume = SUM ( Prices[Volume] )

// Raw ticks: OHLC of each date (or simply use the Price role)
Open = VAR _first = MIN ( Ticks[Timestamp] ) RETURN CALCULATE ( MAX ( Ticks[Price] ), Ticks[Timestamp] = _first )
Close = VAR _last = MAX ( Ticks[Timestamp] ) RETURN CALCULATE ( MAX ( Ticks[Price] ), Ticks[Timestamp] = _last )

// Event text
Event = SWITCH ( MAX ( Prices[Date] ), DATE ( 2025, 3, 14 ), "Supplier price increase", BLANK () )

// Position state ★: long when the 20-day average is above the 50-day average (computed in the model)
Position state = MAX ( Prices[Position] )
```

Do not filter dates with a slicer to zoom: long indicators would start empty. Use the range buttons, `data.range` or `data.displayFrom`.

### Indicator list syntax

`indicators.list` (« Indicateurs (une ligne chacun) », also written by the in-visual **Indicators** manager in edit mode): one line per indicator, `name params [source] [#RRGGBB] [signal=N] [levels=a/b] [from=YYYY-MM-DD] [signals] [hidden]`, e.g. `sma 50`, `ema 200 #C0392B`, `rsi 14 signal=9 levels=80/20 signals`, `bb 20 2 hlc3`, `vwap from=2025-03-03`, `macd 12 26 9`, `ichimoku`, `supertrend 10 3`. Lines starting with `//` are comments; an unreadable line is reported in edit mode and ignored. The same indicator can be added several times.

Indicator IDs (63). Free: `sma`, `ema`, `hl2`, `hlc3`, `ohlc4`. Premium ★: moving averages `wma`, `vwma`, `rma` (SMMA), `dema`, `tema`, `hma`, `lsma`, `alma`, `kama`, `mcginley`, `macross`; bands `bb`, `keltner`, `donchian`, `envelope`; trend `psar`, `supertrend`, `vwap`, `hl52`, `ichimoku`, `alligator`, `fractals`, `zigzag`; momentum panes `rsi`, `macd`, `stoch`, `stochrsi`, `cci`, `willr`, `mom`, `roc`, `ppo`, `ao`, `uo`, `trix`, `tsi`, `cmo`, `dpo`, `fisher`, `bop`, `efi`; strength `adx`, `aroon`, `vortex`, `chop`; volatility `atr`, `stdev`, `bbpct`, `bbw`, `hv`; volume `obv`, `cmf`, `mfi`, `adl`, `chaikin`, `pvt`, `eom`, `volosc`. Aliases: `smma`, `bollinger`, `bbands`, `kc`, `dc`, `sar`, `st`, `williams`, `%r`, `dmi`, `52w`, `ad`, `a/d`, `ichi`, `zz`, `stochastic`, `momentum`. Conventions as TradingView and TA-Lib (Wilder smoothing for RSI, ATR, ADX; EMA seeded by the SMA; population standard deviation).

Manual annotations ★ (`annotations.list`): `date | text | icon | color | position`, e.g. `2025-03-14 | Supplier price increase | flag | #C0392B | below`. Manual positions ★ (`positions.list`): `long|short|neutral | entry date | exit date (empty or open = open position) | entry= | exit= | stop= | target= | qty= | fees= | label=`, e.g. `long | 2025-03-03 | 2025-05-12 | stop=95 | target=120 | qty=10 | fees=0.1%`. Everything is anchored on dates, never on bar numbers.

### Interactions with the report

- Click a bar: cross-filter on every row of the bar (all source rows when bars are grouped); Ctrl for several; click a position = all its bars. Cross-highlighting from other visuals dims the other bars. Context menu everywhere.
- Hover: legend and Power BI tooltip (OHLC, change, volume, Tooltips measures, event, hovered position); report-page tooltips are supported.
- Edit mode only: **Indicators**, **Annotate ★** and **Position ★** buttons; they save to `indicators.list`, `annotations.list`, `positions.list` (persistProperties). Zoom, timeframe, symbol and indicators hidden with the eye icon are per session.
- Keyboard: Tab, ← → bar by bar, Home / End, Page Up / Page Down, + / − zoom, Enter selects, Esc clears. High contrast, ARIA labels, French and English.

### Dynamic formats

- **fx button** (Power BI conditional formatting) on colors and texts of the Format pane.
- **"Dynamic format" well** (`format`): measures renamed `card.setting` (e.g. `data.displayFrom`, `title.text`, `layout.type`) drive any setting and win over the fixed value. Driving a ★ setting by DAX still shows the watermark without a key.

```dax
// renamed data.displayFrom
Display from = FORMAT ( EDATE ( TODAY (), -6 ), "yyyy-MM-dd" )
// renamed indicators.list
Indicators = "sma 20" & UNICHAR ( 10 ) & "ema 50"
```

### Format pane: option IDs

- Card order: `license`, `style`, `data`, `layout`, `candles`, `yAxis`, `timeAxis`, `volume`, `indicators`, `panes`, `annotations`, `positions`, `crosshair`, `navigation`, `grid`, `tooltip`, `interaction`, then `title`, `source`, `container`, `texts`. Format pane in version 1.1.0.0 (30/10/2026), top to bottom: `license`, `style`, `layout`, `data`, `candles`, `volume`, `indicators`, `panes`, `positions`, `timeAxis`, `yAxis`, `gridlines`, `legend`, `annotations`, `crosshair`, `navigation`, `tooltip`, `interaction`, `title`, `source`, `container`, `texts`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- `data`: `timeframe` (`auto` | `1m` | `5m` | `15m` | `30m` | `1H` | `4H` | `1D` | `1W` | `1M` | `3M` | `1Y`), `timeframes` (text, e.g. `1D 1W 1M`), `axis` (`bars` | `time`), `weekStart` (`1` | `0` | `6`), `fiscalStart` (1–12), `session` (text), `tzOffset` (−14–14), `range` (`auto` | `1M` | `3M` | `6M` | `YTD` | `1Y` | `5Y` | `all`), `displayFrom` (YYYY-MM-DD), `series`, `compare` ★.
- `layout`: `type` (`candles` | `hollow` | `bars` | `line` | `area` | `heikinAshi` ★ | `baseline` ★ | `hlc` ★ | `lineMarkers` ★), `baseline`, `lineWidth` (0.5–6, 1.5).
- `candles`: `upColor` (#2E7D4F), `downColor` (#C0392B), `neutralColor`, `upBorder`, `downBorder`, `upWick`, `downWick`, `width` (10–100 % of spacing, 70), `volumeShade`.
- `yAxis`: `show`, `position` (`right` | `left`), `fontSize`, `color`, `units` (`auto` | `none` | `k` | `m` | `b`), `decimals` (−1–6), `prefix`, `suffix`, `scale` (`linear` | `log` | `percent` | `base100`), `invert`, `marginTop`, `marginBottom` (0–40 %, 8), `lastLine`, `lastLabel`.
- `timeAxis`: `show`, `fontSize`, `color`, `spacing` (40–300 px, 90), `separators`.
- `volume`: `show`, `mode` (`pane` | `overlay`), `height` (5–50 %, 18), `upColor`, `downColor`, `opacity` (5–100, 45), `ma`, `maLength` (20).
- `indicators`: `list`; `ma1Show` / `ma1Type` / `ma1Length` (20) / `ma1Color`, same for `ma2` (EMA 50) and `ma3` (SMA 200), types `sma` | `ema` | `wma` ★ | `vwma` ★ | `rma` ★ | `dema` ★ | `tema` ★ | `hma` ★; `bbShow` ★, `bbLength` (20), `bbMult` (2), `bbColor`; `rsiShow` ★, `rsiLength` (14), `rsiUpper` (70), `rsiLower` (30); `macdShow` ★, `macdFast` (12), `macdSlow` (26), `macdSignal` (9).
- `panes`: `height` (8–45 %, 22), `separators`, `levels`.
- `annotations`: `show`, `labels` (`label` | `tooltip`), `place` (`auto` | `above` | `below`), `vline`, `color`, `fontSize`, `labelBg` (`surface` | `none` = transparent), `list` ★.
- `positions`: `show`, `winColor`, `lossColor`, `neutralColor`, `labels` (`full` | `result` | `none`), `labelBg` (`surface` | `none`), `qty` (1), `fees` (amount or %), `stats`, `equity`, `list`.
- `crosshair`: `legend.show`, `legend.fontSize` (7–18, 11), `legend.reserve` (on: the price scale keeps the legend's height free), `show`, `magnet` (`magnet` | `free`), `style` (`solid` | `dashed` | `dotted`), `color`.
- `navigation`: `timeframes`, `ranges`, `wheel`, `navigator` ★, `barSpacing` (2–40 px, 8), `rightOffset` (0–50 bars, 3).
- `gridlines`: `horizontal`, `vertical`, `style`, `color`, `sessions`, `layout.watermark`. `tooltip`: `show`, `change`, `volume`. `interaction`: `hover`, `dim` (5–80, 25).

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. Booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes.

```json
{
  "visualType": "plumeCandleChart4DCBF4C29CE24C99BB068D8F6EC07CA0",
  "query": {
    "queryState": {
      "time":   { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Prices" } }, "Property": "Date" } }, "queryRef": "Prices.Date", "nativeQueryRef": "Date" } ] },
      "series": { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Prices" } }, "Property": "Symbol" } }, "queryRef": "Prices.Symbol", "nativeQueryRef": "Symbol" } ] },
      "open":   { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Prices" } }, "Property": "Open price" } }, "queryRef": "Prices.Open price", "nativeQueryRef": "Open price" } ] },
      "high":   { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Prices" } }, "Property": "High price" } }, "queryRef": "Prices.High price", "nativeQueryRef": "High price" } ] },
      "low":    { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Prices" } }, "Property": "Low price" } }, "queryRef": "Prices.Low price", "nativeQueryRef": "Low price" } ] },
      "close":  { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Prices" } }, "Property": "Close price" } }, "queryRef": "Prices.Close price", "nativeQueryRef": "Close price" } ] },
      "volume": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Prices" } }, "Property": "Traded volume" } }, "queryRef": "Prices.Traded volume", "nativeQueryRef": "Traded volume" } ] }
    }
  },
  "objects": {
    "data":       [ { "properties": { "range": { "expr": { "Literal": { "Value": "'1Y'" } } } } } ],
    "indicators": [ { "properties": { "ma1Show": { "expr": { "Literal": { "Value": "true" } } },
                                       "ma2Show": { "expr": { "Literal": { "Value": "true" } } },
                                       "list": { "expr": { "Literal": { "Value": "'rsi 14'" } } } } } ],
    "license":    [ { "properties": { "key": { "expr": { "Literal": { "Value": "'PLUM1.…'" } } } } } ]
  }
}
```

The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from the `.pbiviz` file).

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`. Candle colors set in the Candles card win over the style.
- `style.themeJson` (Theme JSON ★): a JSON theme as plain text (format v2 with optional `extends` and groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`). Full reference: https://plumevisuals.com/ai/tutorials/en/themes-json.md.

### Common pitfalls

- One bar per year, or a single bar: the date hierarchy is used instead of the date column.
- "Add the Close measure (or Price)": no Close or Price field.
- Flat candles: the four measures return the same value (e.g. an average of a single price); use Price (single value).
- A long average starts in the middle: dates are filtered; use range buttons or Display from.
- The 1m or 1H button is missing: the data is daily; bars are only grouped upward.
- The legend hides the top of the candles: `legend.reserve` turned off.
- Labels hide the candles: `annotations.labelBg` / `positions.labelBg` = `none`.
- Watermark visible: a ★ chart type, Bollinger, RSI, MACD or any indicator other than SMA, EMA, hl2, hlc3, ohlc4, signals, two indicator panes, manual annotations, positions, comparison, navigator, a ★ style or a theme JSON, without a valid key.
- An ignored line reported at the bottom: typo in a list (indicator name, date YYYY-MM-DD).
- The visual makes no network request: data and license key stay in the report; no R or Python.

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

Drawing tools (trend lines, Fibonacci, channels, rectangles, measuring), Renko, Kagi, Point & Figure, Line Break, volume profiles, bars projected into the future (Ichimoku's leading spans stop at the last bar), an indicator computed on another indicator's output (except the `signal=N` average), annotations created by readers in reading view, exporting the chart as an image, live market data feeds (the visual only shows the report's data).

## Candle Plume: data fields

- `time` Date / time / Date / heure (column, 1 max): Date or date-time column (not the automatic date hierarchy): one row per source bar.
- `series` Symbol (series) / Symbole (série) (column, 1 max): 
- `open` Open / Ouverture (measure, 1 max): 
- `high` High / Plus haut (measure, 1 max): 
- `low` Low / Plus bas (measure, 1 max): 
- `close` Close / Clôture (measure, 1 max): 
- `price` Price (single value) / Prix (valeur unique) (measure, 1 max): Instead of Open, High, Low and Close: one price per row (ticks, readings); the visual builds each bar.
- `volume` Volume (measure, 1 max): 
- `overlay` Lines on prices / Courbes sur les prix (measure, 5 max): Measures drawn over the prices: target, benchmark, forecast.
- `eventText` Event text / Texte d'événement (measure, 1 max): Text measure: a marker with this text on each bar where it is not empty.
- `eventType` Event type / Type d'événement (measure, 1 max): Chooses the icon: buy, sell, flag, circle, star, diamond, or a letter.
- `position` Position state ★ / État de position ★ ★ (measure, 1 max): Measure returning +1 (long), -1 (short) or 0 (out of the market) per bar: each change opens or closes a position.
- `entryPrice` Entry price ★ / Prix d'entrée ★ ★ (measure, 1 max): 
- `exitPrice` Exit price ★ / Prix de sortie ★ ★ (measure, 1 max): 
- `tooltips` Tooltips / Infobulles (measure, several max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Candle Plume: Format pane options (197)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Layout / Disposition (`layout`)
- `layout.type` Chart type / Type de graphique: dropdown, default `auto`; values: `auto` Automatic (candles; line with the Price field alone); `candles` Candles; `hollow` Hollow candles; `bars` OHLC bars; `line` Line; `area` Area; `heikinAshi` Heikin-Ashi ★; `baseline` Baseline ★; `hlc` HLC columns ★; `lineMarkers` Line with markers ★. Automatic: candles with Open, High, Low and Close; a line when only the Price field is filled and each bar has a single price.
- `layout.baseline` Baseline value / Valeur de base: text, default (empty). Visible when `layout.type` = `baseline`
- `layout.lineWidth` Line width / Épaisseur de la ligne: number, default `1.5`; values: 0.5 to 6. Visible when `layout.type` = `auto` or `line` or `area` or `baseline` or `lineMarkers`
- `layout.watermark` Symbol watermark / Symbole en filigrane: toggle, default `false`; values: true / false

### Data and timeframe / Données et unité de temps (`data`)
- `data.timeframe` Default timeframe / Unité par défaut: dropdown, default `auto`; values: `auto` Same as the data; `1m` 1 minute; `5m` 5 minutes; `15m` 15 minutes; `30m` 30 minutes; `1H` 1 hour; `4H` 4 hours; `1D` 1 day; `1W` 1 week; `1M` 1 month; `3M` 1 quarter; `1Y` 1 year. Bars are aggregated up only (minutes to hours, never the reverse): open = first open, high = highest, low = lowest, close = last close, volume = sum.
- `data.timeframes` Timeframes offered to readers / Unités proposées au lecteur: text, default (empty). Buttons of the timeframe selector, separated by spaces: 1m 5m 15m 30m 1H 4H 1D 1W 1M 3M 1Y. Only units at least as long as the data are shown.
- `data.axis` Time axis / Axe du temps: dropdown, default `bars`; values: `bars` One bar per step (no weekend gaps); `time` Real time (gaps shown)
- `data.weekStart` Week starts on / Début de semaine: dropdown, default `1`; values: `1` Monday; `0` Sunday; `6` Saturday
- `data.fiscalStart` First month of the fiscal year (quarters, years) / Premier mois de l'exercice (trimestres, années): number, default `1`; values: 1 to 12
- `data.session` Market session (intraday) / Séance (intrajournalier): text, default (empty). Intraday rows outside this session are ignored; 1H and 4H bars start at the session start.
- `data.tzOffset` Time zone offset (hours) / Décalage horaire (heures): number, default `0`; values: -14 to 14
- `data.range` Initial range / Plage au démarrage: dropdown, default `auto`; values: `auto` Automatic (readable bars); `1M` 1 month; `3M` 3 months; `6M` 6 months; `YTD` Year to date; `1Y` 1 year; `5Y` 5 years; `all` All
- `data.displayFrom` Display from / Afficher à partir du: text, default (empty). Earlier bars are only used to warm up the indicators (a 200-bar average starts at once). Drive it with a DAX measure through the fx button.
- `data.series` Series shown / Série affichée: text, default (empty)
- `data.compare` Compare series in % ★ / Comparer les séries en % ★ ★: toggle, default `false`; values: true / false. The other series are drawn as lines, in % from the first visible bar.

### Candles / Bougies (`candles`)
- `candles.upColor` Up / Haussière: color, default `#2E7D4F`; values: hex color
- `candles.downColor` Down / Baissière: color, default `#C0392B`; values: hex color
- `candles.neutralColor` Unchanged (empty = secondary) / Neutre (vide = secondaire): color, default (empty); values: hex color
- `candles.upBorder` Up border (empty = body) / Bordure haussière (vide = corps): color, default (empty); values: hex color
- `candles.downBorder` Down border (empty = body) / Bordure baissière (vide = corps): color, default (empty); values: hex color
- `candles.upWick` Up wick (empty = body) / Mèche haussière (vide = corps): color, default (empty); values: hex color
- `candles.downWick` Down wick (empty = body) / Mèche baissière (vide = corps): color, default (empty); values: hex color
- `candles.width` Body width (% of spacing) / Largeur du corps (% du pas): number, default `70`; values: 10 to 100
- `candles.volumeShade` Shade by volume / Opacité selon le volume: toggle, default `false`; values: true / false. Bars with a low volume are paler.

### Volume (`volume`)
- `volume.show` Show (with the Volume field) / Afficher (avec le champ Volume): toggle, default `true`; values: true / false
- `volume.mode` Placement: dropdown, default `pane`; values: `pane` Pane below prices; `overlay` Overlay at the bottom of prices
- `volume.height` Height (%) / Hauteur (%): number, default `18`; values: 5 to 50
- `volume.upColor` Up (empty = candles) / Haussier (vide = bougies): color, default (empty); values: hex color
- `volume.downColor` Down (empty = candles) / Baissier (vide = bougies): color, default (empty); values: hex color
- `volume.opacity` Opacity (%) / Opacité (%): number, default `45`; values: 5 to 100
- `volume.ma` Volume average / Moyenne du volume: toggle, default `false`; values: true / false
- `volume.maLength` Average length / Période de la moyenne: number, default `20`; values: 1 to 500. Visible when `volume.ma` = `true`

### Indicators / Indicateurs (`indicators`)
- `indicators.list` Indicators (one per line) / Indicateurs (une ligne chacun): textarea, default (empty). Written by the Indicators button of the visual (edit mode), or by hand: name, parameters, then optionally a source (close, hl2, hlc3…), a color #RRGGBB, signal=9, levels=70/30, signals, hidden.
- `indicators.ma1Show` Moving average 1 / Moyenne mobile 1: toggle, default `false`; values: true / false
- `indicators.ma1Type` Type: dropdown, default `sma`; values: `sma` Simple (SMA); `ema` Exponential (EMA); `wma` Weighted (WMA) ★; `vwma` Volume-weighted (VWMA) ★; `rma` Smoothed (SMMA) ★; `dema` Double EMA (DEMA) ★; `tema` Triple EMA (TEMA) ★; `hma` Hull (HMA) ★. Visible when `indicators.ma1Show` = `true`
- `indicators.ma1Length` Length (bars) / Période (barres): number, default `20`; values: 1 to 500. Visible when `indicators.ma1Show` = `true`
- `indicators.ma1Color` Color (empty = palette) / Couleur (vide = palette): color, default (empty); values: hex color. Visible when `indicators.ma1Show` = `true`
- `indicators.ma2Show` Moving average 2 / Moyenne mobile 2: toggle, default `false`; values: true / false
- `indicators.ma2Type` Type: dropdown, default `ema`; values: `sma` Simple (SMA); `ema` Exponential (EMA); `wma` Weighted (WMA) ★; `vwma` Volume-weighted (VWMA) ★; `rma` Smoothed (SMMA) ★; `dema` Double EMA (DEMA) ★; `tema` Triple EMA (TEMA) ★; `hma` Hull (HMA) ★. Visible when `indicators.ma2Show` = `true`
- `indicators.ma2Length` Length (bars) / Période (barres): number, default `50`; values: 1 to 500. Visible when `indicators.ma2Show` = `true`
- `indicators.ma2Color` Color (empty = palette) / Couleur (vide = palette): color, default (empty); values: hex color. Visible when `indicators.ma2Show` = `true`
- `indicators.ma3Show` Moving average 3 / Moyenne mobile 3: toggle, default `false`; values: true / false
- `indicators.ma3Type` Type: dropdown, default `sma`; values: `sma` Simple (SMA); `ema` Exponential (EMA); `wma` Weighted (WMA) ★; `vwma` Volume-weighted (VWMA) ★; `rma` Smoothed (SMMA) ★; `dema` Double EMA (DEMA) ★; `tema` Triple EMA (TEMA) ★; `hma` Hull (HMA) ★. Visible when `indicators.ma3Show` = `true`
- `indicators.ma3Length` Length (bars) / Période (barres): number, default `200`; values: 1 to 500. Visible when `indicators.ma3Show` = `true`
- `indicators.ma3Color` Color (empty = palette) / Couleur (vide = palette): color, default (empty); values: hex color. Visible when `indicators.ma3Show` = `true`
- `indicators.bbShow` Bollinger Bands ★ / Bandes de Bollinger ★ ★: toggle, default `false`; values: true / false
- `indicators.bbLength` Length / Période: number, default `20`; values: 2 to 500
- `indicators.bbMult` Standard deviations / Écarts types: number, default `2`; values: 0.1 to 10
- `indicators.bbColor` Color (empty = palette) / Couleur (vide = palette): color, default (empty); values: hex color
- `indicators.rsiShow` RSI ★ ★: toggle, default `false`; values: true / false
- `indicators.rsiLength` Length / Période: number, default `14`; values: 2 to 500
- `indicators.rsiUpper` Upper level / Seuil haut: number, default `70`; values: 0 to 100
- `indicators.rsiLower` Lower level / Seuil bas: number, default `30`; values: 0 to 100
- `indicators.macdShow` MACD ★ ★: toggle, default `false`; values: true / false
- `indicators.macdFast` Fast length / Période rapide: number, default `12`; values: 1 to 500
- `indicators.macdSlow` Slow length / Période lente: number, default `26`; values: 1 to 500
- `indicators.macdSignal` Signal: number, default `9`; values: 1 to 500

### Panes / Panneaux (`panes`)
- `panes.height` Height of each indicator pane (%) / Hauteur de chaque panneau d'indicateur (%): number, default `22`; values: 8 to 45
- `panes.separators` Separator lines / Traits de séparation: toggle, default `true`; values: true / false
- `panes.levels` Levels and band between them / Seuils et zone entre les seuils: toggle, default `true`; values: true / false

### Positions ★ (`positions`)
- `positions.show` Show / Afficher: toggle, default `true`; values: true / false. Positions come from the Position state field (+1 long, -1 short, 0 out of the market) or from the Position button of the visual.
- `positions.winColor` Profit / Gain: color, default `#2E7D4F`; values: hex color
- `positions.lossColor` Loss / Perte: color, default `#C0392B`; values: hex color
- `positions.neutralColor` Neutral period (empty = accent) / Période neutre (vide = accent): color, default (empty); values: hex color
- `positions.labels` Label / Étiquette: dropdown, default `full`; values: `full` Result, %, duration, risk / reward; `result` Result in %; `none` None
- `positions.labelBg` Label background / Fond des étiquettes: dropdown, default `surface`; values: `surface` Visual background color; `none` Transparent
- `positions.qty` Default quantity / Quantité par défaut: number, default `1`; values: 0 to …
- `positions.fees` Default fees (amount or %) / Frais par défaut (montant ou %): text, default (empty)
- `positions.stats` Statistics panel / Panneau de statistiques: toggle, default `false`; values: true / false
- `positions.equity` Equity curve / Courbe de capital: toggle, default `false`; values: true / false
- `positions.list` Positions (one per line) / Positions (une ligne chacune): textarea, default (empty). Written by the Position button (edit mode) or by hand: long, short or neutral | entry date | exit date (empty = open) | entry= exit= stop= target= qty= fees= label=.

### Time axis / Axe du temps (`timeAxis`)
- `timeAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `timeAxis.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `timeAxis.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `timeAxis.spacing` Label spacing (px) / Écart entre les libellés (px): number, default `90`; values: 40 to 300
- `timeAxis.separators` Day / month / year separators / Séparateurs de jour / mois / année: toggle, default `false`; values: true / false

### Price axis / Axe des prix (`yAxis`)
- `yAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `yAxis.position` Position: dropdown, default `right`; values: `right` Right; `left` Left
- `yAxis.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `yAxis.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `yAxis.units` Display units / Unités d'affichage: dropdown, default `none`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `yAxis.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `yAxis.prefix` Prefix / Préfixe: text, default (empty)
- `yAxis.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)
- `yAxis.scale` Scale / Échelle: dropdown, default `linear`; values: `linear` Linear; `log` Logarithmic; `percent` Percent (from the first visible bar); `base100` Indexed to 100
- `yAxis.min` Minimum: text, default (empty). Fixed bottom of the price scale (prices). Keep it under a filter with a DAX measure in the Dynamic format field named yAxis.min, e.g. CALCULATE(MIN(Prices[Low]), REMOVEFILTERS()).
- `yAxis.max` Maximum: text, default (empty). Fixed top of the price scale. DAX: a yAxis.max measure, e.g. CALCULATE(MAX(Prices[High]), REMOVEFILTERS()).
- `yAxis.invert` Invert axis / Inverser l'axe: toggle, default `false`; values: true / false
- `yAxis.marginTop` Top margin (%) / Marge haute (%): number, default `8`; values: 0 to 40
- `yAxis.marginBottom` Bottom margin (%) / Marge basse (%): number, default `8`; values: 0 to 40
- `yAxis.lastLine` Last price line / Ligne du dernier prix: toggle, default `true`; values: true / false
- `yAxis.lastLabel` Label on the axis / Étiquette sur l'axe: toggle, default `true`; values: true / false
- `yAxis.showTitle` Axis title / Titre de l'axe: toggle, default `false`; values: true / false
- `yAxis.titleText` Title text / Texte du titre: text, default (empty). Visible when `yAxis.showTitle` = `true`

### Gridlines / Quadrillage (`gridlines`)
- `gridlines.horizontal` Horizontal: toggle, default `true`; values: true / false
- `gridlines.vertical` Vertical: toggle, default `true`; values: true / false
- `gridlines.style` Line style / Style du trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `gridlines.color` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color
- `gridlines.width` Width / Épaisseur: number, default `1`; values: 0.5 to 4
- `gridlines.sessions` Alternate session bands / Bandes de séances alternées: toggle, default `false`; values: true / false

### Legend / Légende (`legend`)
- `legend.show` Show (OHLC and indicators) / Afficher (OHLC et indicateurs): toggle, default `true`; values: true / false
- `legend.fontSize` Size / Taille: number, default `11`; values: 7 to 18
- `legend.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `legend.reserve` Keep room for the legend / Réserver la place de la légende: toggle, default `true`; values: true / false. The price scale leaves the height of the legend free at the top: candles never run under the legend text.

### Annotations (`annotations`)
- `annotations.show` Show / Afficher: toggle, default `true`; values: true / false
- `annotations.labels` Text / Texte: dropdown, default `label`; values: `label` Label on the chart; `tooltip` Tooltip only
- `annotations.place` Marker position / Position du repère: dropdown, default `auto`; values: `auto` Automatic (buy below, sell above); `above` Above the high; `below` Below the low
- `annotations.vline` Vertical line across panes / Ligne verticale sur tous les panneaux: toggle, default `false`; values: true / false
- `annotations.color` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `annotations.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `annotations.labelWidth` Label width (px) / Largeur des étiquettes (px): number, default `180`; values: 60 to 600. A longer text goes to the next line (up to the maximum number of lines) instead of being cut.
- `annotations.maxLines` Maximum lines / Lignes au plus: number, default `3`; values: 1 to 10
- `annotations.labelBg` Label background / Fond des étiquettes: dropdown, default `surface`; values: `surface` Visual background color; `none` Transparent
- `annotations.list` Manual annotations ★ / Annotations manuelles ★ ★: textarea, default (empty). Written by the Annotate button (edit mode) or by hand: date | text | icon (flag, up, down, circle, star, diamond, or a letter) | color | above, below or a price. Copy it to another report.

### Crosshair / Réticule (`crosshair`)
- `crosshair.show` Show / Afficher: toggle, default `true`; values: true / false
- `crosshair.magnet` Mode: dropdown, default `magnet`; values: `magnet` Snapped to the close; `free` Free
- `crosshair.style` Line style / Style du trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `crosshair.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color

### Navigation (`navigation`)
- `navigation.timeframes` Timeframe selector / Sélecteur d'unité de temps: toggle, default `true`; values: true / false
- `navigation.ranges` Range buttons (1M, 3M… All) / Boutons de plage (1M, 3M… Tout): toggle, default `true`; values: true / false
- `navigation.wheel` Mouse wheel zoom / Zoom à la molette: toggle, default `true`; values: true / false
- `navigation.navigator` Navigator (mini chart) ★ / Navigateur (mini-graphique) ★ ★: toggle, default `false`; values: true / false
- `navigation.barSpacing` Initial bar spacing (px) / Écart entre les barres au démarrage (px): number, default `8`; values: 2 to 40
- `navigation.rightOffset` Right margin (bars) / Espace à droite (barres): number, default `3`; values: 0 to 50

### Interactions (`interaction`)
- `interaction.hover` Highlight on hover / Mettre en avant au survol: toggle, default `true`; values: true / false
- `interaction.dim` Dimmed items opacity (%) / Opacité des éléments estompés (%): number, default `25`; values: 5 to 80

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).
- `tooltip.change` Change and % / Variation et %: toggle, default `true`; values: true / false
- `tooltip.volume` Volume: toggle, default `true`; values: true / false

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Chord Plume

- Who exchanges with whom, both ways: a readable chord diagram, with labels that never overlap and years replayed with animation.
- Slug `chord` · version 1.1.0.0 · GUID (`visualType`) `plumeChordC66BF01D5AA54B1F91E8D1DA4CFB6000` · page https://plumevisuals.com/en/visuals/chord

### What the visual does

Chord Plume (identifier `chord`) is a Power BI custom visual (version 1.1.0.0, installed from its `.pbiviz` file; not yet on AppSource) that draws **chord diagrams**: names (regions, countries, teams, brands) as arcs around a circle, and one ribbon per pair of names showing what they exchange. Power BI Desktop has no native chord diagram (only Microsoft's older free "Chord" custom visual).

**New in version 1.1.0.0 (30/10/2026):** Format pane reorganized (`labels.*` → `categoryLabels.*`); free parity with Microsoft's Chord: bold / italic category labels, bold / italic / rotated ticks, ribbon outline color and width, axis sort.

- **Both directions**: with `layout.direction` = `both` ("Both ways in one ribbon"), each end of a ribbon is as wide as what its arc sends to the other (asymmetric ribbon) and the arc length is what the name sends; `arrows` draws one ribbon per direction with an arrowhead at the destination (arc = sent + received); `undirected` adds both directions (equal ends). `auto` (default) picks `both` when every name sends something, otherwise `arrows` (a name that only receives would have no arc).
- **Two kinds of data**: one row per flow (From, To, Value), or a **matrix**: no To field and two or more measures in Value, each measure being a destination named after the measure.
- **Labels never overlap**: along the arcs (curved), radial, or horizontal with leader lines; `auto` puts each label along its arc when it fits, otherwise horizontal (wide visual) or radial; labels that still do not fit are shortened (…) or left out, largest arcs first.
- **Busy data**: the names with the most traffic (sent + received) keep their arc, the rest is merged into a gray "Others" arc (`layout.maxGroups`, 20); small ribbons can be hidden ★ (`flows.minShare`); self-flows (A → A) drawn as loops or hidden; ticks in values or % of total ★.
- **Order**: largest first, alphabetical, data order (respects Sort by column), custom list, fewer crossings ★ (partners side by side), net balance ★. Ribbon ends inside each arc are ordered by the position of the partner, which avoids crossings.
- **Play axis ★**: one diagram per period (dates and numbers sorted, text in data order), most recent period shown first, animated transitions between periods; arcs keep their place and color over all periods (order, Others and colors are computed on the whole data).
- Premium ★: two half circles (`layout.shape` = `bipartite`: From on the left, To on the right), indicator ring (`ring.kind` = `inout` sent / received, `net` net balance ▲▼, `change` change since the previous or first period), net balance and fewer-crossings orders, groups (From group / To group fields: grouped arcs under a named outer arc, color shades), highlighted names (`flows.focus`), gradient ribbons, ribbons colored by the stronger direction, small ribbons hidden, ticks in % of total, and the play axis (since the 22/10/2026 rebalancing).

### 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 (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium**.
- Free in Chord Plume: circle shape, matrix of measures, all flow directions, colors by origin / destination / neutral, all label placements and contents, ticks in values, Others, self-loops, orders size / alpha / data / custom, hover modes, selection, highlighting, tooltips.
- Premium features of Chord Plume: the Play axis field with at least one value (« Axe de lecture ★ », card « Lecture ★ » / « Playback ★ »); `layout.shape` = `bipartite`; `layout.order` = `net`, or `auto` with at least 3 names; `flows.colorBy` = `gradient`, or `dominant` with one ribbon per direction or two half circles; `flows.minShare` when at least one ribbon is actually hidden; `ticks.unit` = `percent` with ticks shown; `flows.focus` (any name); `ring.kind` = `inout`, `net` or `change` (change only counts when a Play axis field is present); the From group / To group fields with at least one value.
- 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 `chord` 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 flow, with a measure for the size.

| From (`source`) | To (`target`) | Play axis (`play`) | Value (`value`) |
|---|---|---|---|
| Île-de-France | Nouvelle-Aquitaine | 2025 | 5,540 |
| Nouvelle-Aquitaine | Île-de-France | 2025 | 1,540 |

- **From** (`source`, « De », one column, required): one arc per value. A name found in From and To is a single arc (circle shape).
- **To** (`target`, « Vers », one column): required unless the Value well holds two or more measures (matrix).
- **Value** (`value`, « Valeur (ou une mesure par destination) », 1 to 30 measures): rows of the same pair are added up; without a measure each row counts as 1 (a hint says so); negative values are left out with a warning icon; blanks ignored.
- **Play axis ★** (`play`, « Axe de lecture ★ », one column): one diagram per value; premium (watermark without a key, never blocked).
- **From group ★** / **To group ★** (`sourceGroup`, `targetGroup`, one column each): group of each origin / destination (continent, division).
- **Tooltips** (`tooltips`, up to 5 measures) and **Dynamic format** (`format`, see below).
- Volume of data: windows of 30,000 rows, more fetched with `fetchMoreData`; 100,004 rows (60 names, 28 periods) render in well under 2.5 s.

### DAX recipes

```dax
// One row per flow: a simple sum
People moving = SUM ( Moves[People] )

// Matrix (one column per destination): one measure per column, named after the destination
Sales = SUM ( 'Shared work'[To Sales] )
Marketing = SUM ( 'Shared work'[To Marketing] )

// Dynamic title (renamed title.text in the Dynamic format well)
Dynamic title = "Moves between regions: " & FORMAT ( CALCULATE ( [People moving], ALLSELECTED () ), "#,0" ) & " people"
```

To compare two periods without the play axis, filter the visual on one year and use the tooltip; with the play axis, `ring.kind` = `change` ★ shows the change since the previous or first period.

### Interactions with the report

- Hover an arc: its ribbons stay sharp, the others are dimmed (`interaction.hoverFlows`: `both`, `out` sent only, `in` received only). Hover a ribbon: that ribbon.
- Click an arc: cross-filter on all its flows (every From + To combination of its ribbons, up to 5,000 identities); click a ribbon: the pair (both directions in one ribbon, or one direction with arrows); Ctrl + click adds; click empty space clears. Cross-highlighting from other visuals is drawn as the highlighted part at the start of each ribbon end and arc. Context menu everywhere (arcs, ribbons, empty space, labels, title, landing page).
- Tooltips: arc = name, period, group, sent, received, internal, net balance (▲ / ▼), share of total, change since the reference period, highlighted; ribbon = A → B, B → A, net balance, share of what A sends, Tooltips measures. Report-page tooltips are supported.
- Keyboard: Tab to the chart, arrows move from arc to arc then ribbon to ribbon (announced to screen readers), Enter selects, Esc clears. High contrast: ribbons drawn as host-colored strokes, arcs and ring in host colors. French and English.
- The visual never calls `persistProperties`: every setting comes from the Format pane.

### Dynamic formats

- **fx button** (Power BI conditional formatting) on colors and texts of the Format pane, and on each name's color in Data colors.
- **"Dynamic format" well** (`format`): measures renamed `card.setting` (e.g. `title.text`, `layout.order`, `flows.focus`, `ring.kind`) drive any setting and win over the fixed value. Driving a ★ setting by DAX still shows the watermark without a key. These measures never become flows.

### Format pane: option IDs

- Card order: `license`, `style`, `dataColors`, `layout`, `flows`, `ring`, (`groups` with a group field), `categoryLabels`, `ticks`, `interaction`, then `play` (shared player card) when the Play axis field is used, then `title`, `source`, `container`, `texts`. Format pane in version 1.1.0.0 (30/10/2026), top to bottom: `license`, `style`, `layout`, `dataColors`, `flows`, `ring`, `groups`, `categoryLabels`, `ticks`, `play`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- `dataColors`: `mode` (`auto` | `single`), `single`, `fill` (per name).
- `layout`: `shape` (`circle` | `bipartite` ★), `direction` (`auto` | `both` | `arrows` | `undirected`), `order` (`size` | `auto` ★ | `alpha` | `data` | `custom` | `net` ★), `customOrder` (text, `;`-separated), `startAngle` (0–359, 0), `clockwise` (true), `padAngle` (0–20 degrees, 2), `arcWidth` (2–60 px, 12), `size` (40–100 %, 100), `maxGroups` (2–60, 20), `selfLoops` (`show` | `hide`).
- `flows`: `colorBy` (`source` | `target` | `dominant` ★ | `gradient` ★ | `neutral`), `opacity` (5–100, 68), `outline` (true), `arrowSize` (0–40 px, 10), `minShare` ★ (0–20 % of total, 0), `focus` ★ (text, `;`-separated names), `dimOpacity` (5–100, 30).
- `ring`: `kind` (`none` | `inout` ★ | `net` ★ | `change` ★), `reference` (`previous` | `first`), `width` (3–40 px, 10), `values` (true).
- `groups` ★: `show` (true), `gap` (0–30 degrees, 6), `shades` (true), `fontSize` (9).
- `categoryLabels`: `show`, `placement` (`auto` | `curved` | `radial` | `horizontal`), `content` (`name` | `nameValue` | `namePct` | `all`), `fontSize` (10), `color`, `maxWidth` (10–45 %, 25), `halo`, `units`, `decimals`, `prefix`, `suffix`.
- `ticks`: `show` (false), `unit` (`value` | `percent` ★), `step` (0 = automatic), `fontSize` (8), `color`.
- `interaction`: `hover` (true), `dim` (5–80, 25), `hoverFlows` (`both` | `out` | `in`).
- `play` ★ (shared Plume player, card « Lecture ★ », shown with a Play axis field; session state only, never saved): `start` (`last` | `first`), `speed` (100–10000 ms per frame, 1000), `loop` (false), `autoPlay` (false), `transition` (true), `controls` (true), `position` (`bottom` | `top`), `ticks` (`auto` | `all` | `none`), `tickLabels`, `stepButtons`, `speedButton`, `showLabel` (true), `labelSize` (12–160, 44), `labelPosition` (`bottomRight` | `topRight` | `topLeft` | `bottomLeft` | `center`). Play bar: play / pause, slider, start / end buttons, speed ×0.5 to ×4; keyboard Space, arrows, Page Up / Down, Home / End.

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. Booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes.

```json
{
  "visualType": "plumeChordC66BF01D5AA54B1F91E8D1DA4CFB6000",
  "query": {
    "queryState": {
      "source": { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Moves" } }, "Property": "Origin region" } }, "queryRef": "Moves.Origin region", "nativeQueryRef": "Origin region" } ] },
      "target": { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Moves" } }, "Property": "Destination region" } }, "queryRef": "Moves.Destination region", "nativeQueryRef": "Destination region" } ] },
      "value":  { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Moves" } }, "Property": "People moving" } }, "queryRef": "Moves.People moving", "nativeQueryRef": "People moving" } ] },
      "play":   { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Moves" } }, "Property": "Year" } }, "queryRef": "Moves.Year", "nativeQueryRef": "Year" } ] }
    }
  },
  "objects": {
    "layout": [ { "properties": { "order": { "expr": { "Literal": { "Value": "'auto'" } } }, "maxGroups": { "expr": { "Literal": { "Value": "12D" } } } } } ],
    "ring":   [ { "properties": { "kind": { "expr": { "Literal": { "Value": "'net'" } } } } } ]
  }
}
```

The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from the `.pbiviz` file).

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`. Style-specific defaults: Minimal = thin arcs, no ribbon outline; Unknown Pleasures = neutral ribbons; Neon, Graphite, Hologram = more opaque ribbons and glow.
- `style.themeJson` (Theme JSON ★): a JSON theme as plain text (format v2 with optional `extends` and groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`). Full reference: https://plumevisuals.com/ai/tutorials/en/themes-json.md.

### Common pitfalls

- A name has two arcs: it is spelled differently in From and To (space, accent, case), or the shape is two half circles (by design).
- Pointed ribbons with no width on one side: the flow only goes one way (both-ways mode); use `arrows` if preferred.
- The landing page asks for "To": From and a single measure only; add To or a second measure (matrix).
- "Without Value, each From → To row counts as 1": no measure in Value.
- A gray "Others" arc: more names than `layout.maxGroups`.
- The "Change" ring draws nothing: no Play axis field (a hint says so; no watermark then).
- Watermark visible: a Play axis field, two half circles, net balance or fewer-crossings order, gradient or stronger-direction ribbons, hidden small ribbons, ticks in %, a highlighted name, an indicator ring, a group field, 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)

Ribbon color driven by a measure, value labels written on the ribbons, dragging arcs to reorder them, zooming into a group on click, images or flags at the end of the arcs, two diagrams side by side for a comparison, hierarchical edge bundling, network (force-directed) layouts, exporting the chart as an image.

## Chord Plume: data fields

- `source` From / De (column, 1 max): Origin of each flow (country, department, product…). With To: one flow per row.
- `target` To / Vers (column, 1 max): Destination of each flow. Without To, drop several measures in Value: each measure is a destination (matrix).
- `value` Value (or one measure per destination) / Valeur (ou une mesure par destination) (measure, 30 max): Size of the flows. Without To, each measure is a destination named after the measure (matrix of measures).
- `play` Play axis ★ / Axe de lecture ★ ★ (column, 1 max): Premium: year, month…: one diagram per value, played with animated transitions.
- `sourceGroup` From group ★ / Groupe de De ★ ★ (column, 1 max): Premium: group of each From item (continent, division…): grouped arcs with an outer ring.
- `targetGroup` To group ★ / Groupe de Vers ★ ★ (column, 1 max): Premium: group of each To item (often the same field as From group, from the destination table).
- `tooltips` Tooltips / Infobulles (measure, 5 max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Chord Plume: Format pane options (138)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Layout / Disposition (`layout`)
- `layout.shape` Shape / Forme: dropdown, default `circle`; values: `circle` Circle (one arc per name); `bipartite` Two half circles (From on the left, To on the right) ★. Two half circles: origins on the left, destinations on the right (exporters and importers, channels and products). A name found on both sides gets two arcs.
- `layout.direction` Flow direction / Sens des flux: dropdown, default `auto`; values: `auto` Automatic; `both` Both ways in one ribbon (each end = what it sends); `arrows` One ribbon per direction, with an arrow; `undirected` Undirected (both ways added up). Automatic: both ways in one ribbon when every name sends something, otherwise one ribbon per direction with an arrow (a name that only receives would have no arc).
- `layout.order` Arc order / Ordre des arcs: dropdown, default `size`; values: `size` Largest first; `auto` Fewer crossings (partners side by side) ★; `alpha` Alphabetical; `data` Data order (Sort by column); `custom` Custom (list); `net` Net balance (gainers first) ★. Order of the arcs, clockwise from the start angle. Net balance: names that receive more than they send come first.
- `layout.customOrder` Custom order (separated by ;) / Ordre personnalisé (séparé par ;): text, default (empty). Visible when `layout.order` = `custom`. Names in this order, the others after them (largest first).
- `layout.startAngle` Start angle (degrees, 0 = top) / Angle de départ (degrés, 0 = en haut): number, default `0`; values: 0 to 359
- `layout.clockwise` Clockwise / Sens des aiguilles d'une montre: toggle, default `true`; values: true / false
- `layout.padAngle` Space between arcs (degrees) / Espace entre les arcs (degrés): number, default `2`; values: 0 to 20
- `layout.arcWidth` Arc thickness (px) / Épaisseur des arcs (px): number, default `12`; values: 2 to 60
- `layout.size` Circle size (%) / Taille du cercle (%): number, default `100`; values: 40 to 100
- `layout.maxGroups` Names shown at most (the rest in « Others ») / Noms affichés au plus (le reste dans « Autres »): number, default `20`; values: 2 to 60. The names with the most traffic (sent + received) keep their arc; the others are merged into « Others ».
- `layout.selfLoops` Flows to itself (A → A) / Flux vers soi-même (A → A): dropdown, default `show`; values: `show` Show (loop on the arc); `hide` Hide. Moves inside the same name (internal transfers, moves within a region).

### Data colors / Couleurs des données (`dataColors`, one entry per item with a selector)
- `dataColors.mode` Coloring / Coloration: dropdown, default `auto`; values: `auto` Palette (one color per name); `single` Single color
- `dataColors.single` Color / Couleur: color, default (empty); values: hex color
- `dataColors.fill` Color / Couleur: color, default (empty); values: hex color

### Ribbons / Rubans (`flows`)
- `flows.colorBy` Ribbon color / Couleur des rubans: dropdown, default `source`; values: `source` Origin; `target` Destination; `dominant` The stronger direction ★; `gradient` Gradient origin → destination ★; `neutral` Neutral (gray). The stronger direction (with one ribbon per direction): both ribbons of a pair take the color of the name that sends the most.
- `flows.opacity` Opacity (%) / Opacité (%): number, default `68`; values: 5 to 100
- `flows.outline` Ribbon outline / Contour des rubans: toggle, default `true`; values: true / false
- `flows.outlineColor` Outline color (empty = ribbon color) / Couleur du contour (vide = couleur du ruban): color, default (empty); values: hex color. Visible when `flows.outline` = `true`
- `flows.outlineWidth` Outline width / Épaisseur du contour: number, default `0.6`; values: 0.2 to 4. Visible when `flows.outline` = `true`
- `flows.arrowSize` Arrow length (px) / Longueur des flèches (px): number, default `10`; values: 0 to 40. Used with « One ribbon per direction ».
- `flows.minShare` Hide ribbons below (% of total) ★ / Masquer les rubans sous (% du total) ★ ★: number, default `0`; values: 0 to 20. Ribbons smaller than this share of the total are not drawn (the arcs keep their size).
- `flows.focus` Highlight ★ / Mettre en avant ★ ★: text, default (empty). Only the arcs and ribbons of these names keep their color (several names separated by ;). Stays on the page, in PDF exports too.
- `flows.dimOpacity` Dimmed ribbons: opacity (% of opacity) / Rubans en retrait : opacité (% de l'opacité): number, default `30`; values: 5 to 100. Ribbons set back by a highlight.

### Indicator ring / Anneau d'indicateurs (`ring`)
- `ring.kind` Ring around the arcs / Anneau autour des arcs: dropdown, default `none`; values: `none` None; `inout` Sent and received (share of each way) ★; `net` Net balance (received − sent) ★; `change` Change since the reference period ★. Net balance: a bar outside each arc, ▲ when the name receives more than it sends, ▼ otherwise. Change: needs a Play axis field.
- `ring.reference` Reference period / Période de référence: dropdown, default `previous`; values: `previous` The previous period; `first` The first period. Visible when `ring.kind` = `change`
- `ring.width` Thickness (px) / Épaisseur (px): number, default `10`; values: 3 to 40
- `ring.values` Write the values (▲ ▼) / Écrire les valeurs (▲ ▼): toggle, default `true`; values: true / false

### Groups (hierarchy) ★ / Groupes (hiérarchie) ★ (`groups`)
- `groups.show` Outer group arcs / Arc extérieur des groupes: toggle, default `true`; values: true / false. With a From group / To group field (★): the names of a group stay together, under an outer arc with the group name.
- `groups.gap` Space between groups (degrees) / Espace entre les groupes (degrés): number, default `6`; values: 0 to 30
- `groups.shades` Group color, shades for its names / Couleur du groupe, nuances pour ses noms: toggle, default `true`; values: true / false
- `groups.fontSize` Text size / Taille du texte: number, default `9`; values: 6 to 20

### Category labels / Étiquettes des catégories (`categoryLabels`)
- `categoryLabels.show` Show / Afficher: toggle, default `true`; values: true / false
- `categoryLabels.placement` Placement: dropdown, default `auto`; values: `auto` Automatic (along the arc, otherwise radial); `curved` Along the arcs; `radial` Radial; `horizontal` Horizontal, with a leader line. Labels never overlap: a label that does not fit is shortened (…) or left out, the largest arcs first.
- `categoryLabels.content` Content / Contenu: dropdown, default `namePct`; values: `name` Name; `nameValue` Name and value; `namePct` Name and % of total; `all` Name, value and %
- `categoryLabels.fontSize` Text size / Taille du texte: number, default `10`; values: 6 to 24
- `categoryLabels.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `categoryLabels.maxWidth` Maximum label room (% of the visual) / Place maximale des étiquettes (% du visuel): number, default `25`; values: 10 to 45
- `categoryLabels.halo` Text halo / Halo autour du texte: toggle, default `true`; values: true / false
- `categoryLabels.bold` Bold (name) / Gras (nom): toggle, default `true`; values: true / false
- `categoryLabels.italic` Italic / Italique: toggle, default `false`; values: true / false
- `categoryLabels.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `categoryLabels.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `categoryLabels.prefix` Prefix / Préfixe: text, default (empty)
- `categoryLabels.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)

### Ticks / Graduations (`ticks`)
- `ticks.show` Show / Afficher: toggle, default `false`; values: true / false
- `ticks.unit` Scale in / Graduer en: dropdown, default `value`; values: `value` Values; `percent` % of total ★
- `ticks.step` Step (0 = automatic) / Pas (0 = automatique): number, default `0`; values: 0 to …
- `ticks.fontSize` Text size / Taille du texte: number, default `8`; values: 6 to 16
- `ticks.color` Color (empty = secondary) / Couleur (vide = secondaire): color, default (empty); values: hex color
- `ticks.bold` Bold / Gras: toggle, default `false`; values: true / false
- `ticks.italic` Italic / Italique: toggle, default `false`; values: true / false
- `ticks.rotate` Rotate values along the circle / Valeurs tournées le long du cercle: toggle, default `true`; values: true / false. Off: the tick values stay horizontal.

### Playback ★ / Lecture ★ (`play`)
- `play.start` Frame shown on opening / Image affichée à l'ouverture: dropdown, default `last`; values: `last` The last one (most recent); `first` The first one
- `play.speed` Duration of a frame (ms) / Durée d'une image (ms): number, default `1000`; values: 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, default `false`; values: true / false
- `play.autoPlay` Play automatically on opening / Lecture automatique à l'ouverture: toggle, default `false`; values: 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, default `true`; values: true / false. Values, positions and colors move smoothly from one frame to the next.
- `play.controls` Play bar / Barre de lecture: toggle, default `true`; values: true / false
- `play.position` Bar position / Position de la barre: dropdown, default `bottom`; values: `bottom` Bottom; `top` Top. Visible when `play.controls` = `true`
- `play.ticks` Tick marks / Graduations: dropdown, default `auto`; values: `auto` Automatic; `all` Every frame; `none` None. Visible when `play.controls` = `true`
- `play.tickLabels` Tick labels / Étiquettes des graduations: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.stepButtons` Start and end buttons / Boutons début et fin: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.speedButton` Speed button / Bouton de vitesse: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.showLabel` Current value in large type / Valeur en cours en grand: toggle, default `true`; values: true / false
- `play.labelSize` Large value size / Taille de la valeur en grand: number, default `44`; values: 12 to 160. Visible when `play.showLabel` = `true`
- `play.labelPosition` Large value position / Position de la valeur en grand: dropdown, default `bottomRight`; values: `bottomRight` Bottom right; `topRight` Top right; `topLeft` Top left; `bottomLeft` Bottom left; `center` Center. Visible when `play.showLabel` = `true`

### Interactions (`interaction`)
- `interaction.hover` Highlight on hover / Mettre en avant au survol: toggle, default `true`; values: true / false
- `interaction.dim` Dimmed items opacity (%) / Opacité des éléments estompés (%): number, default `25`; values: 5 to 80
- `interaction.hoverFlows` Hovering an arc: ribbons shown / Survol d'un arc : rubans montrés: dropdown, default `both`; values: `both` Sent and received; `out` Sent only; `in` Received only

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Sunburst Plume

- A hierarchy in rings: a click opens the level beneath, or every level is shown at once.
- Slug `sunburst` · version 1.1.0.0 · GUID (`visualType`) `plumeSunburstE157D96C0C32496286BD12E747C8F76F` · page https://plumevisuals.com/en/visuals/sunburst

### What the visual does

Sunburst Plume (identifier `sunburst`) is a Power BI custom visual (version 1.1.0.0, installed from its `.pbiviz` file; not yet on AppSource) that draws **sunburst charts**: 1 to 8 levels of a hierarchy as concentric rings, from the center (first level) to the edge (last level). Power BI Desktop has no native sunburst chart.

**New in version 1.1.0.0 (30/10/2026):** Format pane reorganized to the shared v2 order (Tooltips, Title, Source note, Frame, Language and numbers); no new feature (native parity was already complete).

- **Two modes** (`layout.mode`): `explore` (default) shows `layout.depth` rings at once (2 by default); a click on a sector **opens the level beneath** with an animated zoom (the sector takes the whole circle), the **breadcrumb** (`nav`) and a click on the **center** go back; `all` shows every ring and a click selects (cross-filter).
- `interaction.click` (explore mode): `zoom` (open; Ctrl + click selects), `zoomSelect` (open and filter the other visuals; going back to the top clears the filter), `select` (never open). A sector with no level beneath is always selected.
- **Labels** follow the arcs when they fit (`labels.orientation` = `auto`), otherwise turn radial, otherwise are shortened with "…" or hidden (never upside down, never one letter, numbers never cut); content: name, value, % of the parent, of the total or of the opened sector.
- **Center**: total, opened sector or hovered sector, with its share of the parent.
- **Others**: at most `rings.maxChildren` sectors per parent (12 by default) and, ★, sectors under `rings.minShare` % of their parent are grouped in one "Others" sector (tooltip lists their names; a click selects them all).
- **Ragged hierarchies**: a blank value stops the branch (`rings.blanks` = `hide`) or shows "(Blank)" (`show`).
- In explore mode, a thin line (`rings.cue`) marks the sectors that can be opened.
- **Play axis ★** (`play` role, premium since the 22/10/2026 rebalancing; usable with the watermark, never blocked): one value of a year, date or ordered text column at a time, with a play bar (▶, start, end, slider, speed ×0.5–×4) and the current value in large type; arcs grow and shrink from one frame to the next (animated transitions), branch colors and the opened sector stay the same. Same shared player and same `play` settings as Scatter Plume.

### 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 (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium**.
- Free in Sunburst Plume: both modes, levels shown at once, the breadcrumb, the center, labels and their orientations, % of parent / total / opened sector, Others by maximum count, sorting, blank handling, equal rings, gaps, corners, start angle, colors by branch or single, the legend, tooltips, cross-filtering, highlighting, keyboard.
- Premium features of Sunburst Plume:
  - `layout.view` = `half` (half circle) or `icicle` (rectangular partition);
  - coloring `dataColors.mode` = `measure` (gradient by the Color field or by the size) or `target` (variance to target); the `auto` mode becomes premium when the Color or Target field is filled;
  - the Comparison field with `compare.band` or `compare.arrows` on (variance band on each sector's outer edge, ▲▼ in labels and center);
  - `rings.summary` (hidden levels drawn as thin rings, explore mode);
  - `interaction.highlight` (sector names that keep their color, the rest dimmed);
  - since the 22/10/2026 rebalancing: the Play axis field with at least one value (« Axe de lecture ★ », card « Lecture ★ » / « Playback ★ »); `dataColors.mode` = `level` (one color per level); `layout.ringSizing` = `area` or `inner` with at least two rings shown (not in icicle); `rings.minShare` when at least one sector is actually grouped by it.
- 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 `sunburst` 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, key accepted for 30 more days, reminders 30 and 7 days before the end). Prices: 39 € personal, 99 € SME, 299 € enterprise per year, or the catalog pack (199 € / 399 € / 1,199 € per year; tiers by number of users: personal 1–10, SME 11–200, enterprise more than 200).

### Expected data shape

One row per combination of the finest level, one column per level, and measures.

| Region (`groups`) | City (`groups`) | Category (`groups`) | Revenue (`value`) | Revenue LY (`comparison` ★) |
|---|---|---|---|---|
| London | Westminster | Furniture | 41,000 | 37,500 |
| London | Camden | Decor | 32,000 | 34,100 |

- **Groups (center to edge)** (`groups`, « Groupes (du centre vers le bord) », 1 to 8 columns, required): the first field is the center ring. Text, numbers (years shown without a thousands separator) and dates (formatted with the column format).
- **Size** (`value`, « Taille », one measure): sector size; only positive values count (negative rows are left out with a warning icon, blank rows ignored). Without it, rows are counted (title "Count by …"). Use an additive measure.
- **Color (measure) ★** (`colorBy`, « Couleur (mesure) »): gradient on the style's gradient palette; a parent gets the size-weighted average of its rows.
- **Target ★** (`target`, « Objectif »): color by variance to target (summed for parents).
- **Comparison ★** (`comparison`, « Comparaison »): value to compare with (e.g. previous year), summed for parents.
- **Play axis ★** (`play`, « Axe de lecture ★ », one column, optional, premium): each value is a frame showing only its rows. Numbers and dates in ascending order (years without a thousands separator, dates with the column format), texts in Power BI's order ("Sort by column" included), blanks last. One value only: no play bar. The tooltip gets a line with the field name and the current frame.
- **Tooltips** (`tooltips`, up to 5 measures, summed for parents) and **Dynamic format** (`format`, see below).
- Volume of data: windows of 30,000 rows, more fetched with `fetchMoreData` up to 1,000,000 rows; Others keeps the number of sectors drawn low (at most 6,000 drawn). 100,004 rows render in well under 3 s.

### DAX recipes

```dax
Revenue = SUM ( Sales[Amount] )
Revenue LY = CALCULATE ( [Revenue], SAMEPERIODLASTYEAR ( Calendar[Date] ) )   // Comparison ★
Margin rate = DIVIDE ( [Margin], [Revenue] )                                    // Color (measure) ★
Planned budget = SUM ( Expenses[Budget] )                                       // Target ★ (with compare.lowerIsBetter = true for costs)
```

### Interactions with the report

- Click: open (explore) or select; the selection ID of a sector combines its path (Region, then City…), so a city selects Region + City. Ctrl for several; click an empty area to clear. A selected sector keeps its parents and children bright.
- Cross-highlighting from other visuals: sectors step back and the highlighted part is drawn in full color.
- Hover: tooltip (path, value, share of parent, share of total, share of the opened sector, Others members, comparison and change, target and variance, color measure, Tooltips measures); report-page tooltips supported; with `interaction.trace` the hovered sector's parents and children stay bright; the center shows the hovered sector.
- Play bar: Space or Enter plays or pauses, arrows step one frame, Page Up / Page Down a tenth, Home / End; the frame is announced to screen readers. On a dashboard tile: opening frame, no autoplay, no transition.
- Keyboard: Tab, arrows to browse sectors, Enter to open (explore) or select, Backspace to go up one level, Esc to clear. High contrast, ARIA labels, French and English.
- Context menu everywhere (sector, empty area, center, breadcrumb, landing page). The opened sector is session state: it is kept after a filter (back to the top if it disappears) but never saved in the report.

### Dynamic formats

- **fx button** (Power BI conditional formatting) on colors and texts of the Format pane; per-category fx on the first-level colors.
- **"Dynamic format" well** (`format`): measures renamed `card.setting` (e.g. `layout.mode`, `title.text`, `center.text`) drive any setting and win over the fixed value. Driving a ★ setting by DAX still shows the watermark without a key.

```dax
// renamed title.text
Dynamic title = "Revenue by channel · 2025 vs 2024: " & FORMAT ( CALCULATE ( DIVIDE ( [Revenue], [Revenue LY] ) - 1, ALLSELECTED () ), "+0.0 %;-0.0 %" )
```

### Format pane: option IDs

- Card order: `license`, `style`, `dataColors`, `layout`, `rings`, `labels`, `center`, `nav`, `compare`, `play`, `legend`, `interaction`, then `title`, `source`, `container`, `texts`. Format pane in version 1.1.0.0 (30/10/2026), top to bottom: `license`, `style`, `dataColors`, `layout`, `rings`, `labels`, `center`, `nav`, `compare`, `play`, `legend`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- `dataColors`: `mode` (`auto` | `branch` | `level` ★ | `single` | `measure` ★ | `target` ★), `single`, `shade` (0–60, 22), `fill` per first-level category.
- `layout`: `mode` (`explore` | `all`), `depth` (1–8, 2), `view` (`sunburst` | `half` ★ | `icicle` ★), `innerRadius` (0–80 %, 30), `ringSizing` (`equal` | `area` ★ | `inner` ★), `ringGap` (0–10, 1.5), `padding` (0–6, 1), `cornerRadius` (0–16, 3), `startAngle` (−180–180, 0).
- `rings`: `sort` (`value` | `valueAsc` | `alpha` | `data`), `maxChildren` (0–200, 12), `minShare` ★ (0–25 %, 0), `othersLabel`, `blanks` (`hide` | `show`), `cue`, `summary` ★.
- `labels`: `show`, `content` (`name` | `nameValue` | `namePct` | `value` | `pct`), `pctOf` (`parent` | `total` | `view`), `orientation` (`auto` | `curved` | `radial` | `tangential`), `fontSize` (10), `color`, `bold`, `units`, `decimals`, `prefix`, `suffix`.
- `center`: `show`, `content` (`auto` | `view` | `total`), `text`, `valueSize` (22), `labelSize` (11), `color`, `back`.
- `nav`: `show`, `rootLabel`, `hint`, `position` (`top` | `bottom`).
- `compare`: `band` ★, `bandWidth` (2–12, 4), `arrows`, `lowerIsBetter`, `neutral` (0–50 %, 2), `scale` (2–200 %, 25), `compareLabel`.
- `play` ★ (card « Lecture ★ », shown with the Play axis field): `start` (`last` | `first`), `speed` (100–10,000 ms per frame, 1000), `loop` (false), `autoPlay` (false; never when animations are reduced), `transition` (true; off as well when `style.animate` is false or the system reduces motion), `controls` (true), `position` (`bottom` | `top`), `ticks` (`auto` | `all` | `none`), `tickLabels`, `stepButtons`, `speedButton` (true), `showLabel` (true), `labelSize` (12–160, 44), `labelPosition` (`bottomRight` | `topRight` | `topLeft` | `bottomLeft` | `center`).
- `legend`: off by default (`show`, `position` = `right`…). `interaction`: `hover`, `dim` (5–80, 25), `click` (`zoom` | `zoomSelect` | `select`), `trace`, `highlight` ★.

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. Booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes.

```json
{
  "visualType": "plumeSunburstE157D96C0C32496286BD12E747C8F76F",
  "query": {
    "queryState": {
      "groups": { "projections": [
        { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Region" } }, "queryRef": "Sales.Region", "nativeQueryRef": "Region" },
        { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "City" } }, "queryRef": "Sales.City", "nativeQueryRef": "City" } ] },
      "value": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Revenue" } }, "queryRef": "Sales.Revenue", "nativeQueryRef": "Revenue" } ] }
    }
  },
  "objects": {
    "layout": [ { "properties": { "mode": { "expr": { "Literal": { "Value": "'all'" } } } } } ],
    "labels": [ { "properties": { "content": { "expr": { "Literal": { "Value": "'namePct'" } } } } } ],
    "license": [ { "properties": { "key": { "expr": { "Literal": { "Value": "'PLUM1.…'" } } } } } ]
  }
}
```

The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from the `.pbiviz` file).

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`. Branch colors come from the style's categorical palette (or custom series 1–8); `minimal` removes corner rounding, the style's `fill` token (hatch, outlined, glass…) paints the sectors.
- `style.themeJson` (Theme JSON ★): a JSON theme as plain text (format v2 with optional `extends` and groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`). Full reference: https://plumevisuals.com/ai/tutorials/en/themes-json.md.

### Common pitfalls

- A single ring although several fields are in Groups: explore mode shows `layout.depth` rings; click a sector or raise the depth, or use `layout.mode` = `all`.
- "Count by …" title: no measure in Size.
- Warning "Negative values ignored": negative rows cannot be ring shares.
- Many gray "Others" sectors: raise `rings.maxChildren` or set 0.
- A click does not filter the page: explore mode opens sectors; use Ctrl + click or `interaction.click` = `zoomSelect`.
- Names missing: sectors too small for their text; enlarge the visual, lower `labels.fontSize`, read the tooltip.
- Watermark visible: a Play axis field, one color per level, comparable-area or first-ring-thicker rings, grouping below a % of the parent, half circle, icicle, measure or target coloring (including `auto` with the Color or Target field), comparison band or arrows, summary rings, highlight, 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)

Small multiples, images or icons in the center, labels outside the circle with leader lines, saving the opened sector in the report or in bookmarks, Power BI's native drill buttons (the visual zooms by itself), values computed from non-additive measures at parent level (parents add up their rows; the Color measure is a size-weighted average).

## Sunburst Plume: data fields

- `groups` Groups (center to edge) / Groupes (du centre vers le bord) (column, 8 max): 1 to 8 fields, from the center ring to the outer ring (e.g. Region, Country, City).
- `value` Size / Taille (measure, 1 max): Measure that sizes each sector (without it, rows are counted).
- `colorBy` Color (measure) ★ / Couleur (mesure) ★ ★ (measure, 1 max): Premium: colors the sectors on the gradient palette (margin rate, satisfaction…).
- `target` Target ★ / Objectif ★ ★ (measure, 1 max): Premium: colors each sector by its variance to target (favorable / unfavorable).
- `comparison` Comparison ★ / Comparaison ★ ★ (measure, 1 max): Premium: value to compare with (e.g. last year), shown as a band on the edge of each sector with ▲▼.
- `play` Play axis ★ / Axe de lecture ★ ★ (column, 1 max): Premium: a date, a year or an ordered category: the sectors grow and shrink from one value to the next (play button).
- `tooltips` Tooltips / Infobulles (measure, 5 max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Sunburst Plume: Format pane options (145)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Layout / Disposition (`layout`)
- `layout.mode` Mode: dropdown, default `explore`; values: `explore` Explore: a click opens the level beneath; `all` All levels always shown. Explore: click a sector to zoom into it (animated), the breadcrumb or the center goes back. All levels: every ring is shown and a click selects (cross-filter).
- `layout.depth` Levels shown at once / Niveaux visibles à la fois: number, default `2`; values: 1 to 8. Visible when `layout.mode` = `explore`. Number of rings shown from the opened sector. The deeper levels open with a click.
- `layout.view` Shape / Forme: dropdown, default `sunburst`; values: `sunburst` Sunburst (circle); `half` Half circle ★; `icicle` Rectangular partition (icicle) ★. Icicle: the same hierarchy as nested bars, from left to right; long names stay readable.
- `layout.innerRadius` Center hole (% of radius) / Trou central (% du rayon): number, default `30`; values: 0 to 80
- `layout.ringSizing` Ring thickness / Épaisseur des anneaux: dropdown, default `equal`; values: `equal` Equal; `area` Comparable areas (outer rings thinner) ★; `inner` First ring thicker ★. With at least two rings shown.
- `layout.ringGap` Space between rings (px) / Espace entre les anneaux (px): number, default `1.5`; values: 0 to 10
- `layout.padding` Space between sectors (px) / Espace entre les secteurs (px): number, default `1`; values: 0 to 6
- `layout.cornerRadius` Sector corner radius (px) / Arrondi des secteurs (px): number, default `3`; values: 0 to 16
- `layout.startAngle` Start angle (°) / Angle de départ (°): number, default `0`; values: -180 to 180. Visible when `layout.view` = `sunburst`

### Data colors / Couleurs des données (`dataColors`, one entry per item with a selector)
- `dataColors.mode` Coloring / Coloration: dropdown, default `auto`; values: `auto` Automatic (by branch; by the Color or Target field when filled); `branch` By branch (first-level color, lighter outward); `level` One color per level ★; `single` Single color; `measure` Gradient by the Color field (or the size) ★; `target` Variance to target (favorable / unfavorable) ★
- `dataColors.single` Color / Couleur: color, default (empty); values: hex color
- `dataColors.fill` Color / Couleur: color, default (empty); values: hex color
- `dataColors.shade` Lighten at each level (%) / Éclaircir à chaque niveau (%): number, default `22`; values: 0 to 60. By branch and single color: each ring is lighter than the one inside it, so the levels stay readable.

### Sectors and levels / Secteurs et niveaux (`rings`)
- `rings.sort` Sector order / Ordre des secteurs: dropdown, default `value`; values: `value` Largest first; `valueAsc` Smallest first; `alpha` Alphabetical; `data` Data order (Sort by column)
- `rings.maxChildren` Sectors per parent at most (0 = all) / Secteurs par parent au plus (0 = tous): number, default `12`; values: 0 to 200. The smallest sectors of a parent beyond this number are grouped in « Others ».
- `rings.minShare` Group below (% of parent) ★ / Regrouper sous (% du parent) ★ ★: number, default `0`; values: 0 to 25. Sectors smaller than this share of their parent join « Others » (in addition to the maximum number).
- `rings.othersLabel` Grouping label / Libellé du regroupement: text, default (empty)
- `rings.blanks` Blank values of a level / Valeurs vides d'un niveau: dropdown, default `hide`; values: `hide` Stop the branch (ragged hierarchy); `show` Show « (Blank) ». Stop: a country without regions keeps its sector, with nothing outside it.
- `rings.cue` Hidden levels cue / Repère des niveaux masqués: toggle, default `true`; values: true / false. Exploration: a thin line outside the sectors that can be opened.
- `rings.summary` Summarize hidden levels (thin rings) ★ / Résumer les niveaux masqués (anneaux fins) ★ ★: toggle, default `false`; values: true / false. Exploration: the levels beyond « Levels shown at once » are drawn as thin rings, so the whole depth stays visible.

### Data labels / Étiquettes de données (`labels`)
- `labels.show` Show / Afficher: toggle, default `true`; values: true / false
- `labels.content` Content / Contenu: dropdown, default `name`; values: `name` Name; `nameValue` Name and value; `namePct` Name and percentage; `value` Value; `pct` Percentage
- `labels.pctOf` Percentage of / Pourcentage calculé sur: dropdown, default `parent`; values: `parent` The parent; `total` The total; `view` The opened sector (center)
- `labels.orientation` Orientation: dropdown, default `auto`; values: `auto` Automatic (along the arc, else radial); `curved` Along the arc (curved); `radial` Radial; `tangential` Tangential (straight). A label that does not fit its sector is shortened (…) or hidden: it stays in the tooltip.
- `labels.fontSize` Text size / Taille du texte: number, default `10`; values: 6 to 24
- `labels.color` Color (empty = automatic) / Couleur (vide = automatique): color, default (empty); values: hex color. Automatic: white or dark depending on the sector color.
- `labels.bold` Bold / Gras: toggle, default `false`; values: true / false
- `labels.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `labels.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `labels.prefix` Prefix / Préfixe: text, default (empty)
- `labels.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)

### Center / Centre (`center`)
- `center.show` Show / Afficher: toggle, default `true`; values: true / false
- `center.content` Content / Contenu: dropdown, default `auto`; values: `auto` Opened sector, or hovered one; `view` Opened sector only; `total` Always the total
- `center.text` Total label / Libellé du total: text, default (empty)
- `center.valueSize` Value size / Taille de la valeur: number, default `22`; values: 8 to 72. Shrinks automatically when the center is small.
- `center.labelSize` Label size / Taille du libellé: number, default `11`; values: 6 to 30
- `center.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `center.back` Click the center = go up one level / Clic au centre = remonter d'un niveau: toggle, default `true`; values: true / false

### Breadcrumb / Fil d'Ariane (`nav`)
- `nav.show` Show (explore mode) / Afficher (exploration): toggle, default `true`; values: true / false
- `nav.rootLabel` First item label / Libellé du premier élément: text, default (empty)
- `nav.hint` « Click to open » hint / Aide « cliquez pour ouvrir »: toggle, default `true`; values: true / false
- `nav.position` Position: dropdown, default `top`; values: `top` Top; `bottom` Bottom

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

### Comparison and target / Comparaison et objectif (`compare`)
- `compare.band` Variance band on the sector edge ★ / Bande d'écart au bord des secteurs ★ ★: toggle, default `true`; values: true / false. With the Comparison field: a thin band on the outer edge of each sector, favorable or unfavorable, darker when the change is larger.
- `compare.bandWidth` Band width (px) / Épaisseur de la bande (px): number, default `4`; values: 2 to 12
- `compare.arrows` ▲▼ and change in labels / ▲▼ et écart dans les étiquettes: toggle, default `true`; values: true / false
- `compare.lowerIsBetter` A decrease is favorable / Une baisse est favorable: toggle, default `false`; values: true / false. Costs, delays, returns: below the comparison or the target is good.
- `compare.neutral` Neutral zone (± %) / Zone neutre (± %): number, default `2`; values: 0 to 50
- `compare.scale` Change for the strongest color (%) / Écart pour la couleur la plus forte (%): number, default `25`; values: 2 to 200
- `compare.compareLabel` Comparison name / Nom de la comparaison: text, default (empty)

### Playback ★ / Lecture ★ (`play`)
- `play.start` Frame shown on opening / Image affichée à l'ouverture: dropdown, default `last`; values: `last` The last one (most recent); `first` The first one
- `play.speed` Duration of a frame (ms) / Durée d'une image (ms): number, default `1000`; values: 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, default `false`; values: true / false
- `play.autoPlay` Play automatically on opening / Lecture automatique à l'ouverture: toggle, default `false`; values: 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, default `true`; values: true / false. Values, positions and colors move smoothly from one frame to the next.
- `play.controls` Play bar / Barre de lecture: toggle, default `true`; values: true / false
- `play.position` Bar position / Position de la barre: dropdown, default `bottom`; values: `bottom` Bottom; `top` Top. Visible when `play.controls` = `true`
- `play.ticks` Tick marks / Graduations: dropdown, default `auto`; values: `auto` Automatic; `all` Every frame; `none` None. Visible when `play.controls` = `true`
- `play.tickLabels` Tick labels / Étiquettes des graduations: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.stepButtons` Start and end buttons / Boutons début et fin: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.speedButton` Speed button / Bouton de vitesse: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.showLabel` Current value in large type / Valeur en cours en grand: toggle, default `true`; values: true / false
- `play.labelSize` Large value size / Taille de la valeur en grand: number, default `44`; values: 12 to 160. Visible when `play.showLabel` = `true`
- `play.labelPosition` Large value position / Position de la valeur en grand: dropdown, default `bottomRight`; values: `bottomRight` Bottom right; `topRight` Top right; `topLeft` Top left; `bottomLeft` Bottom left; `center` Center. Visible when `play.showLabel` = `true`

### Interactions (`interaction`)
- `interaction.hover` Highlight on hover / Mettre en avant au survol: toggle, default `true`; values: true / false
- `interaction.dim` Dimmed items opacity (%) / Opacité des éléments estompés (%): number, default `25`; values: 5 to 80
- `interaction.click` Click on a sector (explore mode) / Clic sur un secteur (exploration): dropdown, default `zoom`; values: `zoom` Open the sector (Ctrl + click: select); `zoomSelect` Open and filter the other visuals; `select` Select only. A sector without a level beneath is always selected.
- `interaction.trace` Trace the path on hover / Suivre le chemin au survol: toggle, default `true`; values: true / false. Hovering a sector keeps its parents and its children bright; the rest steps back.
- `interaction.highlight` Highlight ★ / Mettre en avant ★ ★: text, default (empty). Only these sectors (any level, separated by ;), their parents and their children keep their color. Stays on the page, in PDF exports too.

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Stream Plume

- How the make-up of a total changes over time: flowing streams, named where they are thickest.
- Slug `stream-graph` · version 1.1.0.0 · GUID (`visualType`) `plumeStreamGraphBD58E5BDB1F84D8B9E68756C1DFFB2D4` · page https://plumevisuals.com/en/visuals/stream-graph

### What the visual does

Stream Plume (identifier `stream-graph`) is a Power BI custom visual (version 1.1.0.0, installed from its `.pbiviz` file; not yet on AppSource) that draws **streamgraphs**: stacked areas flowing around a central axis, to show how the make-up of a total changes over time. Power BI Desktop has no native streamgraph (only stacked areas on zero); Microsoft's free Stream Graph visual has per-point labels and fixed tooltips.

**New in version 1.1.0.0 (30/10/2026):** Format pane reorganized (new **Gridlines** card, `events` → `annotations`, `reference` → `refPeriod`); free reference lines (Analytics pane), annotations like Line Plume (anchored on a stream), playback on the shared player (`play.speed` per frame, autoplay); `play.duration` is no longer read.

- **Four layouts** (`streams.offset`): `wiggle` (flowing streams, Byron and Wattenberg's weighted-wiggle baseline, then straightened so the chart does not drift), `silhouette` (symmetric around a straight line), `expand` (each date = 100%), `zero` (classic stacked areas with a Y axis).
- **Stream order** (`streams.order`, bottom to top): `insideOut` (largest in the middle, default), `total`, `peak` ★ (by peak date), `name`, `data`, `custom` (`streams.customOrder` = names separated by `;`; others follow); `streams.reverse`.
- **Smooth edges that never cross** (`streams.curve` = `smooth`, a clamped B-spline like d3.curveBasis), `linear` or `step` ★.
- **Stream names written inside the streams**, where they are thickest, sized by thickness (`streamLabels.autoSize`, `fontSize` min 10, `maxSize` 15), never overlapping; a stream too thin keeps no label. Content: name, name and value, name and total, name and share, name and change vs. the reference period ★.
- **Size scale**: flowing and centered streams have no zero, so a vertical "↕ 200 k€" marker replaces the Y axis (`yAxis.scaleBar`); `zero` and `expand` show a real Y axis.
- Hover a stream: the others fade; tooltip with value, share, rank, change vs. previous point, total at the date, Tooltips measures (or every stream at the date with `tooltip.tipAll`). Click = select the stream (Ctrl for several), legend click too, cross-highlighting drawn as the highlighted part of each stream.
- **Small multiples** (`multiples` role): one panel per value, shared scale (same thickness for the same value) free, independent scale ★.
- **Time**: a left-to-right reveal when shown and when the data changes (`streams.reveal`), edges glide when only values change; "Reduce motion" respected. ★ playback cursor (`play.controls`, premium since the 22/10/2026 rebalancing; the reveal on loading stays free), with a ★ live ranking; ★ navigator.

### 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` ("Theme JSON ★") are **premium**.
- Free in Stream Plume: the four layouts, the orders `insideOut`, `total`, `name`, `data`, `custom`, smooth and straight edges, solid and **hatch** fills, opacity and separator, labels (name, value, total), size scale, Y axis, legend, small multiples with a shared scale, reveal animation, tooltips, selection, highlighting, keyboard.
- Premium features of Stream Plume:
  - `dataColors.mode` = `gradient` (style gradient by size) or `highlight` (`highlightWhat` = `risers` | `fallers` | `top` | `names`, `highlightN`, `highlightNames`, `highlightColor`, `othersColor`);
  - `streams.fill` = `gradient` (gradient toward the present); `streams.topN` (Top N + "Others": `n`, `othersLabel`, `othersColor`);
  - `edgeValues.show` (start and end values, `side`, `content` = `value` | `share` | `valueChange` | `nameValue`);
  - `streamLabels.content` = `nameChange`;
  - `refPeriod.show` (Analytics pane: `from`, `to`, `label`, `shade`, `color`, `opacity`, `tooltip`);
  - `events` (Analytics pane: `list`) and the `events` role (text measure);
  - `navigator.show` (`height`, `from`, `to`); `play.ranking` (ranking at the cursor date, `rankCount`; counts only when `play.controls` is on);
  - `smallMultiples.scale` = `independent`;
  - since the 22/10/2026 rebalancing: `play.controls` (playback cursor, card « Lecture ★ » / « Playback ★ », at least two axis positions); `streams.order` = `peak` (at least two streams); `streams.curve` = `step` (at least two positions); `streamLabels.content` = `nameShare` (labels shown).
- The watermark is decided on ★ features **really applied**: a highlight that finds no stream, a Top N that groups nothing, a reference period outside the axis or an empty event list show no watermark.
- 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.
- Accepted keys: only keys starting with `PLUM1.` shown in the buyer's account on plumevisuals.com, checked offline (Ed25519 signature), covering `stream-graph` or the whole catalog. Licenses last one year (one-time payment). Prices: 39 € personal, 99 € SME, 299 € enterprise per year, or the catalog pack.

### Expected data shape

One row per date and per category, with a measure for the amount.

| Time axis (`axis`) | Streams (`series`) | Values (`values`) |
|---|---|---|
| 2025-01-01 | Web | 61,000 |
| 2025-01-01 | Stores | 42,000 |
| 2025-02-01 | Web | 66,000 |

- **Time axis** (`axis`, « Axe de temps », one column, required): a date **column** (not the automatic date hierarchy) gives a continuous time axis; an integer column between 1000 and 3000 is read as years; text gives a category axis in data order (`xAxis.type` = `categorical` forces it).
- **Streams (legend)** (`series`, « Flux (légende) », one column): one stream per value, with exactly one measure in Values. Without it, each measure in Values is a stream.
- **Values** (`values`, « Valeurs »): the thickness. Negative values count as zero (warning in edit mode); missing values count as zero.
- **Small multiples** (`multiples`), **Events (text) ★** (`events`, text measure: a marker wherever it is not empty), **Tooltips** (`tooltips`), **Dynamic format** (`format`).
- Data view: categorical mapping with Small multiples, Time axis and Streams as **categories** (one row per point), so the 30,000-row window applies to every point; more rows are fetched with `fetchMoreData` up to 100,000. Beyond one point per 1.5 pixels, neighboring dates are averaged into groups (tooltip "start – end"). 100,004 rows render in under 4 s.

### DAX recipes

```dax
Revenue = SUM ( Sales[Amount] )
// Events (text) ★: a marker on September 2023
Event = IF ( MAX ( Sales[Month] ) = DATE ( 2023, 9, 1 ), "Marketplaces launch" )
// Dynamic format, renamed title.text: a title computed on the whole selection
Sales title = "Revenue by channel: " & FORMAT ( CALCULATE ( [Revenue], ALLSELECTED () ), "$#,0" )
```

### List syntax

- `streams.customOrder`: `Stores; Web` (bottom to top, case and accents ignored).
- `dataColors.highlightNames`: `Web; Export`.
- `annotations.list` ★: one line per event, `x | text | #RRGGBB` (color optional), `x1..x2 | text` for a shaded period; x = date (`2020-03-17`, `2020-03`, `2020`, `17/03/2020`), number or category as displayed; `#` or `//` lines are comments.
- `refPeriod.from` / `refPeriod.to`, `navigator.from` / `navigator.to`: same formats; an empty `refPeriod.to` = the same period (`2019` = the 12 months of 2019).

### Interactions with the report

- Click a stream: cross-filter on that stream value (identity of the Streams value alone); Ctrl for several; click "Others" = all grouped streams; click an empty area clears. Legend click selects, legend hover brings the stream forward.
- Context menu everywhere (on a stream: the point = small multiple + date + stream; elsewhere: the visual).
- Keyboard: Tab to the chart, ← → dates, ↑ ↓ streams, Enter selects, Esc clears (and stops playback). ARIA labels and screen reader announcements in French and English.
- Navigator ★: drag the window or its handles, wheel zoom on the chart, double-click to reset; the window is per session (not saved). Playback ★: ▶ / Pause button at the top right, Esc stops; steps instead of a smooth glide when motion is reduced.
- The visual never calls `persistProperties`.

### Format pane: option IDs

- Card order: `license`, `style`, `dataColors`, `streams`, `streamLabels`, `edgeValues`, `xAxis`, `yAxis`, `legend`, `smallMultiples`, `navigator`, `play`, `interaction`, then `title`, `source`, `container`, `texts`; Analytics pane: `reference`, `annotations`. Format pane in version 1.1.0.0 (30/10/2026), top to bottom: `license`, `style`, `dataColors`, `streams`, `streamLabels`, `edgeValues`, `xAxis`, `yAxis`, `gridlines`, `legend`, `annotations`, `navigator`, `smallMultiples`, `play`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`; Analytics pane: `refPeriod`, `reference`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- `streams`: `offset` (`wiggle` | `silhouette` | `expand` | `zero`), `order` (`insideOut` | `total` | `peak` ★ | `name` | `data` | `custom`), `customOrder`, `reverse`, `curve` (`smooth` | `linear` | `step` ★), `fill` (`solid` | `gradient` ★ | `hatch`), `opacity` (10–100, 92), `outline`, `outlineWidth` (0.8), `reveal`, `topN` ★, `n` (8), `othersLabel`, `othersColor`.
- `streamLabels`: `show`, `content` (`name` | `nameValue` | `nameTotal` | `nameShare` ★ | `nameChange` ★), `placement` (`thickest` | `end` | `start`), `autoSize`, `fontSize` (10), `maxSize` (15), `color`, `bold`, `halo`, `hideLegend`, `units`, `decimals`, `prefix`, `suffix`.
- `edgeValues` ★: `show`, `side` (`both` | `end` | `start`), `content`, `fontSize` (9), `colorBy` (`series` | `text`), `units`, `decimals`, `prefix`, `suffix`.
- `xAxis`: `show`, `fontSize`, `color`, `labelMode`, `maxSize`, `line`, `type` (`auto` | `continuous` | `categorical`), `dateFormat`, `showTitle`, `titleText`, `gridlines.vShow` (on), `gridlines.vStyle`.
- `yAxis`: `show`, `scaleBar`, `position`, `fontSize`, `color`, `units`, `decimals`, `prefix`, `suffix`, `line`, `min`, `max`, `ticks`, `showTitle`, `titleText`, `gridlines.hShow`, `gridlines.hStyle`, `gridlines.hColor`, `gridlines.zeroLine`.
- `smallMultiples`: `columns` (0 = auto), `gap` (14), `scale` (`shared` | `independent` ★), `border`, `titleShow`, `titleSize`, `titleColor`, `titleTotal`.
- `navigator` ★: `show`, `height` (38), `from`, `to`. `play` (shared player): `controls` ★, `speed` (duration of one frame in ms; replaces the former `duration` of a whole run, which is no longer read), `loop`, `autoPlay`, `start`, `ranking` ★ (off), `rankCount` (5).
- `interaction`: `hover`, `dim` (25), `crosshair`, `tooltip.tipAll`. `reference` ★ and `events` ★: see above.

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs.

```json
{
  "visualType": "plumeStreamGraphBD58E5BDB1F84D8B9E68756C1DFFB2D4",
  "query": {
    "queryState": {
      "axis":   { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Month" } }, "queryRef": "Sales.Month", "nativeQueryRef": "Month" } ] },
      "series": { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Channel" } }, "queryRef": "Sales.Channel", "nativeQueryRef": "Channel" } ] },
      "values": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Revenue" } }, "queryRef": "Sales.Revenue", "nativeQueryRef": "Revenue" } ] }
    }
  },
  "objects": {
    "streams":      [ { "properties": { "offset": { "expr": { "Literal": { "Value": "'silhouette'" } } } } } ],
    "streamLabels": [ { "properties": { "content": { "expr": { "Literal": { "Value": "'nameTotal'" } } }, "hideLegend": { "expr": { "Literal": { "Value": "true" } } } } } ]
  }
}
```

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual. `minimal` hides the vertical grid and the legend (names stay in the streams); `blackWhite` uses hatching; a style with `fill` = `hatch` or `outlined` changes the fill when it was left at its default.
- `style.themeJson` (Theme JSON ★): see https://plumevisuals.com/ai/tutorials/en/themes-json.md.

### Common pitfalls

- One wide stream, or one stream per year: the date hierarchy is used instead of the date column.
- No Y axis: expected for `wiggle` and `silhouette` (no zero); read the size scale or use `zero` / `expand`.
- A stream has no label: it is too thin everywhere; lower `streamLabels.fontSize`.
- "Negative values counted as zero": a stream cannot be negative; use Waterfall Plume or Bar Plume for changes.
- Watermark visible: a ★ feature really applied (see above), 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)

Negative streams or diverging streams, a saved navigator window or playback position, streams scrolled vertically in small multiples, image textures, exporting the chart as an image, a separate Play axis field (the time axis itself is played: `play.controls`), speed buttons on a play bar.

## Stream Plume: data fields

- `axis` Time axis / Axe de temps (column, 4 max): Date, year, number or ordered category (months, quarters…) along which the streams flow.
- `series` Streams (legend) / Flux (légende) (column, 1 max): One stream per value of this field. Without it, each measure in Values is a stream.
- `values` Values / Valeurs (measure, several max): 
- `multiples` Small multiples / Petits multiples (column, 1 max): 
- `events` Annotations (text) ★ / Annotations (texte) ★ ★ (measure, 1 max): Optional text measure: a vertical marker with its text wherever it is not empty.
- `tooltips` Tooltips / Infobulles (measure, several max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Stream Plume: Format pane options (249)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Data colors / Couleurs des données (`dataColors`, one entry per item with a selector)
- `dataColors.mode` Coloring / Coloration: dropdown, default `auto`; values: `auto` Palette (one color per stream); `gradient` Style gradient (largest to smallest) ★; `highlight` Highlight streams ★
- `dataColors.single` Color / Couleur: color, default (empty); values: hex color
- `dataColors.fill` Color / Couleur: color, default (empty); values: hex color
- `dataColors.highlightWhat` Highlighted streams / Flux mis en avant: dropdown, default `risers`; values: `risers` Biggest risers; `fallers` Biggest fallers; `top` Largest; `names` Named streams. Risers and fallers: from the first to the last point shown (or since the reference period when it is shown).
- `dataColors.highlightN` Number of streams / Nombre de flux: number, default `2`; values: 1 to 20
- `dataColors.highlightNames` Stream names (separated by ;) / Noms des flux (séparés par ;): text, default (empty)
- `dataColors.highlightColor` Highlight color (empty = stream color) / Couleur mise en avant (vide = celle du flux): color, default (empty); values: hex color
- `dataColors.othersColor` Other streams color (empty = style gray) / Couleur des autres flux (vide = gris du style): color, default (empty); values: hex color

### Streams / Flux (`streams`)
- `streams.offset` Layout / Disposition: dropdown, default `wiggle`; values: `wiggle` Flowing streams (streamgraph); `silhouette` Centered on the axis; `expand` 100% (shares of the total); `zero` Stacked areas (from zero). Flowing streams: the baseline follows the streams to minimize slopes (Byron and Wattenberg streamgraph). Centered: symmetric around a line. 100%: each date adds up to 100%. Stacked areas: from zero, with a Y axis.
- `streams.order` Stream order / Ordre des flux: dropdown, default `insideOut`; values: `insideOut` Largest in the middle; `total` By total (largest at the bottom); `peak` By peak date ★; `name` By name (A → Z, bottom to top); `data` Data order; `custom` Custom order
- `streams.customOrder` Bottom-to-top order (names separated by ;) / Ordre de bas en haut (noms séparés par ;): text, default (empty). Visible when `streams.order` = `custom`. Streams not listed follow, in "Largest in the middle" order.
- `streams.reverse` Reverse the order / Inverser l'ordre: toggle, default `false`; values: true / false
- `streams.curve` Edge shape / Forme des bords: dropdown, default `smooth`; values: `smooth` Smooth; `linear` Straight; `step` Step ★
- `streams.fill` Fill / Remplissage: dropdown, default `solid`; values: `solid` Solid; `gradient` Gradient toward the present ★; `hatch` Hatching (print, color blindness)
- `streams.opacity` Opacity (%) / Opacité (%): number, default `92`; values: 10 to 100
- `streams.outline` Separator between streams / Liseré entre les flux: toggle, default `true`; values: true / false
- `streams.outlineWidth` Separator width / Épaisseur du liseré: number, default `0.8`; values: 0.2 to 4. Visible when `streams.outline` = `true`
- `streams.reveal` Left-to-right reveal / Révélation de gauche à droite: toggle, default `true`; values: true / false. Streams draw along time when shown and when the data changes (never when the system asks to reduce motion).
- `streams.topN` Show / Afficher: toggle, default `false`; values: true / false. Keeps the N largest streams (total over the period) and groups the rest into an "Others" stream.
- `streams.n` N: number, default `8`; values: 1 to 50
- `streams.othersLabel` "Others" label / Libellé « Autres »: text, default (empty)
- `streams.othersColor` "Others" color (empty = gray) / Couleur de « Autres » (vide = gris): color, default (empty); values: hex color

### Stream labels / Étiquettes des flux (`streamLabels`)
- `streamLabels.show` Show / Afficher: toggle, default `true`; values: true / false. Writes each stream's name inside the stream, where it is thickest, without overlap; a stream that is too thin stays unlabeled (its name is in the legend and the tooltip).
- `streamLabels.content` Content / Contenu: dropdown, default `name`; values: `name` Name; `nameValue` Name and value at that point; `nameTotal` Name and total; `nameShare` Name and share of the total ★; `nameChange` Name and change vs. the reference period ★
- `streamLabels.placement` Position: dropdown, default `thickest`; values: `thickest` Where the stream is thickest; `end` Near the end; `start` Near the start
- `streamLabels.autoSize` Size follows stream thickness / Taille selon l'épaisseur du flux: toggle, default `true`; values: true / false
- `streamLabels.fontSize` Size (minimum when automatic) / Taille (minimale si automatique): number, default `10`; values: 6 to 24
- `streamLabels.maxSize` Maximum size / Taille maximale: number, default `15`; values: 6 to 40. Visible when `streamLabels.autoSize` = `true`
- `streamLabels.color` Color (empty = automatic) / Couleur (vide = automatique): color, default (empty); values: hex color. Automatic: white or dark depending on the stream color.
- `streamLabels.bold` Bold / Gras: toggle, default `true`; values: true / false
- `streamLabels.halo` Text halo / Halo autour du texte: toggle, default `false`; values: true / false
- `streamLabels.hideLegend` Hide the legend / Masquer la légende: toggle, default `false`; values: true / false. Streams are named in the chart: the legend can go.
- `streamLabels.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `streamLabels.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `streamLabels.prefix` Prefix / Préfixe: text, default (empty)
- `streamLabels.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)

### Edge values ★ / Valeurs aux bords ★ (`edgeValues`)
- `edgeValues.show` Show / Afficher: toggle, default `false`; values: true / false. Value of each stream at the first and last point, facing the stream, on both sides of the chart (without overlap).
- `edgeValues.side` Sides / Côtés: dropdown, default `both`; values: `both` Start and end; `end` End; `start` Start
- `edgeValues.content` Content / Contenu: dropdown, default `valueChange`; values: `value` Value; `share` Share of the total at that date; `valueChange` Value, and change at the end; `nameValue` Name and value
- `edgeValues.fontSize` Text size / Taille du texte: number, default `9`; values: 6 to 20
- `edgeValues.colorBy` Color / Couleur: dropdown, default `series`; values: `series` Stream color; `text` Text
- `edgeValues.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `edgeValues.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `edgeValues.prefix` Prefix / Préfixe: text, default (empty)
- `edgeValues.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)

### Time axis / Axe de temps (`xAxis`)
- `xAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `xAxis.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `xAxis.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `xAxis.labelMode` Long labels / Étiquettes longues: dropdown, default `auto`; values: `auto` Automatic; `wrap` Two lines; `rotate45` Tilted (45°); `rotate90` Vertical; `truncate` Truncated (…)
- `xAxis.maxSize` Maximum room (% of the visual) / Place maximale (% du visuel): number, default `30`; values: 10 to 60
- `xAxis.line` Axis line / Trait de l'axe: toggle, default `true`; values: true / false
- `xAxis.type` Axis type / Type d'axe: dropdown, default `auto`; values: `auto` Automatic; `continuous` Continuous; `categorical` Categorical. Continuous: dates and numbers are spaced by their real gap.
- `xAxis.dateFormat` Date format / Format des dates: text, default (empty)
- `xAxis.showTitle` Show / Afficher: toggle, default `false`; values: true / false
- `xAxis.titleText` Text / Texte: text, default (empty). Visible when `xAxis.showTitle` = `true`

### Y axis / Axe Y (`yAxis`)
- `yAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `yAxis.scaleBar` Size scale (flowing and centered streams) / Échelle de grandeur (flux ondulants et centrés): toggle, default `true`; values: true / false. Flowing and centered streams have no zero: instead of the axis, a vertical marker shows the thickness of a round value (e.g. ↕ 100k).
- `yAxis.position` Position: dropdown, default `left`; values: `left` Left; `right` Right
- `yAxis.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `yAxis.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `yAxis.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `yAxis.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `yAxis.prefix` Prefix / Préfixe: text, default (empty)
- `yAxis.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)
- `yAxis.line` Axis line / Trait de l'axe: toggle, default `false`; values: true / false
- `yAxis.min` Minimum: text, default (empty). Stacked areas only (flowing, centered and 100% streams have their own scale).
- `yAxis.max` Maximum: text, default (empty)
- `yAxis.ticks` Number of ticks (approx.) / Nombre de graduations (environ): number, default `5`; values: 2 to 20
- `yAxis.showTitle` Show / Afficher: toggle, default `false`; values: true / false
- `yAxis.titleText` Text / Texte: text, default (empty). Visible when `yAxis.showTitle` = `true`

### Gridlines / Quadrillage (`gridlines`)
- `gridlines.hShow` Show / Afficher: toggle, default `true`; values: true / false
- `gridlines.hColor` Color (empty = style grid) / Couleur (vide = grille du style): color, default (empty); values: hex color
- `gridlines.hWidth` Width / Épaisseur: number, default `1`; values: 0.5 to 6
- `gridlines.hStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `gridlines.zeroLine` Zero line / Ligne du zéro: toggle, default `true`; values: true / false
- `gridlines.vShow` Show / Afficher: toggle, default `true`; values: true / false
- `gridlines.vColor` Color (empty = style grid) / Couleur (vide = grille du style): color, default (empty); values: hex color
- `gridlines.vWidth` Width / Épaisseur: number, default `1`; values: 0.5 to 6
- `gridlines.vStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted

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

### Annotations ★ (`annotations`)
- `annotations.show` Show / Afficher: toggle, default `true`; values: true / false
- `annotations.list` Annotations (one per line) / Annotations (une par ligne): textarea, default (empty). "x | text": vertical marker on the date; "x | stream | text": attached to the stream's layer; "x1..x2 | text": shaded period. x = date (2024-03-15, 2024-03, 2024), number or category as displayed. Optional color #RRGGBB last ("… | #C0392B"). "\n" starts a new line. The measure in the "Annotations (text)" field adds its own.
- `annotations.content` Displayed content / Contenu affiché: dropdown, default `text`; values: `text` Text; `textX` Text and date; `textValue` Text and value (stream)
- `annotations.editOnChart` Edit on the chart (edit mode) / Modifier sur le graphique (mode édition): toggle, default `true`; values: true / false. In edit mode, annotations can be dragged, edited with a double-click and removed with × (single panel).
- `annotations.style` Style: dropdown, default `plain`; values: `bubble` Bubble; `filled` Filled label; `plain` Text only
- `annotations.color` Color (empty = secondary text or stream) / Couleur (vide = texte secondaire ou flux): color, default (empty); values: hex color
- `annotations.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `annotations.bold` Bold / Gras: toggle, default `true`; values: true / false
- `annotations.maxWidth` Maximum width (px) / Largeur maximale (px): number, default `160`; values: 60 to 400
- `annotations.anchor` Vertical marker text / Texte des repères verticaux: dropdown, default `top`; values: `top` Top; `bottom` Bottom; `none` None (line only)
- `annotations.lineStyle` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `annotations.width` Width / Épaisseur: number, default `1`; values: 0.5 to 6
- `annotations.bandOpacity` Periods opacity (%) / Opacité des périodes (%): number, default `10`; values: 2 to 60
- `annotations.marker` Marker on the stream / Repère sur le flux: toggle, default `true`; values: true / false
- `annotations.connector` Connector / Trait vers le flux: dropdown, default `line`; values: `line` Line; `none` None
- `annotations.position` Default position / Position par défaut: dropdown, default `auto`; values: `auto` Automatic (no overlap); `above` Above; `below` Below; `right` Right; `left` Left
- `annotations.distance` Distance from the point (px) / Distance au point (px): number, default `18`; values: 6 to 160

### Navigator ★ / Navigateur ★ (`navigator`)
- `navigator.show` Show / Afficher: toggle, default `false`; values: true / false. Mini chart under the streams: drag the window or its edges to zoom into a period, double-click to see everything again. The mouse wheel also zooms the chart.
- `navigator.height` Height (px) / Hauteur (px): number, default `38`; values: 20 to 120
- `navigator.from` Window start when opened / Début de la fenêtre à l'ouverture: text, default (empty). Date, year, number or category (e.g. 2024-01). Empty: from the start.
- `navigator.to` Window end when opened / Fin de la fenêtre à l'ouverture: text, default (empty)

### Small multiples / Petits multiples (`smallMultiples`)
- `smallMultiples.columns` Columns (0 = automatic) / Colonnes (0 = automatique): number, default `0`; values: 0 to 12
- `smallMultiples.gap` Spacing (px) / Espacement (px): number, default `14`; values: 0 to 60
- `smallMultiples.scale` Stream scale / Échelle des flux: dropdown, default `shared`; values: `shared` Shared by all panels; `independent` Independent per panel ★. Shared: the same value has the same thickness in every panel.
- `smallMultiples.border` Panel border / Cadre des panneaux: toggle, default `false`; values: true / false
- `smallMultiples.titleShow` Title of each panel / Titre de chaque panneau: toggle, default `true`; values: true / false
- `smallMultiples.titleSize` Text size / Taille du texte: number, default `10`; values: 6 to 24. Visible when `smallMultiples.titleShow` = `true`
- `smallMultiples.titleColor` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color. Visible when `smallMultiples.titleShow` = `true`
- `smallMultiples.titleTotal` Total in the title / Total dans le titre: toggle, default `false`; values: true / false. Visible when `smallMultiples.titleShow` = `true`

### Playback ★ / Lecture ★ (`play`)
- `play.start` Frame shown on opening / Image affichée à l'ouverture: dropdown, default `last`; values: `last` The last one (most recent); `first` The first one
- `play.speed` Duration of a frame (ms) / Durée d'une image (ms): number, default `400`; values: 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, default `false`; values: true / false
- `play.autoPlay` Play automatically on opening / Lecture automatique à l'ouverture: toggle, default `false`; values: 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, default `true`; values: true / false. Values, positions and colors move smoothly from one frame to the next.
- `play.controls` Play bar / Barre de lecture: toggle, default `false`; values: true / false. ▶ button, graduated slider, start / end and speed: a cursor travels through time and veils what comes next. The left-to-right reveal on loading (Streams card) stays free.
- `play.position` Bar position / Position de la barre: dropdown, default `bottom`; values: `bottom` Bottom; `top` Top. Visible when `play.controls` = `true`
- `play.ticks` Tick marks / Graduations: dropdown, default `auto`; values: `auto` Automatic; `all` Every frame; `none` None. Visible when `play.controls` = `true`
- `play.tickLabels` Tick labels / Étiquettes des graduations: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.stepButtons` Start and end buttons / Boutons début et fin: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.speedButton` Speed button / Bouton de vitesse: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.showLabel` Current value in large type / Valeur en cours en grand: toggle, default `false`; values: true / false
- `play.labelSize` Large value size / Taille de la valeur en grand: number, default `44`; values: 12 to 160. Visible when `play.showLabel` = `true`
- `play.labelPosition` Large value position / Position de la valeur en grand: dropdown, default `bottomRight`; values: `bottomRight` Bottom right; `topRight` Top right; `topLeft` Top left; `bottomLeft` Bottom left; `center` Center. Visible when `play.showLabel` = `true`
- `play.ranking` Ranking at the cursor date ★ / Classement à la date du curseur ★ ★: toggle, default `false`; values: true / false. Box with the top streams (value and share) at the cursor date, updated during playback.
- `play.rankCount` Streams in the ranking / Flux dans le classement: number, default `5`; values: 1 to 20. Visible when `play.ranking` = `true`

### Interactions (`interaction`)
- `interaction.hover` Highlight on hover / Mettre en avant au survol: toggle, default `true`; values: true / false
- `interaction.dim` Dimmed items opacity (%) / Opacité des éléments estompés (%): number, default `25`; values: 5 to 80
- `interaction.crosshair` Vertical guide on hover / Repère vertical au survol: toggle, default `true`; values: true / false

### Reference period ★ / Période de référence ★ (`refPeriod`, Analytics pane)
- `refPeriod.show` Show / Afficher: toggle, default `false`; values: true / false. Shades a period (e.g. 2019 or 2020-01..2020-06) and compares each stream to its average over that period: change in the tooltip, in the labels and for highlighted streams.
- `refPeriod.from` Start (date, year, number or category) / Début (date, année, nombre ou catégorie): text, default (empty)
- `refPeriod.to` End (empty = same period) / Fin (vide = même période): text, default (empty)
- `refPeriod.label` Label / Libellé: text, default (empty)
- `refPeriod.shade` Shade the period / Ombrer la période: toggle, default `true`; values: true / false
- `refPeriod.color` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `refPeriod.opacity` Opacity (%) / Opacité (%): number, default `10`; values: 2 to 60
- `refPeriod.tooltip` Change in the tooltip / Écart dans l'infobulle: toggle, default `true`; values: true / false

### Reference lines / Lignes de référence (`reference`, Analytics pane)
- `reference.show1` Show / Afficher: toggle, default `false`; values: true / false
- `reference.kind1` Value / Valeur: dropdown, default `average`; values: `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile
- `reference.value1` Constant value / Valeur constante: number, default `0`. Visible when `reference.kind1` = `constant`
- `reference.pct1` Percentile / Centile: number, default `90`; values: 1 to 99. Visible when `reference.kind1` = `percentile`
- `reference.label1` Label / Libellé: text, default (empty)
- `reference.showValue1` Show the value / Afficher la valeur: toggle, default `true`; values: true / false
- `reference.color1` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.style1` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `reference.width1` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `reference.labelPos1` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None
- `reference.show2` Show / Afficher: toggle, default `false`; values: true / false
- `reference.kind2` Value / Valeur: dropdown, default `constant`; values: `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile
- `reference.value2` Constant value / Valeur constante: number, default `0`. Visible when `reference.kind2` = `constant`
- `reference.pct2` Percentile / Centile: number, default `90`; values: 1 to 99. Visible when `reference.kind2` = `percentile`
- `reference.label2` Label / Libellé: text, default (empty)
- `reference.showValue2` Show the value / Afficher la valeur: toggle, default `true`; values: true / false
- `reference.color2` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.style2` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `reference.width2` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `reference.labelPos2` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None
- `reference.show3` Show / Afficher: toggle, default `false`; values: true / false
- `reference.kind3` Value / Valeur: dropdown, default `median`; values: `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile
- `reference.value3` Constant value / Valeur constante: number, default `0`. Visible when `reference.kind3` = `constant`
- `reference.pct3` Percentile / Centile: number, default `90`; values: 1 to 99. Visible when `reference.kind3` = `percentile`
- `reference.label3` Label / Libellé: text, default (empty)
- `reference.showValue3` Show the value / Afficher la valeur: toggle, default `true`; values: true / false
- `reference.color3` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.style3` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `reference.width3` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `reference.labelPos3` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None
- `reference.band` Show / Afficher: toggle, default `false`; values: true / false
- `reference.bandFrom` From / De: number, default `0`
- `reference.bandTo` To / À: number, default `0`
- `reference.bandLabel` Label / Libellé: text, default (empty)
- `reference.bandColor` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.bandOpacity` Opacity (%) / Opacité (%): number, default `12`; values: 2 to 60

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).
- `tooltip.tipAll` Every stream at that date / Tous les flux de la date: toggle, default `false`; values: true / false. Otherwise the tooltip details the hovered stream: value, share, rank, change.

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Bump Plume

- Who climbs, who falls, who enters the top: rankings over time, computed in the visual, as curves, ribbons or a metro map.
- Slug `bump-chart` · version 1.1.0.0 · GUID (`visualType`) `plumeBumpChart65AF1CF0250B4188882D035A1EA77D58` · page https://plumevisuals.com/en/visuals/bump-chart

### What the visual does

Bump Plume (identifier `bump-chart`) is a Power BI custom visual (version 1.1.0.0, installed from its `.pbiviz` file; AppSource submission in preparation) that draws **bump charts**: how rankings change over time. Power BI has no native bump chart; its closest visual is the ribbon chart (no rank axis, no names on the ribbons).

**New in version 1.1.0.0 (30/10/2026):** Format pane reorganized (end labels in **End labels**, `labels.v*` → `labels.*`, gridlines in **Gridlines**); free full data labels with totals above columns, axis titles, gridlines, drill-down, highlight color, "keep ranks under filters", two-line long names in the metro map, annotations like Line Plume.

- **Ranks computed in the visual**: put a measure in `value` ("Value (ranked by the visual)"); in each period the entities are ranked by it (`ranking.order` = `desc`: highest value first, `asc`: lowest first). No `RANKX` needed. A rank you already compute goes in `rank` ("Rank (optional)") and wins over the value.
- **Ties** (`ranking.ties`): `competition` 1-2-2-4 (= RANKX Skip, default), `dense` 1-2-2-3 (= RANKX Dense), premium `modified` ★ 1-3-3-4 and `ordinal` ★ 1-2-3-4 (ties broken by the previous rank, then by name; premium only when the visual ranks the Value field). Tied entities are never drawn on top of each other: each gets its own row ("slot"), ordered by previous rank then name; labels write "=2" (`ranking.tieMark`), tooltips "(tied)".
- **Top N** (`ranking.topN`, 10 by default, 0 = all) with `ranking.topBasis`: `period` (the first N of each period; an entity that leaves drops with dashes into an "Outside the top N" row with an exit marker ▼ and comes back with an entry marker ▲), `last` (the first N of the last period, followed over all periods), `any` ★ (entities in the top N at least once).
- **Rank 1 at the top** (`ranking.rankOneTop`, on). A period without a value breaks the line (`ranking.missing` = `gap`) or is skipped (`connect`); 0 is ranked.
- **Designs** (`design.type`): `curve` S-curves (default, `design.curvature` 0–100), `straight` sharp breaks, `stacked` stacked ribbons like the Power BI ribbon chart (spacing, transparency 30, border), and premium `step` (steps), `metro` (metro map: thick lines, horizontal runs and 45° bends, stations, interchange capsules where two entities swap places, terminus badges) and `ribbon` (ribbons as thick as their value, centered on the rank).
- Markers with the rank number inside, names at the start and the end of the lines, values on points, hover to bring an entity forward (others fade), lines drawn period by period when data changes, and premium playback: a discreet ▶ button or a play bar that reveals periods one by one with labels following the head of the lines.

### 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 (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium**.
- Free in Bump Plume: ranks from Value or Rank, standard and dense ties (like RANKX), Top N per period or on the last period with entries and exits, curves, sharp breaks, stacked ribbons, markers, names at both ends, values on points, axes, banded rows, the ranks view, drawing animation when data changes, palette or single colors, tooltips, legend, keyboard.
- Premium features of Bump Plume:
  - `design.type` = `step`, `metro` or `ribbon`;
  - `ranking.ties` = `modified` or `ordinal` (when the visual ranks the Value field) and `ranking.topBasis` = `any` (Top N ≠ 0);
  - playback: `play.controls` (play bar), `play.button` (discreet ▶ button) or `play.autoPlay`, on an interactive visual with at least two periods (since the 22/10/2026 rebalancing; the ▶ button is off by default);
  - `dataColors.mode` = `highlight` (named entities in color, others gray; `dataColors.highlightNames` separated by `;`, empty = the leader at the end) or `finalRank` (gradient by final rank);
  - `endLabels.change` (rank change ▲3 / ▼2 at the end of the lines);
  - `view.mode` = `value` (values view), also when a reader picks "Values" with the `view.toggle` button;
  - `zones.show` (ranking zones: podium, relegation);
  - the `image` role (logos) when images are shown, and annotations (`notes` role or `annotations.list`) when shown.
- 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 `bump-chart` 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 period and per entity, with a measure.

| Axis (`axis`) | Legend (`legend`) | Value (`value`) |
|---|---|---|
| 2023 | Alpha | 400,000 |
| 2023 | Bravo | 300,000 |
| 2024 | Alpha | 300,000 |
| 2024 | Bravo | 350,000 |

- **Axis (time)** (`axis`, « Axe (temps) », one column, required): a date, year, month, number or sorted category. Dates and numbers are sorted by the visual; text keeps Power BI's sort order.
- **Legend (entity)** (`legend`, « Légende (entité) », one column, required): one line per value, up to 200.
- **Value (ranked by the visual)** (`value`, « Valeur (classée par le visuel) », one measure): required unless Rank is used. Also sets ribbon thickness.
- **Rank (optional)** (`rank`, « Rang (facultatif) », one measure): 1 = first; decimals allowed.
- **Image ★** (`image`, text measure): embedded images only: `data:image/png|jpeg|gif|webp|bmp|svg+xml;base64,…`, raw base64 or SVG text (SVG is sanitized); web addresses are ignored (no network). The last non-blank image of each entity is used.
- **Annotations ★** (`notes`, text measure): a note pinned to the entity's point in that period.
- **Tooltips** (`tooltips`) and **Dynamic format** (`format`).
- Volume: categories (periods) in windows of 30,000, more fetched with `fetchMoreData`; 100,004 rows (4 entities × 25,001 days) render in under 2.5 s; markers hide automatically when there is no room.

### DAX recipes

```dax
// One row per period and entity: a simple sum
Total revenue = SUM ( Sales[Revenue] )

// Rank 1 = fastest: keep the measure as is and set ranking.order = asc
Average lead time = AVERAGE ( Deliveries[Lead time] )

// Logo ★ from a column holding base64 text
Logo = "data:image/png;base64," & SELECTEDVALUE ( Brands[Logo base64] )

// Dynamic title (renamed title.text in the Dynamic format well)
Ranking title =
VAR y = CALCULATE ( MAX ( Sales[Year] ), ALLSELECTED () )
VAR t = CALCULATETABLE ( TOPN ( 1, VALUES ( Sales[Brand] ), CALCULATE ( SUM ( Sales[Revenue] ) ), DESC ), ALLSELECTED (), Sales[Year] = y )
RETURN "Brand ranking: " & CONCATENATEX ( t, Sales[Brand], ", " ) & " leads in " & y
```

### Interactions with the report

- Hover a line, marker or label: the entity comes in front (`interaction.front`), others fade (`interaction.dim`); tooltip with entity, period, rank (tied, outside the top), value, change since the previous period, best rank, annotation, Tooltips measures; report-page tooltips are supported.
- Click a line or a label: cross-filter on the entity; click a marker: entity × period; Ctrl for several; click an empty area: clear. Cross-highlighting from other visuals dims the other entities. Context menu everywhere.
- Keyboard: Tab to reach the chart, ↑ ↓ through entities in final-rank order (announced: "rank 3 in 2025, ▲2 since 2018, best rank 1"), Enter selects, Esc clears.
- Playback uses the shared Plume player (same settings as other Plume visuals): `play.controls` ★ (play bar with tick-marked slider, start / end, speed ×0.5–×4, keyboard; off by default), `play.button` ★ (discreet ▶ on hover when there is no bar, off by default), `play.autoPlay` ★, `play.speed` (ms per frame, 700), `play.loop`, `play.transition`, `play.follow` (labels follow the line heads), `play.showLabel` / `labelSize` (40) / `labelPosition` (current period while playing). `play.draw` (free) draws the lines period by period when data changes (`play.drawDuration`, 1400 ms); filters make points glide to their new place. "Reduce motion" is respected. Nothing is saved with persistProperties; the view chosen with the Ranks / Values button lasts for the session.

### Dynamic formats

- **fx button** (Power BI conditional formatting) on colors and texts of the Format pane, and on each entity color.
- **"Dynamic format" well** (`format`): measures renamed `card.setting` (e.g. `title.text`, `design.type`, `ranking.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`, `ranking`, `design`, `markers`, `labels`, `xAxis`, `yAxis`, `zones`, `view`, `play`, `annotations`, `tooltip`, `legend`, `interaction`, then `title`, `source`, `container`, `texts`. Format pane in version 1.1.0.0 (30/10/2026), top to bottom: `license`, `style`, `dataColors`, `ranking`, `view`, `design`, `markers`, `labels`, `endLabels`, `xAxis`, `yAxis`, `gridlines`, `legend`, `zones`, `annotations`, `play`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- `dataColors`: `mode` (`auto` | `single` | `highlight` ★ | `finalRank` ★), `single`, `fill` (per entity), `highlightNames`, `othersColor`.
- `ranking`: `order` (`desc` | `asc`), `ties` (`competition` | `dense` | `modified` ★ | `ordinal` ★), `tieMark`, `topN` (0–200, 10), `topBasis` (`period` | `last` | `any` ★), `missing` (`gap` | `connect`), `rankOneTop`.
- `design`: `type` (`curve` | `straight` | `step` ★ | `stacked` | `metro` ★ | `ribbon` ★), `curvature` (0–100, 50), `width` (0.5–20, 3), `casing`, `interchanges`, `ribbonSize` (10–100, 80), `spacing` (0–50, 12), `transparency` (0–90, 30), `border`.
- `markers`: `show` (`auto` | `all` | `ends` | `none`), `shape` (`circle` | `square` | `diamond`), `size` (4–48, 20), `rankInside`, `fill` (`solid` | `hollow`), `entryExit`.
- `endLabels`: `start`, `end`, `content` (`name` | `rankName` | `nameValue` | `rankNameValue`), `fontSize` (10), `color`, `bold`, `maxWidth` (8–45, 22), `images`, `change` ★, `changeBase` (`start` | `prev`), `upColor`, `downColor`.
- `labels` (values on the points): `show`, `position` (`below` | `above`), `units`, `decimals`, `prefix`, `suffix`.
- `xAxis`: `show`, `position` (`bottom` | `top` | `both`), `fontSize`, `color`, `dateFormat`, `gridlines.vShow`, `gridlines.vStyle`. `yAxis`: `show`, `position` (`left` | `right` | `both`), `fontSize`, `color`, `prefix`, `gridlines.hShow`, `gridlines.banding`, `outsideLabel`.
- `zones`: `show` ★, `topCount` (3), `topLabel`, `topColor`, `bottomCount` (0), `bottomLabel`, `bottomColor`, `opacity` (10). `view`: `mode` (`rank` | `value` ★), `toggle`, `zero`.
- `play`: `draw`, `drawDuration`, `speed`, `loop`, `autoPlay` ★, `transition`, `follow`, `controls` ★ (bool), `button` ★, `position` (`bottom` | `top`), `ticks` (`auto` | `all` | `none`), `tickLabels`, `stepButtons`, `speedButton`, `showLabel`, `labelSize`, `labelPosition`. `annotations`: `show`, `list` ★ (`entity | period | text` per line), `fontSize`, `color`. `tooltip`: `show`, `value`, `change`, `best`. `interaction`: `hover`, `dim` (25), `front`.

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID `plumeBumpChart65AF1CF0250B4188882D035A1EA77D58`, `queryState` keys are the data role names (`axis`, `legend`, `value`, `rank`, `image`, `notes`, `tooltips`, `format`), `objects` keys are the option IDs. Booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes, e.g. `"ranking": [ { "properties": { "topN": { "expr": { "Literal": { "Value": "5D" } } } } } ]`.

### Common pitfalls

- "Add what is ranked… in Legend (entity)": the Legend well is empty (one line per entity is required).
- Ranks differ from RANKX: tie method or direction (`ranking.ties`, `ranking.order`).
- Periods out of order: text axis sorted alphabetically ("R10" before "R2"); use a number or Sort by column.
- Entities missing: Top N (`ranking.topN`, 0 = all).
- "Ribbons: negative values count as zero": stacked ribbons cannot stack negatives.
- Image ignored: web address or unknown format; only embedded base64 images.
- Watermark visible: play bar, ▶ button or autoplay, steps, modified or unique ties, Top N on any period, metro, ribbons sized by value, highlight or final-rank colors, rank change, values view, zones, images, annotations, a ★ style or a theme JSON, without a valid key.

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

Small multiples, reference lines and trend lines (Analytics pane), images loaded from web addresses, average ranks for ties (1, 2.5, 2.5, 4), ranking several measures without a Legend field, exporting the chart as an image, saving the reader's view in the report.

## Bump Plume: data fields

- `axis` Axis (time) / Axe (temps) (column, 4 max): Periods in order: a date, a year, a month or any ordered category (rounds, seasons, waves). Several fields: drill down (year › quarter › month).
- `legend` Legend (entity) / Légende (entité) (column, 1 max): What is ranked: products, teams, regions, brands… One line per value.
- `value` Value (ranked by the visual) / Valeur (classée par le visuel) (measure, 1 max): The visual ranks the entities by this measure in each period (no RANKX needed). Also sets the ribbon thickness.
- `rank` Rank (optional) / Rang (facultatif) (measure, 1 max): A rank you already compute (1 = first). Used instead of ranking the Value field. Computed with ALL(), it keeps the ranking under a filter.
- `image` Image ★ ★ (measure, 1 max): Text measure returning an embedded image (data:image/png;base64,…): logo or photo shown at both ends of the line.
- `notes` Annotations ★ ★ (measure, 1 max): Text measure: a note pinned to the point of the entity at that period where it is not empty.
- `tooltips` Tooltips / Infobulles (measure, several max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Bump Plume: Format pane options (205)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Data colors / Couleurs des données (`dataColors`, one entry per item with a selector)
- `dataColors.mode` Coloring / Coloration: dropdown, default `auto`; values: `auto` Palette (one color per entity); `single` Single color; `highlight` Highlight entities ★; `finalRank` Gradient by final rank ★
- `dataColors.single` Color / Couleur: color, default (empty); values: hex color
- `dataColors.fill` Color / Couleur: color, default (empty); values: hex color
- `dataColors.highlightNames` Highlighted entities (separated by ;, empty = first at the end) / Entités mises en avant (séparées par ;, vide = la 1re à la fin): text, default (empty)
- `dataColors.highlightColor` Highlight color (empty = entity color) / Couleur mise en avant (vide = celle de l'entité): color, default (empty); values: hex color
- `dataColors.othersColor` Other entities color (empty = style gray) / Couleur des autres entités (vide = gris du style): color, default (empty); values: hex color

### Ranking / Classement (`ranking`)
- `ranking.order` Rank 1 = / Rang 1 =: dropdown, default `desc`; values: `desc` Highest value; `asc` Lowest value. When the visual ranks the Value field. Lowest value: times, costs, golf scores, delays…
- `ranking.ties` Ties / Ex aequo: dropdown, default `competition`; values: `competition` Standard: 1, 2, 2, 4 (RANKX Skip); `dense` Dense: 1, 2, 2, 3 (RANKX Dense); `modified` Modified: 1, 3, 3, 4 ★; `ordinal` Unique: 1, 2, 3, 4 (previous rank breaks ties) ★. Tied entities never hide each other: they sit side by side, ordered by their previous rank, then by name.
- `ranking.tieMark` Mark ties (=2) / Signaler les ex aequo (=2): toggle, default `true`; values: true / false
- `ranking.topN` Number of entities (Top N, 0 = all) / Nombre d'entités (Top N, 0 = toutes): number, default `10`; values: 0 to 200
- `ranking.topBasis` Top N based on / Top N calculé: dropdown, default `period`; values: `period` Each period (entries and exits); `last` The last period; `any` Any period ★. Visible when `ranking.topN` = . Each period: an entity leaving the Top N drops into the « Outside the top » row (▼) and comes back up when it returns (▲).
- `ranking.missing` Period without a rank / Période sans rang: dropdown, default `gap`; values: `gap` Break the line; `connect` Connect points
- `ranking.rankOneTop` Rank 1 at the top / Rang 1 en haut: toggle, default `true`; values: true / false
- `ranking.highlight` Highlight from another visual / Surbrillance venue d'un autre visuel: dropdown, default `dim`; values: `dim` Dim the other entities; `hide` Hide the others (ranks kept). Ranks are always computed over every row received: a highlighted entity keeps its rank in the full ranking. To keep the ranking under a filter (slicer), set the other visual's interaction to "Highlight" or put a rank computed with ALL() in "Rank".

### Ranks or values / Rangs ou valeurs (`view`)
- `view.mode` View / Vue: dropdown, default `rank`; values: `rank` Ranks (bump chart); `value` Values (lines) ★. Values: the same lines placed at their value, to see the gaps behind the ranks.
- `view.toggle` Ranks / Values button in the visual / Bouton Rangs / Valeurs dans le visuel: toggle, default `false`; values: true / false. Readers switch views; lines glide to their new place. The values view is premium (★).
- `view.zero` Values view: include zero / Vue des valeurs : inclure zéro: toggle, default `false`; values: true / false

### Design / Dessin (`design`)
- `design.type` Design / Dessin: dropdown, default `curve`; values: `curve` S-curves; `straight` Sharp breaks; `step` Steps ★; `stacked` Stacked ribbons (ribbon chart); `metro` Metro map ★; `ribbon` Ribbons sized by value ★. Metro map: thick lines, 45° bends, round stations and interchanges where entities swap places. Ribbons sized by value: each line is as thick as its value. Stacked ribbons: the Power BI ribbon chart.
- `design.curvature` Curvature (%) / Courbure (%): number, default `50`; values: 0 to 100. Visible when `design.type` = `curve` or `ribbon` or `stacked`
- `design.width` Width / Épaisseur: number, default `3`; values: 0.5 to 20. Visible when `design.type` = `curve` or `straight` or `step` or `metro`
- `design.lineStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `design.type` = `curve` or `straight` or `step`
- `design.casing` Casing at crossings / Liseré aux croisements: toggle, default `true`; values: true / false. Visible when `design.type` = `curve` or `straight` or `step` or `metro`. A thin outline in the background color separates the lines where they cross.
- `design.interchanges` Interchanges (swapped places) / Correspondances (échanges de places): toggle, default `true`; values: true / false. Visible when `design.type` = `metro`
- `design.ribbonSize` Maximum thickness (% of the row) / Épaisseur maximale (% de la rangée): number, default `80`; values: 10 to 100. Visible when `design.type` = `ribbon`
- `design.spacing` Spacing (%) / Espacement (%): number, default `12`; values: 0 to 50. Visible when `design.type` = `stacked`
- `design.transparency` Ribbon transparency (%) / Transparence des rubans (%): number, default `30`; values: 0 to 90. Visible when `design.type` = `ribbon` or `stacked`
- `design.border` Ribbon border / Bordure des rubans: toggle, default `false`; values: true / false. Visible when `design.type` = `ribbon` or `stacked`
- `design.totals` Total above the columns / Total au-dessus des colonnes: toggle, default `false`; values: true / false. Visible when `design.type` = `stacked`. Like the total labels of the native ribbon chart.

### Markers / Marqueurs (`markers`)
- `markers.show` Show / Afficher: dropdown, default `auto`; values: `auto` Automatic (when there is room); `all` At every period; `ends` At the start and the end; `none` None
- `markers.shape` Shape / Forme: dropdown, default `circle`; values: `circle` Circle; `square` Square; `diamond` Diamond. Visible when `markers.show` = `auto` or `all` or `ends`
- `markers.size` Maximum size (px) / Taille maximale (px): number, default `20`; values: 4 to 48. Visible when `markers.show` = `auto` or `all` or `ends`
- `markers.rankInside` Rank number inside the marker / Numéro du rang dans le marqueur: toggle, default `true`; values: true / false. Visible when `markers.show` = `auto` or `all` or `ends`
- `markers.fill` Fill / Remplissage: dropdown, default `solid`; values: `solid` Solid; `hollow` Hollow (colored outline). Visible when `markers.show` = `auto` or `all` or `ends`
- `markers.entryExit` Top N entries and exits (▲ ▼) / Entrées et sorties du Top N (▲ ▼): toggle, default `true`; values: true / false

### Data labels / Étiquettes de données (`labels`)
- `labels.show` Show / Afficher: toggle, default `false`; values: true / false
- `labels.position` Position: dropdown, default `below`; values: `below` Below the point; `above` Above the point
- `labels.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `labels.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `labels.bold` Bold / Gras: toggle, default `false`; values: true / false
- `labels.halo` Text halo / Halo autour du texte: toggle, default `true`; values: true / false
- `labels.declutter` Hide overlapping labels / Masquer les étiquettes qui se chevauchent: toggle, default `true`; values: true / false
- `labels.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `labels.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `labels.prefix` Prefix / Préfixe: text, default (empty)
- `labels.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)

### End labels / Noms aux extrémités (`endLabels`)
- `endLabels.show` Show / Afficher: toggle, default `true`; values: true / false
- `endLabels.start` At the start / Au début: toggle, default `true`; values: true / false
- `endLabels.end` At the end / À la fin: toggle, default `true`; values: true / false
- `endLabels.content` Content / Contenu: dropdown, default `name`; values: `name` Name; `rankName` Rank and name; `nameValue` Name and value; `rankNameValue` Rank, name and value
- `endLabels.fontSize` Size / Taille: number, default `10`; values: 6 to 24
- `endLabels.color` Color (empty = entity color) / Couleur (vide = celle de l'entité): color, default (empty); values: hex color
- `endLabels.bold` Bold / Gras: toggle, default `false`; values: true / false
- `endLabels.maxWidth` Maximum width (% of the visual) / Largeur maximale (% du visuel): number, default `22`; values: 8 to 45
- `endLabels.wrap` Long names on two lines / Noms longs sur deux lignes: toggle, default `true`; values: true / false. A name wider than the reserved room goes on two lines (metro terminus badges included) instead of being cut.
- `endLabels.images` Images from the Image field ★ / Images du champ Image ★ ★: toggle, default `true`; values: true / false. Logos or photos (embedded data:image/…;base64 text) next to the names. Web addresses are ignored: a certified visual loads nothing from the internet.
- `endLabels.change` Show (▲3, ▼2) ★ / Afficher (▲3, ▼2) ★ ★: toggle, default `false`; values: true / false. Places gained or lost, after the name at the end of each line.
- `endLabels.changeBase` Since / Depuis: dropdown, default `start`; values: `start` The first period; `prev` The previous period
- `endLabels.upColor` Places gained / Places gagnées: color, default `#2E7D4F`; values: hex color
- `endLabels.downColor` Places lost / Places perdues: color, default `#C0392B`; values: hex color

### Period axis / Axe des périodes (`xAxis`)
- `xAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `xAxis.position` Position: dropdown, default `bottom`; values: `bottom` Bottom; `top` Top; `both` Top and bottom
- `xAxis.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `xAxis.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `xAxis.dateFormat` Date format / Format des dates: text, default (empty)
- `xAxis.showTitle` Show / Afficher: toggle, default `false`; values: true / false
- `xAxis.titleText` Text / Texte: text, default (empty). Visible when `xAxis.showTitle` = `true`

### Rank axis / Axe des rangs (`yAxis`)
- `yAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `yAxis.position` Position: dropdown, default `left`; values: `left` Left; `right` Right; `both` Both sides
- `yAxis.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `yAxis.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `yAxis.prefix` Rank prefix (e.g. #) / Préfixe des rangs (ex. #): text, default (empty)
- `yAxis.outsideLabel` Outside-the-top row label / Libellé de la rangée hors top: text, default (empty)
- `yAxis.showTitle` Show / Afficher: toggle, default `false`; values: true / false
- `yAxis.titleText` Text / Texte: text, default (empty). Visible when `yAxis.showTitle` = `true`

### Gridlines / Quadrillage (`gridlines`)
- `gridlines.vShow` Show / Afficher: toggle, default `true`; values: true / false
- `gridlines.vColor` Color (empty = style grid) / Couleur (vide = grille du style): color, default (empty); values: hex color
- `gridlines.vWidth` Width / Épaisseur: number, default `1`; values: 0.5 to 6
- `gridlines.vStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `gridlines.hShow` Show / Afficher: toggle, default `false`; values: true / false
- `gridlines.hColor` Color (empty = style grid) / Couleur (vide = grille du style): color, default (empty); values: hex color
- `gridlines.hWidth` Width / Épaisseur: number, default `1`; values: 0.5 to 6
- `gridlines.hStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `gridlines.banding` Banded rows / Rangées alternées: toggle, default `false`; values: true / false

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

### Ranking zones ★ / Zones de classement ★ (`zones`)
- `zones.show` Show ★ / Afficher ★ ★: toggle, default `false`; values: true / false. Colored bands behind the first and the last ranks: podium, qualification, relegation…
- `zones.topCount` Top zone: number of ranks / Zone haute : nombre de rangs: number, default `3`; values: 0 to 50
- `zones.topLabel` Top zone label / Libellé de la zone haute: text, default (empty)
- `zones.topColor` Top zone color / Couleur de la zone haute: color, default `#2E7D4F`; values: hex color
- `zones.bottomCount` Bottom zone: number of ranks / Zone basse : nombre de rangs: number, default `0`; values: 0 to 50
- `zones.bottomLabel` Bottom zone label / Libellé de la zone basse: text, default (empty)
- `zones.bottomColor` Bottom zone color / Couleur de la zone basse: color, default `#C0392B`; values: hex color
- `zones.opacity` Opacity (%) / Opacité (%): number, default `10`; values: 3 to 50

### Annotations ★ (`annotations`)
- `annotations.show` Show / Afficher: toggle, default `true`; values: true / false
- `annotations.list` Annotations (one per line) / Annotations (une par ligne): textarea, default (empty). One line per annotation: "period | text" (vertical marker on the period) or "period | entity | text" (attached to the entity's point). Period: date (2024-06-01, 2024-06, 06/15/2024), year, number or displayed label. "\n" starts a new line. The former "entity | period | text" order is still read. The Annotations ★ field adds notes from a text measure.
- `annotations.content` Displayed content / Contenu affiché: dropdown, default `text`; values: `text` Text; `textRank` Text and rank; `textValue` Text and value
- `annotations.editOnChart` Edit on the chart (edit mode) / Modifier sur le graphique (mode édition): toggle, default `true`; values: true / false. In edit mode, annotations can be dragged, edited with a double-click and removed with ×.
- `annotations.style` Style: dropdown, default `bubble`; values: `bubble` Bubble; `filled` Filled label; `plain` Text only
- `annotations.color` Color (empty = entity color) / Couleur (vide = celle de l'entité): color, default (empty); values: hex color
- `annotations.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `annotations.bold` Bold / Gras: toggle, default `false`; values: true / false
- `annotations.maxWidth` Maximum width (px) / Largeur maximale (px): number, default `160`; values: 60 to 400
- `annotations.marker` Marker on the point / Repère sur le point: toggle, default `true`; values: true / false
- `annotations.connector` Connector / Trait vers le point: dropdown, default `line`; values: `line` Line; `none` None
- `annotations.connectorStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `annotations.connector` = `line`
- `annotations.position` Default position / Position par défaut: dropdown, default `auto`; values: `auto` Automatic (no overlap); `above` Above; `below` Below; `right` Right; `left` Left. Position of annotations that have not been dragged.
- `annotations.distance` Distance from the point (px) / Distance au point (px): number, default `22`; values: 6 to 160

### Playback / Lecture (`play`)
- `play.draw` Draw the lines period by period / Dessiner les lignes période par période: toggle, default `true`; values: true / false. When the data changes, the lines draw themselves from the first period to the last. Off when animations are reduced (Style › Animations or the system).
- `play.drawDuration` Drawing duration (ms) / Durée du dessin (ms): number, default `1400`; values: 200 to 8000. Visible when `play.draw` = `true`
- `play.speed` Duration of a frame (ms) / Durée d'une image (ms): number, default `700`; values: 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, default `false`; values: true / false
- `play.autoPlay` Play automatically on opening ★ / Lecture automatique à l'ouverture ★ ★: toggle, default `false`; values: 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, default `true`; values: true / false. Values, positions and colors move smoothly from one frame to the next.
- `play.follow` Labels follow the head of the lines / Étiquettes qui suivent la tête des lignes: toggle, default `true`; values: true / false
- `play.controls` Play bar ★ / Barre de lecture ★ ★: toggle, default `false`; values: true / false
- `play.button` Discreet ▶ button (on hover) ★ / Bouton ▶ discret (au survol) ★ ★: toggle, default `false`; values: true / false. Visible when `play.controls` = `false`. Without the play bar: a small round button at the top right of the chart, shown on hover.
- `play.position` Bar position / Position de la barre: dropdown, default `bottom`; values: `bottom` Bottom; `top` Top. Visible when `play.controls` = `true`
- `play.ticks` Tick marks / Graduations: dropdown, default `auto`; values: `auto` Automatic; `all` Every frame; `none` None. Visible when `play.controls` = `true`
- `play.tickLabels` Tick labels / Étiquettes des graduations: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.stepButtons` Start and end buttons / Boutons début et fin: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.speedButton` Speed button / Bouton de vitesse: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.showLabel` Current value in large type / Valeur en cours en grand: toggle, default `true`; values: true / false
- `play.labelSize` Large value size / Taille de la valeur en grand: number, default `40`; values: 12 to 160. Visible when `play.showLabel` = `true`
- `play.labelPosition` Large value position / Position de la valeur en grand: dropdown, default `bottomRight`; values: `bottomRight` Bottom right; `topRight` Top right; `topLeft` Top left; `bottomLeft` Bottom left; `center` Center. Visible when `play.showLabel` = `true`

### Interactions (`interaction`)
- `interaction.hover` Highlight on hover / Mettre en avant au survol: toggle, default `true`; values: true / false
- `interaction.dim` Dimmed items opacity (%) / Opacité des éléments estompés (%): number, default `25`; values: 5 to 80
- `interaction.front` Hover: entity in front / Survol : entité au premier plan: toggle, default `true`; values: true / false. The hovered line comes in front of the others, which fade.

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).
- `tooltip.value` Value / Valeur: toggle, default `true`; values: true / false
- `tooltip.change` Change since the previous period / Variation depuis la période précédente: toggle, default `true`; values: true / false
- `tooltip.best` Best rank / Meilleur rang: toggle, default `true`; values: true / false

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Dumbbell Plume

- The gap between two values, for every category, at a glance: before / after, plan / actual, last year / this year.
- Slug `dumbbell` · version 1.1.0.0 · GUID (`visualType`) `plumeDumbbell1F438EFD90304AF8992B164EFBAA8481` · page https://plumevisuals.com/en/visuals/dumbbell

### 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.

## Dumbbell Plume: data fields

- `category` Category (one dumbbell each) / Catégorie (une haltère par valeur) (column, 4 max): 
- `start` Start (first point) / Début (premier point) (measure, 1 max): First value of each dumbbell (before, plan, last year…)
- `end` End (last point) / Fin (dernier point) (measure, 1 max): Last value of each dumbbell (after, actual, this year…); the gap is End − Start
- `values` Values (more points) / Valeurs (plus de points) (measure, 8 max): 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 max): 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 max): Gathers the dumbbells under a header per value (region > country, department > product)
- `target` Target ★ / Objectif ★ ★ (measure, 1 max): A tick per dumbbell; the last point can show whether it is reached
- `bandLow` Range minimum ★ / Plage : minimum ★ ★ (measure, 1 max): Lower bound of a band drawn behind each dumbbell (historical low, market range…)
- `bandHigh` Range maximum ★ / Plage : maximum ★ ★ (measure, 1 max): Upper bound of the band drawn behind each dumbbell
- `image` Category image ★ / Image de la catégorie ★ ★ (measure, 1 max): 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 max): 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 max): Not blank and not 0: the dumbbell stands out, the others turn gray
- `play` Play axis ★ / Axe de lecture ★ ★ (column, 1 max): 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 max): One small dumbbell chart per value, sharing the same scale
- `tooltips` Tooltips / Infobulles (measure, several max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Dumbbell Plume: Format pane options (256)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Data colors / Couleurs des données (`dataColors`, one entry per item with a selector)
- `dataColors.mode` Coloring / Coloration: dropdown, default `series`; values: `series` One color per point (series); `direction` By direction of the gap; `single` Single color
- `dataColors.single` Color / Couleur: color, default (empty); values: hex color
- `dataColors.fill` Color / Couleur: color, default (empty); values: hex color
- `dataColors.startLight` Lighter first point / Premier point plus clair: toggle, default `true`; values: 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`)
- `dumbbells.orientation` Orientation: dropdown, default `horizontal`; values: `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, default `22`; values: 10 to 80. Below that, the chart scrolls.
- `dumbbells.rowMax` Maximum row height (px) / Hauteur maximale d'une ligne (px): number, default `48`; values: 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, default `start`; values: `start` At the start; `end` At the end
- `dumbbells.shape` Shape / Forme: dropdown, default `circle`; values: `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, default `12`; values: 4 to 40
- `dumbbells.hollowFirst` Hollow first point / Premier point creux: toggle, default `false`; values: 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, default `true`; values: true / false
- `dumbbells.outlineColor` Outline color (empty = background) / Couleur du contour (vide = fond): color, default (empty); values: hex color. Visible when `dumbbells.outline` = `true`
- `dumbbells.connector` Show / Afficher: toggle, default `true`; values: true / false
- `dumbbells.width` Width (px) / Épaisseur (px): number, default `3`; values: 0.5 to 24
- `dumbbells.lineStyle` Line style / Style du trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `dumbbells.colorMode` Color / Couleur: dropdown, default `neutral`; values: `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, default (empty); values: hex color. Visible when `dumbbells.colorMode` = `neutral`
- `dumbbells.opacity` Opacity (%) / Opacité (%): number, default `100`; values: 10 to 100
- `dumbbells.arrow` Arrow / Flèche: dropdown, default `none`; values: `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`)
- `direction.lowerIsBetter` A decrease is favorable / Une baisse est favorable: toggle, default `false`; values: true / false. Costs, delays, churn: a decrease is shown in the favorable color.
- `direction.favorable` Favorable: color, default `#2E7D4F`; values: hex color
- `direction.unfavorable` Unfavorable / Défavorable: color, default `#C0392B`; values: hex color
- `direction.neutral` Stable (empty = secondary text) / Stable (vide = texte secondaire): color, default (empty); values: hex color
- `direction.stable` Stability threshold ★ / Seuil de stabilité ★ ★: number, default `0`; values: 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, default `percent`; values: `percent` % of the first value; `value` Value (measure unit)

### Gap / Écart (`gap`)
- `gap.show` Show / Afficher: toggle, default `true`; values: true / false
- `gap.content` Content / Contenu: dropdown, default `value`; values: `value` Value (end − start); `percent` Percentage; `both` Value and percentage; `points` Percentage points (% measures); `ratio` Ratio (× end ÷ start) ★
- `gap.position` Position: dropdown, default `column`; values: `column` Column on the right (or on top); `end` After the last point; `middle` Above the connector
- `gap.arrows` ▲▼ arrows / Flèches ▲▼: toggle, default `true`; values: true / false
- `gap.header` Column title / Titre de la colonne: text, default (empty). Visible when `gap.position` = `column`
- `gap.fontSize` Size / Taille: number, default `10`; values: 6 to 24
- `gap.bold` Bold / Gras: toggle, default `true`; values: true / false
- `gap.colorBy` Color / Couleur: dropdown, default `direction`; values: `direction` By direction; `text` Text
- `gap.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `gap.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `gap.prefix` Prefix / Préfixe: text, default (empty)
- `gap.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)
- `gap.pctDecimals` Percentage decimals (-1 = auto) / Décimales du pourcentage (-1 = auto): number, default `-1`; values: -1 to 4. Automatic: one decimal under 10 %, none above.

### Data labels / Étiquettes de données (`labels`)
- `labels.show` Show / Afficher: toggle, default `true`; values: true / false
- `labels.content` Content / Contenu: dropdown, default `value`; values: `value` Value; `seriesValue` Series and value; `series` Series
- `labels.position` Position: dropdown, default `outside`; values: `outside` At the ends (outside); `above` Above the points; `below` Below the points
- `labels.which` Labeled points / Points étiquetés: dropdown, default `ends`; values: `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, default `false`; values: true / false. Writes the series names above the points of the first dumbbell: no legend needed.
- `labels.fontSize` Size / Taille: number, default `10`; values: 6 to 24
- `labels.color` Color (empty = automatic) / Couleur (vide = automatique): color, default (empty); values: hex color. Automatic: readable color depending on the background (inside bars: white or dark).
- `labels.bold` Bold / Gras: toggle, default `false`; values: true / false
- `labels.halo` Text halo / Halo autour du texte: toggle, default `true`; values: true / false
- `labels.declutter` Hide overlapping labels / Masquer les étiquettes qui se chevauchent: toggle, default `true`; values: true / false
- `labels.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `labels.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `labels.prefix` Prefix / Préfixe: text, default (empty)
- `labels.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)

### Category axis / Axe des catégories (`catAxis`)
- `catAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `catAxis.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `catAxis.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `catAxis.bold` Bold / Gras: toggle, default `false`; values: true / false
- `catAxis.maxSize` Maximum room (% of the visual) / Place maximale (% du visuel): number, default `30`; values: 10 to 60
- `catAxis.wrap` Long names on two lines / Noms longs sur deux lignes: toggle, default `true`; values: true / false
- `catAxis.showTitle` Show / Afficher: toggle, default `false`; values: true / false
- `catAxis.titleText` Text / Texte: text, default (empty). Visible when `catAxis.showTitle` = `true`

### Value axis / Axe des valeurs (`valAxis`)
- `valAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `valAxis.position` Position: dropdown, default `bottom`; values: `bottom` Bottom; `top` Top
- `valAxis.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `valAxis.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `valAxis.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `valAxis.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `valAxis.prefix` Prefix / Préfixe: text, default (empty)
- `valAxis.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)
- `valAxis.line` Axis line / Trait de l'axe: toggle, default `false`; values: true / false
- `valAxis.scale` Scale / Échelle: dropdown, default `linear`; values: `linear` Linear; `log` Logarithmic ★
- `valAxis.min` Minimum: text, default (empty)
- `valAxis.max` Maximum: text, default (empty)
- `valAxis.zero` Always include zero / Toujours inclure zéro: toggle, default `false`; values: true / false. Visible when `valAxis.scale` = `linear`
- `valAxis.ticks` Number of ticks (approx.) / Nombre de graduations (environ): number, default `5`; values: 2 to 20
- `valAxis.invert` Invert axis / Inverser l'axe: toggle, default `false`; values: true / false
- `valAxis.showTitle` Show / Afficher: toggle, default `false`; values: true / false
- `valAxis.titleText` Text / Texte: text, default (empty). Visible when `valAxis.showTitle` = `true`

### Gridlines / Quadrillage (`gridlines`)
- `gridlines.vShow` Show / Afficher: toggle, default `true`; values: true / false
- `gridlines.vColor` Color (empty = style grid) / Couleur (vide = grille du style): color, default (empty); values: hex color
- `gridlines.vWidth` Width / Épaisseur: number, default `1`; values: 0.5 to 6
- `gridlines.vStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `gridlines.zeroLine` Zero line / Ligne du zéro: toggle, default `true`; values: true / false
- `gridlines.cShow` Show / Afficher: toggle, default `true`; values: 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, default (empty); values: hex color
- `gridlines.cWidth` Width / Épaisseur: number, default `1`; values: 0.5 to 6
- `gridlines.cStyle` Line style / Style de trait: dropdown, default `dotted`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `gridlines.banding` Banded rows / Lignes alternées: toggle, default `false`; values: true / false

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

### Sort / Tri (`sort`)
- `sort.by` Sort by / Trier par: dropdown, default `end`; values: `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, default `desc`; values: `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, default `0`; values: 0 to 5000
- `sort.groupsSorted` Sort the groups too / Trier aussi les groupes: toggle, default `false`; values: true / false. Groups follow the average of their dumbbells; otherwise they keep the model order.

### Images ★ (`images`)
- `images.catPosition` Position: dropdown, default `label`; values: `label` Next to the name; `instead` Instead of the name; `after` After the last point
- `images.catSize` Size (px) / Taille (px): number, default `22`; values: 8 to 120
- `images.catShape` Shape / Forme: dropdown, default `circle`; values: `circle` Round; `rounded` Rounded corners; `square` Square; `contain` Whole image (no crop)
- `images.catBorder` Border / Bordure: toggle, default `false`; values: true / false
- `images.pointSize` Size of a point with an image (px) / Taille d'un point avec image (px): number, default `24`; values: 8 to 120
- `images.pointOn` Without Legend: image on / Sans Légende : image sur: dropdown, default `end`; values: `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, default `true`; values: true / false

### Target ★ / Objectif ★ (`target`)
- `target.shape` Marker / Repère: dropdown, default `tick`; values: `tick` Tick; `diamond` Diamond; `triangle` Triangle
- `target.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `target.width` Width / Épaisseur: number, default `2`; values: 0.5 to 8
- `target.status` Mark the target as reached (✓) or missed (✗) / Marquer l'objectif atteint (✓) ou manqué (✗): toggle, default `true`; values: 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, default `false`; values: true / false

### Range ★ / Plage ★ (`band`)
- `band.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `band.opacity` Opacity (%) / Opacité (%): number, default `16`; values: 3 to 80
- `band.height` Thickness (% of the row) / Épaisseur (% de la ligne): number, default `70`; values: 10 to 100
- `band.history` Historical range (play axis) ★ / Plage historique (axe de lecture) ★ ★: toggle, default `false`; values: 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`)
- `groups.fontSize` Group header size / Taille des titres de groupe: number, default `10`; values: 6 to 24
- `groups.color` Header color (empty = text) / Couleur des titres (vide = texte): color, default (empty); values: hex color
- `groups.separator` Line between groups / Trait entre les groupes: toggle, default `true`; values: true / false
- `groups.spacing` Space before a group (px) / Espace avant un groupe (px): number, default `6`; values: 0 to 40
- `groups.summary` Group average dumbbell / Haltère moyenne du groupe: toggle, default `false`; values: true / false. Adds a dumbbell with the average of each point under the header.

### Highlight ★ / Mise en avant ★ (`highlight`)
- `highlight.names` Highlighted categories ★ / Catégories mises en avant ★ ★: textarea, default (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, default `true`; values: true / false
- `highlight.othersOpacity` Other dumbbells opacity (%) / Opacité des autres haltères (%): number, default `45`; values: 5 to 100
- `highlight.bold` Bold name / Nom en gras: toggle, default `true`; values: true / false

### Small multiples ★ / Petits multiples ★ (`smallMultiples`)
- `smallMultiples.columns` Columns (0 = automatic) / Colonnes (0 = automatique): number, default `0`; values: 0 to 12
- `smallMultiples.minWidth` Minimum chart width (px) / Largeur minimale d'un graphique (px): number, default `200`; values: 80 to 800
- `smallMultiples.gap` Spacing (px) / Espacement (px): number, default `14`; values: 0 to 60
- `smallMultiples.titleSize` Title size / Taille des titres: number, default `10`; values: 6 to 24
- `smallMultiples.border` Frame around each chart / Cadre autour de chaque graphique: toggle, default `false`; values: true / false

### Playback ★ / Lecture ★ (`play`)
- `play.start` Frame shown on opening / Image affichée à l'ouverture: dropdown, default `last`; values: `last` The last one (most recent); `first` The first one
- `play.speed` Duration of a frame (ms) / Durée d'une image (ms): number, default `1000`; values: 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, default `false`; values: true / false
- `play.autoPlay` Play automatically on opening / Lecture automatique à l'ouverture: toggle, default `false`; values: 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, default `true`; values: true / false. Values, positions and colors move smoothly from one frame to the next.
- `play.controls` Play bar / Barre de lecture: toggle, default `true`; values: true / false
- `play.position` Bar position / Position de la barre: dropdown, default `bottom`; values: `bottom` Bottom; `top` Top. Visible when `play.controls` = `true`
- `play.ticks` Tick marks / Graduations: dropdown, default `auto`; values: `auto` Automatic; `all` Every frame; `none` None. Visible when `play.controls` = `true`
- `play.tickLabels` Tick labels / Étiquettes des graduations: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.stepButtons` Start and end buttons / Boutons début et fin: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.speedButton` Speed button / Bouton de vitesse: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.showLabel` Current value in large type / Valeur en cours en grand: toggle, default `true`; values: true / false
- `play.labelSize` Large value size / Taille de la valeur en grand: number, default `44`; values: 12 to 160. Visible when `play.showLabel` = `true`
- `play.labelPosition` Large value position / Position de la valeur en grand: dropdown, default `bottomRight`; values: `bottomRight` Bottom right; `topRight` Top right; `topLeft` Top left; `bottomLeft` Bottom left; `center` Center. Visible when `play.showLabel` = `true`
- `play.resort` Re-sort on every frame / Retrier à chaque image: toggle, default `true`; values: 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)
- `reference.show1` Show / Afficher: toggle, default `false`; values: true / false
- `reference.kind1` Value / Valeur: dropdown, default `average`; values: `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile; `measure` Average of the target
- `reference.value1` Constant value / Valeur constante: number, default `0`. Visible when `reference.kind1` = `constant`
- `reference.pct1` Percentile / Centile: number, default `90`; values: 1 to 99. Visible when `reference.kind1` = `percentile`
- `reference.label1` Label / Libellé: text, default (empty)
- `reference.showValue1` Show the value / Afficher la valeur: toggle, default `true`; values: true / false
- `reference.color1` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.style1` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `reference.width1` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `reference.labelPos1` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None
- `reference.show2` Show / Afficher: toggle, default `false`; values: true / false
- `reference.kind2` Value / Valeur: dropdown, default `constant`; values: `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile; `measure` Average of the target
- `reference.value2` Constant value / Valeur constante: number, default `0`. Visible when `reference.kind2` = `constant`
- `reference.pct2` Percentile / Centile: number, default `90`; values: 1 to 99. Visible when `reference.kind2` = `percentile`
- `reference.label2` Label / Libellé: text, default (empty)
- `reference.showValue2` Show the value / Afficher la valeur: toggle, default `true`; values: true / false
- `reference.color2` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.style2` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `reference.width2` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `reference.labelPos2` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None
- `reference.show3` Show / Afficher: toggle, default `false`; values: true / false
- `reference.kind3` Value / Valeur: dropdown, default `median`; values: `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile; `measure` Average of the target
- `reference.value3` Constant value / Valeur constante: number, default `0`. Visible when `reference.kind3` = `constant`
- `reference.pct3` Percentile / Centile: number, default `90`; values: 1 to 99. Visible when `reference.kind3` = `percentile`
- `reference.label3` Label / Libellé: text, default (empty)
- `reference.showValue3` Show the value / Afficher la valeur: toggle, default `true`; values: true / false
- `reference.color3` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.style3` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `reference.width3` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `reference.labelPos3` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None
- `reference.band` Show / Afficher: toggle, default `false`; values: true / false
- `reference.bandFrom` From / De: number, default `0`
- `reference.bandTo` To / À: number, default `0`
- `reference.bandLabel` Label / Libellé: text, default (empty)
- `reference.bandColor` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.bandOpacity` Opacity (%) / Opacité (%): number, default `12`; values: 2 to 60

### Averages ★ / Moyennes ★ (`means`, Analytics pane)
- `means.show` Show ★ / Afficher ★ ★: toggle, default `false`; values: true / false. A line at the average of each point (series), in its color.
- `means.style` Line style / Style du trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `means.width` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `means.label` Show the value / Afficher la valeur: toggle, default `true`; values: true / false

### Interactions (`interaction`)
- `interaction.hover` Highlight on hover / Mettre en avant au survol: toggle, default `true`; values: true / false
- `interaction.dim` Dimmed items opacity (%) / Opacité des éléments estompés (%): number, default `25`; values: 5 to 80

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Image Plume

- Your base64 images, finally shown well: even beyond 32,766 characters, placed, sized, clipped into circles or shapes, and filtering the report on click.
- Slug `image` · version 1.1.0.0 · GUID (`visualType`) `plumeImageF765EB2CC018408786BADCD7A1C0464F` · page https://plumevisuals.com/en/visuals/image

### What the visual does

Image Plume (identifier `image`) is a Power BI custom visual (version 1.1.0.0, installed from its `.pbiviz` file; not yet on AppSource) that shows **images stored in the report as base64 text or data URIs**. It never loads a web address.

**New in version 1.1.0.0 (30/10/2026):** Free native-parity additions: cross-filtering without an "Image key" field, **link opened on click** (web URL action), "Brighter" hover state.

- **Sources**: a column or a measure in the `image` role (raw base64, `data:image/png|jpeg|gif|webp|bmp;base64,…`, `data:image/svg+xml` or SVG markup), or an image pasted in **Format › Pasted image and fallback** (`fallback.pasted`), shown when no field is set (a logo) or as a fallback for empty images (`fallback.whenEmpty` = `fallback`).
- **Images over 32,766 characters** (the limit of Power BI column texts): split them into rows (one chunk per row) and drop the chunk number in **Chunk index** (`chunkIndex`): the visual sorts the chunks numerically (2 before 10), keeps a repeated index once, joins them, one image per **Image key**, and reports missing indexes in edit mode. A DAX measure with `CONCATENATEX` works too (a measure is not limited to 32,766 characters).
- **Web addresses refused**: `http(s)://`, `//`, `www.`, `file:`, `ftp:`, `blob:`, `C:\…`, `\\server` are never loaded (Microsoft certification); a message explains it in edit mode ("Embedded images only: web addresses are never loaded (convert the image to base64)"). SVGs are cleaned (whitelist: scripts, `foreignObject`, external links, event handlers, `<text>` and `<image>` removed) and re-encoded.
- **Displays** (`layout.mode`): `single` (first or last row, a highlighted image first), `grid` (gallery: automatic or fixed columns, spacing, cell shape, maximum number of images, vertical scrolling), `carousel` ★ (arrows, dots, auto-advance with pause, fade or slide), `compare` ★ (before / after slider: first two images), `stack` ★ (layers: the first image opaque, the others at `layout.layerOpacity`).
- **Position and size**: 9-point `position.align` + `offsetX` / `offsetY`, `padding`; `sizeMode` `fit` (whole image), `fill` (frame full, cropped; the position picks the visible part), `stretch`, `original` (pixels), `fixed` (`width` × `height`, `keepRatio`), `percent` (share of the frame); premium `rotate` ★ `90` | `180` | `270` (default `0`), `flipH` ★, `flipV` ★.
- **Masks** (`mask.kind`): `rounded` (`radius` px), `ellipse` (`circle` = perfect circle), `shape` (153 shapes of the Plume library, 22 free), `svg` ★ (`mask.svg`: markup, SVG data URI or a path "d"); `fit` `contain` | `stretch`, `scale` (10–100 %). The outline and the drop shadow ★ follow the mask.
- **Adjustments**: opacity, brightness, contrast, grayscale; ★ saturation (0–300 %), ★ blur, ★ sepia, vintage, warm, cool, duotone (style colors or `duoDark` / `duoLight`), negative, hue.
- **Image by value ★** (`conditional`): with the `value` role, `pick` shows the 1st image below `t1`, the 2nd between `t1` and `t2`, the 3rd from `t2` (traffic lights, conditional logos, no DAX); `fade` greys images below `t1` and rings images from `t2` (in a gallery).
- **Play axis ★** (`play` role, premium since the 22/10/2026 rebalancing: watermark as soon as the field holds data): slideshow, one image (or one gallery) per date / year with the shared Plume player (play, slider, speed, loop, cross-fade).
- Selection and cross-filtering by **Image key**, highlighting from other visuals, tooltips (key, caption, value, Tooltips measures, image size in pixels), magnifier ★ on hover.

### 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` ("Theme JSON ★") are **premium**.
- Free in Image Plume: every source (column, measure, pasted image, chunks), single image and grid, every position and size option (without rotation and flips), masks `rounded`, `ellipse` and the 22 free shapes (`circle`, `square`, `roundedSquare`, `rectangle`, `triangle`, `diamond`, `hexagon`, `star`, `heart`, `cloud`, `drop`, `bubble`, `arrow`, `person`, `house`, `barrel`, `bottle`, `glass`, `wineGlass`, `thermometer`, `battery`, `batteryVertical`), outline, opacity, brightness, contrast, grayscale, captions, selection, tooltips, "Slight zoom" hover.
- Premium features of Image Plume: `layout.mode` = `carousel`, `compare` or `stack` (with at least two images); `mask.kind` = `svg`; any other `mask.shape` (131 shapes); `adjust.preset` = `sepia`, `vintage`, `warm`, `cool`, `duotone`, `invert`; `adjust.hue` ≠ 0; `conditional.show` with the Value field; `interaction.hover` = `loupe`; and since 22/10/2026: a filled **Play axis** field, `outline.shadow`, `adjust.saturation` ≠ 100, `adjust.blur` > 0, `position.rotate` ≠ `0`, `position.flipH`, `position.flipV`.
- 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 `image` 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 image, or one row per chunk of an image.

| Image key (`category`) | Chunk index (`chunkIndex`) | Image (`image`) | Caption (`label`) |
|---|---|---|---|
| Arcachon | 1 | `iVBORw0KGgo…` (30,000 characters) | Bay and stilt huts |
| Arcachon | 2 | `…` | Bay and stilt huts |
| Sarlat | 1 | `iVBORw0KGgo…` | Medieval town |

- **Image (base64)** (`image`, « Image (base64) », one column **or** measure, required unless an image is pasted in the pane): the image text. As a column it is used as is (no aggregation).
- **Image key (category)** (`category`, « Clé de l'image (catégorie) », one column): one image per value; selection and cross-filtering.
- **Chunk index** (`chunkIndex`, « Index du morceau », one column of numbers): order of the chunks.
- **Caption** (`label`, « Légende », one column or measure): text with the image; in a grid or carousel, the key is shown when it is empty.
- **Value (thresholds) ★** (`value`, « Valeur (seuils) ★ », one measure) for Image by value.
- **Play axis** (`play`, « Axe de lecture », one column), **Tooltips** (`tooltips`), **Dynamic format** (`format`).
- Volume: windows of 30,000 rows, more fetched with `fetchMoreData`; only displayed images are decoded (at most `layout.maxImages`, default 100, max 500).

### Power Query and DAX recipes

```m
// A folder of images → one row per 30,000-character chunk (Name, Chunk index, Chunk)
let
    Source = Folder.Files("C:\Images"),
    Bin    = Table.AddColumn(Source, "B64", each Binary.ToText([Content], BinaryEncoding.Base64), type text),
    Chunks = Table.AddColumn(Bin, "Chunks", each let t = [B64], n = Number.RoundUp(Text.Length(t) / 30000)
             in Table.FromColumns({ {1..n}, List.Transform({0..n - 1}, (i) => Text.Middle(t, i * 30000, 30000)) }, { "Chunk index", "Chunk" })),
    Rows   = Table.ExpandTableColumn(Table.SelectColumns(Chunks, { "Name", "Chunks" }), "Chunks", { "Chunk index", "Chunk" })
in
    Rows
```

```dax
// One image per filter context, joined in DAX (alternative to the Chunk index field)
Full image = "data:image/png;base64," & CONCATENATEX ( Images, Images[Chunk], "", Images[Chunk index], ASC )

// Default logo when nothing is selected: return BLANK and set fallback.whenEmpty = fallback with a pasted logo
Logo shown = IF ( HASONEVALUE ( Companies[Company] ), SELECTEDVALUE ( Companies[Logo] ), BLANK () )
```

### Interactions with the report

- Click an image (with an Image key): select and cross-filter; Ctrl + click for several; click the background to clear. Other images fade (`interaction.dim`, 30 %). Highlighting from other visuals fades non-highlighted images (single mode: the highlighted image is shown).
- Context menu everywhere (images, captions, carousel controls, slider, empty area, landing page).
- Keyboard: Tab to the visual; arrows move between images (grid), change image (carousel), move the before / after slider (Shift = 10 %, Home, End) or the play axis; Enter selects; Esc clears. Screen readers: role img with the alternative text (`fallback.alt`, else caption, else key), slider role for the before / after handle, announcements in French and English.
- Nothing is saved with persistProperties: carousel position, slider and magnifier are session state.

### Dynamic formats

- **fx button** on colors and texts (e.g. `outline.color`, `caption.color`, `fallback.pasted`).
- **"Dynamic format" well** (`format`): measures renamed `card.setting` (e.g. `adjust.brightness`, `mask.kind`, `title.text`) drive any setting. Driving a ★ setting by DAX still shows the watermark without a key.

```dax
// renamed title.text
Featured title = "Featured: " & SELECTEDVALUE ( Places[Place], "Nouvelle-Aquitaine" )
// renamed adjust.brightness
Brightness by filter = IF ( HASONEVALUE ( Places[Place] ), 100, 90 )
```

### Format pane: option IDs

- Card order: `license`, `style`, `layout`, `position`, `mask`, `outline`, `adjust`, `caption`, `conditional`, `interaction`, `fallback`, `play` (only with a Play axis field), then `title`, `source`, `container`, `texts`. Format pane in version 1.1.0.0 (30/10/2026), top to bottom: `license`, `style`, `layout`, `layers`, `position`, `mask`, `outline`, `adjust`, `caption`, `conditional`, `fallback`, `play`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- `layout`: `mode` (`single` | `grid` | `carousel` ★ | `compare` ★ | `stack` ★), `pick` (`first` | `last`), `columns` (0 = auto, 0–24), `gap` (0–60, 8), `cellRatio` (`auto` | `square` | `landscape` | `wide` | `portrait`), `maxImages` (1–500, 100), `interval` (1,000–30,000 ms, 4,000), `autoAdvance`, `effect` (`fade` | `slide` | `none`), `arrows`, `dots`, `split` (0–100, 50), `compareLabels`, `layerOpacity` (0–100, 60).
- `position`: `align` (`topLeft` | `top` | `topRight` | `left` | `center` | `right` | `bottomLeft` | `bottom` | `bottomRight`), `sizeMode` (`fit` | `fill` | `stretch` | `original` | `fixed` | `percent`), `width`, `height` (160), `keepRatio`, `percent` (80), `offsetX`, `offsetY`, `padding`, `rotate` (`0` | `90` ★ | `180` ★ | `270` ★), `flipH` ★, `flipV` ★.
- `mask`: `kind` (`none` | `rounded` | `ellipse` | `shape` | `svg` ★), `radius` (16), `circle` (on), `shape` (153 shape IDs, default `hexagon`), `svg` ★, `fit` (`contain` | `stretch`), `scale` (10–100, 100).
- `outline`: `show`, `width` (2), `color` (empty = accent), `shadow` ★, `shadowColor`, `shadowOpacity` (30), `shadowBlur` (10), `shadowOffset` (4).
- `adjust`: `opacity`, `brightness`, `contrast`, `saturation` ★ (100), `blur` ★ (0), `preset` (`none` | `grayscale` | `sepia` ★ | `vintage` ★ | `warm` ★ | `cool` ★ | `duotone` ★ | `invert` ★), `duoDark`, `duoLight`, `hue` ★ (−180–180).
- `caption`: `show`, `position` (`below` | `above` | `overlayBottom` | `overlayTop`), `fontSize` (12), `bold`, `color`, `align`, `lines` (2), `band`.
- `conditional` ★: `show`, `mode` (`pick` | `fade`), `t1`, `t2`. `interaction`: `select`, `dim` (30), `hover` (`none` | `lift` | `loupe` ★), `loupeZoom` (250), `loupeSize` (140). `fallback`: `pasted`, `whenEmpty` (`placeholder` | `fallback` | `hide`), `alt`.
- `play` ★ (card "Playback ★"): shared player (`start`, `speed`, `loop`, `autoPlay`, `transition`, `controls`, `position`, `ticks`, `tickLabels`, `stepButtons`, `speedButton`, `showLabel`, `labelSize`, `labelPosition`).

### Editing a PBIP report (visual.json)

```json
{
  "visualType": "plumeImageF765EB2CC018408786BADCD7A1C0464F",
  "query": {
    "queryState": {
      "category":   { "projections": [ { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Places" } }, "Property": "Place" } }, "queryRef": "Places.Place", "nativeQueryRef": "Place" } ] },
      "chunkIndex": { "projections": [ { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Places" } }, "Property": "Chunk index" } }, "queryRef": "Places.Chunk index", "nativeQueryRef": "Chunk index" } ] },
      "image":      { "projections": [ { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Places" } }, "Property": "Image" } }, "queryRef": "Places.Image", "nativeQueryRef": "Image" } ] }
    }
  },
  "objects": {
    "layout":   [ { "properties": { "mode": { "expr": { "Literal": { "Value": "'grid'" } } } } } ],
    "position": [ { "properties": { "sizeMode": { "expr": { "Literal": { "Value": "'fill'" } } } } } ],
    "mask":     [ { "properties": { "kind": { "expr": { "Literal": { "Value": "'ellipse'" } } } } } ]
  }
}
```

### Common pitfalls

- Image cut or a gray placeholder: text truncated at 32,766 characters; split into chunks and add Chunk index.
- "Embedded images only…": the column holds web addresses; convert to base64.
- All chunks mixed into one image: several images without an Image key.
- One image instead of a gallery: `layout.mode` is `single`.
- Watermark visible: a filled play axis, drop shadow, saturation or blur, rotation or flips, carousel, before / after or layers with two images or more, a ★ shape or SVG mask, a ★ filter or hue, Image by value with the Value field, magnifier, a ★ style or a theme JSON, without a valid key.
- Text inside an SVG used as a mask or as an image is removed by the cleaning (draw logos with shapes).

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

Loading images from a URL, SharePoint or OneLake; opening a web link or a report page on click; interactive cropping saved in the report; per-layer settings (each layer has the same position, size and mask); playback control of animated GIFs; exporting or downloading the image.

## Image Plume: data fields

- `image` Image (base64) (GroupingOrMeasure, 1 max): Column or measure with base64 text or a data URI (PNG, JPEG, GIF, WebP, BMP, SVG). With “Chunk index”: one piece of the image per row.
- `category` Image key (category) / Clé de l'image (catégorie) (column, 1 max): One image per value (product, person, site): gallery, carousel, selection and cross-filtering.
- `chunkIndex` Chunk index / Index du morceau (column, 1 max): Order of the pieces of an image split into rows (beyond the 32,766-character limit of Power BI texts): the visual joins them back.
- `label` Caption / Légende (GroupingOrMeasure, 1 max): Text shown with the image (and read by screen readers).
- `value` Value (thresholds) ★ / Valeur (seuils) ★ ★ (measure, 1 max): Number compared with the thresholds of “Image by value ★”: picks the image (traffic lights, conditional logos) or fades the images below the threshold.
- `play` Play axis ★ / Axe de lecture ★ ★ (column, 1 max): A date, a year or an ordered category: the visual moves from one value to the next (play button)
- `tooltips` Tooltips / Infobulles (measure, several max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Image Plume: Format pane options (156)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Layout / Disposition (`layout`)
- `layout.mode` Display / Affichage: dropdown, default `single`; values: `single` Single image; `grid` Grid (gallery); `carousel` Carousel ★; `compare` Before / after (slider) ★; `stack` Stacked layers ★. One image (the first row, or the highlighted one), a gallery grid, a carousel, a before / after slider or stacked layers.
- `layout.pick` Image shown / Image affichée: dropdown, default `first`; values: `first` The first one; `last` The last one. Visible when `layout.mode` = `single`. With several rows: the first or the last one (a highlighted or selected image comes first).
- `layout.columns` Columns (0 = automatic) / Colonnes (0 = automatique): number, default `0`; values: 0 to 24. Visible when `layout.mode` = `grid`
- `layout.gap` Spacing (px) / Espacement (px): number, default `8`; values: 0 to 60. Visible when `layout.mode` = `grid`
- `layout.cellRatio` Cell shape / Format des cases: dropdown, default `auto`; values: `auto` Automatic (fill the visual); `square` Square; `landscape` Landscape 4:3; `wide` Wide 16:9; `portrait` Portrait 3:4. Visible when `layout.mode` = `grid`
- `layout.maxImages` Maximum number of images / Nombre maximal d'images: number, default `100`; values: 1 to 500. Visible when `layout.mode` = `grid` or `carousel` or `stack`
- `layout.interval` Duration of an image (ms) / Durée d'une image (ms): number, default `4000`; values: 1000 to 30000. Visible when `layout.mode` = `carousel`
- `layout.autoAdvance` Auto-advance / Défilement automatique: toggle, default `true`; values: true / false. Visible when `layout.mode` = `carousel`. Pauses on hover and keyboard focus; the pause button stops it. Never on a dashboard tile.
- `layout.effect` Transition: dropdown, default `fade`; values: `fade` Fade; `slide` Slide; `none` None. Visible when `layout.mode` = `carousel`
- `layout.arrows` Arrows / Flèches: toggle, default `true`; values: true / false. Visible when `layout.mode` = `carousel`
- `layout.dots` Navigation dots / Points de navigation: toggle, default `true`; values: true / false. Visible when `layout.mode` = `carousel`
- `layout.split` Initial slider position (%) / Position du curseur au départ (%): number, default `50`; values: 0 to 100. Visible when `layout.mode` = `compare`
- `layout.compareLabels` Before / after labels / Libellés avant / après: toggle, default `true`; values: true / false. Visible when `layout.mode` = `compare`
- `layout.layerOpacity` Opacity of upper layers (%) / Opacité des calques du dessus (%): number, default `60`; values: 0 to 100. Visible when `layout.mode` = `stack`

### Per-layer settings ★ / Réglages par calque ★ (`layers`, one entry per item with a selector)
- `layers.show` Show the layer / Afficher le calque: toggle, default `true`; values: true / false
- `layers.opacity` Layer opacity (%, -1 = shared) / Opacité du calque (%, -1 = commune): number, default `-1`; values: -1 to 100. -1: the opacity of upper layers set in Layout. The first layer stays opaque unless you set it here.

### Position and size / Position et taille (`position`)
- `position.align` Position: dropdown, default `center`; values: `topLeft` Top left; `top` Top; `topRight` Top right; `left` Left; `center` Center; `right` Right; `bottomLeft` Bottom left; `bottom` Bottom; `bottomRight` Bottom right. Where the image sits in its frame; with “Fill”, the part of the image that stays visible.
- `position.sizeMode` Size / Taille: dropdown, default `fit`; values: `fit` Fit (whole image); `fill` Fill (crop); `stretch` Stretch; `original` Original size; `fixed` Fixed size (px); `percent` Share of the frame (%)
- `position.width` Width (px) / Largeur (px): number, default `160`; values: 1 to 4000. Visible when `position.sizeMode` = `fixed`
- `position.height` Height (px) / Hauteur (px): number, default `160`; values: 1 to 4000. Visible when `position.sizeMode` = `fixed`
- `position.keepRatio` Keep proportions / Garder les proportions: toggle, default `true`; values: true / false. Visible when `position.sizeMode` = `fixed`
- `position.percent` Share (%) / Proportion (%): number, default `80`; values: 1 to 100. Visible when `position.sizeMode` = `percent`
- `position.offsetX` Horizontal offset (px) / Décalage horizontal (px): number, default `0`; values: -2000 to 2000
- `position.offsetY` Vertical offset (px) / Décalage vertical (px): number, default `0`; values: -2000 to 2000
- `position.padding` Margin around the image (px) / Marge autour de l'image (px): number, default `0`; values: 0 to 200
- `position.rotate` Rotation: dropdown, default `0`; values: `0` None; `90` 90° (clockwise) ★; `180` 180° ★; `270` 90° (counterclockwise) ★
- `position.flipH` Flip horizontally ★ / Miroir horizontal ★ ★: toggle, default `false`; values: true / false
- `position.flipV` Flip vertically ★ / Miroir vertical ★ ★: toggle, default `false`; values: true / false

### Mask (clipping) / Masque (découpe) (`mask`)
- `mask.kind` Clip the image / Découper l'image: dropdown, default `none`; values: `none` No; `rounded` Rounded corners; `ellipse` Ellipse or circle; `shape` Shape from the library; `svg` Custom SVG ★. Rounded corners, ellipse or circle, one of the 153 shapes of the library (22 free) or your own SVG ★.
- `mask.radius` Corner radius (px) / Rayon des angles (px): number, default `16`; values: 0 to 1000. Visible when `mask.kind` = `rounded`
- `mask.circle` Perfect circle / Cercle parfait: toggle, default `true`; values: true / false. Visible when `mask.kind` = `ellipse`. Off: an ellipse that fills the frame of the image.
- `mask.shape` Shape / Forme: dropdown, default `hexagon`; values: `circle` Basic · Circle; `square` Basic · Square; `roundedSquare` Basic · Rounded square; `rectangle` Basic · Rectangle; `triangle` Basic · Triangle; `diamond` Basic · Diamond; `hexagon` Basic · Hexagon; `star` Basic · Star; `heart` Basic · Heart; `ellipse` Basic · Ellipse ★; `pentagon` Basic · Pentagon ★; `octagon` Basic · Octagon ★; `rightTriangle` Basic · Right triangle ★; `parallelogram` Basic · Parallelogram ★; `trapezoid` Basic · Trapezoid ★; `ring` Basic · Ring ★; `semicircle` Basic · Semicircle ★; `arch` Basic · Arch ★; `capsule` Basic · Pill ★; `star6` Basic · Six-pointed star ★; `seal` Basic · Seal ★; `cross` Basic · Cross ★; `arrow` Arrows and symbols · Arrow; `arrowUp` Arrows and symbols · Arrow up ★; `arrowDown` Arrows and symbols · Arrow down ★; `arrowLeft` Arrows and symbols · Arrow left ★; `doubleArrow` Arrows and symbols · Double arrow ★; `chevron` Arrows and symbols · Chevron ★; `check` Arrows and symbols · Check mark ★; `close` Arrows and symbols · Close (X) ★; `plus` Arrows and symbols · Plus ★; `minus` Arrows and symbols · Minus ★; `warning` Arrows and symbols · Warning ★; `info` Arrows and symbols · Information ★; `playButton` Arrows and symbols · Play button ★; `bubble` Arrows and symbols · Speech bubble; `thought` Arrows and symbols · Thought bubble ★; `flag` Arrows and symbols · Flag ★; `bookmark` Arrows and symbols · Bookmark ★; `tag` Arrows and symbols · Tag ★; `bolt` Arrows and symbols · Lightning bolt ★; `shield` Arrows and symbols · Shield ★; `award` Arrows and symbols · Award ★; `puzzle` Arrows and symbols · Puzzle piece ★; `gear` Arrows and symbols · Gear ★; `lock` Arrows and symbols · Lock ★; `key` Arrows and symbols · Key ★; `bell` Arrows and symbols · Bell ★; `eye` Arrows and symbols · Eye ★; `cloud` Nature and weather · Cloud; `drop` Nature and weather · Drop; `sun` Nature and weather · Sun ★; `moon` Nature and weather · Moon ★; `snowflake` Nature and weather · Snowflake ★; `leaf` Nature and weather · Leaf ★; `pine` Nature and weather · Pine tree ★; `tree` Nature and weather · Tree ★; `flower` Nature and weather · Flower ★; `mountain` Nature and weather · Mountain ★; `wave` Nature and weather · Wave ★; `flame` Nature and weather · Flame ★; `umbrella` Nature and weather · Umbrella ★; `apple` Nature and weather · Apple ★; `fish` Nature and weather · Fish ★; `paw` Nature and weather · Paw print ★; `rain` Nature and weather · Rain ★; `sprout` Nature and weather · Sprout ★; `person` People · Person; `man` People · Man ★; `woman` People · Woman ★; `child` People · Child ★; `people` People · Group of people ★; `bust` People · User bust ★; `house` Objects and buildings · House; `building` Objects and buildings · Office building ★; `factory` Objects and buildings · Factory ★; `castle` Objects and buildings · Castle ★; `shop` Objects and buildings · Shop ★; `bank` Objects and buildings · Bank ★; `hospital` Objects and buildings · Hospital ★; `book` Objects and buildings · Book ★; `envelope` Objects and buildings · Envelope ★; `phone` Objects and buildings · Phone ★; `laptop` Objects and buildings · Laptop ★; `monitor` Objects and buildings · Monitor ★; `gift` Objects and buildings · Gift ★; `clock` Objects and buildings · Clock ★; `calendar` Objects and buildings · Calendar ★; `pencil` Objects and buildings · Pencil ★; `lightbulb` Objects and buildings · Light bulb ★; `cup` Objects and buildings · Trophy ★; `crown` Objects and buildings · Crown ★; `trashCan` Objects and buildings · Trash can ★; `barrel` Containers and gauges · Barrel; `bottle` Containers and gauges · Bottle; `wineGlass` Containers and gauges · Wine glass; `glass` Containers and gauges · Glass; `mug` Containers and gauges · Mug ★; `jar` Containers and gauges · Jar ★; `bucket` Containers and gauges · Bucket ★; `battery` Containers and gauges · Battery; `batteryVertical` Containers and gauges · Vertical battery; `thermometer` Containers and gauges · Thermometer; `testTube` Containers and gauges · Test tube ★; `tank` Containers and gauges · Tank ★; `funnel` Containers and gauges · Funnel ★; `hourglass` Containers and gauges · Hourglass ★; `bag` Containers and gauges · Bag ★; `piggyBank` Containers and gauges · Piggy bank ★; `flask` Containers and gauges · Flask ★; `beaker` Containers and gauges · Beaker ★; `can` Containers and gauges · Can ★; `coffeeCup` Containers and gauges · Coffee cup ★; `vase` Containers and gauges · Vase ★; `milkCarton` Containers and gauges · Milk carton ★; `france` Maps and places · Metropolitan France ★; `africa` Maps and places · Africa ★; `australia` Maps and places · Australia ★; `southAmerica` Maps and places · South America ★; `pin` Maps and places · Map pin ★; `globe` Maps and places · Globe ★; `foldedMap` Maps and places · Folded map ★; `compass` Maps and places · Compass ★; `city` Maps and places · City skyline ★; `target` Business · Target ★; `barChart` Business · Bar chart ★; `pieChart` Business · Pie chart ★; `trendUp` Business · Trend up ★; `coin` Business · Coin ★; `banknote` Business · Banknote ★; `wallet` Business · Wallet ★; `creditCard` Business · Credit card ★; `cart` Business · Shopping cart ★; `briefcase` Business · Briefcase ★; `percent` Business · Percent ★; `podium` Business · Podium ★; `megaphone` Business · Megaphone ★; `gem` Business · Gem ★; `medal` Business · Medal ★; `clipboard` Business · Clipboard ★; `handshake` Business · Handshake ★; `car` Transport · Car ★; `truck` Transport · Truck ★; `bus` Transport · Bus ★; `bicycle` Transport · Bicycle ★; `plane` Transport · Plane ★; `boat` Transport · Sailboat ★; `train` Transport · Train ★; `rocket` Transport · Rocket ★; `helicopter` Transport · Helicopter ★; `ship` Transport · Cargo ship ★; `fuel` Transport · Fuel pump ★; `scooter` Transport · Scooter ★. 153 shapes in 9 families; 22 of them are free, the others ★.
- `mask.svg` Clipping SVG ★ / SVG de la découpe ★ ★: textarea, default (empty). Visible when `mask.kind` = `svg`. Paste an SVG (markup, data URI or a path “d”): its filled shapes cut the image. Cleaned, nothing is ever loaded.
- `mask.fit` Shape fit / Ajustement de la forme: dropdown, default `contain`; values: `contain` Keep proportions; `stretch` Fill the frame (distorted). Visible when `mask.kind` = `shape` or `svg`
- `mask.scale` Shape size (%) / Taille de la forme (%): number, default `100`; values: 10 to 100. Visible when `mask.kind` = `ellipse` or `shape` or `svg`

### Outline and shadow / Contour et ombre (`outline`)
- `outline.show` Outline / Contour: toggle, default `false`; values: true / false. Follows the mask.
- `outline.width` Width (px) / Épaisseur (px): number, default `2`; values: 1 to 30. Visible when `outline.show` = `true`
- `outline.color` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color. Visible when `outline.show` = `true`
- `outline.shadow` Drop shadow ★ / Ombre portée ★ ★: toggle, default `false`; values: true / false. Follows the mask and the transparent parts of the image.
- `outline.shadowColor` Shadow color / Couleur de l'ombre: color, default `#000000`; values: hex color. Visible when `outline.shadow` = `true`
- `outline.shadowOpacity` Shadow opacity (%) / Opacité de l'ombre (%): number, default `30`; values: 0 to 100. Visible when `outline.shadow` = `true`
- `outline.shadowBlur` Shadow blur (px) / Flou de l'ombre (px): number, default `10`; values: 0 to 60. Visible when `outline.shadow` = `true`
- `outline.shadowOffset` Shadow offset (px) / Décalage de l'ombre (px): number, default `4`; values: 0 to 40. Visible when `outline.shadow` = `true`

### Image adjustments / Réglages de l'image (`adjust`)
- `adjust.opacity` Opacity (%) / Opacité (%): number, default `100`; values: 0 to 100
- `adjust.brightness` Brightness (%) / Luminosité (%): number, default `100`; values: 0 to 300
- `adjust.contrast` Contrast (%) / Contraste (%): number, default `100`; values: 0 to 300
- `adjust.saturation` Saturation (%) ★ ★: number, default `100`; values: 0 to 300
- `adjust.blur` Blur (px) ★ / Flou (px) ★ ★: number, default `0`; values: 0 to 40
- `adjust.preset` Filter / Filtre: dropdown, default `none`; values: `none` None; `grayscale` Grayscale; `sepia` Sepia ★; `vintage` Vintage ★; `warm` Warm ★; `cool` Cool ★; `duotone` Duotone (style colors) ★; `invert` Negative ★
- `adjust.duoDark` Duotone: shadows (empty = style) / Duotone : ombres (vide = style): color, default (empty); values: hex color. Visible when `adjust.preset` = `duotone`
- `adjust.duoLight` Duotone: highlights (empty = style) / Duotone : lumières (vide = style): color, default (empty); values: hex color. Visible when `adjust.preset` = `duotone`
- `adjust.hue` Hue (degrees) ★ / Teinte (degrés) ★ ★: number, default `0`; values: -180 to 180

### Caption / Légende de l'image (`caption`)
- `caption.show` Show / Afficher: toggle, default `true`; values: true / false. Text of the “Caption” field; in a gallery or a carousel, the image key when the field is empty.
- `caption.position` Position: dropdown, default `below`; values: `below` Below the image; `above` Above the image; `overlayBottom` On the image, bottom; `overlayTop` On the image, top
- `caption.fontSize` Size / Taille: number, default `12`; values: 6 to 40
- `caption.bold` Bold / Gras: toggle, default `false`; values: true / false
- `caption.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `caption.align` Alignment / Alignement: dropdown, default `center`; values: `left` Left; `center` Center; `right` Right
- `caption.lines` Maximum lines / Lignes au plus: number, default `2`; values: 1 to 6
- `caption.band` Band behind the text (on the image) / Bandeau sous le texte (sur l'image): toggle, default `true`; values: true / false

### Image by value ★ / Image selon la valeur ★ (`conditional`)
- `conditional.show` Enable ★ / Activer ★ ★: toggle, default `false`; values: true / false. Needs the “Value (thresholds)” field. No DAX needed: traffic lights, conditional logos, status pictures.
- `conditional.mode` Effect / Effet: dropdown, default `pick`; values: `pick` Pick the image (1st, 2nd or 3rd row) by threshold; `fade` Fade below threshold 1, ring above threshold 2
- `conditional.t1` Threshold 1 / Seuil 1: number, default `0`
- `conditional.t2` Threshold 2 (ignored unless above threshold 1) / Seuil 2 (ignoré s'il n'est pas au-dessus du seuil 1): number, default `0`

### Pasted image and fallback / Image collée et repli (`fallback`)
- `fallback.pasted` Pasted image (base64, data URI or SVG) / Image collée (base64, data URI ou SVG): textarea, default (empty). Shown without any field (a logo), or when an image of the data is empty. Web addresses are refused.
- `fallback.whenEmpty` Empty or unreadable image / Image vide ou illisible: dropdown, default `placeholder`; values: `placeholder` Discreet placeholder; `fallback` Pasted image; `hide` Nothing
- `fallback.alt` Alternative text (accessibility) / Texte de remplacement (accessibilité): text, default (empty). Read by screen readers. Empty: the caption, then the image key.

### Playback ★ / Lecture ★ (`play`)
- `play.start` Frame shown on opening / Image affichée à l'ouverture: dropdown, default `last`; values: `last` The last one (most recent); `first` The first one
- `play.speed` Duration of a frame (ms) / Durée d'une image (ms): number, default `1000`; values: 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, default `false`; values: true / false
- `play.autoPlay` Play automatically on opening / Lecture automatique à l'ouverture: toggle, default `false`; values: 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, default `true`; values: true / false. Values, positions and colors move smoothly from one frame to the next.
- `play.controls` Play bar / Barre de lecture: toggle, default `true`; values: true / false
- `play.position` Bar position / Position de la barre: dropdown, default `bottom`; values: `bottom` Bottom; `top` Top. Visible when `play.controls` = `true`
- `play.ticks` Tick marks / Graduations: dropdown, default `auto`; values: `auto` Automatic; `all` Every frame; `none` None. Visible when `play.controls` = `true`
- `play.tickLabels` Tick labels / Étiquettes des graduations: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.stepButtons` Start and end buttons / Boutons début et fin: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.speedButton` Speed button / Bouton de vitesse: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.showLabel` Current value in large type / Valeur en cours en grand: toggle, default `true`; values: true / false
- `play.labelSize` Large value size / Taille de la valeur en grand: number, default `44`; values: 12 to 160. Visible when `play.showLabel` = `true`
- `play.labelPosition` Large value position / Position de la valeur en grand: dropdown, default `bottomRight`; values: `bottomRight` Bottom right; `topRight` Top right; `topLeft` Top left; `bottomLeft` Bottom left; `center` Center. Visible when `play.showLabel` = `true`

### Interactions (`interaction`)
- `interaction.select` Click = filter the report / Clic = filtrer le rapport: toggle, default `true`; values: true / false. A click selects the image and filters the other visuals (Ctrl + click: several). Identity: the “Image key” field, otherwise the “Caption” or “Image” column.
- `interaction.link` Link opened on click (https://…) / Lien ouvert au clic (https://…): text, default (empty). Like the Web URL action of the native Image visual: Power BI asks before opening it. With a link, Ctrl + click still selects. Can come from a measure (fx).
- `interaction.dim` Opacity of unselected images (%) / Opacité des images non sélectionnées (%): number, default `30`; values: 5 to 90
- `interaction.hover` Hover / Survol: dropdown, default `lift`; values: `none` No effect; `lift` Slight zoom; `brighten` Brighter; `loupe` Magnifier ★
- `interaction.loupeZoom` Magnifier zoom (%) / Grossissement de la loupe (%): number, default `250`; values: 150 to 800. Visible when `interaction.hover` = `loupe`
- `interaction.loupeSize` Magnifier diameter (px) / Diamètre de la loupe (px): number, default `140`; values: 60 to 400. Visible when `interaction.hover` = `loupe`

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Shape Gauge Plume

- A drop, a barrel or your logo fills up with color to show a percentage: value and target, one shape per category, your logo.
- Slug `shape-gauge` · version 1.1.0.0 · GUID (`visualType`) `plumeShapeGaugeF50F8ABFCB9F44309B5AF1FB9BD1EA96` · page https://plumevisuals.com/en/visuals/shape-gauge

### What the visual does

Shape Gauge Plume (identifier `shape-gauge`) is a Power BI custom visual (version 1.1.0.0, installed from its `.pbiviz` file; AppSource submission in preparation) that turns **any shape into a gauge**: a drop, a barrel, a bottle or a logo fills up with color to show a percentage (e.g. a barrel 50% full of burgundy for 50%). Power BI has no native shape gauge (the native gauge is an arc); Microsoft's old Liquid Fill Gauge (circle only) is no longer in the store.

**New in version 1.1.0.0 (30/10/2026):** Free native-parity addition: **minimum and maximum labels** at the ends of the scale.

- **Percentage** = (value − minimum) / (maximum − minimum). Minimum: `minimum` role, else `scale.min`, else 0. Maximum: `maximum` role, else the `target` role ("Target (100 %)"), else `scale.max`, else automatic: 1 when values are fractions (% format or all between 0 and 1), else the largest value.
- **153 shapes** from the shared Plume library (22 free), including **22 containers** (barrel, bottle, wine glass, glass, mug, jar, bucket, battery, vertical battery, thermometer, test tube, tank, funnel, hourglass, bag, piggy bank, flask, beaker, can, coffee cup, vase, milk carton) that fill **only their inside**; hoops, graduations and sleeves are drawn over the liquid. Own SVG ★ pasted in the pane or returned by a text measure (sanitized).
- **Fill directions**: bottom → top, top → bottom, left → right, right → left, "from the shape" (battery: left → right), circular ★ (start angle, clockwise or not), radial ★. `fill.measure` = `area` ★ makes the filled **area** exactly the percentage.
- Wavy surface, animated fill on opening (900 ms, not on resize), visible overflow above 100% (dome) or cap, two-tone label placed at the widest point of the filled area, target mark with an arrow, tick marks ★, one shape per category in an automatic grid, and the shared **play axis** ★: the shape fills up frame after frame with animated transitions.

### 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 (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium**.
- Free in Shape Gauge Plume: the 22 free shapes (`circle`, `square`, `roundedSquare`, `rectangle`, `triangle`, `diamond`, `hexagon`, `star`, `heart`, `cloud`, `drop` (default), `bubble`, `arrow`, `person`, `house`, `barrel`, `bottle`, `glass`, `wineGlass`, `thermometer`, `battery`, `batteryVertical`); vertical and horizontal fills (height of the level); single color (also driven by DAX), one color per category; empty part color and opacity, container color, outline; wavy surface; every label option; target, overflow; one shape per category; sort, columns, limit.
- Premium features of Shape Gauge Plume: the 131 other shapes (among them 15 of the 22 containers: mug, jar, bucket, test tube, tank, funnel, hourglass, bag, piggy bank, flask, beaker, can, coffee cup, vase, milk carton); `shape.source` = `svg` and the `shapeSvg` role; `shape.svgPaint` = `original`; `fill.direction` = `circular` or `radial`; `dataColors.mode` = `gradient` or `scale`; `shape.emptyPattern` = `hatch`, `dots` or `grid`; `fill.waveMotion` (only when animations are not reduced); `fill.bubbles` (only for bottom-to-top fills); `layout.mode` = `pictograms`; the `comparison` role with `scale.compareShow`; the `layers` role; since the rebalancing of 22/10/2026: the `play` role (play axis, as soon as it holds data), `dataColors.mode` = `thresholds`, `fill.measure` = `area`, `scale.ticks` (vertical and horizontal fills). A ★ option with no effect shows no watermark (an unreadable SVG falls back to the free drop).
- 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 `shape-gauge` 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, key accepted for 30 more days, reminders 30 and 7 days before the end). Prices: 39 € personal, 99 € SME, 299 € enterprise per year, or the catalog pack (199 € / 399 € / 1,199 € per year; tiers by number of users: personal 1–10, SME 11–200, enterprise more than 200).

### Expected data shape

One row per category (and per play-axis value), with measures.

| Category (`category`) | Play axis (`play`) | Value (`value`) | Target (`target`) |
|---|---|---|---|
| West | 2024 | 410,000 | 600,000 |
| West | 2025 | 520,000 | 600,000 |

- **Category (one shape each)** (`category`, « Catégorie (une forme chacune) », one column): one shape per value; click = cross-filter. At most `layout.maxItems` shapes (60, up to 200); a note says so in edit mode.
- **Play axis ★** (`play`, « Axe de lecture ★ », one column, premium): date, year or ordered category; one frame per value. Clicking a shape selects the category only.
- **Value** (`value`, « Valeur », one measure): required unless Stacked layers are used.
- **Target (100 %)** (`target`, « Objectif (100 %) »): the value of a full shape; with `maximum` (or `scale.max`), drawn as a target mark instead.
- **Minimum** (`minimum`), **Maximum** (`maximum`): the empty and full values.
- **Comparison (previous period) ★** (`comparison`): ghost level and the change in points (▲ +8 pts).
- **Stacked layers ★** (`layers`, up to 8 measures): stacked in the shape, one color each, with a legend; their sum is the level.
- **SVG shape (measure) ★** (`shapeSvg`, text measure): SVG markup, data URI or a bare path `d`; one shape per category.
- **Tooltips** (`tooltips`) and **Dynamic format** (`format`, see below).
- Volume of data: windows of 30,000 rows, more fetched with `fetchMoreData` up to 100,000 rows; 100,004 categories render the first 60 shapes in a few seconds.

### DAX recipes

```dax
// Value and target: the shape is full when Revenue = Target
Revenue = SUM ( Sales[Amount] )
Target = SUM ( Sales[Target amount] )

// A ratio can go straight into Value (0.62 = 62%, no target needed)
Achievement = DIVIDE ( [Revenue], [Target] )

// Comparison ★
Prior-year revenue = CALCULATE ( [Revenue], SAMEPERIODLASTYEAR ( Dates[Date] ) )

// SVG shape per product ★ (text measure in the "SVG shape (measure)" well)
Product shape = SWITCH ( SELECTEDVALUE ( Products[Name] ), "Bike", "<svg viewBox='0 0 24 24'><path d='M2 20h20L12 2z'/></svg>", BLANK () )
```

### Interactions with the report

- Click a shape: cross-filter on its category; Ctrl for several; click the empty area to clear. Cross-highlighting from other visuals fills the highlighted part and keeps the full value as a light ghost level. Context menu everywhere (shapes, empty area, title, landing page).
- Hover: Power BI tooltip (category, frame, value, percentage, layers, full and empty values, target, comparison and change, threshold, Tooltips measures); report-page tooltips are supported.
- Play axis: play / pause, slider, speed ×0.5 to ×4, loop, start / end buttons, current frame in large type; keyboard in the play bar: Space, ← →, Page Up / Down, Home / End. Frame, play state and speed are per session (never saved).
- Keyboard on the shapes: Tab, arrows, Home / End, Enter selects, Esc clears; each shape is announced ("West: 62% (520,000)"). High contrast (host colors, no gradient, haloed label), "Reduce motion" respected (no fill animation, no moving wave), French and English.

### Dynamic formats

- **fx button** (Power BI conditional formatting) on colors and texts of the Format pane.
- **"Dynamic format" well** (`format`): measures renamed `card.setting` (e.g. `dataColors.single`, `title.text`, `fill.direction`, `shape.shape`) drive any setting and win over the fixed value. Driving a ★ setting by DAX still shows the watermark without a key.

```dax
// renamed dataColors.single
Result color = IF ( DIVIDE ( [Revenue], [Target] ) >= 0.8, "#2E7D4F", "#C0392B" )
// renamed title.text
Dynamic title = "Target achieved at " & FORMAT ( DIVIDE ( [Revenue], [Target] ), "0%" )
```

### Format pane: option IDs

- Card order: `license`, `style`, `dataColors`, `shape`, `fill`, `labels`, `scale`, `layout`, `legend` (with 2+ layers), `play` (« Lecture ★ », with a play axis), `interaction`, then `title`, `source`, `container`, `texts`. Format pane in version 1.1.0.0 (30/10/2026), top to bottom: `license`, `style`, `layout`, `dataColors`, `shape`, `fill`, `labels`, `scale`, `legend`, `play`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- `dataColors`: `mode` (`single` | `category` | `thresholds` ★ | `gradient` ★ | `scale` ★), `single`, `fill` (per category or per layer), `color2`, `color3`, `t1` (50), `t2` (80), `cLow`, `cMid` (#B26B00), `cHigh`, `lowerBetter`.
- `shape`: `source` (`library` | `svg` ★), `shape` (153 IDs, default `drop`; containers `barrel`, `bottle`, `wineGlass`, `glass`, `mug`, `jar`, `bucket`, `battery`, `batteryVertical`, `thermometer`, `testTube`, `tank`, `funnel`, `hourglass`, `bag`, `piggyBank`, `flask`, `beaker`, `can`, `coffeeCup`, `vase`, `milkCarton`), `svg` (text), `svgPaint` (`fill` | `original` ★), `fillArea` (`inner` | `whole`), `fit` (`contain` | `stretch`), `emptyColor`, `emptyOpacity` (0–100, 100), `emptyPattern` (`none` | `hatch` ★ | `dots` ★ | `grid` ★), `bodyColor`, `outline` (on), `outlineColor`, `outlineWidth` (0.5–8, 1.5).
- `fill`: `direction` (`auto` | `up` | `down` | `right` | `left` | `circular` ★ | `radial` ★), `startAngle` (−360–360, 0 = 12 o'clock), `clockwise` (on), `measure` (`level` | `area` ★), `overflow` (`show` | `cap`), `wave` (on), `waveHeight` (1–12, 3), `waveMotion` ★, `waveSpeed` (1–20 s, 4), `bubbles` ★, `grow` (on), `duration` (100–5000 ms, 900).
- `labels`: `show`, `content` (`percent` | `value` | `percentValue` | `valuePercent` | `valueTarget`), `position` (`center` | `level` | `below` | `above`), `autoSize` (on), `fontSize` (24), `color`, `bold` (on), `pctDecimals` (0–4, 0), `delta` (on), `units`, `decimals`, `prefix`, `suffix`, `catShow` (on), `catPosition` (`below` | `above`), `catSize` (12), `catColor`.
- `scale`: `min`, `max` (text), `ticks` ★ (off), `tickStep` (5–50 %, 25), `targetShow` (on), `targetValue` (text), `targetLabel`, `targetColor`, `targetStyle` (`solid` | `dashed` | `dotted`), `compareShow` ★ (on), `compareColor`.
- `layout`: `mode` (`multiples` | `pictograms` ★), `units` (2–50, 10), `unitsPerRow` (0 = auto), `columns` (0 = auto), `gap` (0–80 px, 16), `sort` (`data` | `desc` | `asc` | `name`), `maxItems` (1–200, 60).
- `play` (shared player, ★ as a whole): `start` (`last` | `first`), `speed` (100–10000 ms, 1000), `loop`, `autoPlay`, `transition`, `controls`, `position`, `ticks`, `tickLabels`, `stepButtons`, `speedButton`, `showLabel`, `labelSize` (36), `labelPosition` (`topRight`). `interaction`: `hover`, `dim` (5–80, 25).

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. Booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes; colors as `{ "solid": { "color": … } }`.

```json
{
  "visualType": "plumeShapeGaugeF50F8ABFCB9F44309B5AF1FB9BD1EA96",
  "query": {
    "queryState": {
      "category": { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Region" } }, "queryRef": "Sales.Region", "nativeQueryRef": "Region" } ] },
      "value":    { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Revenue" } }, "queryRef": "Sales.Revenue", "nativeQueryRef": "Revenue" } ] },
      "target":   { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Target" } }, "queryRef": "Sales.Target", "nativeQueryRef": "Target" } ] }
    }
  },
  "objects": {
    "shape":      [ { "properties": { "shape": { "expr": { "Literal": { "Value": "'barrel'" } } } } } ],
    "dataColors": [ { "properties": { "single": { "solid": { "color": { "expr": { "Literal": { "Value": "'#7B1E2B'" } } } } } } } ],
    "license":    [ { "properties": { "key": { "expr": { "Literal": { "Value": "'PLUM1.…'" } } } } } ]
  }
}
```

The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from the `.pbiviz` file).

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`. The style's first series color is the default fill; thresholds use the style's favorable / unfavorable colors; `minimal`, `unknownPleasures` and `blueprint` turn the wave off.
- `style.themeJson` (Theme JSON ★): a JSON theme as plain text (format v2 with optional `extends` and groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`). Full reference: https://plumevisuals.com/ai/tutorials/en/themes-json.md.

### Common pitfalls

- The shape is always full: a single value with no target or maximum (the largest value is 100%); add the Target or `scale.max`.
- "—" instead of a percentage: the Value measure is blank for that category or frame.
- Empty shape with a negative label: the value is below the minimum.
- A dome above the shape: the value is above 100% (`fill.overflow` = `cap` to remove it).
- The play-axis year shows as "2,024": the column format has a thousands separator.
- Only 60 shapes: `layout.maxItems`.
- Watermark visible: a ★ shape, SVG, circular or radial fill, gradient or palette color, pattern, moving wave, bubbles, pictograms, comparison, layers, a ★ style or a theme JSON, without a valid key.
- An SVG is ignored ("Library shape used instead" in edit mode): unreadable or empty SVG; scripts, images, links and web addresses are always removed.
- The visual makes no network request: data, SVG and license key stay in the report.

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

Filling a PNG or JPEG image (only shapes and SVG paths), loading an SVG from a web address, several values per shape other than stacked layers, liquid physics (tilt, sloshing), 3D shapes, a native gauge arc with a needle (use a circular fill instead), exporting the shape as an image.

## Shape Gauge Plume: data fields

- `category` Category (one shape each) / Catégorie (une forme chacune) (column, 1 max): One shape per value of the field (region, product, team…).
- `play` Play axis ★ / Axe de lecture ★ ★ (column, 1 max): A date, a year or an ordered category: the visual moves from one value to the next (play button)
- `value` Value / Valeur (measure, 1 max): The value that fills the shape.
- `target` Target (100 %) / Objectif (100 %) (measure, 1 max): Value of a full shape: percentage = value / target. With Maximum as well, the target is drawn as a mark.
- `minimum` Minimum (measure, 1 max): Value of an empty shape (0 by default).
- `maximum` Maximum (measure, 1 max): Value of a full shape (otherwise the target, else automatic).
- `comparison` Comparison (previous period) ★ / Comparaison (période précédente) ★ ★ (measure, 1 max): Drawn as a ghost level with the change in points (previous year, budget…).
- `layers` Stacked layers ★ / Couches empilées ★ ★ (measure, 8 max): Several measures stacked in the shape, one color each (their sum fills the shape).
- `shapeSvg` SVG shape (measure) ★ / Forme SVG (mesure) ★ ★ (measure, 1 max): Text measure returning SVG markup (or a path d): one shape per category, sanitized, never loaded from the web.
- `tooltips` Tooltips / Infobulles (measure, several max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Shape Gauge Plume: Format pane options (165)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Layout / Disposition (`layout`)
- `layout.mode` Presentation / Présentation: dropdown, default `multiples`; values: `multiples` One shape per category; `pictograms` Pictograms (n shapes = 100%) ★
- `layout.units` Number of pictograms / Nombre de pictogrammes: number, default `10`; values: 2 to 50. Visible when `layout.mode` = `pictograms`
- `layout.unitsPerRow` Pictograms per row (0 = auto) / Pictogrammes par ligne (0 = auto): number, default `0`; values: 0 to 50. Visible when `layout.mode` = `pictograms`
- `layout.columns` Columns (0 = auto) / Colonnes (0 = auto): number, default `0`; values: 0 to 30
- `layout.gap` Gap between shapes (px) / Espace entre les formes (px): number, default `16`; values: 0 to 80
- `layout.sort` Order / Ordre: dropdown, default `data`; values: `data` Data order; `desc` Percentage descending; `asc` Percentage ascending; `name` Alphabetical
- `layout.maxItems` Shapes at most / Formes au plus: number, default `60`; values: 1 to 200. 60 by default, 200 at most. Beyond, a note under the shapes says how many are shown.

### Data colors / Couleurs des données (`dataColors`, one entry per item with a selector)
- `dataColors.mode` Coloring / Coloration: dropdown, default `single`; values: `single` Single color; `category` One color per category; `thresholds` By thresholds (unfavorable, middle, favorable) ★; `gradient` Gradient along the fill ★; `scale` Color by percentage (palette) ★
- `dataColors.single` Color / Couleur: color, default (empty); values: hex color
- `dataColors.fill` Color / Couleur: color, default (empty); values: hex color
- `dataColors.color2` Gradient end (empty = accent) / Fin du dégradé (vide = accent): color, default (empty); values: hex color
- `dataColors.color3` Gradient middle (optional) / Milieu du dégradé (optionnel): color, default (empty); values: hex color
- `dataColors.t1` Threshold 1 (%) / Seuil 1 (%): number, default `50`; values: -1000 to 1000
- `dataColors.t2` Threshold 2 (%) / Seuil 2 (%): number, default `80`; values: -1000 to 1000
- `dataColors.cLow` Below threshold 1 / Sous le seuil 1: color, default `#C0392B`; values: hex color
- `dataColors.cMid` Between thresholds / Entre les seuils: color, default `#B26B00`; values: hex color
- `dataColors.cHigh` Above threshold 2 / Au-dessus du seuil 2: color, default `#2E7D4F`; values: hex color
- `dataColors.lowerBetter` Lower is better (swaps the colors) / Plus bas = mieux (inverse les couleurs): toggle, default `false`; values: true / false

### Shape / Forme (`shape`)
- `shape.source` Source: dropdown, default `library`; values: `library` Plume library (153 shapes); `svg` Pasted SVG ★. The "SVG shape (measure)" field wins when it is filled (one shape per category).
- `shape.shape` Shape / Forme: dropdown, default `drop`; values: `barrel` Containers and gauges · Barrel; `bottle` Containers and gauges · Bottle; `wineGlass` Containers and gauges · Wine glass; `glass` Containers and gauges · Glass; `mug` Containers and gauges · Mug ★; `jar` Containers and gauges · Jar ★; `bucket` Containers and gauges · Bucket ★; `battery` Containers and gauges · Battery; `batteryVertical` Containers and gauges · Vertical battery; `thermometer` Containers and gauges · Thermometer; `testTube` Containers and gauges · Test tube ★; `tank` Containers and gauges · Tank ★; `funnel` Containers and gauges · Funnel ★; `hourglass` Containers and gauges · Hourglass ★; `bag` Containers and gauges · Bag ★; `piggyBank` Containers and gauges · Piggy bank ★; `flask` Containers and gauges · Flask ★; `beaker` Containers and gauges · Beaker ★; `can` Containers and gauges · Can ★; `coffeeCup` Containers and gauges · Coffee cup ★; `vase` Containers and gauges · Vase ★; `milkCarton` Containers and gauges · Milk carton ★; `circle` Basic · Circle; `square` Basic · Square; `roundedSquare` Basic · Rounded square; `rectangle` Basic · Rectangle; `triangle` Basic · Triangle; `diamond` Basic · Diamond; `hexagon` Basic · Hexagon; `star` Basic · Star; `heart` Basic · Heart; `ellipse` Basic · Ellipse ★; `pentagon` Basic · Pentagon ★; `octagon` Basic · Octagon ★; `rightTriangle` Basic · Right triangle ★; `parallelogram` Basic · Parallelogram ★; `trapezoid` Basic · Trapezoid ★; `ring` Basic · Ring ★; `semicircle` Basic · Semicircle ★; `arch` Basic · Arch ★; `capsule` Basic · Pill ★; `star6` Basic · Six-pointed star ★; `seal` Basic · Seal ★; `cross` Basic · Cross ★; `arrow` Arrows and symbols · Arrow; `arrowUp` Arrows and symbols · Arrow up ★; `arrowDown` Arrows and symbols · Arrow down ★; `arrowLeft` Arrows and symbols · Arrow left ★; `doubleArrow` Arrows and symbols · Double arrow ★; `chevron` Arrows and symbols · Chevron ★; `check` Arrows and symbols · Check mark ★; `close` Arrows and symbols · Close (X) ★; `plus` Arrows and symbols · Plus ★; `minus` Arrows and symbols · Minus ★; `warning` Arrows and symbols · Warning ★; `info` Arrows and symbols · Information ★; `playButton` Arrows and symbols · Play button ★; `bubble` Arrows and symbols · Speech bubble; `thought` Arrows and symbols · Thought bubble ★; `flag` Arrows and symbols · Flag ★; `bookmark` Arrows and symbols · Bookmark ★; `tag` Arrows and symbols · Tag ★; `bolt` Arrows and symbols · Lightning bolt ★; `shield` Arrows and symbols · Shield ★; `award` Arrows and symbols · Award ★; `puzzle` Arrows and symbols · Puzzle piece ★; `gear` Arrows and symbols · Gear ★; `lock` Arrows and symbols · Lock ★; `key` Arrows and symbols · Key ★; `bell` Arrows and symbols · Bell ★; `eye` Arrows and symbols · Eye ★; `cloud` Nature and weather · Cloud; `drop` Nature and weather · Drop; `sun` Nature and weather · Sun ★; `moon` Nature and weather · Moon ★; `snowflake` Nature and weather · Snowflake ★; `leaf` Nature and weather · Leaf ★; `pine` Nature and weather · Pine tree ★; `tree` Nature and weather · Tree ★; `flower` Nature and weather · Flower ★; `mountain` Nature and weather · Mountain ★; `wave` Nature and weather · Wave ★; `flame` Nature and weather · Flame ★; `umbrella` Nature and weather · Umbrella ★; `apple` Nature and weather · Apple ★; `fish` Nature and weather · Fish ★; `paw` Nature and weather · Paw print ★; `rain` Nature and weather · Rain ★; `sprout` Nature and weather · Sprout ★; `person` People · Person; `man` People · Man ★; `woman` People · Woman ★; `child` People · Child ★; `people` People · Group of people ★; `bust` People · User bust ★; `house` Objects and buildings · House; `building` Objects and buildings · Office building ★; `factory` Objects and buildings · Factory ★; `castle` Objects and buildings · Castle ★; `shop` Objects and buildings · Shop ★; `bank` Objects and buildings · Bank ★; `hospital` Objects and buildings · Hospital ★; `book` Objects and buildings · Book ★; `envelope` Objects and buildings · Envelope ★; `phone` Objects and buildings · Phone ★; `laptop` Objects and buildings · Laptop ★; `monitor` Objects and buildings · Monitor ★; `gift` Objects and buildings · Gift ★; `clock` Objects and buildings · Clock ★; `calendar` Objects and buildings · Calendar ★; `pencil` Objects and buildings · Pencil ★; `lightbulb` Objects and buildings · Light bulb ★; `cup` Objects and buildings · Trophy ★; `crown` Objects and buildings · Crown ★; `trashCan` Objects and buildings · Trash can ★; `france` Maps and places · Metropolitan France ★; `africa` Maps and places · Africa ★; `australia` Maps and places · Australia ★; `southAmerica` Maps and places · South America ★; `pin` Maps and places · Map pin ★; `globe` Maps and places · Globe ★; `foldedMap` Maps and places · Folded map ★; `compass` Maps and places · Compass ★; `city` Maps and places · City skyline ★; `target` Business · Target ★; `barChart` Business · Bar chart ★; `pieChart` Business · Pie chart ★; `trendUp` Business · Trend up ★; `coin` Business · Coin ★; `banknote` Business · Banknote ★; `wallet` Business · Wallet ★; `creditCard` Business · Credit card ★; `cart` Business · Shopping cart ★; `briefcase` Business · Briefcase ★; `percent` Business · Percent ★; `podium` Business · Podium ★; `megaphone` Business · Megaphone ★; `gem` Business · Gem ★; `medal` Business · Medal ★; `clipboard` Business · Clipboard ★; `handshake` Business · Handshake ★; `car` Transport · Car ★; `truck` Transport · Truck ★; `bus` Transport · Bus ★; `bicycle` Transport · Bicycle ★; `plane` Transport · Plane ★; `boat` Transport · Sailboat ★; `train` Transport · Train ★; `rocket` Transport · Rocket ★; `helicopter` Transport · Helicopter ★; `ship` Transport · Cargo ship ★; `fuel` Transport · Fuel pump ★; `scooter` Transport · Scooter ★. Visible when `shape.source` = `library`. Containers (barrel, wine glass, thermometer…) only fill their inside.
- `shape.svg` SVG code / Code SVG: textarea, default (empty). Visible when `shape.source` = `svg`. <svg> markup, data URI or a bare d attribute. Sanitized (no script, no image, no web address).
- `shape.svgPaint` SVG colors / Couleurs du SVG: dropdown, default `fill`; values: `fill` Fill color; `original` Original colors (logo) ★. Original colors: the filled part keeps the logo colors, the empty part is grayed out.
- `shape.fillArea` Filled area / Zone remplie: dropdown, default `inner`; values: `inner` Inside of the container; `whole` Whole shape
- `shape.fit` Fit / Cadrage: dropdown, default `contain`; values: `contain` Keep proportions; `stretch` Stretched
- `shape.emptyColor` Empty part (empty = tint of the fill) / Partie vide (vide = teinte du remplissage): color, default (empty); values: hex color
- `shape.emptyOpacity` Empty part opacity (%) / Opacité de la partie vide (%): number, default `100`; values: 0 to 100
- `shape.emptyPattern` Empty part pattern / Motif de la partie vide: dropdown, default `none`; values: `none` None; `hatch` Hatching ★; `dots` Dots ★; `grid` Grid ★
- `shape.bodyColor` Container (empty = style gray) / Récipient (vide = gris du style): color, default (empty); values: hex color
- `shape.outline` Outline / Contour: toggle, default `true`; values: true / false
- `shape.outlineColor` Outline color (empty = fill) / Couleur du contour (vide = remplissage): color, default (empty); values: hex color. Visible when `shape.outline` = `true`
- `shape.outlineWidth` Outline width / Épaisseur du contour: number, default `1.5`; values: 0.5 to 8. Visible when `shape.outline` = `true`

### Fill / Remplissage (`fill`)
- `fill.direction` Fill direction / Sens du remplissage: dropdown, default `auto`; values: `auto` From the shape (bottom → top; battery: left → right); `up` Vertical, bottom → top; `down` Vertical, top → bottom; `right` Horizontal, left → right; `left` Horizontal, right → left; `circular` Circular (start angle) ★; `radial` Radial (from the center) ★
- `fill.startAngle` Start angle (°, 0 = 12 o'clock) / Angle de départ (°, 0 = midi): number, default `0`; values: -360 to 360. Visible when `fill.direction` = `circular`
- `fill.clockwise` Clockwise / Sens des aiguilles d'une montre: toggle, default `true`; values: true / false. Visible when `fill.direction` = `circular`
- `fill.measure` The percentage sets / Le pourcentage donne: dropdown, default `level`; values: `level` The level height; `area` The filled area (exact) ★. Exact area: 25% really fills a quarter of the shape's surface (round bottom of a drop, neck of a bottle…).
- `fill.overflow` Above 100% / Au-delà de 100 %: dropdown, default `show`; values: `show` Visible overflow; `cap` Capped at 100%
- `fill.wave` Wavy surface / Surface en vague: toggle, default `true`; values: true / false
- `fill.waveHeight` Wave height / Hauteur de la vague: number, default `3`; values: 1 to 12. Visible when `fill.wave` = `true`
- `fill.waveMotion` Moving wave ★ / Vague animée ★ ★: toggle, default `false`; values: true / false. Visible when `fill.wave` = `true`. Never when animations are reduced (Style › Animations or the system).
- `fill.waveSpeed` Wave period (s) / Durée d'une vague (s): number, default `4`; values: 1 to 20. Visible when `fill.wave` = `true`
- `fill.bubbles` Bubbles ★ / Bulles ★ ★: toggle, default `false`; values: true / false
- `fill.grow` Animated fill on opening / Remplissage animé à l'ouverture: toggle, default `true`; values: true / false. When data changes (not on resize). Turned off by Style › Animations.
- `fill.duration` Fill duration (ms) / Durée du remplissage (ms): number, default `900`; values: 100 to 5000. Visible when `fill.grow` = `true`

### Data labels / Étiquettes de données (`labels`)
- `labels.show` Show / Afficher: toggle, default `true`; values: true / false
- `labels.content` Content / Contenu: dropdown, default `percent`; values: `percent` Percentage; `value` Value; `percentValue` Percentage and value; `valuePercent` Value and percentage; `valueTarget` Value / target
- `labels.position` Position: dropdown, default `center`; values: `center` Center of the shape; `level` At the fill level; `below` Below the shape; `above` Above the shape
- `labels.autoSize` Automatic size / Taille automatique: toggle, default `true`; values: true / false
- `labels.fontSize` Text size / Taille du texte: number, default `24`; values: 6 to 120. Visible when `labels.autoSize` = `false`
- `labels.color` Color (empty = automatic) / Couleur (vide = automatique): color, default (empty); values: hex color. Automatic: style text, light over the filled part (two colors).
- `labels.bold` Bold / Gras: toggle, default `true`; values: true / false
- `labels.pctDecimals` Percentage decimals / Décimales du pourcentage: number, default `0`; values: 0 to 4
- `labels.delta` Change vs comparison (▲▼ points) / Écart à la comparaison (▲▼ points): toggle, default `true`; values: true / false
- `labels.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `labels.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `labels.prefix` Prefix / Préfixe: text, default (empty)
- `labels.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)
- `labels.catShow` Show / Afficher: toggle, default `true`; values: true / false
- `labels.catPosition` Position: dropdown, default `below`; values: `below` Below the shape; `above` Above the shape. Visible when `labels.catShow` = `true`
- `labels.catSize` Text size / Taille du texte: number, default `12`; values: 6 to 40. Visible when `labels.catShow` = `true`
- `labels.catColor` Color (empty = secondary) / Couleur (vide = secondaire): color, default (empty); values: hex color. Visible when `labels.catShow` = `true`

### Scale and target / Échelle et objectif (`scale`)
- `scale.min` Minimum (empty shape) / Minimum (forme vide): text, default (empty). The Minimum field wins.
- `scale.max` Maximum (full shape) / Maximum (forme pleine): text, default (empty). The Maximum field, then the Target field win. Automatic: 1 when values are percentages (0 to 1), else the largest value.
- `scale.ticks` Tick marks ★ / Graduations ★ ★: toggle, default `false`; values: true / false. Along vertical and horizontal directions (not circular, radial or pictograms).
- `scale.tickStep` Tick step (%) / Pas des graduations (%): number, default `25`; values: 5 to 50. Visible when `scale.ticks` = `true`
- `scale.minMax` Minimum and maximum labels / Étiquettes du minimum et du maximum: toggle, default `false`; values: true / false. Values of the empty and the full shape, at the ends of the scale (like the data labels of the native gauge). No effect with tick marks.
- `scale.targetShow` Target mark / Trait d'objectif: toggle, default `true`; values: true / false. With the Target field and a maximum (field or value), or a fixed value below.
- `scale.targetValue` Fixed target (value) / Objectif fixe (valeur): text, default (empty). Visible when `scale.targetShow` = `true`
- `scale.targetLabel` Label / Libellé: text, default (empty). Visible when `scale.targetShow` = `true`
- `scale.targetColor` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color. Visible when `scale.targetShow` = `true`
- `scale.targetStyle` Line style / Style du trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `scale.targetShow` = `true`
- `scale.compareShow` Ghost level of the comparison ★ / Niveau fantôme de la comparaison ★ ★: toggle, default `true`; values: true / false. With the Comparison field (previous period, budget…).
- `scale.compareColor` Color (empty = secondary) / Couleur (vide = secondaire): color, default (empty); values: hex color. Visible when `scale.compareShow` = `true`

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

### Playback ★ / Lecture ★ (`play`)
- `play.start` Frame shown on opening / Image affichée à l'ouverture: dropdown, default `last`; values: `last` The last one (most recent); `first` The first one
- `play.speed` Duration of a frame (ms) / Durée d'une image (ms): number, default `1000`; values: 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, default `false`; values: true / false
- `play.autoPlay` Play automatically on opening / Lecture automatique à l'ouverture: toggle, default `false`; values: 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, default `true`; values: true / false. Values, positions and colors move smoothly from one frame to the next.
- `play.controls` Play bar / Barre de lecture: toggle, default `true`; values: true / false
- `play.position` Bar position / Position de la barre: dropdown, default `bottom`; values: `bottom` Bottom; `top` Top. Visible when `play.controls` = `true`
- `play.ticks` Tick marks / Graduations: dropdown, default `auto`; values: `auto` Automatic; `all` Every frame; `none` None. Visible when `play.controls` = `true`
- `play.tickLabels` Tick labels / Étiquettes des graduations: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.stepButtons` Start and end buttons / Boutons début et fin: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.speedButton` Speed button / Bouton de vitesse: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.showLabel` Current value in large type / Valeur en cours en grand: toggle, default `true`; values: true / false
- `play.labelSize` Large value size / Taille de la valeur en grand: number, default `36`; values: 12 to 160. Visible when `play.showLabel` = `true`
- `play.labelPosition` Large value position / Position de la valeur en grand: dropdown, default `topRight`; values: `bottomRight` Bottom right; `topRight` Top right; `topLeft` Top left; `bottomLeft` Bottom left; `center` Center. Visible when `play.showLabel` = `true`

### Interactions (`interaction`)
- `interaction.hover` Highlight on hover / Mettre en avant au survol: toggle, default `true`; values: true / false
- `interaction.dim` Dimmed items opacity (%) / Opacité des éléments estompés (%): number, default `25`; values: 5 to 80

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Word Cloud Plume

- A readable word cloud that is always the same: topics, customer reviews or open answers, in the shape and font of your choice.
- Slug `word-cloud` · version 1.1.0.0 · GUID (`visualType`) `plumeWordCloudEF71B057859746CE8A28DD8261953560` · page https://plumevisuals.com/en/visuals/word-cloud

### What the visual does

Word Cloud Plume (identifier `word-cloud`) is a Power BI custom visual (version 1.1.0.0, installed from its `.pbiviz` file; not yet on AppSource) that draws **word clouds**. Power BI Desktop has no native word cloud; Microsoft's free Word Cloud visual has English stop words only, no shapes and no font choice.

**New in version 1.1.0.0 (30/10/2026):** Format pane reorganized (`compare` → `comparison`); free "Keep special characters (#, @, emojis)" and a maximum-size weight to keep sizes under filters (`wordFont.weightMax`).

- **Words or long texts**: one column (`words` role). Short labels are kept whole; long texts (comments, survey answers) are **split into words automatically** (`words.split` = `auto`: when at least 20% of the values have 4 words or more, or 3 words on average), or always (`on`) / never (`off`).
- **Text cleaning built in**: French and English stop words (`words.stopWords` = `auto` | `fr` | `en` | `none`), French elisions removed (l', d', qu'… → `words.elision`), numbers ignored, minimum length (3 letters), case and accents merged (the most frequent form is shown; with split text a lowercase form wins over a sentence-initial capital), optional plural merging ★ (`words.mergePlurals`), excluded words from the pane (`words.customStop`) or from a text measure (`exclude` role, e.g. `CONCATENATEX`).
- **Size** = the `weight` measure, otherwise the number of occurrences (`words.countMode` = `occurrences` | `rows` ★: once per row). Empty, zero or negative sizes remove the word. Top N (`words.maxWords`, 150) and minimum weight.
- **Layout**: words placed largest first along an Archimedean or rectangular spiral from the center of the shape, collision test on a bitmap of the shape (like d3-cloud, written for Plume), adjustable spacing, **deterministic** (same data → same cloud; `layout.seed` gives another arrangement). A word that does not fit is retried in the other orientation, then smaller down to the minimum size; words that still do not fit are **counted** ("n word(s) not placed" note in edit mode, with the list in its tooltip), never dropped silently. 500 words are laid out in under a second in the test harness.
- **Shapes**: an oval (default) and a rectangle that fill the visual, plus the 153 shapes of the Plume shape library (22 free: circle, square, rounded square, rectangle, triangle, diamond, hexagon, star, heart, cloud, drop, bubble, arrow, person, house, barrel, bottle, glass, wine glass, thermometer, battery, vertical battery), a custom SVG ★ pasted in the pane or returned by the `shapeSvg` measure (sanitized: no script, no image, no web link; only its geometry is used); keep proportions or stretch; optional silhouette ★.
- **Orientation**: all horizontal, horizontal and vertical (share of rotated words, reading direction), all vertical, diagonals ±45°, N even steps from one angle to another, free angles between two limits. A word always keeps the same orientation.
- **Fonts**: the style font or one of 55 fonts installed with Windows or Microsoft Office (no web font), with fallback stacks; weight (regular, semibold, bold, bold for the largest words), italic; minimum / maximum size; size scale linear, square root (default), logarithmic ★ or by rank ★; "Fill the shape" adapts the largest size.
- **Colors**: style palette (in size order or fixed per word), single color, ★ gradient by size, one color per word (categories), colors given as text by the `colorBy` field; ★ gradient by a numeric `colorBy` measure (the weighted average of the rows using the word, e.g. review sentiment; sequential or diverging around 0); ★ change versus the `compare` measure.
- ★ **Phrases**: two-word, words + two-word, or three-word phrases (`words.ngrams`); a stop word never starts or ends a phrase and phrases never cross punctuation.
- ★ **Comparison**: with a `compare` measure (same measure for an earlier period), words get ▲ (rising), ▼ (falling), ✦ (new) written small after the word, favorable / unfavorable / gray colors, "a decrease is favorable", negligible change threshold, a clickable legend and the change in % in the tooltip.
- ★ **Repeated words** (`layout.repeat`): smaller copies fill the room left in the shape (texture), decorative only.
- ★ **Play axis** (`play` role, premium since the rebalancing of 22/10/2026): one cloud per value (month, year) with the shared Plume play bar; common words keep a reference position and glide to their new place, the others fade in or out.

### Free vs premium (★)

- Every feature works without a key and nothing is ever blocked. Free features never show a watermark, and a freshly inserted visual uses only free settings.
- 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 (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium**.
- Free in Word Cloud Plume: splitting, stop words, elisions, case, exclusions, top N; the oval, the rectangle and the 22 free shapes; every orientation; every font; sizes (linear or square-root scale), spacing, spiral, layout variant, intro animation; palette, single color, per-word colors, text colors from `colorBy`; selection, tooltips, keyboard.
- Premium features of Word Cloud Plume: `words.ngrams` other than `1` (when the text is split); `dataColors.mode` = `field` with a numeric Color field (also chosen automatically when the mode is left on `palette`); the `compare` role (`dataColors.mode` = `change`); `shape.shape` other than `oval`, `rect` and the 22 free shapes; `shape.shape` = `custom` with an SVG, or the `shapeSvg` role; `layout.repeat`; since the rebalancing of 22/10/2026: the `play` role (as soon as it holds data), `dataColors.mode` = `weight`, `wordFont.sizeScale` = `log` or `rank`, `words.mergePlurals`, `words.countMode` = `rows` (when the text is split), `shape.silhouette`.
- 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 `word-cloud` 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, key accepted for 30 more days, reminders 30 and 7 days before the end). Prices: 39 € personal, 99 € SME, 299 € enterprise per year, or the catalog pack (199 € / 399 € / 1,199 € per year; tiers by number of users: personal 1–10, SME 11–200, enterprise more than 200).

### Expected data shape

Either one row per word with a measure, or one row per text.

| Words or text (`words`) | Size (`weight`) | Color (`colorBy`) | Comparison (`compare`) |
|---|---|---|---|
| delivery | 980 | | 784 |
| customer service | 790 | | 963 |
| "Fast delivery, careful packaging" | 1 | 0.82 | |

- **Words or text** (`words`, « Mots ou texte », one column, required): words, labels or long texts. Numbers and dates are written with the column format.
- **Size** (`weight`, « Taille », one measure): the size; with split text, each word receives the row value for each occurrence. Power BI groups identical texts into one row: use a count measure (`COUNTROWS`) so that identical comments count.
- **Color** (`colorBy`, « Couleur », one measure): a color as text (`#RRGGBB`, `red`) applied as is, or a number for a gradient ★.
- **Comparison ★** (`compare`, « Comparaison »), **Excluded words** (`exclude`, « Mots exclus », text measure), **Shape (SVG) ★** (`shapeSvg`, « Forme (SVG) »), **Play axis ★** (`play`, « Axe de lecture ★ », one column, premium), **Tooltips** (`tooltips`), **Dynamic format** (`format`).
- Volume of data: windows of 30,000 rows, more fetched with `fetchMoreData` up to 100,000 rows; 100,004 comments are split and drawn in a few seconds (2 to 4 s measured in the test harness).

### DAX recipes

```dax
// Size: count the reviews behind each text (identical texts are grouped by Power BI)
Number of reviews = COUNTROWS ( Reviews )
// Color ★: average sentiment (−1 to 1) of the reviews that use the word
Average sentiment = AVERAGE ( Reviews[Sentiment] )
// Comparison ★: the same measure one year earlier
Mentions last year = CALCULATE ( [Number of mentions], SAMEPERIODLASTYEAR ( 'Date'[Date] ) )
// Excluded words: from a table
Excluded word list = CONCATENATEX ( 'Excluded words', 'Excluded words'[Word], ";" )
```

### Interactions with the report

- Click a word: cross-filter on every row that contains it (up to 5,000 rows per word); Ctrl for several; click the background to clear; a click on a legend group of the comparison selects its words. Context menu everywhere (word, background, landing page).
- Hover: the hovered word stands out (`interaction.hover`); Power BI tooltip with the word, size, occurrences, comparison and change, color value, Tooltips measures; report-page tooltips are supported. No cross-highlighting from other visuals (the visual is filtered instead).
- Keyboard: Tab to the cloud, arrows from the largest word to the smallest, Enter selects, Esc clears; the cloud is labeled with its five largest words for screen readers. High contrast, French and English.

### Dynamic formats

- **fx button** (Power BI conditional formatting) on colors and texts of the Format pane (e.g. `title.text`, `shape.svg`).
- **"Dynamic format" well** (`format`): measures renamed `card.setting` (e.g. `wordFont.maxSize`, `layout.orientation`, `shape.shape`) 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`, `words`, `wordFont`, `shape`, `layout`, `comparison` (with the Comparison field), `legend` (with a gradient or the comparison), `play` (« Lecture ★ », with the Play axis field), `interaction`, then `title`, `source`, `container`, `texts`. Format pane in version 1.1.0.0 (30/10/2026), top to bottom: `license`, `style`, `layout`, `dataColors`, `words`, `wordFont`, `shape`, `legend`, `comparison`, `play`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- `dataColors`: `mode` (`palette` | `single` | `weight` ★ | `field` ★ | `change` ★), `single`, `gradient` (`sequential` | `diverging`), `byRank` (true), `fill` per word (category selector).
- `words`: `split` (`auto` | `on` | `off`), `ngrams` (`1` | `2` ★ | `12` ★ | `3` ★), `countMode` (`occurrences` | `rows` ★), `minLength` (1–20, 3), `removeNumbers` (true), `elision` (true), `mergePlurals` ★ (false), `textCase` (`auto` | `lower` | `upper` | `title`), `stopWords` (`auto` | `fr` | `en` | `none`), `customStop` (text), `maxWords` (1–1000, 150), `minWeight` (0).
- `wordFont`: `font` (`auto` or a font name such as `Segoe UI`, `Calibri`, `Georgia`, `Bahnschrift SemiCondensed`, `Segoe Print`, `Impact`), `fontWeight` (`normal` | `semibold` | `bold` | `bySize`), `italic`, `minSize` (6–80, 11), `maxSize` (8–300, 64), `sizeScale` (`linear` | `sqrt` | `log` ★ | `rank` ★).
- `shape`: `shape` (`oval` | `rect` | `custom` ★ | a library shape ID such as `heart`, `cloud`, `star`, `france` ★, `tree` ★), `svg` (text), `fit` (`contain` | `stretch`), `silhouette` ★, `silhouetteColor`, `silhouetteOpacity` (5–100, 40), `margin` (0–80, 4).
- `layout`: `orientation` (`horizontal` | `hv` | `vertical` | `diagonal` | `range` | `random`), `rotatedShare` (0–100, 25), `verticalDir` (`up` | `down`), `angleFrom` (−90–90, −60), `angleTo` (60), `steps` (2–19, 5), `spacing` (0–30 px, 2), `fit` (`auto` | `shrink` | `none`), `spiral` (`archimedean` | `rectangular`), `seed` (1–999, 1), `repeat` ★, `repeatOpacity` (10–100, 55), `repeatMax` (50–3000, 900), `intro` (`grow` | `fade` | `none`).
- `comparison`: `arrows` (true), `lowerIsBetter`, `neutral` (0–100 %, 5), `risingColor`, `fallingColor`, `newWords` (true).
- `legend`: `show`, `position` (`bottom`), `align` (`center`), `showTitle`, `titleText`, `fontSize` (9), `color`, `interactive`.
- `play`: `start` (`last` | `first`), `speed` (100–10000 ms, 1000), `loop`, `autoPlay`, `transition`, `controls`, `position`, `ticks`, `tickLabels`, `stepButtons`, `speedButton`, `showLabel`, `labelSize` (44), `labelPosition`.
- `interaction`: `hover`, `dim` (5–80, 25).

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. Booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes.

```json
{
  "visualType": "plumeWordCloudEF71B057859746CE8A28DD8261953560",
  "query": {
    "queryState": {
      "words":  { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Reviews" } }, "Property": "Comment" } }, "queryRef": "Reviews.Comment", "nativeQueryRef": "Comment" } ] },
      "weight": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Reviews" } }, "Property": "Number of reviews" } }, "queryRef": "Reviews.Number of reviews", "nativeQueryRef": "Number of reviews" } ] }
    }
  },
  "objects": {
    "shape":    [ { "properties": { "shape": { "expr": { "Literal": { "Value": "'heart'" } } }, "silhouette": { "expr": { "Literal": { "Value": "true" } } } } } ],
    "layout":   [ { "properties": { "orientation": { "expr": { "Literal": { "Value": "'horizontal'" } } }, "spacing": { "expr": { "Literal": { "Value": "1D" } } } } } ],
    "wordFont": [ { "properties": { "font": { "expr": { "Literal": { "Value": "'Georgia'" } } } } } ]
  }
}
```

The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from the `.pbiviz` file).

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`. The style gives the palette and the font ("Style font"); `minimal`, `unknownPleasures`, `terminal` and `blueprint` lay words out horizontally when the orientation is left by default.
- `style.themeJson` (Theme JSON ★): a JSON theme as plain text (format v2 with optional `extends` and groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`). Full reference: https://plumevisuals.com/ai/tutorials/en/themes-json.md.

### Common pitfalls

- Every word has the same size: no Size measure and each word appears once.
- A whole comment shows as one word: texts are short; set `words.split` = `on`.
- Identical comments count once: Power BI groups identical values; put `COUNTROWS` in Size.
- "n word(s) not placed": the shape is too small; enlarge the visual, lower `wordFont.minSize`, `layout.spacing` or `words.maxWords`, or use a wider shape / `shape.fit` = `stretch`.
- Words in an unexpected font on a Mac or in a browser: the chosen Windows or Office font is missing there; the fallback stack is used.
- Pale words with a diverging gradient: tints too light are darkened automatically; choose `sequential` for stronger colors.
- "SVG shape: …" message: the pasted SVG is unreadable or has no filled shape; the oval is used meanwhile.
- Watermark visible: phrases, a ★ shape or custom SVG, a numeric Color field, the Comparison field, repeated words, a ★ style or a theme JSON, without a valid key.
- The visual makes no network request: data, SVG and license key stay in the report.

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

Images loaded from a web address as a shape (only pasted or measure SVG), web fonts, automatic sentiment analysis or language detection (sentiment comes from a measure), lemmatization beyond simple plurals, lasso selection, cross-highlighting (the cloud is filtered instead), editing words by hand in the visual, exporting the cloud as an image.

## Word Cloud Plume: data fields

- `words` Words or text / Mots ou texte (column, 1 max): A column of words or labels, or long texts (comments, answers) that the visual splits into words
- `weight` Size / Taille (measure, 1 max): A measure that sizes the words; without it, the number of occurrences
- `colorBy` Color / Couleur (measure, 1 max): A color (#RRGGBB, red…) per word, or a number for a gradient ★
- `compare` Comparison ★ / Comparaison ★ ★ (measure, 1 max): The same measure for an earlier period: words on the rise or falling, new words ★
- `exclude` Excluded words / Mots exclus (measure, 1 max): A text measure listing words to remove, separated by ; , or new lines (e.g. CONCATENATEX)
- `shapeSvg` Shape (SVG) ★ / Forme (SVG) ★ ★ (measure, 1 max): A measure that returns an SVG: the words fill this shape (cleaned, no web link)
- `play` Play axis ★ / Axe de lecture ★ ★ (column, 1 max): A date, a year or an ordered category: one cloud per value, common words glide to their new place
- `tooltips` Tooltips / Infobulles (measure, several max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Word Cloud Plume: Format pane options (145)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Layout / Disposition (`layout`)
- `layout.orientation` Word orientation / Orientation des mots: dropdown, default `hv`; values: `horizontal` All horizontal; `hv` Horizontal and vertical; `vertical` All vertical; `diagonal` Horizontal and diagonals (±45°); `range` From one angle to another (even steps); `random` Free angles between two limits
- `layout.rotatedShare` Share of rotated words (%) / Part des mots tournés (%): number, default `25`; values: 0 to 100. Visible when `layout.orientation` = `hv` or `diagonal`
- `layout.verticalDir` Direction of vertical words / Sens des mots verticaux: dropdown, default `up`; values: `up` Bottom to top; `down` Top to bottom. Visible when `layout.orientation` = `hv` or `vertical`
- `layout.angleFrom` Start angle (°) / Angle de départ (°): number, default `-60`; values: -90 to 90. Visible when `layout.orientation` = `range` or `random`
- `layout.angleTo` End angle (°) / Angle d'arrivée (°): number, default `60`; values: -90 to 90. Visible when `layout.orientation` = `range` or `random`
- `layout.steps` Number of orientations / Nombre d'orientations: number, default `5`; values: 2 to 19. Visible when `layout.orientation` = `range`
- `layout.spacing` Spacing between words (px) / Espacement entre les mots (px): number, default `2`; values: 0 to 30
- `layout.fit` Size fitting / Ajustement des tailles: dropdown, default `auto`; values: `auto` Fill the shape (shrink or enlarge); `shrink` Shrink only when needed; `none` Fixed sizes. Fill the shape: the words grow until they fill the shape (never below the minimum size); when the shape is small for every word, the least frequent ones are left out rather than shrinking everything.
- `layout.spiral` Placement spiral / Spirale de placement: dropdown, default `archimedean`; values: `archimedean` Round (cloud); `rectangular` Rectangular (block)
- `layout.seed` Layout variant / Variante de disposition: number, default `1`; values: 1 to 999. The layout is always the same for the same data; change this number to try another arrangement.
- `layout.repeat` Fill the shape with repeated words ★ / Remplir la forme avec des répétitions ★ ★: toggle, default `false`; values: true / false. Once every word is placed, smaller copies fill the remaining space so that the shape reads clearly (texture).
- `layout.repeatOpacity` Repeated words opacity (%) / Opacité des répétitions (%): number, default `55`; values: 10 to 100
- `layout.repeatMax` Maximum number of repetitions / Nombre maximal de répétitions: number, default `900`; values: 50 to 3000
- `layout.intro` Words appear / Apparition des mots: dropdown, default `grow`; values: `grow` From the center; `fade` Fade; `none` None. When the data changes. Never when animations are reduced (Style › Animations or the system).

### Data colors / Couleurs des données (`dataColors`, one entry per item with a selector)
- `dataColors.mode` Coloring / Coloration: dropdown, default `palette`; values: `palette` Palette (one color per word); `single` Single color; `weight` Gradient by size ★; `field` Gradient by the “Color” field ★; `change` Change (“Comparison” field) ★
- `dataColors.single` Color / Couleur: color, default (empty); values: hex color
- `dataColors.fill` Color / Couleur: color, default (empty); values: hex color
- `dataColors.gradient` Gradient / Dégradé: dropdown, default `sequential`; values: `sequential` Sequential (style palette); `diverging` Diverging (around the middle)
- `dataColors.byRank` Colors in size order / Couleurs dans l'ordre des tailles: toggle, default `true`; values: true / false. Palette: the largest word takes the first color, the next one the second… Off: each word keeps its color whatever its size.

### Words / Mots (`words`)
- `words.split` Split text into words / Découper le texte en mots: dropdown, default `auto`; values: `auto` Automatic (long texts); `on` Yes; `off` No (one value = one word or phrase). Automatic: values of several words (comments, titles) are split into words; short labels are kept whole.
- `words.ngrams` Phrases / Expressions: dropdown, default `1`; values: `1` Single words; `2` Two-word phrases ★; `12` Words and two-word phrases ★; `3` Three-word phrases ★. Phrases (“customer service”, “delivery time”) are counted like words; stop words never start or end a phrase.
- `words.countMode` Count / Compter: dropdown, default `occurrences`; values: `occurrences` Every occurrence; `rows` Once per row (answer, comment) ★. Once per row: a word repeated in the same comment counts once (share of answers that use it).
- `words.minLength` Minimum length (letters) / Longueur minimale (lettres): number, default `3`; values: 1 to 20
- `words.removeNumbers` Ignore numbers / Ignorer les nombres: toggle, default `true`; values: true / false
- `words.specialChars` Keep special characters (#, @, emojis) / Garder les caractères spéciaux (#, @, émojis): toggle, default `false`; values: true / false. Hashtags (#sale), mentions (@store), amounts ($20, 20€) and emojis are kept as words.
- `words.elision` Remove French elisions (l', d', qu'…) / Retirer les élisions (l', d', qu'…): toggle, default `true`; values: true / false
- `words.mergePlurals` Merge singular and plural ★ / Regrouper singulier et pluriel ★ ★: toggle, default `false`; values: true / false. “order” and “orders” become one word (the most frequent form is shown).
- `words.textCase` Word case / Casse des mots: dropdown, default `auto`; values: `auto` Most frequent form; `lower` lowercase; `upper` UPPERCASE; `title` Capitalized. Words are always grouped regardless of case (“Delivery” and “delivery” are one word).
- `words.stopWords` Built-in stop words / Mots vides intégrés: dropdown, default `auto`; values: `auto` French and English; `fr` French; `en` English; `none` None. Common words without meaning of their own (the, and, le, de, pour…) are removed when the text is split.
- `words.customStop` Other words to exclude / Autres mots à exclure: textarea, default (empty). Case and accents ignored. The “Excluded words” field does the same with a text measure.
- `words.maxWords` Maximum number of words (top N) / Nombre maximal de mots (N premiers): number, default `150`; values: 1 to 1000
- `words.minWeight` Minimum weight (0 = all) / Poids minimal (0 = tous): number, default `0`; values: 0 to …. Words whose weight (or number of occurrences) is below this value are not shown.

### Word text / Texte des mots (`wordFont`)
- `wordFont.font` Font / Police: dropdown, default `auto`; values: `auto` Style font; `Segoe UI` Segoe UI; `Segoe UI Light` Segoe UI Light; `Segoe UI Semilight` Segoe UI Semilight; `Segoe UI Semibold` Segoe UI Semibold; `Segoe UI Black` Segoe UI Black; `Arial` Arial; `Arial Narrow` Arial Narrow · Office; `Aptos` Aptos · Office; `Bahnschrift` Bahnschrift; `Bahnschrift SemiCondensed` Bahnschrift SemiCondensed; `Bahnschrift Condensed` Bahnschrift Condensed; `Calibri` Calibri; `Calibri Light` Calibri Light; `Candara` Candara; `Century Gothic` Century Gothic · Office; `Corbel` Corbel; `Ebrima` Ebrima; `Franklin Gothic Medium` Franklin Gothic Medium; `Gadugi` Gadugi; `Gill Sans MT` Gill Sans MT · Office; `Leelawadee UI` Leelawadee UI; `Lucida Sans Unicode` Lucida Sans Unicode; `Microsoft Sans Serif` Microsoft Sans Serif; `Nirmala UI` Nirmala UI; `Tahoma` Tahoma; `Trebuchet MS` Trebuchet MS; `Tw Cen MT` Tw Cen MT · Office; `Verdana` Verdana; `Book Antiqua` Book Antiqua (serif) · Office; `Bookman Old Style` Bookman Old Style (serif) · Office; `Cambria` Cambria (serif); `Constantia` Constantia (serif); `Garamond` Garamond (serif) · Office; `Georgia` Georgia (serif); `Palatino Linotype` Palatino Linotype (serif); `Rockwell` Rockwell (serif) · Office; `Sitka Text` Sitka Text (serif); `Sitka Heading` Sitka Heading (serif); `Sylfaen` Sylfaen (serif); `Times New Roman` Times New Roman (serif); `Cascadia Code` Cascadia Code (monospace); `Cascadia Mono` Cascadia Mono (monospace); `Consolas` Consolas (monospace); `Courier New` Courier New (monospace); `Lucida Console` Lucida Console (monospace); `Comic Sans MS` Comic Sans MS (handwriting); `Gabriola` Gabriola (handwriting); `Ink Free` Ink Free (handwriting); `MV Boli` MV Boli (handwriting); `Segoe Print` Segoe Print (handwriting); `Segoe Script` Segoe Script (handwriting); `Bradley Hand ITC` Bradley Hand ITC (handwriting) · Office; `Lucida Handwriting` Lucida Handwriting (handwriting) · Office; `Arial Black` Arial Black (display); `Impact` Impact (display). Fonts installed with Windows or Microsoft Office (no web font); a similar font is used when one is missing.
- `wordFont.fontWeight` Weight / Graisse: dropdown, default `semibold`; values: `normal` Regular; `semibold` Semibold; `bold` Bold; `bySize` Bold for the largest words
- `wordFont.italic` Italic / Italique: toggle, default `false`; values: true / false
- `wordFont.minSize` Minimum size (px) / Taille minimale (px): number, default `11`; values: 6 to 80
- `wordFont.maxSize` Maximum size (px) / Taille maximale (px): number, default `64`; values: 8 to 300
- `wordFont.sizeScale` Size by weight / Taille selon le poids: dropdown, default `sqrt`; values: `linear` Linear; `sqrt` Square root (balanced); `log` Logarithmic (compressed) ★; `rank` By rank ★. Weight = the “Size” measure, or the number of occurrences without it.
- `wordFont.weightMax` Weight at the maximum size (empty = automatic) / Poids de la taille maximale (vide = automatique): text, default (empty). Keeps the sizes when another visual filters the cloud: a measure named wordFont.weightMax in “Dynamic format”, e.g. CALCULATE ( MAXX ( VALUES ( Topics[Topic] ), [Mentions] ), ALL ( Topics ) ) (ALL or REMOVEFILTERS ignores the filter; ALLSELECTED follows it), with Layout › Size fitting › Fixed sizes.

### Shape / Forme (`shape`)
- `shape.shape` Shape / Forme: dropdown, default `oval`; values: `oval` Oval (fills the visual); `rect` Rectangle (fills the visual); `custom` Custom SVG ★; `circle` Basic · Circle; `square` Basic · Square; `roundedSquare` Basic · Rounded square; `rectangle` Basic · Rectangle; `triangle` Basic · Triangle; `diamond` Basic · Diamond; `hexagon` Basic · Hexagon; `star` Basic · Star; `heart` Basic · Heart; `ellipse` Basic · Ellipse ★; `pentagon` Basic · Pentagon ★; `octagon` Basic · Octagon ★; `rightTriangle` Basic · Right triangle ★; `parallelogram` Basic · Parallelogram ★; `trapezoid` Basic · Trapezoid ★; `ring` Basic · Ring ★; `semicircle` Basic · Semicircle ★; `arch` Basic · Arch ★; `capsule` Basic · Pill ★; `star6` Basic · Six-pointed star ★; `seal` Basic · Seal ★; `cross` Basic · Cross ★; `arrow` Arrows and symbols · Arrow; `arrowUp` Arrows and symbols · Arrow up ★; `arrowDown` Arrows and symbols · Arrow down ★; `arrowLeft` Arrows and symbols · Arrow left ★; `doubleArrow` Arrows and symbols · Double arrow ★; `chevron` Arrows and symbols · Chevron ★; `check` Arrows and symbols · Check mark ★; `close` Arrows and symbols · Close (X) ★; `plus` Arrows and symbols · Plus ★; `minus` Arrows and symbols · Minus ★; `warning` Arrows and symbols · Warning ★; `info` Arrows and symbols · Information ★; `playButton` Arrows and symbols · Play button ★; `bubble` Arrows and symbols · Speech bubble; `thought` Arrows and symbols · Thought bubble ★; `flag` Arrows and symbols · Flag ★; `bookmark` Arrows and symbols · Bookmark ★; `tag` Arrows and symbols · Tag ★; `bolt` Arrows and symbols · Lightning bolt ★; `shield` Arrows and symbols · Shield ★; `award` Arrows and symbols · Award ★; `puzzle` Arrows and symbols · Puzzle piece ★; `gear` Arrows and symbols · Gear ★; `lock` Arrows and symbols · Lock ★; `key` Arrows and symbols · Key ★; `bell` Arrows and symbols · Bell ★; `eye` Arrows and symbols · Eye ★; `cloud` Nature and weather · Cloud; `drop` Nature and weather · Drop; `sun` Nature and weather · Sun ★; `moon` Nature and weather · Moon ★; `snowflake` Nature and weather · Snowflake ★; `leaf` Nature and weather · Leaf ★; `pine` Nature and weather · Pine tree ★; `tree` Nature and weather · Tree ★; `flower` Nature and weather · Flower ★; `mountain` Nature and weather · Mountain ★; `wave` Nature and weather · Wave ★; `flame` Nature and weather · Flame ★; `umbrella` Nature and weather · Umbrella ★; `apple` Nature and weather · Apple ★; `fish` Nature and weather · Fish ★; `paw` Nature and weather · Paw print ★; `rain` Nature and weather · Rain ★; `sprout` Nature and weather · Sprout ★; `person` People · Person; `man` People · Man ★; `woman` People · Woman ★; `child` People · Child ★; `people` People · Group of people ★; `bust` People · User bust ★; `house` Objects and buildings · House; `building` Objects and buildings · Office building ★; `factory` Objects and buildings · Factory ★; `castle` Objects and buildings · Castle ★; `shop` Objects and buildings · Shop ★; `bank` Objects and buildings · Bank ★; `hospital` Objects and buildings · Hospital ★; `book` Objects and buildings · Book ★; `envelope` Objects and buildings · Envelope ★; `phone` Objects and buildings · Phone ★; `laptop` Objects and buildings · Laptop ★; `monitor` Objects and buildings · Monitor ★; `gift` Objects and buildings · Gift ★; `clock` Objects and buildings · Clock ★; `calendar` Objects and buildings · Calendar ★; `pencil` Objects and buildings · Pencil ★; `lightbulb` Objects and buildings · Light bulb ★; `cup` Objects and buildings · Trophy ★; `crown` Objects and buildings · Crown ★; `trashCan` Objects and buildings · Trash can ★; `barrel` Containers and gauges · Barrel; `bottle` Containers and gauges · Bottle; `wineGlass` Containers and gauges · Wine glass; `glass` Containers and gauges · Glass; `mug` Containers and gauges · Mug ★; `jar` Containers and gauges · Jar ★; `bucket` Containers and gauges · Bucket ★; `battery` Containers and gauges · Battery; `batteryVertical` Containers and gauges · Vertical battery; `thermometer` Containers and gauges · Thermometer; `testTube` Containers and gauges · Test tube ★; `tank` Containers and gauges · Tank ★; `funnel` Containers and gauges · Funnel ★; `hourglass` Containers and gauges · Hourglass ★; `bag` Containers and gauges · Bag ★; `piggyBank` Containers and gauges · Piggy bank ★; `flask` Containers and gauges · Flask ★; `beaker` Containers and gauges · Beaker ★; `can` Containers and gauges · Can ★; `coffeeCup` Containers and gauges · Coffee cup ★; `vase` Containers and gauges · Vase ★; `milkCarton` Containers and gauges · Milk carton ★; `france` Maps and places · Metropolitan France ★; `africa` Maps and places · Africa ★; `australia` Maps and places · Australia ★; `southAmerica` Maps and places · South America ★; `pin` Maps and places · Map pin ★; `globe` Maps and places · Globe ★; `foldedMap` Maps and places · Folded map ★; `compass` Maps and places · Compass ★; `city` Maps and places · City skyline ★; `target` Business · Target ★; `barChart` Business · Bar chart ★; `pieChart` Business · Pie chart ★; `trendUp` Business · Trend up ★; `coin` Business · Coin ★; `banknote` Business · Banknote ★; `wallet` Business · Wallet ★; `creditCard` Business · Credit card ★; `cart` Business · Shopping cart ★; `briefcase` Business · Briefcase ★; `percent` Business · Percent ★; `podium` Business · Podium ★; `megaphone` Business · Megaphone ★; `gem` Business · Gem ★; `medal` Business · Medal ★; `clipboard` Business · Clipboard ★; `handshake` Business · Handshake ★; `car` Transport · Car ★; `truck` Transport · Truck ★; `bus` Transport · Bus ★; `bicycle` Transport · Bicycle ★; `plane` Transport · Plane ★; `boat` Transport · Sailboat ★; `train` Transport · Train ★; `rocket` Transport · Rocket ★; `helicopter` Transport · Helicopter ★; `ship` Transport · Cargo ship ★; `fuel` Transport · Fuel pump ★; `scooter` Transport · Scooter ★. The words fill this shape. ★ shapes and the custom SVG show the premium watermark without a license.
- `shape.svg` Shape SVG / SVG de la forme: textarea, default (empty). Visible when `shape.shape` = `custom`. Paste an SVG (or a path “d”); it is cleaned (no script, no web link). The “Shape (SVG)” field does the same with a measure.
- `shape.fit` Proportions: dropdown, default `contain`; values: `contain` Keep proportions; `stretch` Stretch to fill the visual. Visible when `shape.shape` = `custom` or `circle` or `square` or `roundedSquare` or `rectangle` or `triangle` or `diamond` or `hexagon` or `star` or `heart` or `ellipse` or `pentagon` or `octagon` or `rightTriangle` or `parallelogram` or `trapezoid` or `ring` or `semicircle` or `arch` or `capsule` or `star6` or `seal` or `cross` or `arrow` or `arrowUp` or `arrowDown` or `arrowLeft` or `doubleArrow` or `chevron` or `check` or `close` or `plus` or `minus` or `warning` or `info` or `playButton` or `bubble` or `thought` or `flag` or `bookmark` or `tag` or `bolt` or `shield` or `award` or `puzzle` or `gear` or `lock` or `key` or `bell` or `eye` or `cloud` or `drop` or `sun` or `moon` or `snowflake` or `leaf` or `pine` or `tree` or `flower` or `mountain` or `wave` or `flame` or `umbrella` or `apple` or `fish` or `paw` or `rain` or `sprout` or `person` or `man` or `woman` or `child` or `people` or `bust` or `house` or `building` or `factory` or `castle` or `shop` or `bank` or `hospital` or `book` or `envelope` or `phone` or `laptop` or `monitor` or `gift` or `clock` or `calendar` or `pencil` or `lightbulb` or `cup` or `crown` or `trashCan` or `barrel` or `bottle` or `wineGlass` or `glass` or `mug` or `jar` or `bucket` or `battery` or `batteryVertical` or `thermometer` or `testTube` or `tank` or `funnel` or `hourglass` or `bag` or `piggyBank` or `flask` or `beaker` or `can` or `coffeeCup` or `vase` or `milkCarton` or `france` or `africa` or `australia` or `southAmerica` or `pin` or `globe` or `foldedMap` or `compass` or `city` or `target` or `barChart` or `pieChart` or `trendUp` or `coin` or `banknote` or `wallet` or `creditCard` or `cart` or `briefcase` or `percent` or `podium` or `megaphone` or `gem` or `medal` or `clipboard` or `handshake` or `car` or `truck` or `bus` or `bicycle` or `plane` or `boat` or `train` or `rocket` or `helicopter` or `ship` or `fuel` or `scooter`. Keep proportions: a heart stays a heart (it fills the height of a wide visual). Stretch: the shape covers the whole visual.
- `shape.silhouette` Silhouette in the background ★ / Silhouette en fond ★ ★: toggle, default `false`; values: true / false
- `shape.silhouetteColor` Silhouette color (empty = grid) / Couleur de la silhouette (vide = grille): color, default (empty); values: hex color. Visible when `shape.silhouette` = `true`
- `shape.silhouetteOpacity` Silhouette opacity (%) / Opacité de la silhouette (%): number, default `40`; values: 5 to 100. Visible when `shape.silhouette` = `true`
- `shape.margin` Margin around the shape (px) / Marge autour de la forme (px): number, default `4`; values: 0 to 80

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

### Comparison ★ / Comparaison ★ (`comparison`)
- `comparison.arrows` ▲▼ arrows in the cloud / Flèches ▲▼ dans le nuage: toggle, default `true`; values: true / false. The direction is also written in the tooltip: the meaning never relies on color alone.
- `comparison.lowerIsBetter` A decrease is favorable / Une baisse est favorable: toggle, default `false`; values: true / false
- `comparison.neutral` Negligible change (± %) / Variation négligeable (± %): number, default `5`; values: 0 to 100
- `comparison.risingColor` Favorable color (empty = style) / Couleur favorable (vide = style): color, default (empty); values: hex color
- `comparison.fallingColor` Unfavorable color (empty = style) / Couleur défavorable (vide = style): color, default (empty); values: hex color
- `comparison.newWords` Mark new words (✦) / Marquer les nouveaux mots (✦): toggle, default `true`; values: true / false

### Playback ★ / Lecture ★ (`play`)
- `play.start` Frame shown on opening / Image affichée à l'ouverture: dropdown, default `last`; values: `last` The last one (most recent); `first` The first one
- `play.speed` Duration of a frame (ms) / Durée d'une image (ms): number, default `1000`; values: 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, default `false`; values: true / false
- `play.autoPlay` Play automatically on opening / Lecture automatique à l'ouverture: toggle, default `false`; values: 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, default `true`; values: true / false. Values, positions and colors move smoothly from one frame to the next.
- `play.controls` Play bar / Barre de lecture: toggle, default `true`; values: true / false
- `play.position` Bar position / Position de la barre: dropdown, default `bottom`; values: `bottom` Bottom; `top` Top. Visible when `play.controls` = `true`
- `play.ticks` Tick marks / Graduations: dropdown, default `auto`; values: `auto` Automatic; `all` Every frame; `none` None. Visible when `play.controls` = `true`
- `play.tickLabels` Tick labels / Étiquettes des graduations: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.stepButtons` Start and end buttons / Boutons début et fin: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.speedButton` Speed button / Bouton de vitesse: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.showLabel` Current value in large type / Valeur en cours en grand: toggle, default `true`; values: true / false
- `play.labelSize` Large value size / Taille de la valeur en grand: number, default `44`; values: 12 to 160. Visible when `play.showLabel` = `true`
- `play.labelPosition` Large value position / Position de la valeur en grand: dropdown, default `bottomRight`; values: `bottomRight` Bottom right; `topRight` Top right; `topLeft` Top left; `bottomLeft` Bottom left; `center` Center. Visible when `play.showLabel` = `true`

### Interactions (`interaction`)
- `interaction.hover` Highlight on hover / Mettre en avant au survol: toggle, default `true`; values: true / false
- `interaction.dim` Dimmed items opacity (%) / Opacité des éléments estompés (%): number, default `25`; values: 5 to 80

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Pie Plume

- The donut Power BI is missing: a figure in the center, labels that stay readable, Others, half donut, rose and slice breakdown.
- Slug `pie-chart` · version 1.1.0.0 · GUID (`visualType`) `plumePieChartA98296CC7934459199F53486CD90BFCD` · page https://plumevisuals.com/en/visuals/pie-chart

### What the visual does

Pie Plume (identifier `pie-chart`) is a Power BI custom visual (version 1.1.0.0, installed from its `.pbiviz` file; not yet on AppSource) that draws **pie charts, donut charts and Nightingale roses** with the Plume Studio look. It covers the native pie and donut charts (Legend with drill-down, Values, Details, tooltips, detail labels, rotation, inner radius, colors per category, cross-filtering, highlighting, small multiples) and fixes their known gaps.

**New in version 1.1.0.0 (30/10/2026):** Format pane reorganized (`shape.*` split into **Layout** and **Parts**); free **label background** (color, transparency).

- **Text in the center of the donut** (free): the total of the slices, the "Center value" measure, free text with `{total}`, `{count}`, `{measure}`, the number of slices; caption under the value; ★ with `center.hover` (off by default), the hovered or selected slice (name, value, share) replaces it while hovering.
- **Labels that never overlap** (free): outside labels are arranged in two columns (left and right) with leader lines, spread vertically; when room is short, the smallest slices lose their label first, never the large ones. Long names wrap on two lines; "< 1 %" instead of "0 %". Labels can also be inside, automatic (inside when the whole text fits) or around the slices.
- **Sort** by value, name, data order (Sort by column), ★ a custom list; **Top N or threshold + "Others"** ★.
- **Details field**: every slice is cut into sub-parts in shades of its color (free), or ★ one color per sub-category (the same in every slice), a gradient, or concentric layers whose area follows the share.
- **Slice breakdown** ★: the sub-categories of a slice (or the members of "Others") as an outer ring, a pie of pie or a bar of pie, linked to the slice, on click or always shown (largest, "Others", a named slice, all for the ring).
- **Previous period** ★: a thin ring with the former shares, the change of the total (▲ / ▼, %) in the center, change per slice in share points or % in the tooltip.
- **Shapes**: donut (hole 5–92 %), full pie, ★ Nightingale rose (area or radius proportional, equal angles or by value, or angle by Values and radius by the "Radius" measure), rotation, clockwise or not, ★ opening under 360° (half donut, arcs), gaps of constant width, rounded corners, outline; the selected slice pops out (free), ★ the largest or named slices, ★ patterns.
- **Small multiples** (shared legend, panel titles with totals, scrolling grid; ★ pies sized by their total) and a **play axis** ★ (shared Plume player: slices glide from one value to the next, the center total counts).
- Values: only positive values are drawn; negative, zero or empty ones are counted and reported in edit mode. Above 240 slices, the smallest are gathered into "Others" with no watermark (readability limit).

### 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 (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium**. The `blackWhite` style brings its own free patterns.
- Free in Pie Plume: donut, full pie, rotation, direction, gaps, corners, outline, selected slice popping out; total, measure, text or count in the center, caption, sizes and colors; every label option; sort (value, name, data order); Details split in shades; small multiples with the same size; palette (one color per slice); legend; drill-down, tooltips, selection, highlighting, keyboard, high contrast.
- Premium features of Pie Plume (the watermark only shows when the feature really applies):
  - `layout.kind` = `rose` (and the `radius` role); `layout.arc` below 360; `parts.explode` = `largest` or `name`; `parts.patterns`;
  - `sort.others` = `topN` or `threshold` when at least two slices are grouped;
  - with a Details field: `split.colors` = `category` or `gradient`, `split.layout` = `radial`;
  - `breakdown.mode` = `ring`, `pieOfPie` or `barOfPie` (with Details or "Others");
  - the `previous` role while `comparison.show` is on;
  - `smallMultiples.sizeBy` = `total` with small multiples;
  - `dataColors.mode` = `gradient`, `highlight` or `mono` (shades of one color);
  - since the free / ★ rebalance of 22/10/2026: the play axis (`play` role) as soon as it contains data; `sort.by` = `custom` with a non-empty `sort.customOrder`; `center.hover` on (donut with the center shown).
- 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 `pie-chart` 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, key accepted for 30 more days, reminders 30 and 7 days before the end). Prices: 39 € personal, 99 € SME, 299 € enterprise per year, or the catalog pack (199 € / 399 € / 1,199 € per year; tiers by number of users: personal 1–10, SME 11–200, enterprise more than 200).

### Expected data shape

One row per sale (or per category); the visual adds up the measure per slice.

| Legend (`category`) | Details (`detail`) | Values (`values`) |
|---|---|---|
| North West | Lighting | 41,200 |
| North West | Furniture | 38,600 |
| East Midlands | Home linen | 12,400 |

- **Legend (categories)** (`category`, « Légende (catégories) », 1 to 6 columns): one slice per value; several fields make a hierarchy (Power BI drill-down; "Expand all" joins the levels in the label). Without a Legend, up to 12 measures in Values become one slice each (selection by measure).
- **Details (sub-category)** (`detail`, « Détails (sous-catégorie) », 1 column): splits every slice, or feeds the breakdown ★.
- **Values** (`values`, « Valeurs »): 1 measure with a Legend, up to 12 without.
- **Radius (rose) ★** (`radius`, « Rayon (rose) ★ »): with `layout.kind` = `rose`, the angle follows Values and the radius this measure ("Others" uses the value-weighted average).
- **Center value** (`center`, « Valeur au centre »): written in the center with `center.value` = `measure`; write it with `CALCULATE ( …, ALLSELECTED () )`; if values differ per slice, they are added up.
- **Previous period ★** (`previous`, « Période précédente ★ »): same measure for the period before.
- **Small multiples** (`multiples`), **Play axis ★** (`play`, « Axe de lecture ★ »), **Tooltips** (`tooltips`, up to 5 measures), **Dynamic format** (`format`, see below).
- Volume: 30,000-row windows then `fetchMoreData` up to 100,000 rows; 100,004 rows render in well under a second in the test bench.

### DAX recipes

```dax
Total revenue = SUM ( Sales[Revenue] )
// Same value for every slice (center)
Customers (all) = CALCULATE ( DISTINCTCOUNT ( Sales[Customer] ), ALLSELECTED () )
// Current and previous year (Values and Previous period ★)
Revenue 2025 = CALCULATE ( [Total revenue], Sales[Year] = 2025 )
Revenue 2024 = CALCULATE ( [Total revenue], Sales[Year] = 2024 )
// Rose radius ★
Margin rate = DIVIDE ( SUM ( Sales[Margin] ), SUM ( Sales[Revenue] ) )
```

### Interactions with the report

- Click a slice: cross-filter on its category (Details sub-part: category + sub-category; "Others": every grouped category; measures mode: the measure); Ctrl for several; click an empty area to clear. The selected slice pops out (`parts.explode` = `selected`) and, with `center.hover` ★, shows in the center. Cross-highlighting from other visuals fills each slice in proportion (rest dimmed); "Highlighted value" in the tooltip.
- Hover: Power BI tooltip (category, value, share of total, previous value and change, Tooltips measures); report-page tooltips are supported. Context menu everywhere, including the empty area and the landing page.
- Breakdown "on click": selecting one slice opens its detail; clearing the selection closes it. Nothing is saved with `persistProperties` (play frame, hover and breakdown are per session).
- Keyboard: Tab to the chart, ← → slice by slice, Enter selects, Esc clears; with a play axis, Space plays / pauses and Page Up / Page Down step. High contrast (host colors, a pattern per slice), ARIA labels, French and English. "Reduce motion" is respected.

### Dynamic formats

- **fx button** (Power BI conditional formatting) on colors and texts of the Format pane, and per category on the slice colors.
- **"Dynamic format" well** (`format`): measures renamed `card.setting` (e.g. `title.text`, `title.color`, `center.text`, `layout.kind`) drive any setting and win over the fixed value. Driving a ★ setting by DAX still shows the watermark without a key.

```dax
// renamed title.text
Dynamic title = "Revenue 2025: " & FORMAT ( CALCULATE ( [Total revenue], ALLSELECTED (), Sales[Year] = 2025 ), "$#,0" )
// renamed title.color
Title color = IF ( [Revenue 2025] >= [Revenue 2024], "#2E7D4F", "#C0392B" )
```

### Format pane: option IDs

- Card order: `license`, `style`, `dataColors`, `shape`, `center`, `labels`, `sort`, `split`, `breakdown`, `comparison`, `legend`, `smallMultiples`, `play`, `interaction`, then `title`, `source`, `container`, `texts`. Format pane in version 1.1.0.0 (30/10/2026), top to bottom: `license`, `style`, `dataColors`, `layout`, `parts`, `center`, `labels`, `sort`, `split`, `breakdown`, `comparison`, `legend`, `smallMultiples`, `play`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- `dataColors`: `mode` (`category` | `mono` ★ | `gradient` ★ | `highlight` ★), `single`, `fill`, `highlightWhat` (`max` | `min` | `name`), `highlightName`, `highlightColor`, `othersColor`.
- `parts`: `layout.kind` (`donut` | `pie` | `rose` ★), `layout.innerRadius` (5–92, 58), `layout.roseScale` (`area` | `radius`), `layout.roseAngles` (`equal` | `value`), `layout.roseGrid`, `layout.startAngle` (-360–360, 0), `layout.arc` (60–360, 360), `layout.clockwise`, `padAngle` (0–10, 0.8), `cornerRadius` (0–30, 2), `stroke`, `strokeWidth` (0.5–6, 1), `strokeColor`, `patterns` ★, `explode` (`none` | `selected` | `largest` ★ | `name` ★), `explodeName`, `explodeOffset` (0–40, 8).
- `center`: `show`, `value` (`total` | `measure` | `text` | `count` | `none`), `text`, `label`, `hover` ★ (off), `fontSize` (0–96, 0), `color`, `labelSize` (6–30, 11), `labelColor`, `showChange`.
- `labels`: `show`, `content` (`catPct` | `cat` | `value` | `pct` | `catValue` | `valuePct` | `all`), `position` (`outside` | `auto` | `inside`), `leader`, `layout` (`columns` | `around`), `minPct` (0–20, 0), `pctDecimals` (0–3, 0), `wrap`, `fontSize` (6–24, 10), `color`, `bold`, `halo`, `declutter`, `units` (`auto` | `none` | `k` | `m` | `b`), `decimals` (-1–6, -1), `prefix`, `suffix`.
- `sort`: `by` (`valueDesc` | `valueAsc` | `labelAsc` | `labelDesc` | `data` | `custom` ★), `customOrder`, `others` (`none` | `topN` ★ | `threshold` ★), `n` (1–50, 6), `threshold` (0.1–30, 3), `othersLabel`.
- `split`: `colors` (`tints` | `category` ★ | `gradient` ★), `layout` (`angular` | `radial` ★), `separators`, `legend` (`auto` | `categories` | `details`).
- `breakdown`: `mode` (`none` | `ring` ★ | `pieOfPie` ★ | `barOfPie` ★), `trigger` (`click` | `always`), `target` (`largest` | `others` | `name` | `all`), `targetName`, `size` (20–80, 42), `links`.
- `comparison`: `show`, `position` (`outside` | `inside`), `width` (2–20, 5), `change` (`points` | `percent`).
- `legend`: `show`, `position` (`top` | `bottom` | `right` | `left`), `align` (`left` | `center` | `right`), `showTitle`, `titleText`, `fontSize` (6–24, 9), `color`, `interactive`.
- `smallMultiples`: `columns` (0–12, 0), `minHeight` (50–600, 110), `gap` (0–60, 14), `sizeBy` (`same` | `total` ★), `border`, `titleShow`, `titleSize` (6–24, 10), `titleColor`, `titleTotal`.
- `play`: the shared player card (★: the play axis itself is premium) (`start`, `speed`, `loop`, `autoPlay`, `transition`, `controls`, `position`, `ticks`, `tickLabels`, `stepButtons`, `speedButton`, `showLabel`, `labelSize`, `labelPosition`). `interaction`: `hover`, `dim` (5–80, 25).

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. Booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes.

```json
{
  "visualType": "plumePieChartA98296CC7934459199F53486CD90BFCD",
  "query": {
    "queryState": {
      "category": { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Region" } }, "queryRef": "Sales.Region", "nativeQueryRef": "Region" } ] },
      "values":   { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Total revenue" } }, "queryRef": "Sales.Total revenue", "nativeQueryRef": "Total revenue" } ] }
    }
  },
  "objects": {
    "center": [ { "properties": { "label": { "expr": { "Literal": { "Value": "'2025 revenue'" } } } } } ],
    "sort":   [ { "properties": { "others": { "expr": { "Literal": { "Value": "'topN'" } } }, "n": { "expr": { "Literal": { "Value": "5D" } } } } } ]
  }
}
```

The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from the `.pbiviz` file).

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`. Slice colors follow the categorical palette of the style; colors set per category in Data colors win over the style.
- `style.themeJson` (Theme JSON ★): a JSON theme as plain text (format v2 with optional `extends` and groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`). Full reference: https://plumevisuals.com/ai/tutorials/en/themes-json.md.

### Common pitfalls

- "No positive value to draw": every value is empty, zero or negative.
- "n negative or zero value(s) not drawn" (edit mode): those categories have no place in a circle; use Waterfall Plume for balances.
- A small slice has no label: the label column is full; enlarge the visual, reduce the text size or group small slices into "Others" ★.
- The center is empty: `layout.kind` = `pie` (no hole), `center.show` off, or the comparison ring placed in the hole.
- The center measure looks too big: it is evaluated per slice and added up; write it with `ALLSELECTED`.
- The legend does not show: hidden by default (`legend.show`); it shows by itself with small multiples and with `split.colors` = `category`.
- Watermark visible: rose, opening below 360°, patterns, exploded largest / named slice, "Others" grouping two slices or more, sub-category colors / gradient / layers, breakdown, previous period ring, sized small multiples, shades / gradient / highlight colors, custom order, hovered slice in the center, play axis with data, a ★ style or a theme JSON, without a valid key.
- The visual makes no network request: data and license key stay in the report; no R or Python.

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

3D pies, images inside slices, drill-down inside the visual (use Power BI's drill-down on the Legend hierarchy), a summary table, exporting the chart as an image, saving the play frame or the opened breakdown with the report, negative slices.

## Pie Plume: data fields

- `category` Legend (categories) / Légende (catégories) (column, 6 max): One slice per value. Several fields make a hierarchy you can drill into.
- `detail` Details (sub-category) / Détails (sous-catégorie) (column, 1 max): Splits every slice into sub-parts (shades, colors or a gradient), or feeds the breakdown of a slice (outer ring, pie of pie, bar of pie).
- `values` Values / Valeurs (measure, 12 max): Size of the slices. Without a Legend, several measures give one slice each.
- `radius` Radius (rose) ★ / Rayon (rose) ★ ★ (measure, 1 max): Nightingale rose: the angle follows Values and the radius follows this measure.
- `center` Center value / Valeur au centre (measure, 1 max): Measure written in the center of the donut (Format › Center › Value: Center value field).
- `previous` Previous period ★ / Période précédente ★ ★ (measure, 1 max): Same measure for the previous period: a thin ring shows the former shares, the center shows the change.
- `multiples` Small multiples / Petits multiples (column, 1 max): 
- `play` Play axis ★ / Axe de lecture ★ ★ (column, 1 max): A date, a year or an ordered category: the visual moves from one value to the next (play button)
- `tooltips` Tooltips / Infobulles (measure, 5 max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Pie Plume: Format pane options (176)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Layout / Disposition (`layout`)
- `layout.kind` Shape / Forme: dropdown, default `donut`; values: `donut` Donut (ring); `pie` Full pie; `rose` Nightingale rose ★. Rose: every slice gets the same angle (or the angle of its value) and its radius shows the value. With a “Radius” field, the angle follows Values and the radius follows Radius.
- `layout.innerRadius` Inner radius (% of radius) / Rayon intérieur (% du rayon): number, default `58`; values: 5 to 92. Visible when `layout.kind` = `donut` or `rose`. Size of the hole of the donut (the « Spacing › Inner radius » of the native donut chart).
- `layout.roseScale` Rose radius / Rayon de la rose: dropdown, default `area`; values: `area` Area proportional (Nightingale); `radius` Radius proportional. Visible when `layout.kind` = `rose`. Area proportional: a value twice as large covers twice the surface (the honest choice).
- `layout.roseAngles` Rose slice angles / Angle des parts de la rose: dropdown, default `equal`; values: `equal` Equal (one slice per category); `value` By value. Visible when `layout.kind` = `rose`
- `layout.roseGrid` Rose guide circles / Cercles de repère de la rose: toggle, default `true`; values: true / false. Visible when `layout.kind` = `rose`
- `layout.startAngle` Rotation (start angle, °) / Rotation (angle de départ, °): number, default `0`; values: -360 to 360. 0 = the first slice starts at 12 o'clock; 90 = at 3 o'clock.
- `layout.arc` Opening (°, 180 = half circle) / Ouverture (°, 180 = demi-cercle): number, default `360`; values: 60 to 360. Less than 360°: half donut, gauge-like arc (premium). With 180° and a rotation of -90°, the half circle stands on its base.
- `layout.clockwise` Clockwise / Sens des aiguilles d'une montre: toggle, default `true`; values: true / false

### Data colors / Couleurs des données (`dataColors`, one entry per item with a selector)
- `dataColors.mode` Coloring / Coloration: dropdown, default `category`; values: `category` Palette (one color per slice); `mono` Shades of a single color ★; `gradient` Gradient by value ★; `highlight` Highlight one slice ★
- `dataColors.single` Color / Couleur: color, default (empty); values: hex color
- `dataColors.fill` Color / Couleur: color, default (empty); values: hex color
- `dataColors.highlightWhat` Highlighted slice / Part mise en avant: dropdown, default `max`; values: `max` The largest; `min` The smallest; `name` By its name
- `dataColors.highlightName` Slice name / Nom de la part: text, default (empty)
- `dataColors.highlightColor` Highlighted slice color (empty = accent) / Couleur de la part mise en avant (vide = accent): color, default (empty); values: hex color
- `dataColors.othersColor` Other slices color (empty = gray) / Couleur des autres parts (vide = gris): color, default (empty); values: hex color

### Slices / Parts (`parts`)
- `parts.padAngle` Gap between slices (°) / Espace entre les parts (°): number, default `0.8`; values: 0 to 10
- `parts.cornerRadius` Corner radius (px) / Arrondi des angles (px): number, default `2`; values: 0 to 30
- `parts.stroke` Outline / Contour: toggle, default `true`; values: true / false
- `parts.strokeWidth` Outline width / Épaisseur du contour: number, default `1`; values: 0.5 to 6. Visible when `parts.stroke` = `true`
- `parts.strokeColor` Outline color (empty = background) / Couleur du contour (vide = fond): color, default (empty); values: hex color. Visible when `parts.stroke` = `true`
- `parts.patterns` Patterns (hatching, dots) ★ / Motifs (hachures, points) ★ ★: toggle, default `false`; values: true / false. A different pattern on each slice: readable in black and white prints and without colors.
- `parts.explode` Explode / Détacher: dropdown, default `selected`; values: `none` No slice; `selected` The selected slice; `largest` The largest slice ★; `name` A slice chosen by name ★
- `parts.explodeName` Slice name (separated by ;) / Nom de la part (séparés par ;): text, default (empty). Visible when `parts.explode` = `name`
- `parts.explodeOffset` Distance (px): number, default `8`; values: 0 to 40. Visible when `parts.explode` = `selected` or `largest` or `name`

### Donut center / Centre de l'anneau (`center`)
- `center.show` Show / Afficher: toggle, default `true`; values: true / false. Text in the hole of the donut (and of the rose when it has a hole).
- `center.value` Value / Valeur: dropdown, default `total`; values: `total` Total of the slices; `measure` “Center value” field; `text` Free text; `count` Number of slices; `none` None (caption only). Center value field: write the measure with CALCULATE ( [Measure], ALLSELECTED () ) so it is the same for every slice.
- `center.text` Free text / Texte libre: text, default (empty). Visible when `center.value` = `text`. Placeholders: {total}, {count}, {measure}. Also driven by DAX with the fx button.
- `center.label` Caption under the value / Légende sous la valeur: text, default (empty)
- `center.hover` Show the hovered or selected slice ★ / Afficher la part survolée ou sélectionnée ★ ★: toggle, default `false`; values: true / false. Hovering or selecting a slice writes its name, value and share in the center.
- `center.fontSize` Value size (0 = automatic) / Taille de la valeur (0 = automatique): number, default `0`; values: 0 to 96
- `center.color` Value color (empty = text) / Couleur de la valeur (vide = texte): color, default (empty); values: hex color
- `center.labelSize` Caption size / Taille de la légende: number, default `11`; values: 6 to 30
- `center.labelColor` Caption color (empty = secondary) / Couleur de la légende (vide = secondaire): color, default (empty); values: hex color
- `center.showChange` Change from the previous period / Évolution par rapport à la période précédente: toggle, default `true`; values: true / false. With a “Previous period” field: ▲ / ▼ and the change of the total under the value.

### Data labels / Étiquettes de données (`labels`)
- `labels.show` Show / Afficher: toggle, default `true`; values: true / false
- `labels.content` Content / Contenu: dropdown, default `catPct`; values: `catPct` Category and %; `cat` Category; `value` Value; `pct` % of total; `catValue` Category and value; `valuePct` Value and %; `all` Category, value and %
- `labels.position` Position: dropdown, default `outside`; values: `outside` Outside; `auto` Automatic (inside when all fits); `inside` Inside
- `labels.leader` Leader lines / Traits de rappel: toggle, default `true`; values: true / false
- `labels.layout` Outside labels / Étiquettes extérieures: dropdown, default `columns`; values: `columns` Aligned in columns left and right; `around` Around the slices. Columns: labels are spread vertically so they never overlap, with a leader line to their slice.
- `labels.minPct` Hide below (% of total) / Masquer sous (% du total): number, default `0`; values: 0 to 20
- `labels.pctDecimals` Decimals of % / Décimales des %: number, default `0`; values: 0 to 3
- `labels.wrap` Long names on two lines / Noms longs sur deux lignes: toggle, default `true`; values: true / false
- `labels.bg` Background / Arrière-plan: toggle, default `false`; values: true / false. A box behind each label (like the background of the native detail labels).
- `labels.bgColor` Background color (empty = background) / Couleur de l'arrière-plan (vide = fond): color, default (empty); values: hex color. Visible when `labels.bg` = `true`
- `labels.bgTransparency` Background transparency (%) / Transparence de l'arrière-plan (%): slider, default `10`; values: 0 to 100. Visible when `labels.bg` = `true`
- `labels.fontSize` Size / Taille: number, default `10`; values: 6 to 24
- `labels.color` Color (empty = automatic) / Couleur (vide = automatique): color, default (empty); values: hex color. Automatic: readable color depending on the background (inside bars: white or dark).
- `labels.bold` Bold / Gras: toggle, default `false`; values: true / false
- `labels.halo` Text halo / Halo autour du texte: toggle, default `true`; values: true / false
- `labels.declutter` Hide overlapping labels / Masquer les étiquettes qui se chevauchent: toggle, default `true`; values: true / false
- `labels.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `labels.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `labels.prefix` Prefix / Préfixe: text, default (empty)
- `labels.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)

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

### Sort / Tri (`sort`)
- `sort.by` Slice order / Ordre des parts: dropdown, default `valueDesc`; values: `valueDesc` Value descending; `valueAsc` Value ascending; `labelAsc` Name (A → Z); `labelDesc` Name (Z → A); `data` Data order (Sort by column); `custom` Custom ★
- `sort.customOrder` Custom order (separated by ;) / Ordre personnalisé (séparé par ;): text, default (empty). Visible when `sort.by` = `custom`
- `sort.others` Group small slices into “Others” / Regrouper les petites parts dans « Autres »: dropdown, default `none`; values: `none` No; `topN` Keep the N largest ★; `threshold` Slices under a threshold (%) ★
- `sort.n` N: number, default `6`; values: 1 to 50. Visible when `sort.others` = `topN`
- `sort.threshold` Threshold (% of total) / Seuil (% du total): number, default `3`; values: 0.1 to 30. Visible when `sort.others` = `threshold`
- `sort.othersLabel` “Others” label / Libellé de « Autres »: text, default (empty). Visible when `sort.others` = `topN` or `threshold`

### Sub-categories (Details) / Sous-catégories (Détails) (`split`)
- `split.colors` Sub-part colors / Couleurs des sous-parts: dropdown, default `tints`; values: `tints` Shades of the slice color; `category` One color per sub-category (same in every slice) ★; `gradient` Continuous gradient in the slice ★. With a field in “Details”, every slice is cut into sub-parts. One color per sub-category: compare the same product across regions at a glance.
- `split.layout` Cut / Découpe: dropdown, default `angular`; values: `angular` Side by side within the slice angle; `radial` In layers, from the center outward ★
- `split.separators` Lines between sub-parts / Traits entre les sous-parts: toggle, default `true`; values: true / false
- `split.legend` The legend shows / La légende montre: dropdown, default `auto`; values: `auto` Automatic; `categories` The slices; `details` The sub-categories. Automatic: the sub-categories with one color per sub-category, the slices otherwise.

### Slice breakdown / Sous-répartition d'une part (`breakdown`)
- `breakdown.mode` Show / Afficher: dropdown, default `none`; values: `none` No (slices split in place); `ring` Outer ring ★; `pieOfPie` Pie of pie ★; `barOfPie` Bar of pie ★. Shows the detail of one slice (its “Details” sub-categories, or the members of “Others”): around the slice, or in a second pie or a bar linked to it.
- `breakdown.trigger` When / Quand: dropdown, default `click`; values: `click` On click on a slice; `always` Always shown. Visible when `breakdown.mode` = `ring` or `pieOfPie` or `barOfPie`
- `breakdown.target` Detailed slice (always shown) / Part détaillée (toujours affichée): dropdown, default `largest`; values: `largest` The largest; `others` “Others”; `name` By its name; `all` All (outer ring only). Visible when `breakdown.mode` = `ring` or `pieOfPie` or `barOfPie`
- `breakdown.targetName` Slice name / Nom de la part: text, default (empty). Visible when `breakdown.mode` = `ring` or `pieOfPie` or `barOfPie`
- `breakdown.size` Detail size (% of width) / Taille du détail (% de la largeur): number, default `42`; values: 20 to 80. Visible when `breakdown.mode` = `ring` or `pieOfPie` or `barOfPie`
- `breakdown.links` Connector lines / Traits de liaison: toggle, default `true`; values: true / false. Visible when `breakdown.mode` = `ring` or `pieOfPie` or `barOfPie`

### Comparison / Comparaison (`comparison`)
- `comparison.show` Previous period ring / Anneau de la période précédente: toggle, default `true`; values: true / false
- `comparison.position` Position: dropdown, default `outside`; values: `outside` Around the chart; `inside` In the hole
- `comparison.width` Width (px) / Épaisseur (px): number, default `5`; values: 2 to 20
- `comparison.change` Change in the tooltip / Évolution dans l'infobulle: dropdown, default `points`; values: `points` In share points; `percent` In % of the value

### Small multiples / Petits multiples (`smallMultiples`)
- `smallMultiples.columns` Columns (0 = automatic) / Colonnes (0 = automatique): number, default `0`; values: 0 to 12
- `smallMultiples.minHeight` Minimum panel height (px) / Hauteur minimale d'un panneau (px): number, default `110`; values: 50 to 600. Below that, the grid scrolls vertically.
- `smallMultiples.gap` Spacing (px) / Espacement (px): number, default `14`; values: 0 to 60
- `smallMultiples.sizeBy` Chart size / Taille des graphiques: dropdown, default `same`; values: `same` Same size; `total` Proportional to the panel total ★. Proportional: the surface of each pie follows its total, so panels compare in size as well as in shares.
- `smallMultiples.border` Panel border / Cadre des panneaux: toggle, default `false`; values: true / false
- `smallMultiples.titleShow` Title of each panel / Titre de chaque panneau: toggle, default `true`; values: true / false
- `smallMultiples.titleSize` Text size / Taille du texte: number, default `10`; values: 6 to 24. Visible when `smallMultiples.titleShow` = `true`
- `smallMultiples.titleColor` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color. Visible when `smallMultiples.titleShow` = `true`
- `smallMultiples.titleTotal` Total in the title / Total dans le titre: toggle, default `true`; values: true / false. Visible when `smallMultiples.titleShow` = `true`

### Playback ★ / Lecture ★ (`play`)
- `play.start` Frame shown on opening / Image affichée à l'ouverture: dropdown, default `last`; values: `last` The last one (most recent); `first` The first one
- `play.speed` Duration of a frame (ms) / Durée d'une image (ms): number, default `1000`; values: 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, default `false`; values: true / false
- `play.autoPlay` Play automatically on opening / Lecture automatique à l'ouverture: toggle, default `false`; values: 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, default `true`; values: true / false. Values, positions and colors move smoothly from one frame to the next.
- `play.controls` Play bar / Barre de lecture: toggle, default `true`; values: true / false
- `play.position` Bar position / Position de la barre: dropdown, default `bottom`; values: `bottom` Bottom; `top` Top. Visible when `play.controls` = `true`
- `play.ticks` Tick marks / Graduations: dropdown, default `auto`; values: `auto` Automatic; `all` Every frame; `none` None. Visible when `play.controls` = `true`
- `play.tickLabels` Tick labels / Étiquettes des graduations: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.stepButtons` Start and end buttons / Boutons début et fin: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.speedButton` Speed button / Bouton de vitesse: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.showLabel` Current value in large type / Valeur en cours en grand: toggle, default `true`; values: true / false
- `play.labelSize` Large value size / Taille de la valeur en grand: number, default `44`; values: 12 to 160. Visible when `play.showLabel` = `true`
- `play.labelPosition` Large value position / Position de la valeur en grand: dropdown, default `bottomRight`; values: `bottomRight` Bottom right; `topRight` Top right; `topLeft` Top left; `bottomLeft` Bottom left; `center` Center. Visible when `play.showLabel` = `true`

### Interactions (`interaction`)
- `interaction.hover` Highlight on hover / Mettre en avant au survol: toggle, default `true`; values: true / false
- `interaction.dim` Dimmed items opacity (%) / Opacité des éléments estompés (%): number, default `25`; values: 5 to 80

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Treemap Plume

- The treemap Power BI was missing: nested groups with their header and total, click to zoom, and labels you can actually read.
- Slug `treemap` · version 1.1.0.0 · GUID (`visualType`) `plumeTreemap7562F40DD0CD4981BD6A21FCA2485191` · page https://plumevisuals.com/en/visuals/treemap

### What the visual does

Treemap Plume (identifier `treemap`) is a Power BI custom visual (version 1.1.0.0, installed from its `.pbiviz` file; AppSource submission in preparation) that draws **treemaps**: rectangles split into tiles whose area is proportional to a value, nested by category. It covers everything the built-in treemap does (Category, Details, Values, Tooltips, squarified / binary / alternating tiling, gaps between nodes and groups, category and data labels, colors per category, conditional colors, cross-filtering and highlighting) and fixes its known gaps.

**New in version 1.1.0.0 (30/10/2026):** Free native-parity additions: **category labels** separate from data labels (show, bold, lines, color) and an automatic gradient when the Color field is filled.

- **Nested hierarchy**: 1 to 6 fields in Category (groups) plus Details, all levels shown at once; each group has a **header** (name and total) and optional borders. `layout.depth` = 1 shows one level at a time like the built-in treemap (double-click a tile to drill down).
- **Tiling**: squarified (default, near-square tiles), binary, alternating (columns at the first level, rows at the next), rows, columns; ★ Voronoi (polygonal cells) inside a circle or any of 153 shapes (map of France, heart, hexagon…), areas exact within 1%.
- **Zoom into a group**: click a header (Ctrl + click selects the whole group instead), double-click a tile, breadcrumb and ↑ button to go back, animated transitions; keyboard Alt + Down / Backspace. Zoom is session state, never saved.
- **Readable labels**: name, value, ★ share of the group or of the total, change ▲▼ (with Comparison ★); text grows with the tile (auto size between a minimum and a maximum), wraps on spaces and after hyphens, and a label that does not fit is hidden rather than cut to "C…".
- **Sort**: value descending (default) or ascending, name A → Z / Z → A (natural order), data order (the model's sort-by-column).
- **Play axis ★** (premium since the free / premium rebalancing of 2026-10-22): a year or a date in `play` animates the treemap with the shared Plume player (play / pause, slider, speed, loop, large current value); with `layout.stable` (on) tiles keep their place from frame to frame (rows of the squarified layout computed on the total of all frames).
- Above 4,000 visible tiles, the smallest are merged into their group's color (message); 100,000 rows render in about 2 seconds.

### 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 (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium**.
- Free in Treemap Plume: the whole hierarchy, headers, borders, every tiling except Voronoi, zoom, breadcrumb, sort, labels (name, value), the colorings `category`, `single`, `gradient`, the Color field, cross-filtering and highlighting, tooltips (with the shares of the group and of the total).
- Premium features of Treemap Plume: the `play` role (Play axis ★: watermark as soon as the field holds data, even one frame); `dataColors.mode` = `leaf`, `diverging`, `rules`, `change` (stock map) or `highlight`; `labels.percent` = `parent` or `total` (labels shown); `layout.algorithm` = `voronoi` (any `layout.shape`); `layout.topN`; the `comparison` role (Comparison ★); the `image` role (Image ★); the `multiples` role (Small multiples ★).
- 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 `treemap` 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 combination of categories (Power BI groups the rows), with a measure for the size.

| Region (`category`) | Category (`category`) | Revenue (`values`) | Margin rate (`colorBy`) | Revenue 2024 (`comparison`) |
|---|---|---|---|---|
| London | Furniture | 41,200 | 34% | 38,100 |
| London | Lighting | 18,900 | 52% | 20,400 |

- **Category (groups)** (`category`, « Catégorie (groupes) », 1 to 6 columns, required unless Details is filled): the levels, from the largest group to the smallest, in the order of the well. Blank values form a "(Blank)" tile.
- **Details** (`details`, « Détails », 1 column): one more level, like the built-in treemap.
- **Values** (`values`, « Valeurs », 1 measure): the area. Without it, rows are counted. Negative or blank values count as 0 (message in edit mode).
- **Color (measure)** (`colorBy`, « Couleur (mesure) »): read by the `gradient`, `diverging` ★ and `rules` ★ colorings; for a group shown as one tile, the size-weighted average.
- **Comparison ★** (`comparison`, « Comparaison ★ »): previous value; change = (value − comparison) / |comparison|, shown as "▲ +12%" in labels and tooltips, colors with `change`.
- **Image ★** (`image`, « Image ★ », text measure or column): `data:image/...;base64,...`, raw base64 or SVG text; web addresses are never loaded.
- **Small multiples ★** (`multiples`, « Petits multiples ★ », 1 column): one treemap per value; `smallMultiples.sameScale` makes each panel's area proportional to its total.
- **Play axis ★** (`play`, « Axe de lecture ★ », 1 column): numbers and dates ascending, texts in data order; integer years without a format are written "2024".
- **Tooltips** (`tooltips`) and **Dynamic format** (`format`, see below).
- Volume of data: windows of 30,000 rows, more fetched with `fetchMoreData` up to 100,000 rows.

### DAX recipes

```dax
Revenue = SUM ( Sales[Amount] )
Margin rate = DIVIDE ( SUM ( Sales[Margin] ), [Revenue] )          // Color (measure), gradient (free)
Revenue 2024 = CALCULATE ( [Revenue], Sales[Year] = "2024" )        // Comparison ★, stock map
Variance to target % = DIVIDE ( [Revenue] - [Target], [Target] )    // Color (measure), diverging ★ around 0
// Image ★ longer than 32,766 characters: join chunks stored one per row
Logo = CONCATENATEX ( Images, Images[Chunk], "", Images[Chunk index], ASC )
```

### Interactions with the report

- Click a tile: cross-filter on its whole path (and its small multiple, not the play-axis value); Ctrl for several; click the hatched "Others" tile = all merged categories. Ctrl + click a header selects the whole group. Click an empty area clears.
- Cross-highlighting from other visuals: the highlighted part of each tile is drawn at full color from the bottom, the rest faded.
- Hover: Power BI tooltip (full path, value, share of the group and of the total, Color, Comparison and change, Tooltips measures); report page tooltips are supported. Hovering a legend category dims the other groups.
- Context menu everywhere (tile, header, empty area, landing page).
- Keyboard: Tab to the treemap, arrows from tile to tile, Enter selects, Esc clears, Alt + Down zooms into the focused tile's group, Backspace or Alt + Up zooms out; the play bar has its own keys (Space, arrows, Home, End). High contrast, ARIA labels, French and English.

### Dynamic formats

- **fx button** (Power BI conditional formatting) on colors and texts of the Format pane, and on each category color (`dataColors`, one color per category).
- **"Dynamic format" well** (`format`): measures renamed `card.setting` (e.g. `title.text`, `dataColors.mode`, `layout.depth`) drive any setting and win over the fixed value. Driving a ★ setting by DAX still shows the watermark without a key.

```dax
// renamed title.text
Treemap title = "Revenue by region · " & FORMAT ( CALCULATE ( [Revenue], ALLSELECTED () ), "€#,0" )
```

### Format pane: option IDs

- Card order: `license`, `style`, `dataColors`, `layout`, `groups`, `labels`, `zoom`, `legend`, `images`, `smallMultiples`, `play`, `tooltip`, `interaction`, then `title`, `source`, `container`, `texts`. Format pane in version 1.1.0.0 (30/10/2026), top to bottom: `license`, `style`, `dataColors`, `layout`, `groups`, `labels`, `categoryLabels`, `zoom`, `legend`, `images`, `smallMultiples`, `play`, `tooltip`, `interaction`, `title`, `source`, `container`, `texts`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- `dataColors`: `mode` (`category` | `leaf` ★ | `single` | `gradient` | `diverging` ★ | `rules` ★ | `change` ★ | `highlight` ★), `single`, `fill`, `shade` (on), `gradMin`, `gradMax`, `divMid` (`0`), `rule1`, `rule2`, `ruleLow` (#C0392B), `ruleMid` (#B8BCC6), `ruleHigh` (#2E7D4F), `changeRange` (0.1–1000, 3), `lowerBetter`, `highlightNames`, `highlightColor`, `othersColor`.
- `layout`: `algorithm` (`squarify` | `binary` | `sliceDice` | `slice` | `dice` | `voronoi` ★), `shape` (153 shape IDs, default `circle`), `sort` (`valueDesc` | `valueAsc` | `nameAsc` | `nameDesc` | `data`), `stable` (on), `depth` (0–7, 0), `nodeGap` (0–12, 1), `groupGap` (0–24, 3), `tileRadius` (0–16, 0), `topN` ★, `topNCount` (1–500, 10), `othersLabel`.
- `groups`: `headers` (on), `headerSize` (7–24, 10), `headerBold` (on), `headerValue` (on), `headerFill` (`auto` | `neutral` | `none`), `headerColor`, `borders`, `borderWidth` (0.5–6, 1), `borderColor`, `tileBorder`.
- `labels`: `show` (on), `categoryLabels.show` (on), `showValue` (on), `percent` (`none` | `parent` ★ | `total` ★), `change` (on), `position` (`topLeft` | `center`), `autoSize` (on), `fontSize` (6–40, 10), `maxSize` (8–80, 26), `categoryLabels.wrap` (1–6, 2), `minTile` (0–200, 24), `color`, `categoryLabels.bold` (on), `units` (`auto` | `none` | `k` | `m` | `b`), `decimals` (-1–6, -1), `prefix`, `suffix`.
- `zoom`: `headerClick` (on), `doubleClick` (on), `breadcrumb` (on), `rootLabel`.
- `legend`: `show` (on), `position` (`top` | `bottom` | `right` | `left`), `align` (`left` | `center` | `right`), `showTitle`, `titleText`, `fontSize` (6–24, 9), `color`, `interactive` (on).
- `images`: `fit` (`contain` | `cover`), `size` (10–100, 55), `opacity` (5–100, 100), `round`.
- `smallMultiples`: `columns` (0–12, 0), `sameScale` (on), `titleSize` (7–24, 11), `gap` (0–40, 12).
- `play` (card « Lecture ★ » / "Playback ★", shown with the Play axis ★ field): `start` (`last` | `first`), `speed` (100–10000, 1000), `loop`, `autoPlay`, `transition` (on), `controls` (on), `position` (`bottom` | `top`), `ticks` (`auto` | `all` | `none`), `tickLabels` (on), `stepButtons` (on), `speedButton` (on), `showLabel` (on), `labelSize` (12–160, 44), `labelPosition` (`bottomRight` | `topRight` | `topLeft` | `bottomLeft` | `center`).
- `tooltip`: `show` (on), `path` (on), `shareParent` (on), `shareTotal` (on).
- `interaction`: `hover` (on), `dim` (5–80, 25).

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. Booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes.

```json
{
  "visualType": "plumeTreemap7562F40DD0CD4981BD6A21FCA2485191",
  "query": {
    "queryState": {
      "category": { "projections": [
        { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Region" } }, "queryRef": "Sales.Region", "nativeQueryRef": "Region" },
        { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Category" } }, "queryRef": "Sales.Category", "nativeQueryRef": "Category" } ] },
      "values": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Revenue" } }, "queryRef": "Sales.Revenue", "nativeQueryRef": "Revenue" } ] }
    }
  },
  "objects": {
    "labels":     [ { "properties": { "position": { "expr": { "Literal": { "Value": "'center'" } } } } } ],
    "dataColors": [ { "properties": { "mode": { "expr": { "Literal": { "Value": "'category'" } } } } } ],
    "layout":     [ { "properties": { "depth": { "expr": { "Literal": { "Value": "0D" } } } } } ]
  }
}
```

The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from the `.pbiviz` file).

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`. The category colors come from the style's categorical palette (or Series 1 to 8 of the custom colors); gradients from its sequential and diverging palettes; the style's `fill` token (gradient, glass, hatch…) is applied to the tiles.
- `style.themeJson` (Theme JSON ★): a JSON theme as plain text (format v2 with optional `extends` and groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`). Full reference: https://plumevisuals.com/ai/tutorials/en/themes-json.md.

### Common pitfalls

- The landing page stays: no field in Category (groups) or Details.
- Levels inverted: the fields are in the wrong order in Category (groups).
- All tiles the same size: Values is empty (rows counted).
- "… negative value(s) ignored": negative values have no area; use the `diverging` ★ coloring with a variance measure, or Waterfall Plume.
- A tile has no label: it is too small (`labels.minTile`, auto size); zoom into its group.
- Voronoi falls back to squarified: more than 1,200 cells shown; use Top N ★ or fewer levels (`layout.depth`).
- Watermark visible: Voronoi, the `change` or `highlight` coloring, Top N, a Comparison, Image or Small multiples field, a ★ style or a theme JSON, without a valid key.
- The visual makes no network request: data, images and license key stay in the report.

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

Power BI's own drill-down buttons (the visual drills inside itself: zoom, breadcrumb, `layout.depth`), circle packing, a sparkline inside each tile, annotations, drag-and-drop to reorder tiles, images loaded from a URL, exporting the treemap as an image, negative areas.

## Treemap Plume: data fields

- `category` Category (groups) / Catégorie (groupes) (column, 6 max): 1 to 6 fields, from the largest groups to the smallest (e.g. Region, Country, City).
- `details` Details / Détails (column, 1 max): Splits each tile into smaller tiles of the same color (like the Power BI treemap).
- `values` Values / Valeurs (measure, 1 max): Measure that sizes the tiles (without it, rows are counted). Negative values are ignored.
- `colorBy` Color (measure) / Couleur (mesure) (measure, 1 max): Measure that colors the tiles (gradient, diverging ★ or thresholds ★: Data colors card): margin rate, satisfaction…
- `comparison` Comparison ★ / Comparaison ★ ★ (measure, 1 max): Previous value (e.g. last year, yesterday's close): change ▲▼ in labels and tooltips, stock map coloring.
- `image` Image ★ ★ (measure, 1 max): Text measure or column with a base64 image (data:image/png;base64,…): logo or photo in each tile. Web addresses are never loaded.
- `multiples` Small multiples ★ / Petits multiples ★ ★ (column, 1 max): One treemap per value of this field, side by side.
- `play` Play axis ★ / Axe de lecture ★ ★ (column, 1 max): Premium: a date, a year or an ordered category: the treemap moves from one value to the next (play button), stable layout.
- `tooltips` Tooltips / Infobulles (measure, several max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Treemap Plume: Format pane options (166)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Layout / Disposition (`layout`)
- `layout.algorithm` Tiling method / Méthode de pavage: dropdown, default `squarify`; values: `squarify` Squarified; `binary` Binary; `sliceDice` Alternating (columns, rows); `slice` Rows; `dice` Columns; `voronoi` Voronoi (cells) ★. Squarified: near-square tiles (most readable). Voronoi ★: polygonal cells inside a shape (circle, map of France…).
- `layout.shape` Voronoi shape / Forme du Voronoï: dropdown, default `circle`; values: `circle` Circle; `square` Square; `roundedSquare` Rounded square; `rectangle` Rectangle; `triangle` Triangle; `diamond` Diamond; `hexagon` Hexagon; `star` Star; `heart` Heart; `ellipse` Ellipse ★; `pentagon` Pentagon ★; `octagon` Octagon ★; `rightTriangle` Right triangle ★; `parallelogram` Parallelogram ★; `trapezoid` Trapezoid ★; `ring` Ring ★; `semicircle` Semicircle ★; `arch` Arch ★; `capsule` Pill ★; `star6` Six-pointed star ★; `seal` Seal ★; `cross` Cross ★; `arrow` Arrow; `arrowUp` Arrow up ★; `arrowDown` Arrow down ★; `arrowLeft` Arrow left ★; `doubleArrow` Double arrow ★; `chevron` Chevron ★; `check` Check mark ★; `close` Close (X) ★; `plus` Plus ★; `minus` Minus ★; `warning` Warning ★; `info` Information ★; `playButton` Play button ★; `bubble` Speech bubble; `thought` Thought bubble ★; `flag` Flag ★; `bookmark` Bookmark ★; `tag` Tag ★; `bolt` Lightning bolt ★; `shield` Shield ★; `award` Award ★; `puzzle` Puzzle piece ★; `gear` Gear ★; `lock` Lock ★; `key` Key ★; `bell` Bell ★; `eye` Eye ★; `cloud` Cloud; `drop` Drop; `sun` Sun ★; `moon` Moon ★; `snowflake` Snowflake ★; `leaf` Leaf ★; `pine` Pine tree ★; `tree` Tree ★; `flower` Flower ★; `mountain` Mountain ★; `wave` Wave ★; `flame` Flame ★; `umbrella` Umbrella ★; `apple` Apple ★; `fish` Fish ★; `paw` Paw print ★; `rain` Rain ★; `sprout` Sprout ★; `person` Person; `man` Man ★; `woman` Woman ★; `child` Child ★; `people` Group of people ★; `bust` User bust ★; `house` House; `building` Office building ★; `factory` Factory ★; `castle` Castle ★; `shop` Shop ★; `bank` Bank ★; `hospital` Hospital ★; `book` Book ★; `envelope` Envelope ★; `phone` Phone ★; `laptop` Laptop ★; `monitor` Monitor ★; `gift` Gift ★; `clock` Clock ★; `calendar` Calendar ★; `pencil` Pencil ★; `lightbulb` Light bulb ★; `cup` Trophy ★; `crown` Crown ★; `trashCan` Trash can ★; `barrel` Barrel; `bottle` Bottle; `wineGlass` Wine glass; `glass` Glass; `mug` Mug ★; `jar` Jar ★; `bucket` Bucket ★; `battery` Battery; `batteryVertical` Vertical battery; `thermometer` Thermometer; `testTube` Test tube ★; `tank` Tank ★; `funnel` Funnel ★; `hourglass` Hourglass ★; `bag` Bag ★; `piggyBank` Piggy bank ★; `flask` Flask ★; `beaker` Beaker ★; `can` Can ★; `coffeeCup` Coffee cup ★; `vase` Vase ★; `milkCarton` Milk carton ★; `france` Metropolitan France ★; `africa` Africa ★; `australia` Australia ★; `southAmerica` South America ★; `pin` Map pin ★; `globe` Globe ★; `foldedMap` Folded map ★; `compass` Compass ★; `city` City skyline ★; `target` Target ★; `barChart` Bar chart ★; `pieChart` Pie chart ★; `trendUp` Trend up ★; `coin` Coin ★; `banknote` Banknote ★; `wallet` Wallet ★; `creditCard` Credit card ★; `cart` Shopping cart ★; `briefcase` Briefcase ★; `percent` Percent ★; `podium` Podium ★; `megaphone` Megaphone ★; `gem` Gem ★; `medal` Medal ★; `clipboard` Clipboard ★; `handshake` Handshake ★; `car` Car ★; `truck` Truck ★; `bus` Bus ★; `bicycle` Bicycle ★; `plane` Plane ★; `boat` Sailboat ★; `train` Train ★; `rocket` Rocket ★; `helicopter` Helicopter ★; `ship` Cargo ship ★; `fuel` Fuel pump ★; `scooter` Scooter ★. Visible when `layout.algorithm` = `voronoi`. Outline the cells share (shapes without ★: circle, square, hexagon, heart…).
- `layout.sort` Tile order / Ordre des tuiles: dropdown, default `valueDesc`; values: `valueDesc` Value, descending; `valueAsc` Value, ascending; `nameAsc` Name (A → Z); `nameDesc` Name (Z → A); `data` Data order (Power BI sort). The first tile is at the top left. "Data order" follows the model's sort-by-column (months, priorities…).
- `layout.stable` Stable layout while playing / Disposition stable pendant la lecture: toggle, default `true`; values: true / false. Play axis: tiles grow, shrink and slide, never jumping from one place to another.
- `layout.depth` Levels shown at once (0 = all) / Niveaux affichés à la fois (0 = tous): number, default `0`; values: 0 to 7. 1 = like the Power BI treemap: one level, double-click to drill down. 0 = the whole nested hierarchy.
- `layout.nodeGap` Space between tiles (px) / Espace entre les tuiles (px): number, default `1`; values: 0 to 12
- `layout.groupGap` Space between groups (px) / Espace entre les groupes (px): number, default `3`; values: 0 to 24
- `layout.tileRadius` Tile corner radius / Arrondi des tuiles: number, default `0`; values: 0 to 16
- `layout.topN` Top N + "Others" ★ / Top N + « Autres » ★ ★: toggle, default `false`; values: true / false. In each group, the N largest tiles; the rest is merged into a hatched "Others" tile.
- `layout.topNCount` Tiles kept per group / Nombre de tuiles gardées par groupe: number, default `10`; values: 1 to 500. Visible when `layout.topN` = `true`
- `layout.othersLabel` "Others" label / Libellé de « Autres »: text, default (empty). Visible when `layout.topN` = `true`

### Data colors / Couleurs des données (`dataColors`, one entry per item with a selector)
- `dataColors.mode` Coloring / Coloration: dropdown, default `category`; values: `category` One color per category (top level); `leaf` One color per tile (last level) ★; `single` Single color; `gradient` Gradient by a measure; `diverging` Diverging around a midpoint ★; `rules` Thresholds (3 colors) ★; `change` Stock map: change (Comparison field) ★; `highlight` Highlight ★
- `dataColors.single` Color / Couleur: color, default (empty); values: hex color
- `dataColors.fill` Color / Couleur: color, default (empty); values: hex color
- `dataColors.shade` Shade tiles within a group / Nuancer les tuiles d'un groupe: toggle, default `true`; values: true / false. Smaller tiles of a group are slightly lighter, so neighboring tiles of the same color stand apart.
- `dataColors.gradMin` Start value (empty = minimum) / Valeur du début (vide = minimum): text, default (empty)
- `dataColors.gradMax` End value (empty = maximum) / Valeur de la fin (vide = maximum): text, default (empty)
- `dataColors.divMid` Midpoint value / Valeur du milieu: text, default `0`
- `dataColors.rule1` Low threshold / Seuil bas: text, default (empty)
- `dataColors.rule2` High threshold / Seuil haut: text, default (empty)
- `dataColors.ruleLow` Below the low threshold / Sous le seuil bas: color, default `#C0392B`; values: hex color
- `dataColors.ruleMid` Between thresholds / Entre les seuils: color, default `#B8BCC6`; values: hex color
- `dataColors.ruleHigh` Above the high threshold / Au-dessus du seuil haut: color, default `#2E7D4F`; values: hex color
- `dataColors.changeSource` Change read from / Variation lue dans: dropdown, default `auto`; values: `auto` Automatic (Comparison field, else Color field); `comparison` Values compared with the Comparison field; `measure` Color field (change already computed). Color field: a change measure (e.g. Change % = 0.034 or 3.4%) colors the tiles, whatever measure sizes them (market cap, sales…).
- `dataColors.changeAuto` Automatic change range / Plage de variation automatique: toggle, default `true`; values: true / false. The strongest color matches a round change (±1, 2, 3, 5, 10%…) reached by 90% of the tiles shown. Off: the value below.
- `dataColors.changeRange` Change for the strongest color (%) / Variation de la couleur la plus vive (%): number, default `3`; values: 0.1 to 1000. Like stock market maps: at ±3% the tile takes the strongest favorable or unfavorable color; at 0%, gray.
- `dataColors.lowerBetter` A decrease is favorable / Une baisse est favorable: toggle, default `false`; values: true / false
- `dataColors.highlightNames` Highlighted categories / Catégories mises en avant: text, default (empty). Comma-separated names, at any level. Other tiles are grayed out.
- `dataColors.highlightColor` Highlight color (empty = accent) / Couleur mise en avant (vide = accent): color, default (empty); values: hex color
- `dataColors.othersColor` Other tiles color (empty = gray) / Couleur des autres tuiles (vide = gris): color, default (empty); values: hex color

### Groups (headers and borders) / Groupes (en-têtes et bordures) (`groups`)
- `groups.headers` Group headers / En-têtes des groupes: toggle, default `true`; values: true / false
- `groups.headerSize` Text size / Taille du texte: number, default `10`; values: 7 to 24
- `groups.headerBold` Bold / Gras: toggle, default `true`; values: true / false
- `groups.headerValue` Group total / Total du groupe: toggle, default `true`; values: true / false
- `groups.headerFill` Header background / Fond de l'en-tête: dropdown, default `auto`; values: `auto` Group color; `neutral` Neutral; `none` None
- `groups.headerColor` Text color (empty = automatic) / Couleur du texte (vide = automatique): color, default (empty); values: hex color
- `groups.borders` Border around groups / Bordure autour des groupes: toggle, default `false`; values: true / false
- `groups.borderWidth` Width / Épaisseur: number, default `1`; values: 0.5 to 6. Visible when `groups.borders` = `true`
- `groups.borderColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `groups.borders` = `true`
- `groups.tileBorder` Gap color between tiles (empty = background) / Couleur des espaces entre tuiles (vide = fond): color, default (empty); values: hex color

### Data labels / Étiquettes de données (`labels`)
- `labels.show` Show / Afficher: toggle, default `true`; values: true / false. Values in the tiles. Names are set in « Category labels ».
- `labels.showValue` Value / Valeur: toggle, default `true`; values: true / false
- `labels.percent` Percentage / Pourcentage: dropdown, default `none`; values: `none` None; `parent` Share of the group ★; `total` Share of the total ★
- `labels.change` Change ▲▼ (Comparison field) / Variation ▲▼ (champ Comparaison): toggle, default `true`; values: true / false
- `labels.position` Position: dropdown, default `topLeft`; values: `topLeft` Top left; `center` Center
- `labels.autoSize` Auto size / Taille automatique: toggle, default `true`; values: true / false. Text grows with the tile (from the minimum to the maximum size) and never overflows.
- `labels.fontSize` Size (minimum) / Taille (minimale): number, default `10`; values: 6 to 40
- `labels.maxSize` Maximum size / Taille maximale: number, default `26`; values: 8 to 80. Visible when `labels.autoSize` = `true`
- `labels.minTile` Hide in tiles narrower than (px) / Masquer dans les tuiles plus étroites que (px): number, default `24`; values: 0 to 200
- `labels.color` Color (empty = automatic) / Couleur (vide = automatique): color, default (empty); values: hex color. Automatic: white or dark depending on the tile color.
- `labels.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `labels.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `labels.prefix` Prefix / Préfixe: text, default (empty)
- `labels.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)

### Category labels / Étiquettes des catégories (`categoryLabels`)
- `categoryLabels.show` Show / Afficher: toggle, default `true`; values: true / false
- `categoryLabels.bold` Bold / Gras: toggle, default `true`; values: true / false
- `categoryLabels.wrap` Lines for long names / Lignes pour les noms longs: number, default `2`; values: 1 to 6
- `categoryLabels.color` Color (empty = same as data labels) / Couleur (vide = comme les étiquettes de données): color, default (empty); values: hex color

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

### Zoom (`zoom`)
- `zoom.headerClick` Click a header: zoom into the group / Clic sur un en-tête : zoomer dans le groupe: toggle, default `true`; values: true / false. Ctrl + click on the header: select the whole group (cross-filter).
- `zoom.doubleClick` Double-click a tile: drill down one level / Double-clic sur une tuile : descendre d'un niveau: toggle, default `true`; values: true / false
- `zoom.breadcrumb` Breadcrumb / Fil d'Ariane: toggle, default `true`; values: true / false
- `zoom.rootLabel` Top level label / Libellé du niveau supérieur: text, default (empty)

### Images ★ (`images`)
- `images.fit` Fit / Ajustement: dropdown, default `contain`; values: `contain` Whole (logo); `cover` Fill the tile (photo)
- `images.size` Size (% of the tile) / Taille (% de la tuile): number, default `55`; values: 10 to 100. Visible when `images.fit` = `contain`
- `images.opacity` Opacity (%) / Opacité (%): number, default `100`; values: 5 to 100
- `images.round` Round image / Image ronde: toggle, default `false`; values: true / false. Visible when `images.fit` = `contain`

### Small multiples ★ / Petits multiples ★ (`smallMultiples`)
- `smallMultiples.columns` Columns (0 = automatic) / Colonnes (0 = automatique): number, default `0`; values: 0 to 12
- `smallMultiples.sameScale` Comparable areas across panels / Surfaces comparables entre panneaux: toggle, default `true`; values: true / false. Each panel's area is proportional to its total: a panel half the size weighs half as much.
- `smallMultiples.titleSize` Title size / Taille des titres: number, default `11`; values: 7 to 24
- `smallMultiples.gap` Space between panels (px) / Espace entre les panneaux (px): number, default `12`; values: 0 to 40

### Playback ★ / Lecture ★ (`play`)
- `play.start` Frame shown on opening / Image affichée à l'ouverture: dropdown, default `last`; values: `last` The last one (most recent); `first` The first one
- `play.speed` Duration of a frame (ms) / Durée d'une image (ms): number, default `1000`; values: 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, default `false`; values: true / false
- `play.autoPlay` Play automatically on opening / Lecture automatique à l'ouverture: toggle, default `false`; values: 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, default `true`; values: true / false. Values, positions and colors move smoothly from one frame to the next.
- `play.controls` Play bar / Barre de lecture: toggle, default `true`; values: true / false
- `play.position` Bar position / Position de la barre: dropdown, default `bottom`; values: `bottom` Bottom; `top` Top. Visible when `play.controls` = `true`
- `play.ticks` Tick marks / Graduations: dropdown, default `auto`; values: `auto` Automatic; `all` Every frame; `none` None. Visible when `play.controls` = `true`
- `play.tickLabels` Tick labels / Étiquettes des graduations: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.stepButtons` Start and end buttons / Boutons début et fin: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.speedButton` Speed button / Bouton de vitesse: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.showLabel` Current value in large type / Valeur en cours en grand: toggle, default `true`; values: true / false
- `play.labelSize` Large value size / Taille de la valeur en grand: number, default `44`; values: 12 to 160. Visible when `play.showLabel` = `true`
- `play.labelPosition` Large value position / Position de la valeur en grand: dropdown, default `bottomRight`; values: `bottomRight` Bottom right; `topRight` Top right; `topLeft` Top left; `bottomLeft` Bottom left; `center` Center. Visible when `play.showLabel` = `true`

### Interactions (`interaction`)
- `interaction.hover` Highlight on hover / Mettre en avant au survol: toggle, default `true`; values: true / false
- `interaction.dim` Dimmed items opacity (%) / Opacité des éléments estompés (%): number, default `25`; values: 5 to 80

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).
- `tooltip.path` Full path (every level) / Chemin complet (tous les niveaux): toggle, default `true`; values: true / false
- `tooltip.shareParent` Share of the group / Part du groupe: toggle, default `true`; values: true / false
- `tooltip.shareTotal` Share of the total / Part du total: toggle, default `true`; values: true / false

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Pyramid Plume

- The age pyramid that comes alive: drop the age, the sex and the population, press ▶ and watch generations climb year after year.
- Slug `population-pyramid` · version 1.1.0.0 · GUID (`visualType`) `plumePopulationPyramid247171417FEF4CFEA0FEE64FE39F53DF` · page https://plumevisuals.com/en/visuals/population-pyramid

### What the visual does

Pyramid Plume (identifier `population-pyramid`) is a Power BI custom visual (version 1.1.0.0, installed from its `.pbiviz` file; AppSource submission being prepared) that draws **population pyramids** (age pyramids) and, more generally, **butterfly / tornado charts**: two sides face to face, one row per category. Power BI Desktop has no native population pyramid (the usual workaround is a stacked bar chart with one side made negative).

**New in version 1.1.0.0 (30/10/2026):** Format pane reorganized (`ageAxis` → `catAxis`, gridlines in **Gridlines**); hatched surplus with an "Excess" key, neutral vocabulary option (non-age data), shared Gridlines card.

- **Three fields**: `age` (an age or age band, or any category), `side` (the sex or any two-value field), `value` (a measure). Without `side`, two measures in `value` face each other (butterfly chart).
- **Ages in natural numeric order with no sort column**: the visual reads the number in each label ("0-4", "5 à 9 ans", "100 ans et +", "85+", "under 5", Eurostat codes `Y_LT5`, `Y5-9`, `Y_GE85`) and sorts by itself; young at the bottom. Labels without numbers keep the model order (or are sorted by total for a tornado).
- **Positive values on both sides**: both sides start from the center with positive ticks; negative values (the usual workaround) are read as absolute values.
- **Age bands computed in the visual** ★: 2, 5, 10 or 20-year bands from single ages and an open last band ("90+"), with no calculated column.
- Counts, % of the total population or % of each side; side headers with name, total and share; ★ surplus of one side (darker shade); ★ median and mean age lines (Analytics pane); ★ birth years next to the ages.
- **Play axis ★** (`play` role, a year or date column; premium since the free / premium rebalancing of 2026-10-22): the shared Plume player (play / pause, slider, speed ×0.5 to ×4, loop, keyboard) animates bars, totals and labels year after year, with a fixed scale by default. Playback is per session, never saved in the report.
- Men stay on the left even when the data starts with women; `pyramid.swap` swaps the sides.

### 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 (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium**.
- Free in Pyramid Plume: the age / side / value fields, butterfly mode, numeric ordering, bands already in the data, counts and shares, side headers, data labels, axes, scale maximum, own scale per side, colors, cross-filtering, highlighting, tooltips.
- Premium features of Pyramid Plume:
  - the `play` role ("Play axis ★": watermark as soon as the field holds data, even one year; the Playback settings themselves add nothing);
  - `ages.band` = `2`, `5`, `10` or `20` and `ages.openFrom` > 0 (computed bands, on numeric ages); `pyramid.excess` = `shade` or `outline` (surplus of one side, with two sides); `catAxis.birthYears` (with a known year); `ageLines.median` and `ageLines.mean` (Analytics pane, numeric ages);
  - the `compare` role ("Comparison ★") and the comparison with a frame of the play axis (`comparison.source` = `first`, `previous` or `frame`): outline, ghost bars or markers;
  - `generation.follow` (follow a generation: the cohort born in a given year is highlighted and climbs while playing) and `generation.marks` (generation markers: "1946-1964 = Baby boom");
  - `indicators.show` (demographic indicators: population, median and mean age, shares of young and older people, dependency ratio, ageing index, side ratio);
  - `projection.show` (frames from a given year drawn hatched, pale or dashed, with a "Projection" tag);
  - the `stack` role ("Sub-category ★", stacked from the center) and the `multiples` role ("Small multiples ★").
- The watermark depends on features actually applied: a generation or birth years with no known year (no play axis, `ages.year` = 0), a comparison without its field, bands or median / mean lines on non-numeric categories, or a surplus with a single side draw nothing and show no watermark.
- 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.
- Accepted keys: only keys starting with `PLUM1.` shown in the buyer's account on plumevisuals.com, checked offline (Ed25519 signature), covering `population-pyramid` or the whole catalog. 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 age (or band), per sex and, to animate, per year: `Population[Age]` (whole number or text band), `Population[Sex]` (two values), `Population[Year]` (whole number or date), `Population[Residents]`. The measure is a plain sum.

```dax
Number of residents = SUM ( Population[Residents] )
// Comparison ★ with the whole country while a slicer picks one area (compare shapes with pyramid.measure = pctTotal)
Residents of all areas = CALCULATE ( [Number of residents], REMOVEFILTERS ( Population[Area] ) )
// Comparison ★ with a fixed year
Residents in 1975 = CALCULATE ( [Number of residents], REMOVEFILTERS ( Population[Year] ), Population[Year] = 1975 )
```

Butterfly chart: no `side` field, two measures in `value` (e.g. satisfied managers and satisfied employees), any category in `age`; `ages.order` = `valueDesc` for a tornado; `pyramid.scaleMode` = `perSide` for measures with different units.

### Interactions with the report

- Click a bar: cross-filter on its age (or band: every age in it) and side; the selection is **not** tied to the year, so it stays while playing. Ctrl for several; click a side header = all bars of that side; click an empty area = clear. Cross-highlighting from other visuals draws the highlighted part inside dimmed bars. Context menu everywhere, including the landing screen.
- Hover: Power BI tooltip with age, side, value, share of the total and of the side, comparison and difference, Tooltips measures (summed when ages are grouped); report-page tooltips are supported.
- Keyboard: Tab to the play bar (Space play / pause, arrows, Home, End) or to the chart (arrows browse bars, Enter selects, Esc clears). High contrast, ARIA labels, French and English.

### Dynamic formats

- **fx button** (Power BI conditional formatting) on colors and texts of the Format pane.
- **"Dynamic format" well** (`format`): measures renamed `card.setting` (e.g. `title.text`, `pyramid.measure`, `generation.birthFrom`) drive any setting and win over the fixed value. Driving a ★ setting by DAX still shows the watermark without a key.

```dax
// renamed title.text
Title = "Age pyramid: " & SELECTEDVALUE ( Population[Area], "all areas" )
```

### Format pane: option IDs

- Card order: `license`, `style`, `dataColors`, `pyramid`, `ages`, `catAxis`, `valAxis`, `labels`, `legend`, `comparison`, `generation`, `indicators`, `projection`, `smallMultiples`, `play`, `ageLines` (Analytics pane), `interaction`, then `title`, `source`, `container`, `texts`. Format pane in version 1.1.0.0 (30/10/2026), top to bottom: `license`, `style`, `dataColors`, `pyramid`, `ages`, `labels`, `catAxis`, `valAxis`, `gridlines`, `legend`, `comparison`, `generation`, `indicators`, `projection`, `smallMultiples`, `play`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`; Analytics pane: `ageLines`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- `dataColors`: `mode` (`auto` | `single`), `single`, `fill`, `excessColor`.
- `pyramid`: `measure` (`value` | `pctTotal` | `pctSide`), `swap`, `sideHeaders` (on), `headerShare` (on), `headerSize` (7–24, 11), `thickness` (20–100, 88), `radius` (0–12, 1), `opacity` (10–100, 100), `border`, `excess` (`none` | `shade` ★ | `outline` ★), `fixedScale` (on), `scaleMode` (`shared` | `perSide`), `max`.
- `ages`: `order` (`auto` | `model` | `valueDesc` | `valueAsc` | `labelAsc`), `direction` (`auto` | `bottomUp` | `topDown`), `band` (`1` | `2` ★ | `5` ★ | `10` ★ | `20` ★), `openFrom` ★ (0–150, 0), `year` (0–3000, 0), `convention` (`reached` | `completed`).
- `catAxis`: `show` (on), `position` (`center` | `left` | `right`), `fontSize` (6–24, 9), `color`, `every` (`auto` | `1` | `5` | `10`), `gap` (0–40, 2), `showTitle` (on), `titleText`, `birthYears` ★.
- `valAxis`: `show` (on), `fontSize` (6–24, 9), `color`, `units` (`auto` | `none` | `k` | `m` | `b`), `decimals` (-1–6, -1), `prefix`, `suffix`, `ticks` (1–10, 3), `showTitle`, `titleText`, `gridlines.vShow` (on), `gridlines.vStyle` (`solid` | `dashed` | `dotted`), `gridlines.vColor`.
- `labels`: `show`, `content` (`value` | `pctTotal` | `pctSide` | `valuePct`), `minRow` (4–40, 10), `fontSize` (6–24, 10), `color`, `bold`, `halo` (on), `declutter` (on), `units` (`auto` | `none` | `k` | `m` | `b`), `decimals` (-1–6, -1), `prefix`, `suffix`.
- `legend`: `show` (on), `position` (`top` | `bottom` | `right` | `left`), `align` (`left` | `center` | `right`), `showTitle`, `titleText`, `fontSize` (6–24, 9), `color`, `interactive` (on).
- `comparison`: `show` (on), `source` (`field` | `first` ★ | `previous` ★ | `frame` ★), `frameName`, `style` (`outline` | `ghost` | `marker`), `color`, `width` (0.5–6, 1.5), `lineStyle` (`solid` | `dashed` | `dotted`), `label`.
- `generation`: `follow` ★, `birthFrom` (1000–3000, 1946), `birthTo` (0–3000, 0), `label`, `color`, `marks` ★, `marksColor`.
- `indicators`: `show` ★, `position` (`topLeft` | `topRight` | `bottomLeft` | `bottomRight`), `total` (on), `median` (on), `mean`, `youngShare` (on), `oldShare` (on), `dependency` (on), `ageing`, `ratio`, `youngMax` (1–40, 20), `oldMin` (40–100, 65), `fontSize` (7–20, 10).
- `projection`: `show` ★, `from`, `style` (`hatch` | `pale` | `outline`), `label`.
- `smallMultiples`: `columns` (0–12, 0), `gap` (0–60, 14), `titleSize` (6–24, 10), `titleTotal` (on), `border`.
- `play` (card « Lecture ★ » / "Playback ★", shown with the Play axis ★ field): `start` (`last` | `first`), `speed` (100–10000, 1000), `loop`, `autoPlay`, `transition` (on), `controls` (on), `position` (`bottom` | `top`), `ticks` (`auto` | `all` | `none`), `tickLabels` (on), `stepButtons` (on), `speedButton` (on), `showLabel` (on), `labelSize` (12–160, 44), `labelPosition` (`bottomRight` | `topRight` | `topLeft` | `bottomLeft` | `center`; default `topRight`).
- `ageLines` (Analytics pane): `median` ★, `mean` ★, `per` (`side` | `total`), `color`, `style` (`solid` | `dashed` | `dotted`; default `dashed`), `width` (0.5–6, 1.5), `showLabel` (on).
- `interaction`: `hover` (on), `dim` (5–80, 25).
- `ages.year` (0 = read from the play axis) and `ages.convention` (`reached`: born in 1946 = 74 in 2020; `completed`: 73 on January 1, 2020) are used by birth years and generations. `pyramid.max` is text (e.g. `500000`, or `5` for 5 % in percent mode).

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. Booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes.

```json
{
  "visualType": "plumePopulationPyramid247171417FEF4CFEA0FEE64FE39F53DF",
  "query": {
    "queryState": {
      "age":   { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Population" } }, "Property": "Age" } }, "queryRef": "Population.Age", "nativeQueryRef": "Age" } ] },
      "side":  { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Population" } }, "Property": "Sex" } }, "queryRef": "Population.Sex", "nativeQueryRef": "Sex" } ] },
      "value": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Population" } }, "Property": "Number of residents" } }, "queryRef": "Population.Number of residents", "nativeQueryRef": "Number of residents" } ] },
      "play":  { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Population" } }, "Property": "Year" } }, "queryRef": "Population.Year", "nativeQueryRef": "Year" } ] }
    }
  },
  "objects": {
    "ages":       [ { "properties": { "band": { "expr": { "Literal": { "Value": "'5'" } } }, "openFrom": { "expr": { "Literal": { "Value": "90D" } } } } } ],
    "pyramid":    [ { "properties": { "measure": { "expr": { "Literal": { "Value": "'pctTotal'" } } }, "excess": { "expr": { "Literal": { "Value": "'shade'" } } } } } ],
    "generation": [ { "properties": { "follow": { "expr": { "Literal": { "Value": "true" } } }, "birthFrom": { "expr": { "Literal": { "Value": "1946D" } } } } } ],
    "license":    [ { "properties": { "key": { "expr": { "Literal": { "Value": "'PLUM1.…'" } } } } } ]
  }
}
```

The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from the `.pbiviz` file).

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`. Side colors default to series colors 1 and 2 of the style; colors chosen in Data colors win.
- `style.themeJson` (Theme JSON ★): a JSON theme as plain text. Full reference: https://plumevisuals.com/ai/tutorials/en/themes-json.md.

### Common pitfalls

- Bands in alphabetical order: the labels contain no number ("Young", "Seniors"); use labels with ages or a sort-by column with `ages.order` = `model`.
- Both sides named after the measure: no `side` field (butterfly mode); put the sex in `side` and a single measure in `value`.
- "only … and … are drawn": the side field has more than two values.
- The pyramid adds up every year: no year is filtered and the year is not in `play` ★.
- No generation band, no birth years: unknown year (no play axis in years, `ages.year` = 0), or ages not numeric / not in automatic order; the generation is older than the last age.
- No data labels: rows shorter than `labels.minRow`; group ages or lower it.
- Watermark visible: play axis, computed bands, surplus of one side, birth years, median or mean age lines, comparison, followed generation, generation markers, indicators, projection, sub-category, small multiples, a ★ style or a theme JSON, without a valid key.
- The visual makes no network request: data and license key stay in the report; no R or Python.

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

More than two sides (a third side value is ignored), error bars or vertical reference lines at a value, sorting one side independently of the other, images or flags, a population projection computed by the visual (projections come from the data; the visual only draws them differently), saving the playing year in the report, exporting the animation as a video or GIF.

## Pyramid Plume: data fields

- `age` Age (or age band, category) / Âge (ou tranche, catégorie) (column, 1 max): One row per age or age band (0, 1, 2… or "0-4", "5-9", "100+"): sorted in natural numeric order. Any category for a butterfly chart.
- `side` Side (sex or any two-value field) / Côté (sexe ou champ à deux valeurs) (column, 1 max): Two values face to face (men / women, before / after…). Without it, put two measures in Value.
- `value` Value (or two measures face to face) / Valeur (ou deux mesures face à face) (measure, 2 max): Population, headcount… Negative values (the usual workaround) are read as positive. Without Side: two measures, one per side.
- `play` Play axis ★ / Axe de lecture ★ ★ (column, 1 max): Premium: year or date: the pyramid moves from one year to the next (play button), bars animated.
- `compare` Comparison ★ / Comparaison ★ ★ (measure, 2 max): Premium: another year, another territory or a target, drawn as an outline over the bars (one measure, or one per side without Side).
- `stack` Sub-category ★ / Sous-catégorie ★ ★ (column, 1 max): Premium: splits each bar (nationality, activity, region…), stacked from the center.
- `multiples` Small multiples ★ / Petits multiples ★ ★ (column, 1 max): Premium: one pyramid per value (region, country…), same scale.
- `tooltips` Tooltips / Infobulles (measure, 5 max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Pyramid Plume: Format pane options (197)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Data colors / Couleurs des données (`dataColors`, one entry per item with a selector)
- `dataColors.mode` Coloring / Coloration: dropdown, default `auto`; values: `auto` One color per side (or per sub-category); `single` Single color
- `dataColors.single` Color / Couleur: color, default (empty); values: hex color
- `dataColors.fill` Color / Couleur: color, default (empty); values: hex color
- `dataColors.excessColor` Surplus (empty = darker shade of the side) / Excédent (vide = teinte foncée du côté): color, default (empty); values: hex color

### Pyramid / Pyramide (`pyramid`)
- `pyramid.measure` Show / Afficher: dropdown, default `value`; values: `value` Counts (values); `pctTotal` % of the total population; `pctSide` % of each side. In %, two pyramids of different sizes (two territories, two years) compare by their shape.
- `pyramid.swap` Swap sides / Inverser les côtés: toggle, default `false`; values: true / false. By default, "Men" (or the first value) on the left.
- `pyramid.sideHeaders` Side headers (name and total) / En-tête des côtés (nom et total): toggle, default `true`; values: true / false
- `pyramid.headerShare` Share of each side in the header / Part de chaque côté dans l'en-tête: toggle, default `true`; values: true / false. Visible when `pyramid.sideHeaders` = `true`
- `pyramid.headerSize` Header size / Taille de l'en-tête: number, default `11`; values: 7 to 24. Visible when `pyramid.sideHeaders` = `true`
- `pyramid.thickness` Bar thickness (%) / Épaisseur des barres (%): number, default `88`; values: 20 to 100
- `pyramid.radius` End rounding / Arrondi du bout: number, default `1`; values: 0 to 12
- `pyramid.opacity` Opacity (%) / Opacité (%): number, default `100`; values: 10 to 100
- `pyramid.border` Outline / Contour: toggle, default `false`; values: true / false
- `pyramid.excess` Surplus of one side / Excédent d'un côté: dropdown, default `none`; values: `none` Not marked; `shade` Hatching at the end of the bar ★; `outline` Outline of the opposite side ★. The part of a bar beyond the opposite one (e.g. more women at old ages): hatched in the side color, with an outline, so it is not read as a second series.
- `pyramid.excessLegend` Surplus legend / Légende de l'excédent: toggle, default `true`; values: true / false. Visible when `pyramid.excess` = `shade` or `outline`. A "Surplus" key under the pyramid explains the hatching (or the outline).
- `pyramid.fixedScale` Same scale for every frame of the play axis / Échelle fixe sur toutes les images du lecteur: toggle, default `true`; values: true / false. Off: the scale adapts to each year.
- `pyramid.scaleMode` Scale of both sides / Échelle des deux côtés: dropdown, default `shared`; values: `shared` Shared; `perSide` Own scale per side (two measures). Own scale per side: two measures with different units (headcount and seniority).
- `pyramid.max` Scale maximum / Maximum de l'échelle: text, default (empty)

### Ages and categories / Âges et catégories (`ages`)
- `ages.order` Order / Ordre: dropdown, default `auto`; values: `auto` Automatic (ages in numeric order); `model` Model order; `valueDesc` Total, descending (tornado); `valueAsc` Total, ascending; `labelAsc` Name A → Z. Automatic: "5-9" before "10-14", "100+" last, no sort column needed.
- `ages.direction` Direction / Sens: dropdown, default `auto`; values: `auto` Automatic (young at the bottom); `bottomUp` First category at the bottom; `topDown` First category at the top
- `ages.band` Group ages / Regrouper les âges: dropdown, default `1`; values: `1` No (ages as in the data); `2` 2-year bands ★; `5` 5-year bands ★; `10` 10-year bands ★; `20` 20-year bands ★. Computed by the visual from single ages (0, 1, 2…): no band column to create.
- `ages.openFrom` Open last band from (0 = no) ★ / Dernière tranche ouverte à partir de (0 = non) ★ ★: number, default `0`; values: 0 to 150. E.g. 90: everyone aged 90 and over in "90+".
- `ages.year` Observation year (0 = play axis) / Année d'observation (0 = axe de lecture): number, default `0`; values: 0 to 3000. Used for birth years and generations. Read from the play axis when it is a year or a date.
- `ages.convention` Age counted as / Âge compté: dropdown, default `reached`; values: `reached` Age reached during the year; `completed` Completed age on January 1. Born in 1946: 74 in 2020 (age reached) or 73 on January 1, 2020 (completed age).
- `ages.vocabulary` Wording / Vocabulaire: dropdown, default `auto`; values: `auto` Automatic (ages when the field is about age); `ages` Ages (years, median age…); `neutral` Neutral (categories, values). Neutral: tooltips, indicators and markers say "category", "median", "under 20" instead of "age", "median age", "under 20 years".

### Data labels / Étiquettes de données (`labels`)
- `labels.show` Show / Afficher: toggle, default `false`; values: true / false
- `labels.content` Content / Contenu: dropdown, default `value`; values: `value` Value; `pctTotal` Share of the total population; `pctSide` Share of its side; `valuePct` Value and share of the total
- `labels.minRow` Minimum row height (px) / Hauteur de ligne minimale (px): number, default `10`; values: 4 to 40. Labels are hidden when a row is shorter (many single ages).
- `labels.fontSize` Size / Taille: number, default `10`; values: 6 to 24
- `labels.color` Color (empty = automatic) / Couleur (vide = automatique): color, default (empty); values: hex color. Automatic: readable color depending on the background (inside bars: white or dark).
- `labels.bold` Bold / Gras: toggle, default `false`; values: true / false
- `labels.halo` Text halo / Halo autour du texte: toggle, default `true`; values: true / false
- `labels.declutter` Hide overlapping labels / Masquer les étiquettes qui se chevauchent: toggle, default `true`; values: true / false
- `labels.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `labels.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `labels.prefix` Prefix / Préfixe: text, default (empty)
- `labels.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)

### Category axis / Axe des catégories (`catAxis`)
- `catAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `catAxis.position` Position: dropdown, default `center`; values: `center` Center (between the sides); `left` Left; `right` Right
- `catAxis.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `catAxis.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `catAxis.every` Labels / Étiquettes: dropdown, default `auto`; values: `auto` Automatic (no overlap); `1` All; `5` Every 5 years; `10` Every 10 years
- `catAxis.gap` Center gap (px) / Espace au centre (px): number, default `2`; values: 0 to 40. Visible when `catAxis.position` = `left` or `right`
- `catAxis.showTitle` Axis title / Titre de l'axe: toggle, default `true`; values: true / false
- `catAxis.titleText` Text / Texte: text, default (empty). Visible when `catAxis.showTitle` = `true`
- `catAxis.birthYears` Birth years alongside ★ / Années de naissance en regard ★ ★: toggle, default `false`; values: true / false. On the right, the birth year of each age (observation year known).

### Value axis / Axe des valeurs (`valAxis`)
- `valAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `valAxis.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `valAxis.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `valAxis.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `valAxis.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `valAxis.prefix` Prefix / Préfixe: text, default (empty)
- `valAxis.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)
- `valAxis.ticks` Ticks per side (approx.) / Graduations par côté (environ): number, default `3`; values: 1 to 10
- `valAxis.showTitle` Axis title / Titre de l'axe: toggle, default `false`; values: true / false
- `valAxis.titleText` Text / Texte: text, default (empty). Visible when `valAxis.showTitle` = `true`

### Gridlines / Quadrillage (`gridlines`)
- `gridlines.vShow` Show / Afficher: toggle, default `true`; values: true / false
- `gridlines.vColor` Color (empty = style grid) / Couleur (vide = grille du style): color, default (empty); values: hex color
- `gridlines.vWidth` Width / Épaisseur: number, default `1`; values: 0.5 to 6
- `gridlines.vStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted

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

### Comparison ★ / Comparaison ★ (`comparison`)
- `comparison.show` Show / Afficher: toggle, default `true`; values: true / false. Drawn with the "Comparison ★" field, or from a frame of the play axis.
- `comparison.source` Compare with / Comparer à: dropdown, default `field`; values: `field` "Comparison" field; `first` First frame of the play axis ★; `previous` Previous frame of the play axis ★; `frame` Named frame of the play axis ★. Play axis frame: the pyramid of a fixed year stays drawn as an outline while playing.
- `comparison.frameName` Frame (e.g. 1975) / Image (ex. 1975): text, default (empty). Visible when `comparison.source` = `frame`
- `comparison.style` Drawing / Dessin: dropdown, default `outline`; values: `outline` Step outline; `ghost` Ghost bars behind; `marker` Marker at the end of each bar
- `comparison.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `comparison.width` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `comparison.lineStyle` Line style / Style du trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `comparison.label` Label / Libellé: text, default (empty)

### Generations ★ / Générations ★ (`generation`)
- `generation.follow` Follow a generation ★ / Suivre une génération ★ ★: toggle, default `false`; values: true / false. The generation born in a given year is highlighted and climbs year after year while playing.
- `generation.birthFrom` Born in (or from) / Née en (ou de): number, default `1946`; values: 1000 to 3000
- `generation.birthTo` To (0 = a single year) / Jusqu'à (0 = une seule année): number, default `0`; values: 0 to 3000
- `generation.label` Label / Libellé: text, default (empty)
- `generation.color` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `generation.marks` Markers ★ (birth years = text; separated by ;) / Repères ★ (années de naissance = texte ; séparés par ;) ★: textarea, default (empty). A band and a label at the age of each generation; they climb while playing.
- `generation.marksColor` Markers color (empty = secondary text) / Couleur des repères (vide = texte secondaire): color, default (empty); values: hex color

### Demographic indicators ★ / Indicateurs démographiques ★ (`indicators`)
- `indicators.show` Show ★ / Afficher ★ ★: toggle, default `false`; values: true / false. Computed by the visual for the current frame (numeric ages).
- `indicators.position` Position: dropdown, default `topLeft`; values: `topLeft` Top left; `topRight` Top right; `bottomLeft` Bottom left; `bottomRight` Bottom right
- `indicators.total` Total population / Population totale: toggle, default `true`; values: true / false
- `indicators.median` Median age / Âge médian: toggle, default `true`; values: true / false
- `indicators.mean` Mean age / Âge moyen: toggle, default `false`; values: true / false
- `indicators.youngShare` Share of young people / Part des jeunes: toggle, default `true`; values: true / false
- `indicators.oldShare` Share of older people / Part des âgés: toggle, default `true`; values: true / false
- `indicators.dependency` Dependency ratio / Rapport de dépendance: toggle, default `true`; values: true / false. (young + older) per 100 people of working age.
- `indicators.ageing` Ageing index / Indice de vieillissement: toggle, default `false`; values: true / false. Older people per 100 young people.
- `indicators.ratio` Side ratio (left per 100 right) / Rapport entre les côtés (gauche pour 100 droite): toggle, default `false`; values: true / false. Sex ratio when the sides are the sexes.
- `indicators.youngMax` Young: under (years) / Jeunes : moins de (ans): number, default `20`; values: 1 to 40
- `indicators.oldMin` Older: from (years) / Âgés : à partir de (ans): number, default `65`; values: 40 to 100
- `indicators.fontSize` Size / Taille: number, default `10`; values: 7 to 20

### Projection ★ (`projection`)
- `projection.show` Mark projections ★ / Marquer les projections ★ ★: toggle, default `false`; values: true / false. Play axis frames from a given year on are drawn differently and flagged "Projection".
- `projection.from` Projection from / Projection à partir de: text, default (empty)
- `projection.style` Bar drawing / Dessin des barres: dropdown, default `hatch`; values: `hatch` Hatched; `pale` Pale; `outline` Dashed outline
- `projection.label` Tag / Mention: text, default (empty)

### Small multiples / Petits multiples (`smallMultiples`)
- `smallMultiples.columns` Columns (0 = automatic) / Colonnes (0 = automatique): number, default `0`; values: 0 to 12
- `smallMultiples.gap` Spacing (px) / Espacement (px): number, default `14`; values: 0 to 60
- `smallMultiples.titleSize` Title size / Taille des titres: number, default `10`; values: 6 to 24
- `smallMultiples.titleTotal` Total in the title / Total dans le titre: toggle, default `true`; values: true / false
- `smallMultiples.border` Panel border / Cadre des panneaux: toggle, default `false`; values: true / false

### Playback ★ / Lecture ★ (`play`)
- `play.start` Frame shown on opening / Image affichée à l'ouverture: dropdown, default `last`; values: `last` The last one (most recent); `first` The first one
- `play.speed` Duration of a frame (ms) / Durée d'une image (ms): number, default `1000`; values: 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, default `false`; values: true / false
- `play.autoPlay` Play automatically on opening / Lecture automatique à l'ouverture: toggle, default `false`; values: 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, default `true`; values: true / false. Values, positions and colors move smoothly from one frame to the next.
- `play.controls` Play bar / Barre de lecture: toggle, default `true`; values: true / false
- `play.position` Bar position / Position de la barre: dropdown, default `bottom`; values: `bottom` Bottom; `top` Top. Visible when `play.controls` = `true`
- `play.ticks` Tick marks / Graduations: dropdown, default `auto`; values: `auto` Automatic; `all` Every frame; `none` None. Visible when `play.controls` = `true`
- `play.tickLabels` Tick labels / Étiquettes des graduations: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.stepButtons` Start and end buttons / Boutons début et fin: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.speedButton` Speed button / Bouton de vitesse: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.showLabel` Current value in large type / Valeur en cours en grand: toggle, default `true`; values: true / false
- `play.labelSize` Large value size / Taille de la valeur en grand: number, default `44`; values: 12 to 160. Visible when `play.showLabel` = `true`
- `play.labelPosition` Large value position / Position de la valeur en grand: dropdown, default `topRight`; values: `bottomRight` Bottom right; `topRight` Top right; `topLeft` Top left; `bottomLeft` Bottom left; `center` Center. Visible when `play.showLabel` = `true`

### Median and mean age ★ / Âges médian et moyen ★ (`ageLines`, Analytics pane)
- `ageLines.median` Median age ★ / Âge médian ★ ★: toggle, default `false`; values: true / false
- `ageLines.mean` Mean age ★ / Âge moyen ★ ★: toggle, default `false`; values: true / false
- `ageLines.per` Computed for / Calculé pour: dropdown, default `side`; values: `side` Each side; `total` Everyone
- `ageLines.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `ageLines.style` Line style / Style du trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `ageLines.width` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `ageLines.showLabel` Label with the value / Libellé avec la valeur: toggle, default `true`; values: true / false

### Interactions (`interaction`)
- `interaction.hover` Highlight on hover / Mettre en avant au survol: toggle, default `true`; values: true / false
- `interaction.dim` Dimmed items opacity (%) / Opacité des éléments estompés (%): number, default `25`; values: 5 to 80

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Gauge Plume

- The gauge Power BI never had: red, amber and green ranges, a needle, a readable target and ▲▼ gap, one gauge per category.
- Slug `gauge` · version 1.1.0.0 · GUID (`visualType`) `plumeGauge1F054613CBF04C5D8B56ED96A49BC450` · page https://plumevisuals.com/en/visuals/gauge

### What the visual does

Gauge Plume (identifier `gauge`) is a Power BI custom visual (base range, version 1.1.0.0, installed from its `.pbiviz` file; AppSource submission in preparation) that shows **one value on a scale against a target**, like the native Power BI gauge (same fields: Value, Minimum value, Maximum value, Target value) with what the native gauge lacks:

**New in version 1.1.0.0 (30/10/2026):** Free native-parity addition: target label size, color, units, decimals, prefix and suffix.

- **Nine shapes** (`gauge.type`), eight of them free: semicircle `semi` (default), `arc240`, `arc270`, full ring `ring`, `custom` angles (`gauge.startAngle`, `gauge.sweep`), horizontal `linear`, `vertical`, `bullet` chart (Stephen Few: grey qualitative bands, thin value bar, target line); `thermometer` is premium ★.
- **Color ranges** (red / amber / green): 2 or 3 ranges free, limits in % of the scale, as values, or from measures; ★ in **% of the target** (each gauge of a grid uses its own target) (the Range limits field, up to 4 measures). The fill and the value take the color of the range reached (`gauge.colorByRange`).
- **Readable min / max and target**: min and max labels under the ends of the arc, never cut; the automatic maximum is rounded above the value **and** the target (never "twice the value" unless `scale.autoMax` = `double`); the target label is placed outside the arc and the radius shrinks to keep it readable.
- **Gap to target written under the value**: "▼ 15% below target", colored favorable / unfavorable; ★ with the Comparison field, "▲ +9.4% vs Revenue LY" (`comparison.lowerIsBetter` for costs and lead times).
- **Needle** (free): tapered, line, arrow or pointer on the arc.
- **One gauge per category** (the category field): a grid of gauges with a shared or per-gauge scale, sorted by data, value, % of target or name; clicking a gauge cross-filters the page.
- **Play axis ★** (premium since the free / premium rebalancing of 2026-10-22, common Plume player): steps through periods; the needle and the arc glide from one period to the next on a scale fixed for the whole sequence.
- Values out of scale are flagged with a ▲ tip and the exact value (or the scale is extended); negative scales fill from zero.
- Premium ★: the play axis, the Comparison field, the thermometer, ranges in % of the target, the gap arc, 4 or 5 ranges, continuous gradient ranges, car-dashboard dials, the Sport needle, needles for the target, the comparison and up to 3 extra measures, a history sparkline under each gauge, needle memory (min. and max. reached) while playing.

### Free vs premium (★)

- Every feature works without a key and nothing is ever blocked. Free features never show a watermark. The default view uses no ★ feature.
- 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 (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium**.
- Free in Gauge Plume: eight shapes (all but `thermometer`), Value / Minimum / Maximum / Target fields, 2 or 3 color ranges (limits in % of the scale, as values, or a Range limits field with 1 or 2 measures), range names, limit values on the scale, the needle (shapes `classic`, `line`, `arrow`, `pointer`), ticks, the callout content (`value`, % of scale, % of target, both), the ▲▼ gap to target, one gauge per category, tooltips, dynamic formats.
- Premium features of Gauge Plume (the watermark appears only when they actually apply):
  - a field in **Play axis ★** (`play`) holding data, even a single frame;
  - a measure in **Comparison ★** (`comparison`) with `comparison.show` on (default on);
  - `gauge.type` = `thermometer` ("Thermometer ★");
  - `ranges.mode` = `target` ("In % of the target ★") with `ranges.show` on, a known target and no Range limits measure;
  - `target.gapArc` ("Gap arc ★") with a known target;
  - `ranges.count` = `4` or `5`, or 3 or 4 measures in Range limits; `ranges.gradient` ("Continuous gradient ★"), with `ranges.show` on;
  - `dial.skin` = `classic`, `sport`, `retro` or `cockpit` (arc shapes only);
  - `needle.style` = `sport` ("Sport (counterweight) ★"), with the needle shown;
  - `needle.targetNeedle` (with a target) and `needle.compareNeedle` (with a comparison); any measure in **Extra needles ★** (`needles`);
  - a field in **History (date) ★** (`trend`) with `history.show` on (default on);
  - `play.trace` ("Needle memory ★") with at least two periods in the play axis.
- 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 `gauge` 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, key accepted for 30 more days, reminders 30 and 7 days before the end). Prices per year: 39 € personal, 99 € SME, 299 € enterprise, or the catalog pack (199 € / 399 € / 1,199 € per year; tiers by number of users: personal 1–10, SME 11–200, enterprise more than 200).

### Expected data shape

One number per gauge: measures, evaluated for the current filters (and for each category value when the category field is used).

| Region (`category`) | Revenue (`value`) | Target (`target`) | Revenue LY (`comparison`) |
|---|---|---|---|
| North | 1,412,000 | 1,350,000 | 1,301,000 |
| South | 1,098,000 | 1,180,000 | 1,012,000 |

- **One gauge per… (category)** (`category`, « Une jauge par… (catégorie) », one column): one gauge per value, in a grid (up to `layout.maxGauges`, 60 by default; "+N" beyond).
- **Value** (`value`, « Valeur », one measure, required).
- **Minimum value**, **Maximum value** (`min`, `max`, one measure each): the scale; otherwise `scale.min` / `scale.max` (text), otherwise 0 and the automatic maximum. Field > fixed value > automatic. A percentage measure (format %) with values up to 1 gets a 0–100% scale.
- **Target value** (`target`, « Valeur cible »): marker, label, gap ▲▼; otherwise `target.value` (fixed).
- **Comparison (previous year…) ★** (`comparison`, « Comparaison (année précédente…) ★ »): change ▲▼ under the value and a small hollow marker.
- **Range limits** (`thresholds`, « Limites des plages », up to 4 measures): the limits between ranges, in value units; they replace `ranges.mode`, `ranges.count` and `ranges.t1`–`t4`.
- **Extra needles ★** (`needles`, up to 3 measures): one needle each, with a needle legend.
- **History (date) ★** (`trend`, one column): the gauge shows the **last period**; a sparkline under the gauge shows every period.
- **Play axis ★** (`play`, « Axe de lecture ★ », one column): one frame per value.
- **Tooltips** (`tooltips`) and **Dynamic format** (`format`, see below).
- Volume: windows of 30,000 rows, more fetched with `fetchMoreData` up to 100,000 rows (a warning beyond).

### DAX recipes

```dax
Revenue = SUM ( Sales[Amount] )
Target = SUM ( Sales[Target amount] )
Revenue LY = CALCULATE ( [Revenue], SAMEPERIODLASTYEAR ( 'Date'[Date] ) )

// A rate: return 0.72 for 72% and give the measure the % format (scale 0–100% automatically)
Satisfaction = DIVIDE ( [Satisfied answers], [Answers] )

// Range limits from measures (drop them into Range limits, in this order)
Low limit = [Target] * 0.9
High limit = [Target]

// A scale ending at 120% of the target
Scale max = [Target] * 1.2

// Fill color driven by DAX: rename the measure gauge.fillColor in Dynamic format
Color versus target = IF ( [Revenue] >= [Target], "#2E7D4F", "#2A6F97" )
```

Do not put a column in Value without checking its summarization (sum by default). For a lead time or a cost, choose `ranges.colors` = `greenRed` (and, with a Comparison ★ measure, turn on `comparison.lowerIsBetter`).

### Interactions with the report

- Click a gauge (with the category field): cross-filter on that category; Ctrl + click adds one; click on an empty spot clears. Cross-highlighting from other visuals dims the gauges without highlighted values and shows the highlighted part. Context menu everywhere (right-click on a gauge or on the background).
- Hover: Power BI tooltip with value, target, % of target, comparison and change, minimum, maximum, range reached and the Tooltips measures; report-page tooltips are supported.
- Keyboard: Tab to the gauges, arrows to move, Enter or Space selects, Esc clears; on the play bar, Space plays or pauses, arrows step, Home / End. High contrast, ARIA labels ("Revenue: 1.53M, target 1.8M, 85% of the target…"), French and English.
- Animation: the arc and the needle glide to the new value (650 ms) after a filter; reduced when `style.animate` is off or the system asks for reduced motion.

### Dynamic formats

- **fx button** (Power BI conditional formatting) on colors and texts of the Format pane.
- **"Dynamic format" well** (`format`): measures renamed `card.setting` (e.g. `gauge.fillColor`, `gauge.type`, `ranges.t1`, `target.labelText`, `title.text`) drive any setting and win over the fixed value. Driving a ★ setting by DAX still shows the watermark without a key.

```dax
// renamed gauge.type
Gauge type = IF ( HASONEVALUE ( Sales[Region] ), "semi", "bullet" )
// renamed ranges.names
Range names = "Watch;Close;Reached"
```

### Format pane: option IDs

- Card order: `license`, `style`, `gauge`, `scale`, `ranges`, `needle`, `dial`, `callout`, `target`, `comparison`, `layout`, `history`, `play`, `tooltip`, `interaction`, then `title`, `source`, `container`, `texts`. Cards whose field is empty (Several gauges, History, Playback, Comparison) and settings replaced by a field (`target.value`, `scale.min`, `scale.max`, range limits) are hidden. Format pane in version 1.1.0.0 (30/10/2026), top to bottom: `license`, `style`, `layout`, `gauge`, `scale`, `ranges`, `needle`, `dial`, `callout`, `target`, `comparison`, `history`, `play`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- `gauge`: `type` (`semi` | `arc240` | `arc270` | `ring` | `custom` | `linear` | `vertical` | `bullet` | `thermometer` ★), `startAngle` (−360–360, −120, 0 = top), `sweep` (20–360, 240), `thickness` (3–80 % of the radius or height, 22), `rounded`, `trackColor`, `fillShow`, `fillColor` (empty = style data color), `colorByRange` (true), `fromZero` (true), `overflow` (`mark` | `extend` | `none`).
- `scale`: `min`, `max` (text, empty = automatic), `autoMax` (`nice` | `double` | `target`), `reverse`, `minMax` (true), `ticks` (false), `tickCount` (2–20, 5), `minor` (0–9, 4), `tickLabels`, `fontSize` (9), `color`, `tickUnits`, `tickDecimals`, `tickPrefix`, `tickSuffix`.
- `ranges`: `show` (false), `mode` (`percent` | `target` ★ | `values`), `count` (`2` | `3` | `4` ★ | `5` ★), `t1`–`t4` (50, 80, 90, 95), `colors` (`redGreen` | `greenRed` | `style` | `custom`), `c1`–`c5`, `gradient` ★, `display` (`track` faded in the track | `band` thin outer band | `full` solid speedometer), `opacity` (5–100, 28), `names` (separated by `;`), `showName` (true), `limitLabels`.
- `needle`: `show` (false), `style` (`classic` | `line` | `arrow` | `pointer` | `sport` ★), `color`, `width` (1–16, 4), `length` (40–115 % of the radius, 92), `hub`, `targetNeedle` ★, `compareNeedle` ★, `legend` (true).
- `dial`: `skin` (`none` | `classic` ★ | `sport` ★ | `retro` ★ | `cockpit` ★), `faceColor`.
- `callout`: `show`, `content` (`value` | `pctScale` | `pctTarget` | `valuePct`), `autoSize` (true), `fontSize` (8–120, 32: maximum when automatic), `color` (empty = range reached or text), `bold`, `units`, `decimals` (−1 = auto), `prefix`, `suffix`, `showLabel` (false), `label`, `labelSize` (11).
- `target`: `show`, `value` (fixed, text), `marker` (`line` | `triangle` | `dot`), `color`, `label`, `labelContent` (`nameValue` | `value` | `name`), `labelText`, `gap` (▲▼ under the value, true), `gapArc` ★ (false).
- `comparison` (card « Comparaison ★ », shown with the Comparison ★ field): `show`, `label` (default "vs <measure name>"), `content` (`pct` | `abs` | `both`), `marker`, `lowerIsBetter`, `posColor` (#2E7D4F), `negColor` (#C0392B).
- `layout`: `columns` (0 = automatic, up to 12), `sort` (`data` | `valueDesc` | `valueAsc` | `pctDesc` | `name`), `sharedScale` (true), `labelPosition` (`top` | `bottom` | `none`), `labelSize`, `gap` (12 px), `maxGauges` (1–200, 60).
- `history`: `show` ★ (true), `kind` (`area` | `line` | `columns`), `height` (10–50 % of the gauge, 22), `color`, `targetLine`, `lastDot`.
- `play` (common player): `start` (`last` by default), `speed` (ms per frame, 1000), `loop`, `autoPlay`, `transition`, `controls`, `position`, `ticks`, `tickLabels`, `stepButtons`, `speedButton`, `showLabel` (false in Gauge Plume), `labelSize` (32), `labelPosition` (`topLeft`), `trace` ★.
- `tooltip`: `show`, `pct`, `range`. `interaction`: `dim`.

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. Booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes, colors in `solid.color`.

```json
{
  "visualType": "plumeGauge1F054613CBF04C5D8B56ED96A49BC450",
  "query": {
    "queryState": {
      "category":   { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Region" } }, "queryRef": "Sales.Region", "nativeQueryRef": "Region" } ] },
      "value":      { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Revenue" } }, "queryRef": "Sales.Revenue", "nativeQueryRef": "Revenue" } ] },
      "target":     { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Target" } }, "queryRef": "Sales.Target", "nativeQueryRef": "Target" } ] },
      "comparison": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Revenue LY" } }, "queryRef": "Sales.Revenue LY", "nativeQueryRef": "Revenue LY" } ] }
    }
  },
  "objects": {
    "gauge":  [ { "properties": { "type": { "expr": { "Literal": { "Value": "'arc240'" } } } } } ],
    "ranges": [ { "properties": { "show": { "expr": { "Literal": { "Value": "true" } } },
                                  "mode": { "expr": { "Literal": { "Value": "'target'" } } },
                                  "t1":   { "expr": { "Literal": { "Value": "90D" } } },
                                  "t2":   { "expr": { "Literal": { "Value": "100D" } } } } } ],
    "needle": [ { "properties": { "show": { "expr": { "Literal": { "Value": "true" } } } } } ],
    "layout": [ { "properties": { "sort": { "expr": { "Literal": { "Value": "'pctDesc'" } } } } } ]
  }
}
```

The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from the `.pbiviz` file).

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`. The style sets the fill color, the font and the track; `minimal` draws a thinner arc, rounded styles round the ends, `cockpit`, `terminal` and `blueprint` show tick marks. Colors set in the Gauge, Color ranges and Needle cards win over the style.
- `style.themeJson` (Theme JSON ★): a JSON theme as plain text (format v2 with optional `extends` and groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`). Full reference: https://plumevisuals.com/ai/tutorials/en/themes-json.md.

### Common pitfalls

- "Add a measure in "Value"": only the target or the comparison is placed.
- The gauge is almost empty: the scale is too wide; set `scale.max`, drop a measure into Maximum value, or `scale.autoMax` = `target`.
- "140%" instead of 72%: the rate measure returns 72 instead of 0.72.
- The ranges ignore the target: `ranges.mode` is `percent` (of the scale), or there is no target (the visual then falls back to % of the scale).
- The settings Range limits / Number of ranges disappeared: a measure is in the Range limits field, it decides.
- The gauge shows December only: a field is in History (date) ★; the gauge shows the last period by design. For a total, remove the field or use the Play axis ★.
- A ▲ tip at the end of the arc: the value is above the maximum (`gauge.overflow`).
- Watermark visible: a Play axis ★ field, a Comparison ★ measure, the thermometer, ranges in % of the target, the gap arc, 4 or 5 ranges (or 3–4 limit measures), gradient ranges, a dial skin, the Sport needle, target / comparison / extra needles, History with `history.show`, needle memory, a ★ style or a theme JSON, without a valid key.
- The visual makes no network request: data and license key stay in the report; no R or Python.

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

A logarithmic scale, a custom image or SVG as the dial face, several values stacked in one gauge (concentric rings, multi-series radial bars), a different measure per gauge of the grid (every gauge uses the same Value measure split by the category), a drill-down hierarchy in the category, a "liquid fill" or shape-filling gauge (that is Shape Gauge Plume), dragging the needle or the target to change a value (what-if input), exporting the gauge as an image, sounds or blinking alarms, live data feeds (the visual only shows the report's data).

## Gauge Plume: data fields

- `category` One gauge per… (category) / Une jauge par… (catégorie) (column, 1 max): One gauge for each value of the field (region, product, sales person…), side by side
- `value` Value / Valeur (measure, 1 max): The measure shown by the gauge
- `min` Minimum value / Valeur minimale (measure, 1 max): Start of the scale (otherwise 0 or Format › Scale › Minimum)
- `max` Maximum value / Valeur maximale (measure, 1 max): End of the scale (otherwise rounded above the value and the target, or Format › Scale › Maximum)
- `target` Target value / Valeur cible (measure, 1 max): Goal: a marker and its label on the gauge
- `comparison` Comparison (previous year…) ★ / Comparaison (année précédente…) ★ ★ (measure, 1 max): Premium: value to compare with: change ▲▼ under the value and a small marker on the gauge
- `thresholds` Range limits / Limites des plages (measure, 4 max): Up to 4 measures: the limits between the color ranges (red / orange / green…)
- `needles` Extra needles ★ / Aiguilles supplémentaires ★ ★ (measure, 3 max): Up to 3 measures, each one drawn as its own needle (forecast, budget, best month…)
- `trend` History (date) ★ / Historique (date) ★ ★ (column, 1 max): A date or period: a sparkline of the value under each gauge; the gauge shows the last period
- `play` Play axis ★ / Axe de lecture ★ ★ (column, 1 max): Premium: a date, a year or an ordered category: the needle and the arc move from one value to the next (play button)
- `tooltips` Tooltips / Infobulles (measure, several max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Gauge Plume: Format pane options (191)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Layout / Disposition (`layout`)
- `layout.columns` Columns (0 = automatic) / Colonnes (0 = automatique): number, default `0`; values: 0 to 12
- `layout.sort` Order / Ordre: dropdown, default `data`; values: `data` Data order; `valueDesc` Value, descending; `valueAsc` Value, ascending; `pctDesc` % of target, descending; `name` Name (A → Z)
- `layout.sharedScale` Same scale for every gauge / Même échelle pour toutes les jauges: toggle, default `true`; values: true / false. Off: each gauge computes its own automatic maximum (the Minimum / Maximum fields always apply per gauge).
- `layout.labelPosition` Category name / Nom de la catégorie: dropdown, default `top`; values: `top` Above; `bottom` Below; `none` Hidden
- `layout.labelSize` Name size / Taille du nom: number, default `11`; values: 6 to 30
- `layout.gap` Space between gauges (px) / Espace entre les jauges (px): number, default `12`; values: 0 to 60
- `layout.maxGauges` Maximum number of gauges / Nombre maximal de jauges: number, default `60`; values: 1 to 200

### Gauge / Jauge (`gauge`)
- `gauge.type` Gauge type / Type de jauge: dropdown, default `semi`; values: `semi` Semicircle (180°); `arc240` Arc (240°); `arc270` Arc (270°); `ring` Ring (full circle); `custom` Arc: custom angles; `linear` Horizontal linear; `vertical` Vertical linear; `bullet` Bullet chart; `thermometer` Thermometer ★
- `gauge.startAngle` Start angle (°, 0 = top) / Angle de départ (°, 0 = en haut): number, default `-120`; values: -360 to 360. Visible when `gauge.type` = `custom`
- `gauge.sweep` Arc sweep (°) / Ouverture de l'arc (°): number, default `240`; values: 20 to 360. Visible when `gauge.type` = `custom`
- `gauge.thickness` Thickness (% of radius or height) / Épaisseur (% du rayon ou de la hauteur): number, default `22`; values: 3 to 80
- `gauge.rounded` Rounded ends / Extrémités arrondies: toggle, default `false`; values: true / false
- `gauge.trackColor` Track color (empty = grid) / Couleur de la piste (vide = grille): color, default (empty); values: hex color
- `gauge.fillShow` Fill up to the value / Remplir jusqu'à la valeur: toggle, default `true`; values: true / false
- `gauge.fillColor` Color (empty = style data color) / Couleur (vide = couleur des données du style): color, default (empty); values: hex color. Visible when `gauge.fillShow` = `true`
- `gauge.colorByRange` Color of the range reached / Couleur de la plage atteinte: toggle, default `true`; values: true / false. With color ranges: the fill and the value take the color of the range where the value is.
- `gauge.fromZero` Fill from zero (negative scale) / Remplir depuis zéro (échelle négative): toggle, default `true`; values: true / false. When the scale crosses zero, the fill starts at zero: a negative value fills to the left.
- `gauge.overflow` Value out of scale / Valeur hors de l'échelle: dropdown, default `mark`; values: `mark` Flag it (▲ tip and exact value); `extend` Extend the scale; `none` Stop at the edge

### Scale / Échelle (`scale`)
- `scale.min` Minimum (without field) / Minimum (sans champ): text, default (empty)
- `scale.max` Maximum (without field) / Maximum (sans champ): text, default (empty)
- `scale.autoMax` Automatic maximum / Maximum automatique: dropdown, default `nice`; values: `nice` Rounded above the value and the target; `double` Twice the value (like Power BI); `target` The target (100% = target)
- `scale.reverse` Reverse direction / Sens inversé: toggle, default `false`; values: true / false
- `scale.minMax` Minimum and maximum labels / Étiquettes du minimum et du maximum: toggle, default `true`; values: true / false
- `scale.ticks` Tick marks / Graduations: toggle, default `false`; values: true / false
- `scale.tickCount` Number of major ticks / Nombre de graduations principales: number, default `5`; values: 2 to 20. Visible when `scale.ticks` = `true`
- `scale.minor` Minor ticks between two major ones / Graduations secondaires entre deux principales: number, default `4`; values: 0 to 9. Visible when `scale.ticks` = `true`
- `scale.tickLabels` Tick labels / Étiquettes des graduations: toggle, default `true`; values: true / false. Visible when `scale.ticks` = `true`
- `scale.fontSize` Text size / Taille du texte: number, default `9`; values: 6 to 24
- `scale.color` Color (empty = secondary) / Couleur (vide = secondaire): color, default (empty); values: hex color
- `scale.tickUnits` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `scale.tickDecimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `scale.tickPrefix` Prefix / Préfixe: text, default (empty)
- `scale.tickSuffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)

### Color ranges / Plages de couleurs (`ranges`)
- `ranges.show` Show / Afficher: toggle, default `false`; values: true / false
- `ranges.mode` Range limits / Limites des plages: dropdown, default `percent`; values: `percent` In % of the scale; `target` In % of the target ★; `values` Values. Ignored when the Range limits field is filled (one measure per limit). % of the target: each gauge of a grid uses its own target.
- `ranges.count` Number of ranges / Nombre de plages: dropdown, default `3`; values: `2` 2; `3` 3; `4` 4 ★; `5` 5 ★
- `ranges.t1` Limit 1 / Limite 1: number, default `50`
- `ranges.t2` Limit 2 / Limite 2: number, default `80`. Visible when `ranges.count` = `3` or `4` or `5`
- `ranges.t3` Limit 3 / Limite 3: number, default `90`. Visible when `ranges.count` = `4` or `5`
- `ranges.t4` Limit 4 / Limite 4: number, default `95`. Visible when `ranges.count` = `5`
- `ranges.colors` Colors / Couleurs: dropdown, default `redGreen`; values: `redGreen` Red → green (high is good); `greenRed` Green → red (low is good); `style` Style gradient; `custom` Custom
- `ranges.c1` Range 1 color / Couleur de la plage 1: color, default (empty); values: hex color. Visible when `ranges.colors` = `custom`
- `ranges.c2` Range 2 color / Couleur de la plage 2: color, default (empty); values: hex color. Visible when `ranges.colors` = `custom`
- `ranges.c3` Range 3 color / Couleur de la plage 3: color, default (empty); values: hex color. Visible when `ranges.colors` = `custom`
- `ranges.c4` Range 4 color / Couleur de la plage 4: color, default (empty); values: hex color. Visible when `ranges.colors` = `custom`
- `ranges.c5` Range 5 color / Couleur de la plage 5: color, default (empty); values: hex color. Visible when `ranges.colors` = `custom`
- `ranges.gradient` Continuous gradient ★ / Dégradé continu ★ ★: toggle, default `false`; values: true / false. The colors blend smoothly along the scale instead of solid bands.
- `ranges.display` Range display / Affichage des plages: dropdown, default `track`; values: `track` In the track, faded; `band` Thin outer band; `full` Solid (speedometer)
- `ranges.opacity` Faded ranges opacity (%) / Opacité des plages atténuées (%): number, default `28`; values: 5 to 100. Visible when `ranges.display` = `track`
- `ranges.names` Range names (separated by ;) / Noms des plages (séparés par ;): text, default (empty)
- `ranges.showName` Write the name of the range reached / Écrire le nom de la plage atteinte: toggle, default `true`; values: true / false
- `ranges.limitLabels` Limit values on the scale / Valeurs des limites sur l'échelle: toggle, default `false`; values: true / false

### Needle / Aiguille (`needle`)
- `needle.show` Show / Afficher: toggle, default `false`; values: true / false
- `needle.style` Shape / Forme: dropdown, default `classic`; values: `classic` Tapered; `line` Line; `arrow` Arrow; `pointer` Pointer on the arc; `sport` Sport (counterweight) ★
- `needle.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `needle.width` Width (px) / Largeur (px): number, default `4`; values: 1 to 16
- `needle.length` Length (% of radius) / Longueur (% du rayon): number, default `92`; values: 40 to 115
- `needle.hub` Hub / Moyeu: toggle, default `true`; values: true / false
- `needle.targetNeedle` Needle for the target ★ / Aiguille pour la cible ★ ★: toggle, default `false`; values: true / false
- `needle.compareNeedle` Needle for the comparison ★ / Aiguille pour la comparaison ★ ★: toggle, default `false`; values: true / false
- `needle.legend` Needle legend (several needles) / Légende des aiguilles (plusieurs aiguilles): toggle, default `true`; values: true / false

### Dial / Cadran (`dial`)
- `dial.skin` Skin / Habillage: dropdown, default `none`; values: `none` None; `classic` Classic (meter) ★; `sport` Sport (dashboard) ★; `retro` Retro (pressure gauge) ★; `cockpit` Cockpit (screen) ★. Car-dashboard faces for the arc gauges: face, bezel, ticks and needle drawn in the visual.
- `dial.faceColor` Face color (empty = skin color) / Couleur du fond (vide = celle de l'habillage): color, default (empty); values: hex color. Visible when `dial.skin` = `classic` or `sport` or `retro` or `cockpit`

### Callout value / Valeur centrale (`callout`)
- `callout.show` Show / Afficher: toggle, default `true`; values: true / false
- `callout.content` Content / Contenu: dropdown, default `value`; values: `value` Value; `pctScale` % of the scale; `pctTarget` % of the target; `valuePct` Value and % of the target
- `callout.autoSize` Automatic size / Taille automatique: toggle, default `true`; values: true / false
- `callout.fontSize` Size (maximum when automatic) / Taille (maximum en automatique): number, default `32`; values: 8 to 120
- `callout.color` Color (empty = range reached or text) / Couleur (vide = plage atteinte ou texte): color, default (empty); values: hex color
- `callout.bold` Bold / Gras: toggle, default `true`; values: true / false
- `callout.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `callout.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `callout.prefix` Prefix / Préfixe: text, default (empty)
- `callout.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)
- `callout.showLabel` Label under the value / Libellé sous la valeur: toggle, default `false`; values: true / false
- `callout.label` Label text / Texte du libellé: text, default (empty). Visible when `callout.showLabel` = `true`
- `callout.labelSize` Label size / Taille du libellé: number, default `11`; values: 6 to 30

### Target / Objectif (`target`)
- `target.show` Show / Afficher: toggle, default `true`; values: true / false
- `target.value` Fixed value (without field) / Valeur fixe (sans champ): text, default (empty)
- `target.marker` Marker / Repère: dropdown, default `line`; values: `line` Line; `triangle` Triangle; `dot` Dot
- `target.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `target.label` Label / Étiquette: toggle, default `true`; values: true / false
- `target.labelContent` Label content / Contenu de l'étiquette: dropdown, default `nameValue`; values: `nameValue` Name and value; `value` Value; `name` Name. Visible when `target.label` = `true`
- `target.labelText` Target name / Nom de la cible: text, default (empty). Visible when `target.label` = `true`. Empty: the name of the “Target value” field (“Target” for a fixed value). The gap under the value keeps neutral words (“below target”).
- `target.labelSize` Label size / Taille de l'étiquette: number, default `9`; values: 6 to 30. Visible when `target.label` = `true`
- `target.labelColor` Label color (empty = target color) / Couleur de l'étiquette (vide = couleur de la cible): color, default (empty); values: hex color. Visible when `target.label` = `true`
- `target.labelUnits` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions. Visible when `target.label` = `true`
- `target.labelDecimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6. Visible when `target.label` = `true`
- `target.labelPrefix` Prefix / Préfixe: text, default (empty). Visible when `target.label` = `true`
- `target.labelSuffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty). Visible when `target.label` = `true`
- `target.gap` Gap to target under the value (▲▼) / Écart à la cible sous la valeur (▲▼): toggle, default `true`; values: true / false
- `target.gapArc` Gap arc between value and target ★ / Arc d'écart entre la valeur et la cible ★ ★: toggle, default `false`; values: true / false. Paints the part of the scale between the value and the target: favorable color when the target is beaten, unfavorable otherwise.

### Comparison ★ / Comparaison ★ (`comparison`)
- `comparison.show` Show / Afficher: toggle, default `true`; values: true / false
- `comparison.label` Label / Libellé: text, default (empty)
- `comparison.content` Change shown / Écart affiché: dropdown, default `pct`; values: `pct` In %; `abs` As a value; `both` Value and %
- `comparison.marker` Marker on the gauge / Repère sur la jauge: toggle, default `true`; values: true / false
- `comparison.lowerIsBetter` A decrease is favorable / Une baisse est favorable: toggle, default `false`; values: true / false
- `comparison.posColor` Favorable: color, default `#2E7D4F`; values: hex color
- `comparison.negColor` Unfavorable / Défavorable: color, default `#C0392B`; values: hex color

### History (sparkline) / Historique (mini-courbe) (`history`)
- `history.show` Sparkline under the gauge ★ / Mini-courbe sous la jauge ★ ★: toggle, default `true`; values: true / false. Needs the History (date) field. The gauge shows the last period; the sparkline shows every period.
- `history.kind` Shape / Forme: dropdown, default `area`; values: `area` Area; `line` Line; `columns` Columns
- `history.height` Height (% of the gauge) / Hauteur (% de la jauge): number, default `22`; values: 10 to 50
- `history.color` Color (empty = fill) / Couleur (vide = remplissage): color, default (empty); values: hex color
- `history.targetLine` Target line / Ligne de la cible: toggle, default `true`; values: true / false
- `history.lastDot` Dot on the last period / Point sur la dernière période: toggle, default `true`; values: true / false

### Playback ★ / Lecture ★ (`play`)
- `play.start` Frame shown on opening / Image affichée à l'ouverture: dropdown, default `last`; values: `last` The last one (most recent); `first` The first one
- `play.speed` Duration of a frame (ms) / Durée d'une image (ms): number, default `1000`; values: 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, default `false`; values: true / false
- `play.autoPlay` Play automatically on opening / Lecture automatique à l'ouverture: toggle, default `false`; values: 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, default `true`; values: true / false. Values, positions and colors move smoothly from one frame to the next.
- `play.controls` Play bar / Barre de lecture: toggle, default `true`; values: true / false
- `play.position` Bar position / Position de la barre: dropdown, default `bottom`; values: `bottom` Bottom; `top` Top. Visible when `play.controls` = `true`
- `play.ticks` Tick marks / Graduations: dropdown, default `auto`; values: `auto` Automatic; `all` Every frame; `none` None. Visible when `play.controls` = `true`
- `play.tickLabels` Tick labels / Étiquettes des graduations: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.stepButtons` Start and end buttons / Boutons début et fin: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.speedButton` Speed button / Bouton de vitesse: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.showLabel` Current value in large type / Valeur en cours en grand: toggle, default `false`; values: true / false
- `play.labelSize` Large value size / Taille de la valeur en grand: number, default `32`; values: 12 to 160. Visible when `play.showLabel` = `true`
- `play.labelPosition` Large value position / Position de la valeur en grand: dropdown, default `topLeft`; values: `bottomRight` Bottom right; `topRight` Top right; `topLeft` Top left; `bottomLeft` Bottom left; `center` Center. Visible when `play.showLabel` = `true`
- `play.trace` Needle memory (min. and max. reached) ★ / Mémoire de l'aiguille (min. et max. atteints) ★ ★: toggle, default `false`; values: true / false. While playing, the part of the scale already reached is drawn and the highest and lowest values are marked.

### Interactions (`interaction`)
- `interaction.dim` Dimmed items opacity (%) / Opacité des éléments estompés (%): number, default `25`; values: 5 to 80

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).
- `tooltip.pct` % of the target / % de la cible: toggle, default `true`; values: true / false. Visible when `tooltip.show` = `true`
- `tooltip.range` Range reached / Plage atteinte: toggle, default `true`; values: true / false. Visible when `tooltip.show` = `true`

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Waffle Plume

- A percentage, parts or a headcount as cells or pictograms, with the shape of your choice.
- Slug `waffle` · version 1.1.0.0 · GUID (`visualType`) `plumeWaffleC707BF468E704234BE22DABB0FE758B2` · page https://plumevisuals.com/en/visuals/waffle

### What the visual does

Waffle Plume (identifier `waffle`) is a Power BI custom visual (version 1.1.0.0, installed from its `.pbiviz` file; AppSource submission in preparation) that draws **waffle charts and pictogram charts**: a grid of cells where each cell is a share of a whole, or a number of units. Power BI Desktop has no native waffle chart.

**New in version 1.1.0.0 (30/10/2026):** Free native-parity additions: adjustable category labels (row names) and a large value in Shares mode.

- **Three modes** (`layout.mode`): `percent` (one waffle per category or per measure, the percentage written in large type next to it), `parts` (every category colors its share of one waffle; rounding by largest remainder so the total is always the full grid), `units` ★ (one row of cells per category, 1 cell = N units, isotype style, with a key "= N"). `auto` (default) = `parts` with a Category or several measures, else `percent`.
- **Correct percentages** (`layout.scale`, default `auto`): with the Total field, value ÷ total; a measure formatted as % or values between 0 and 1 are read as ratios; several categories give their share of the sum; a single value ≤ 100 is read in points; otherwise the largest value = 100%. Explicit choices: `share`, `ratio`, `points`, `max`. Above 100%: the waffle is full, the headline shows the real value, the tooltip says "exceeds 100%".
- **Grid**: 1 to 50 rows and columns (10 × 10 by default), six fill orders (`rows`, `rowsBottom`, `columns`, `columnsBottom`, and the premium `snake` ★, `snakeBottom` ★), spacing, corner radius.
- **Shapes** (Savi's idea): 153 shapes of the Plume library (22 free), one shape per category in the Data colors card, a pasted SVG ★ or one SVG icon per category returned by a measure ★. SVG is sanitized (allow-list) and never loaded from the web.
- **Play axis ★** (premium since 10/22/2026, shared Plume player): one frame per value of the Play axis field; from one frame to the next the cells that change switch one by one in fill order (they fill, or empty in reverse order) and the headline counts; grid size and colors are computed over all frames.
- Cell-by-cell reveal (or fade) when data changes, never with reduced motion or on a dashboard tile.

### 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, "Follow report theme" and all custom colors are **free**; every other `style.preset`, the other gradient palettes and `style.themeJson` are **premium**.
- Free in Waffle Plume: the `percent` and `parts` modes (and `auto`), every scale rule, Total field, grid size, the four fill orders `rows`, `rowsBottom`, `columns`, `columnsBottom`, spacing, radius, the **22 free shapes** (`circle`, `square`, `roundedSquare`, `rectangle`, `triangle`, `diamond`, `hexagon`, `star`, `heart`, `cloud`, `drop`, `bubble`, `arrow`, `person`, `house`, `barrel`, `bottle`, `glass`, `wineGlass`, `thermometer`, `battery`, `batteryVertical`) also per category, rounding (`round`, `floor`), empty cells, headline (`pct` or `value`), legend, sorting, Others grouping, one waffle per category or per measure, reveal, tooltips, selection, highlighting.
- Premium features of Waffle Plume:
  - the `play` role ("Play axis ★", « Axe de lecture ★ ») as soon as it holds a value, and its "Playback ★" card (rebalancing of 10/22/2026);
  - `layout.mode` = `units` (Units mode, pictograms);
  - `layout.order` = `snake` or `snakeBottom`;
  - `headline.content` = `pctValue` or `valueTotal`, when the headline is shown in Percentage mode (no effect, so no watermark, in Parts mode);
  - any other shape (131), in `cells.shape` or per category (`dataColors.itemShape`);
  - `cells.shape` = `svg` with a valid `cells.svg`; the `icon` role ("SVG icon ★") with a valid SVG;
  - `cells.partial` = `partial` (partly filled last cell, a cell can be shared by two categories);
  - the `target` role ("Target ★") while `target.show` is on;
  - the `multiples` role ("Small multiples ★").
- 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 `waffle` 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, key accepted for 30 more days, reminders 30 and 7 days before the end). Prices: 39 € personal, 99 € SME, 299 € enterprise per year, or the catalog pack (199 € / 399 € / 1,199 € per year; tiers by number of users: personal 1–10, SME 11–200, enterprise more than 200).

### Expected data shape

One row per category (and per year, region… when those fields are used), with measures.

| Category (`category`) | Value (`value`) | Total (`total`) |
|---|---|---|
| Store | 420,000 | 1,000,000 |
| Web | 310,000 | 1,000,000 |

- **Category** (`category`, « Catégorie », one column): the parts. Beyond `layout.maxItems` (10) the smallest are grouped in "Others" (`layout.othersLabel`).
- **Value** (`value`, « Valeur », 1 to 6 measures): without Category, each measure is a part (e.g. Done, In progress, To do); with Category and several measures, one waffle per measure. Without any measure, rows are counted. Negative values count as zero (warning icon).
- **Total (100%)** (`total`, « Total (100 %) », one measure): denominator; in `parts` mode the largest total of a waffle is used.
- **Target ★** (`target`, « Objectif ★ », one measure, same unit as Value): target cell circled, missing cells dashed (`target.style` = `ring` | `marker`), "Target: 60%" under the headline (`target.label`).
- **Small multiples ★** (`multiples`, « Petits multiples ★ », one column): one waffle per value (48 at most), each with the parts of Category; selection = category + panel.
- **SVG icon ★** (`icon`, « Icône SVG ★ », one text measure): an SVG (markup, data URI or path `d`) per category.
- **Play axis ★** (`play`, « Axe de lecture ★ », one column): year, date or ordered text; premium (watermark without a key).
- **Tooltips** (`tooltips`, up to 5 measures) and **Dynamic format** (`format`, see below).
- Volume of data: windows of 30,000 rows, more fetched with `fetchMoreData` up to 1,000,000 rows; 100,004 rows render in less than 3 seconds (automated test).

### DAX recipes

```dax
// A rate: formatted as a percentage, it fills that many cells out of 100
Success rate = DIVIDE ( [Passed], [Enrolled] )

// Share of one category against all categories
Web share = DIVIDE ( CALCULATE ( [Revenue], Sales[Channel] = "Web" ), CALCULATE ( [Revenue], ALL ( Sales[Channel] ) ) )

// Three parts of a project (three measures in Value, nothing in Category)
Done = DIVIDE ( CALCULATE ( COUNTROWS ( Tasks ), Tasks[Status] = "Done" ), COUNTROWS ( Tasks ) )

// SVG icon ★ per category (single quotes inside the SVG)
Channel icon = SWITCH ( SELECTEDVALUE ( Sales[Channel] ),
    "Store", "<svg viewBox='0 0 24 24'><path d='M3 10L12 3L21 10V21H15V14H9V21H3Z'/></svg>",
    BLANK () )
```

### Interactions with the report

- Click a cell: cross-filter on its category (and its panel with small multiples); Ctrl for several; click the empty space to clear; click a legend entry. Cross-highlighting from other visuals keeps the highlighted share of each category in full color, the rest dimmed. Context menu everywhere (cells, empty cells, empty space, headline, legend, landing page).
- Hover: the category stays bright in every waffle (`interaction.hover`); Power BI tooltip with category, value, share, "31 of 100" cells, total, target and variance, Others members, Tooltips measures; report-page tooltips are supported.
- Keyboard: Tab, arrows (one stop per category and per waffle), Home / End, Enter selects, Esc clears; play bar: Space, arrows, Home / End. High contrast (filled and outlined cells alternate, empty cells dashed, host colors), ARIA labels, French and English.
- The visual never saves anything with persistProperties; the current frame of the play axis is session state.

### Dynamic formats

- **fx button** on colors and texts of the Format pane.
- **"Dynamic format" well** (`format`): measures renamed `card.setting` (e.g. `layout.mode`, `cells.shape`, `title.text`) 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`, `layout`, `cells`, `headline`, `target`, `legend`, `play`, `interaction`, then `title`, `source`, `container`, `texts`. Format pane in version 1.1.0.0 (30/10/2026), top to bottom: `license`, `style`, `dataColors`, `layout`, `cells`, `headline`, `categoryLabels`, `target`, `legend`, `play`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- `dataColors`: `mode` (`category` | `single`), `single`, per category `fill` and `itemShape` (`inherit` or a shape ID, or `svg`).
- `layout`: `mode` (`auto` | `percent` | `parts` | `units` ★), `scale` (`auto` | `share` | `ratio` | `points` | `max`), `rows` (1–50, 10), `columns` (1–50, 10), `order` (`rows` | `rowsBottom` | `columns` | `columnsBottom` | `snake` ★ | `snakeBottom` ★), `unitValue` (0 = automatic round number, at most 20 cells for the largest category), `unitKey`, `gap` (0–60 %, 16), `sort` (`value` | `valueAsc` | `alpha` | `data`), `maxItems` (2–30, 10), `othersLabel`, `perRow` (0–12, 0 = automatic), `panelTitles`, `panelTitleSize` (11).
- `cells`: `shape` (153 shape IDs or `svg`, default `square`), `svg` ★ (text), `radius` (0–50 px, 2), `partial` (`round` | `floor` | `partial` ★), `reveal` (`cascade` | `fade` | `none`), `emptyStyle` (`auto` | `filled` | `outline` | `hidden`), `emptyColor`, `emptyOpacity` (5–100, 100).
- `headline`: `show`, `content` (`pct` | `value` | `pctValue` ★ | `valueTotal` ★), `position` (`auto` | `left` | `top` | `bottom`), `fontSize` (8–96, 26), `color`, `showName`, `nameSize` (11), `units`, `decimals`, `prefix`, `suffix`, `pctDecimals` (−1–3).
- `target` ★: `show`, `style` (`ring` | `marker`), `color`, `label`.
- `legend`: `show`, `content` (`name` | `namePct` | `nameValue` | `namePctValue`), `position` (`top` | `bottom` | `right` | `left`, default `right`), `align`, `showTitle`, `titleText`, `fontSize`, `color`, `interactive`.
- `play` ★ (shared player, card « Lecture ★ » / "Playback ★"): `start` (`last` | `first`), `speed` (100–10,000 ms, 1,000), `loop`, `autoPlay`, `transition`, `controls`, `position`, `ticks`, `tickLabels`, `stepButtons`, `speedButton`, `showLabel` (off by default in Waffle Plume), `labelSize`, `labelPosition`.
- `interaction`: `hover`, `dim` (5–80, 25).
- Shape IDs by group: basic `circle`, `square`, `roundedSquare`, `rectangle`, `triangle`, `diamond`, `hexagon`, `star`, `heart`, `ellipse`, `pentagon`, `octagon`, `rightTriangle`, `parallelogram`, `trapezoid`, `ring`, `semicircle`, `arch`, `capsule`, `star6`, `seal`, `cross`; people `person`, `man`, `woman`, `child`, `people`, `bust`; nature `cloud`, `drop`, `sun`, `moon`, `snowflake`, `leaf`, `pine`, `tree`, `flower`, `mountain`, `wave`, `flame`, `umbrella`, `apple`, `fish`, `paw`, `rain`, `sprout`; objects `house`, `building`, `factory`, `castle`, `shop`, `bank`, `hospital`, `book`, `envelope`, `phone`, `laptop`, `monitor`, `gift`, `clock`, `calendar`, `pencil`, `lightbulb`, `cup`, `crown`, `trashCan`; transport `car`, `truck`, `bus`, `bicycle`, `plane`, `boat`, `train`, `rocket`, `helicopter`, `ship`, `fuel`, `scooter`; business `target`, `barChart`, `pieChart`, `trendUp`, `coin`, `banknote`, `wallet`, `creditCard`, `cart`, `briefcase`, `percent`, `podium`, `megaphone`, `gem`, `medal`, `clipboard`, `handshake`; plus arrows and symbols, containers and maps.

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. Booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes.

```json
{
  "visualType": "plumeWaffleC707BF468E704234BE22DABB0FE758B2",
  "query": {
    "queryState": {
      "category": { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Channel" } }, "queryRef": "Sales.Channel", "nativeQueryRef": "Channel" } ] },
      "value":    { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Sales" } }, "Property": "Revenue" } }, "queryRef": "Sales.Revenue", "nativeQueryRef": "Revenue" } ] }
    }
  },
  "objects": {
    "layout": [ { "properties": { "mode": { "expr": { "Literal": { "Value": "'parts'" } } }, "order": { "expr": { "Literal": { "Value": "'columnsBottom'" } } } } } ],
    "cells":  [ { "properties": { "shape": { "expr": { "Literal": { "Value": "'circle'" } } } } } ]
  }
}
```

The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from the `.pbiviz` file).

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`. Category colors set in Data colors win over the style.
- `style.themeJson` (Theme JSON ★): a JSON theme as plain text. Full reference: https://plumevisuals.com/ai/tutorials/en/themes-json.md.

### Common pitfalls

- A full waffle (100%) with an amount and no category: there is no denominator; add the Total field or a Category, or set `layout.scale`.
- The percentage looks wrong: check `layout.scale` (a measure of 43 without % format is read as 43 points only when it is ≤ 100 and alone).
- "Others" appears: more than `layout.maxItems` categories.
- Tiny shapes: wide shapes (car, truck) are fitted in square cells; use fewer rows and columns.
- The SVG is ignored and squares are drawn: invalid SVG (a message explains why in edit mode) or a web address (never loaded).
- Watermark visible: a filled Play axis field, `layout.mode` = `units`, a snake fill order, `headline.content` = `pctValue` or `valueTotal` (Percentage mode), a ★ shape, pasted or measure SVG, `cells.partial` = `partial`, Target field with `target.show`, Small multiples field, a ★ style or a theme JSON, without a valid key.

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

Images (PNG, JPEG) as cells, loading an SVG or an icon from a URL, icon fonts, a gradient color by measure per cell, spiral or circular waffles, a native drill-down hierarchy, saving the current frame of the play axis in the report, exporting the chart as an image.

## Waffle Plume: data fields

- `category` Category / Catégorie (column, 1 max): Parts of the waffle (e.g. Product line). Without it, each measure is a part.
- `value` Value / Valeur (measure, 6 max): Measure to show (a ratio, a percentage or an amount). Several measures: one part (or one waffle) each.
- `total` Total (100%) / Total (100 %) (measure, 1 max): Optional: the amount that fills the whole waffle (e.g. headcount). The percentage is value ÷ total.
- `target` Target ★ / Objectif ★ ★ (measure, 1 max): Premium: the target cell is circled, the missing cells are dashed.
- `multiples` Small multiples ★ / Petits multiples ★ ★ (column, 1 max): Premium: one waffle per value of this field (e.g. Year, Region), each with the parts of the Category field.
- `icon` SVG icon ★ / Icône SVG ★ ★ (measure, 1 max): Premium: a text measure that returns an SVG for each category (the shape of its cells). Cleaned, never loaded from the web.
- `play` Play axis ★ / Axe de lecture ★ ★ (column, 1 max): Premium: a date, a year or an ordered category; the cells fill or empty one by one from one value to the next (play button).
- `tooltips` Tooltips / Infobulles (measure, 5 max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Waffle Plume: Format pane options (142)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Layout / Disposition (`layout`)
- `layout.mode` Mode: dropdown, default `auto`; values: `auto` Automatic (parts with a category, else percentage); `percent` Percentage: one waffle per category; `parts` Parts of a whole: every category in one waffle; `units` Units: 1 cell = N units (pictograms) ★. Percentage: 43% = 43 cells out of 100. Parts: each category colors its share of the cells. Units ★: one row of cells per category, each cell is worth N units (isotype style).
- `layout.scale` Percentage computed / Pourcentage calculé: dropdown, default `auto`; values: `auto` Automatic; `share` Share of the sum of the categories; `ratio` Value is a ratio (0.43 = 43%); `points` Value in points (43 = 43%); `max` The largest value = 100%. Visible when `layout.mode` = `auto` or `percent` or `parts`. Automatic: with the Total field, value ÷ total; a % formatted measure or values between 0 and 1 are ratios; several categories: share of their sum; else the value in points when it does not exceed 100.
- `layout.rows` Rows / Lignes: number, default `10`; values: 1 to 50. Visible when `layout.mode` = `auto` or `percent` or `parts`
- `layout.columns` Columns (cells per row) / Colonnes (éléments par ligne): number, default `10`; values: 1 to 50
- `layout.order` Fill order / Ordre de remplissage: dropdown, default `rows`; values: `rows` Row by row, from the top; `rowsBottom` Row by row, from the bottom; `columns` Column by column, from the top; `columnsBottom` Column by column, from the bottom; `snake` Snake, from the top ★; `snakeBottom` Snake, from the bottom ★. Visible when `layout.mode` = `auto` or `percent` or `parts`
- `layout.unitValue` Value of one cell (0 = automatic) / Valeur d'un élément (0 = automatique): number, default `0`; values: 0 to …. Visible when `layout.mode` = `units`. Units: each cell is worth this number (e.g. 1,000 people). Automatic: a round number giving at most 20 cells to the largest category.
- `layout.unitKey` Show « 1 cell = … » / Afficher « 1 élément = … »: toggle, default `true`; values: true / false. Visible when `layout.mode` = `units`
- `layout.gap` Space between cells (%) / Espace entre les éléments (%): number, default `16`; values: 0 to 60
- `layout.sort` Category order / Ordre des catégories: dropdown, default `value`; values: `value` Largest first; `valueAsc` Smallest first; `alpha` Alphabetical; `data` Data order (Sort by column)
- `layout.maxItems` Categories at most (the next ones: « Others ») / Catégories au plus (les suivantes : « Autres »): number, default `10`; values: 2 to 30
- `layout.othersLabel` Grouping label / Libellé du regroupement: text, default (empty)
- `layout.perRow` Waffles per row (0 = automatic) / Gaufres par ligne (0 = automatique): number, default `0`; values: 0 to 12. Several waffles (one per category, per measure or per value of the Small multiples field): number of waffles side by side.
- `layout.panelTitles` Title of each waffle / Titre de chaque gaufre: toggle, default `true`; values: true / false
- `layout.panelTitleSize` Waffle title size / Taille des titres des gaufres: number, default `11`; values: 6 to 24

### Data colors / Couleurs des données (`dataColors`, one entry per item with a selector)
- `dataColors.mode` Coloring / Coloration: dropdown, default `category`; values: `category` One color per category; `single` Single color (shades by category)
- `dataColors.single` Color / Couleur: color, default (empty); values: hex color
- `dataColors.fill` Color / Couleur: color, default (empty); values: hex color

### Cells / Éléments (`cells`)
- `cells.shape` Cell shape / Forme des éléments: dropdown, default `square`; values: `circle` Basic · Circle; `square` Basic · Square; `roundedSquare` Basic · Rounded square; `rectangle` Basic · Rectangle; `triangle` Basic · Triangle; `diamond` Basic · Diamond; `hexagon` Basic · Hexagon; `star` Basic · Star; `heart` Basic · Heart; `ellipse` Basic · Ellipse ★; `pentagon` Basic · Pentagon ★; `octagon` Basic · Octagon ★; `rightTriangle` Basic · Right triangle ★; `parallelogram` Basic · Parallelogram ★; `trapezoid` Basic · Trapezoid ★; `ring` Basic · Ring ★; `semicircle` Basic · Semicircle ★; `arch` Basic · Arch ★; `capsule` Basic · Pill ★; `star6` Basic · Six-pointed star ★; `seal` Basic · Seal ★; `cross` Basic · Cross ★; `arrow` Arrows and symbols · Arrow; `arrowUp` Arrows and symbols · Arrow up ★; `arrowDown` Arrows and symbols · Arrow down ★; `arrowLeft` Arrows and symbols · Arrow left ★; `doubleArrow` Arrows and symbols · Double arrow ★; `chevron` Arrows and symbols · Chevron ★; `check` Arrows and symbols · Check mark ★; `close` Arrows and symbols · Close (X) ★; `plus` Arrows and symbols · Plus ★; `minus` Arrows and symbols · Minus ★; `warning` Arrows and symbols · Warning ★; `info` Arrows and symbols · Information ★; `playButton` Arrows and symbols · Play button ★; `bubble` Arrows and symbols · Speech bubble; `thought` Arrows and symbols · Thought bubble ★; `flag` Arrows and symbols · Flag ★; `bookmark` Arrows and symbols · Bookmark ★; `tag` Arrows and symbols · Tag ★; `bolt` Arrows and symbols · Lightning bolt ★; `shield` Arrows and symbols · Shield ★; `award` Arrows and symbols · Award ★; `puzzle` Arrows and symbols · Puzzle piece ★; `gear` Arrows and symbols · Gear ★; `lock` Arrows and symbols · Lock ★; `key` Arrows and symbols · Key ★; `bell` Arrows and symbols · Bell ★; `eye` Arrows and symbols · Eye ★; `cloud` Nature and weather · Cloud; `drop` Nature and weather · Drop; `sun` Nature and weather · Sun ★; `moon` Nature and weather · Moon ★; `snowflake` Nature and weather · Snowflake ★; `leaf` Nature and weather · Leaf ★; `pine` Nature and weather · Pine tree ★; `tree` Nature and weather · Tree ★; `flower` Nature and weather · Flower ★; `mountain` Nature and weather · Mountain ★; `wave` Nature and weather · Wave ★; `flame` Nature and weather · Flame ★; `umbrella` Nature and weather · Umbrella ★; `apple` Nature and weather · Apple ★; `fish` Nature and weather · Fish ★; `paw` Nature and weather · Paw print ★; `rain` Nature and weather · Rain ★; `sprout` Nature and weather · Sprout ★; `person` People · Person; `man` People · Man ★; `woman` People · Woman ★; `child` People · Child ★; `people` People · Group of people ★; `bust` People · User bust ★; `house` Objects and buildings · House; `building` Objects and buildings · Office building ★; `factory` Objects and buildings · Factory ★; `castle` Objects and buildings · Castle ★; `shop` Objects and buildings · Shop ★; `bank` Objects and buildings · Bank ★; `hospital` Objects and buildings · Hospital ★; `book` Objects and buildings · Book ★; `envelope` Objects and buildings · Envelope ★; `phone` Objects and buildings · Phone ★; `laptop` Objects and buildings · Laptop ★; `monitor` Objects and buildings · Monitor ★; `gift` Objects and buildings · Gift ★; `clock` Objects and buildings · Clock ★; `calendar` Objects and buildings · Calendar ★; `pencil` Objects and buildings · Pencil ★; `lightbulb` Objects and buildings · Light bulb ★; `cup` Objects and buildings · Trophy ★; `crown` Objects and buildings · Crown ★; `trashCan` Objects and buildings · Trash can ★; `barrel` Containers and gauges · Barrel; `bottle` Containers and gauges · Bottle; `wineGlass` Containers and gauges · Wine glass; `glass` Containers and gauges · Glass; `mug` Containers and gauges · Mug ★; `jar` Containers and gauges · Jar ★; `bucket` Containers and gauges · Bucket ★; `battery` Containers and gauges · Battery; `batteryVertical` Containers and gauges · Vertical battery; `thermometer` Containers and gauges · Thermometer; `testTube` Containers and gauges · Test tube ★; `tank` Containers and gauges · Tank ★; `funnel` Containers and gauges · Funnel ★; `hourglass` Containers and gauges · Hourglass ★; `bag` Containers and gauges · Bag ★; `piggyBank` Containers and gauges · Piggy bank ★; `flask` Containers and gauges · Flask ★; `beaker` Containers and gauges · Beaker ★; `can` Containers and gauges · Can ★; `coffeeCup` Containers and gauges · Coffee cup ★; `vase` Containers and gauges · Vase ★; `milkCarton` Containers and gauges · Milk carton ★; `france` Maps and places · Metropolitan France ★; `africa` Maps and places · Africa ★; `australia` Maps and places · Australia ★; `southAmerica` Maps and places · South America ★; `pin` Maps and places · Map pin ★; `globe` Maps and places · Globe ★; `foldedMap` Maps and places · Folded map ★; `compass` Maps and places · Compass ★; `city` Maps and places · City skyline ★; `target` Business · Target ★; `barChart` Business · Bar chart ★; `pieChart` Business · Pie chart ★; `trendUp` Business · Trend up ★; `coin` Business · Coin ★; `banknote` Business · Banknote ★; `wallet` Business · Wallet ★; `creditCard` Business · Credit card ★; `cart` Business · Shopping cart ★; `briefcase` Business · Briefcase ★; `percent` Business · Percent ★; `podium` Business · Podium ★; `megaphone` Business · Megaphone ★; `gem` Business · Gem ★; `medal` Business · Medal ★; `clipboard` Business · Clipboard ★; `handshake` Business · Handshake ★; `car` Transport · Car ★; `truck` Transport · Truck ★; `bus` Transport · Bus ★; `bicycle` Transport · Bicycle ★; `plane` Transport · Plane ★; `boat` Transport · Sailboat ★; `train` Transport · Train ★; `rocket` Transport · Rocket ★; `helicopter` Transport · Helicopter ★; `ship` Transport · Cargo ship ★; `fuel` Transport · Fuel pump ★; `scooter` Transport · Scooter ★; `svg` Pasted SVG (below) ★. ★ shapes work with a watermark until a key is entered. A different shape per category: « Data colors » card.
- `cells.svg` Pasted SVG ★ / SVG collé ★ ★: textarea, default (empty). Visible when `cells.shape` = `svg`. Paste the code of an SVG icon (or a data URI, or a d attribute), then colored by category. The SVG is cleaned: scripts, links and images are removed; no web address is ever loaded.
- `cells.radius` Square corner radius (px) / Arrondi des carrés (px): number, default `2`; values: 0 to 50. Visible when `cells.shape` = `square`
- `cells.partial` Last cell / Dernier élément: dropdown, default `round`; values: `round` Rounded to the nearest cell; `floor` Whole cells only; `partial` Partly filled (exact fraction) ★. Rounded: shares are rounded without changing the total (largest remainder). Partly filled: 43.6% fills 43 cells and 60% of the 44th; a cell can be shared by two categories.
- `cells.reveal` Reveal / Apparition: dropdown, default `cascade`; values: `cascade` Cell by cell, in fill order; `fade` Fade; `none` None. Only when the data changes; never when animations are reduced (Style › Animations or the system).
- `cells.emptyStyle` Empty cells / Éléments vides: dropdown, default `auto`; values: `auto` Automatic (hidden in Units mode); `filled` Light tint; `outline` Outline only; `hidden` Hidden
- `cells.emptyColor` Color (empty = style grid) / Couleur (vide = grille du style): color, default (empty); values: hex color
- `cells.emptyOpacity` Opacity (%) / Opacité (%): number, default `100`; values: 5 to 100

### Headline value / Valeur en grand (`headline`)
- `headline.show` Show / Afficher: toggle, default `true`; values: true / false. Percentage mode: the percentage of each waffle in large type. Parts mode: the share of the first category (Single waffle). Units mode: the value at the end of each row.
- `headline.content` Content / Contenu: dropdown, default `pct`; values: `pct` Percentage; `value` Value; `pctValue` Percentage and value ★; `valueTotal` Value of total ★. Percentage mode. « Percentage and value » ★ and « Value of total » ★ (e.g. 43% · 129 or 129 / 300) work with a watermark until a key is entered.
- `headline.position` Position: dropdown, default `auto`; values: `auto` Automatic (left when there is room); `left` Left of the waffle; `top` Above; `bottom` Below
- `headline.fontSize` Value size / Taille de la valeur: number, default `26`; values: 8 to 96. Shrinks automatically when room is short.
- `headline.color` Color (empty = category color) / Couleur (vide = couleur de la catégorie): color, default (empty); values: hex color
- `headline.parts` Single waffle (Parts mode) / Gaufre unique (mode Parts): dropdown, default `first`; values: `first` Percentage of the first category; `none` No headline value. Parts mode (every category in one waffle): the share of the first category (sort order) in large type, with its name, like a percentage waffle.
- `headline.showName` Category name / Nom de la catégorie: toggle, default `true`; values: true / false
- `headline.nameSize` Name size / Taille du nom: number, default `11`; values: 6 to 30
- `headline.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `headline.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `headline.prefix` Prefix / Préfixe: text, default (empty)
- `headline.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)
- `headline.pctDecimals` Percentage decimals (-1 = auto) / Décimales des pourcentages (-1 = auto): number, default `-1`; values: -1 to 3

### Category labels / Étiquettes des catégories (`categoryLabels`)
- `categoryLabels.show` Show / Afficher: toggle, default `true`; values: true / false. Units mode: the name of each row, on the left. Hidden: rows take the whole width (the legend or the tooltip names the categories).
- `categoryLabels.fontSize` Size / Taille: number, default `11`; values: 6 to 30
- `categoryLabels.bold` Bold / Gras: toggle, default `false`; values: true / false
- `categoryLabels.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `categoryLabels.colorByCategory` In the category color / À la couleur de la catégorie: toggle, default `false`; values: true / false
- `categoryLabels.maxWidth` Maximum width (% of the visual) / Largeur maximale (% du visuel): number, default `30`; values: 10 to 60. Longer names are shortened (…); the full name stays in the tooltip.

### Legend / Légende (`legend`)
- `legend.show` Show / Afficher: toggle, default `true`; values: true / false. Shown when the chart has several series.
- `legend.content` Content / Contenu: dropdown, default `namePct`; values: `name` Name; `namePct` Name and percentage; `nameValue` Name and value; `namePctValue` Name, percentage and value. Percentage and value of the waffle (single waffle); with several waffles, the name only.
- `legend.position` Position: dropdown, default `right`; values: `top` Top; `bottom` Bottom; `right` Right; `left` Left
- `legend.align` Alignment / Alignement: dropdown, default `left`; values: `left` Start; `center` Center; `right` End. Visible when `legend.position` = `top` or `bottom`
- `legend.showTitle` Legend title / Titre de la légende: toggle, default `false`; values: true / false
- `legend.titleText` Title text / Texte du titre: text, default (empty). Visible when `legend.showTitle` = `true`
- `legend.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `legend.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `legend.interactive` Click = select the series / Clic = sélectionner la série: toggle, default `true`; values: true / false

### Target ★ / Objectif ★ (`target`)
- `target.show` Show / Afficher: toggle, default `true`; values: true / false. With the Target field: the target cell is circled and the cells still missing to reach it are dashed.
- `target.style` Marker / Repère: dropdown, default `ring`; values: `ring` Circled cell and missing cells dashed; `marker` Circled cell only
- `target.color` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `target.label` « Target: … » under the headline value / « Objectif : … » sous la valeur en grand: toggle, default `true`; values: true / false

### Playback ★ / Lecture ★ (`play`)
- `play.start` Frame shown on opening / Image affichée à l'ouverture: dropdown, default `last`; values: `last` The last one (most recent); `first` The first one
- `play.speed` Duration of a frame (ms) / Durée d'une image (ms): number, default `1000`; values: 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, default `false`; values: true / false
- `play.autoPlay` Play automatically on opening / Lecture automatique à l'ouverture: toggle, default `false`; values: 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, default `true`; values: true / false. Values, positions and colors move smoothly from one frame to the next.
- `play.controls` Play bar / Barre de lecture: toggle, default `true`; values: true / false
- `play.position` Bar position / Position de la barre: dropdown, default `bottom`; values: `bottom` Bottom; `top` Top. Visible when `play.controls` = `true`
- `play.ticks` Tick marks / Graduations: dropdown, default `auto`; values: `auto` Automatic; `all` Every frame; `none` None. Visible when `play.controls` = `true`
- `play.tickLabels` Tick labels / Étiquettes des graduations: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.stepButtons` Start and end buttons / Boutons début et fin: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.speedButton` Speed button / Bouton de vitesse: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.showLabel` Current value in large type / Valeur en cours en grand: toggle, default `false`; values: true / false
- `play.labelSize` Large value size / Taille de la valeur en grand: number, default `44`; values: 12 to 160. Visible when `play.showLabel` = `true`
- `play.labelPosition` Large value position / Position de la valeur en grand: dropdown, default `bottomRight`; values: `bottomRight` Bottom right; `topRight` Top right; `topLeft` Top left; `bottomLeft` Bottom left; `center` Center. Visible when `play.showLabel` = `true`

### Interactions (`interaction`)
- `interaction.hover` Highlight on hover / Mettre en avant au survol: toggle, default `true`; values: true / false
- `interaction.dim` Dimmed items opacity (%) / Opacité des éléments estompés (%): number, default `25`; values: 5 to 80

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Beeswarm Plume

- Every item is a dot: a beeswarm chart with no overlap, with groups, median, quartiles and a play axis that glides the dots.
- Slug `beeswarm` · version 1.1.0.0 · GUID (`visualType`) `plumeBeeswarm2C62844BD5AB404A8D59CCCC7D73C0DF` · page https://plumevisuals.com/en/visuals/beeswarm

### What the visual does

Beeswarm Plume (identifier `beeswarm`) is a Power BI custom visual (version 1.1.0.0, installed from its `.pbiviz` file; AppSource submission in preparation) that draws **beeswarm charts**: every item (customer, store, product, order, town) is a dot placed at its exact value along a value axis, moved sideways just enough so that no dot covers another. Power BI has no native beeswarm, one-dimensional dot plot or box plot; the usual workaround (native scatter chart with a random "jitter" column in DAX) overlaps, changes at every refresh and has no statistics.

**New in version 1.1.0.0 (30/10/2026):** Format pane reorganized (`valueAxis` → `valAxis`, `compare` → `comparison`, search box in **Search**, gridlines in **Gridlines**); free **zoom slider** on the value axis and "Round the range".

- **Deterministic, overlap-free layout**: dots are placed in value order (or by size ★, largest in the middle) at the free position nearest to the baseline; the same data always gives the same picture. On both sides (symmetric) or on one side. Other layouts: random jitter (stable, drawn from each item's key), strip (all dots on one line), sieve ★ (columns of dots, a dot histogram).
- **Automatic dot size**: when a band is crowded, every dot shrinks by the same factor (same size in every band and every play-axis frame; minimum radius 0.6 px; the gap between dots never exceeds half a radius). Beyond about 20,000 dots in one band, a fast staggered-grid layout is used (each dot at most one radius away from its exact value).
- **Groups**: the `group` role gives one band per value, with its name and dot count ("n = 60"); click a name to select all its dots; order by data, count or name, or by median ★.
- **Statistics**: median (on by default), quartile ★ and mean markers, values written next to them; hovering a marker shows n, min, Q1, median, mean, Q3, max of the group. Quantiles use the QUARTILE.INC / PERCENTILE.INC method. Box plot ★ (Tukey 1.5 × IQR, min-max, 5–95 or 10–90 percentile whiskers, ringed outliers) and violin ★ (Gaussian kernel density, Silverman bandwidth) behind the dots; one side + violin = **raincloud plot**.
- **Tooltip**: item name, group, legend, value, size, comparison, and the **rank and percentile** of the dot in its group ("3 of 60 · percentile 95").
- **Play axis ★** (shared Plume player, premium since 10/22/2026): one frame per value of the `play` field; dots **glide** from one frame to the next (each item followed by its identity), enter and leave with a fade, medians and violins glide too; play / pause, slider, ×0.5 to ×4 speed, loop, large current value, keyboard; "Reduce motion" respected. A selected dot stays selected in every frame. ★ history trails of selected or highlighted dots.
- **Comparison with a reference ★** (`compare` role): a stem from each dot's reference value (last year, target) to the dot, a hollow dot at the reference, colors by favorable / unfavorable gap, ▲ / ▼ and % in the tooltip.
- **In-visual search ★**: readers type a name, matching dots stand out and are labeled, Enter selects them. Also a list of names in the Format pane ★ and the `highlight` measure ★.
- Small multiples ★ (up to 36 charts sharing the value axis), embedded images inside dots ★, gradient colors ★, reference lines ★.
- Dots drawn on a canvas: up to 100,000 dots (about 4 s for 100,004 rows in the test bench); 10,000 dots in one band laid out exactly in well under a second.

### 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 (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium**.
- Free in Beeswarm Plume: swarm, jitter and strip layouts, both orientations, both sides, placement by value; Details, Value, Group, Legend, Size, Reference value and Tooltips fields; the 22 free shapes and one shape per legend category; automatic size; median, mean and their values; rank and percentile; data labels (extremes, top or bottom N, selected, all); group order by data, count or name; linear and log scales; legend; rectangle selection; colors by palette, single color, per category.
- Premium features of Beeswarm Plume: the `play` field ("Play axis ★") as soon as it is filled, and its "Playback ★" card; `stats.quartiles`; `swarm.bandOrder` = `medianDesc` or `medianAsc` (with the `group` field); `swarm.order` = `size` (swarm layout, with the `size` field); `labels.which` = `outliers` (labels shown) — rebalancing of 10/22/2026; `swarm.mode` = `sieve`; any of the 131 other shapes in `swarm.shape`; `stats.box`; `stats.violin`; `dataColors.mode` = `gradient`; the `compare` field with `comparison.show` on; `search.show`, `highlight.names` and the `highlight` field; `play.trail` = `selected` or `highlighted`; the `multiples` field; the `image` field; reference lines (`reference.show1`, `show2`, `show3`, `band`).
- 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 `beeswarm` 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, key accepted for 30 more days, reminders 30 and 7 days before the end). Prices: 39 € personal, 99 € SME, 299 € enterprise per year, or the catalog pack (199 € / 399 € / 1,199 € per year; tiers by number of users: personal 1–10, SME 11–200, enterprise more than 200).

### Expected data shape

One row per item (or several rows the measure adds up), with a measure for the value.

| Store (`details`) | Region (`group`) | Format (`legend`) | Sales (`value`) |
|---|---|---|---|
| Bordeaux Lac | Nouvelle-Aquitaine | Out of town | 1,820,000 |
| Pessac | Nouvelle-Aquitaine | Downtown | 640,000 |

- **Details (one dot each)** (`details`, « Détails (un point par valeur) », up to 2 columns, combined): what a dot stands for. Without Details, the measure is aggregated: one dot per group (or a single dot).
- **Value** (`value`, « Valeur », one measure, required): position of each dot. Blank values are not placed; with a log scale, zero and negative values are not placed either (message in edit mode).
- **Group (one band each)** (`group`, « Groupe (une bande par valeur) », one column): one swarm per value.
- **Legend (color)** (`legend`, « Légende (couleur) », one column): color (and, optionally, shape) per category. Without a legend and with a group, dots take their group's color.
- **Size** (`size`, « Taille », one measure): dot area proportional to the absolute value, between `swarm.minSize` and `swarm.maxSize` radii.
- **Play axis ★** (`play`, « Axe de lecture ★ », one column, premium): a year, a date or an ordered category; numbers and dates sorted, texts in Power BI order; dates on January 1 shown as "2024".
- **Compare with ★** (`compare`, « Comparer à ★ », one measure): reference value per dot.
- **Small multiples ★** (`multiples`, one column), **Image ★** (`image`, a text measure returning `data:image/png;base64,…`, SVG, JPEG, GIF, WebP or raw base64; web addresses are never loaded), **Highlight ★** (`highlight`, not blank and not 0 = highlighted).
- **Reference value** (`reference`, one measure): its average is the "Reference value field" option of the reference lines.
- **Tooltips** (`tooltips`) and **Dynamic format** (`format`, see below).
- Volume of data: windows of 30,000 rows, more fetched with `fetchMoreData` up to 200,000 rows.

### DAX recipes

```dax
// One row per store: the value of each dot
Total sales = SUM ( Stores[Sales] )

// Reference for the comparison ★: last year
Sales PY = CALCULATE ( [Total sales], SAMEPERIODLASTYEAR ( 'Date'[Date] ) )

// Highlight ★: stores to watch
To watch = IF ( [Total sales] < 0.8 * [Sales PY], 1 )

// Dynamic title (renamed title.text in the Dynamic format well)
Swarm title = "Sales of " & COUNTROWS ( ALLSELECTED ( Stores ) ) & " stores · median "
    & FORMAT ( CALCULATE ( MEDIAN ( Stores[Sales] ), ALLSELECTED ( Stores ) ), "$#,0" )

// Image ★ stored as base64 text (no web address)
Badge = "data:image/png;base64," & SELECTEDVALUE ( Stores[Logo base64] )
```

To check a median or quartile shown by the visual: `PERCENTILE.INC ( Stores[Sales], 0.25 )` gives the same Q1 as the visual (method 7).

### Interactions with the report

- Click a dot: cross-filters on that item (in every play-axis frame); Ctrl / Shift for several; click again to clear; drag on empty space: rectangle selection (Ctrl adds); click a group name or a legend item: all its dots. Cross-highlighting from other visuals dims the other dots. Selected dots are labeled. Context menu everywhere (dot, empty area, landing page, legend).
- Hover a dot: Power BI tooltip (report-page tooltips supported) and an accent ring; hover a median / quartile / mean marker or a group name: group statistics.
- Keyboard: Tab to the swarm, ← → dots of the group in value order, ↑ ↓ neighboring group, Home / End, Enter selects, Esc clears, Page Up / Page Down previous / next play-axis frame; screen-reader announcement "name: value · rank r of n". High contrast: host colors, one shape per legend category, hollow dots. French and English.
- Session state only (never saved): play-axis frame, search text, keyboard focus.

### Dynamic formats

- **fx button** (Power BI conditional formatting) on colors and texts of the Format pane, including one color per category in Data colors.
- **"Dynamic format" well** (`format`): measures renamed `card.setting` (e.g. `title.text`, `stats.lineColor`, `swarm.size`, `swarm.mode`) 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`, `swarm`, `stats`, `labels`, `valueAxis`, `legend`, `comparison`, `highlight`, `play`, `smallMultiples`, `images`, `interaction`, then `title`, `source`, `container`, `texts`; `reference` in the Analytics pane. `comparison`, `play`, `smallMultiples` and `images` are shown only when their field is filled. Format pane in version 1.1.0.0 (30/10/2026), top to bottom: `license`, `style`, `dataColors`, `swarm`, `stats`, `labels`, `valAxis`, `gridlines`, `legend`, `comparison`, `highlight`, `search`, `zoom`, `play`, `smallMultiples`, `images`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`; Analytics pane: `reference`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- `dataColors`: `mode` (`auto` | `single` | `gradient` ★, default `auto`), `single`, `gradientBy` (`value` | `size` | `delta`, default `value`).
- `swarm`: `mode` (`swarm` | `jitter` | `strip` | `sieve` ★, default `swarm`), `orientation` (`horizontal` | `vertical`, default `horizontal`), `side` (`both` | `positive` | `negative`, default `both`), `order` (`value` | `size` ★, default `value`), `jitterWidth` (5–100, 70), `shape` (153 shape IDs of the shared library; free: `circle`, `square`, `roundedSquare`, `rectangle`, `triangle`, `diamond`, `hexagon`, `star`, `heart`, `cloud`, `drop`, `bubble`, `arrow`, `person`, `house`; default `circle`), `shapeByLegend`, `size` (0.5–40, 5), `autoFit` (on), `padding` (0–12, 1), `minSize` (0.5–40, 3), `maxSize` (1–80, 14), `opacity` (10–100, 88), `hollow`, `outline` (on), `outlineColor`, `bandLabels` (on), `bandLabelSize` (6–24, 10), `showCount` (on), `bandOrder` (`data` | `medianDesc` ★ | `medianAsc` ★ | `count` | `name`, default `data`), `separators` (on), `stripes`, `bandGap` (0–60, 6).
- `stats`: `median` (on), `quartiles` ★, `mean`, `values`, `lineColor`, `lineWidth` (0.5–6, 1.5), `box` ★, `whiskers` (`iqr` | `minmax` | `p5` | `p10`, default `iqr`), `outliers` (on), `boxWidth` (10–100, 70), `violin` ★, `bandwidth` (0–1000000000, 0), `violinOpacity` (0–80, 16).
- `labels`: `show`, `content` (`name` | `nameValue` | `value`, default `name`), `which` (`extremes` | `top` | `bottom` | `outliers` ★ | `selected` | `all`, default `extremes`), `n` (1–100, 5), `fontSize` (6–24, 10), `color`, `bold`, `halo` (on), `declutter` (on), `units` (`auto` | `none` | `k` | `m` | `b`, default `auto`), `decimals` (-1–6, -1), `prefix`, `suffix`.
- `valAxis`: `show` (on), `fontSize` (6–24, 9), `color`, `units` (`auto` | `none` | `k` | `m` | `b`, default `auto`), `decimals` (-1–6, -1), `prefix`, `suffix`, `line`, `scale` (`linear` | `log`, default `linear`), `min`, `max`, `zero`, `ticks` (2–20, 5), `invert`, `showTitle`, `titleText`, `gridlines.vShow` (on), `gridlines.vStyle` (`solid` | `dashed` | `dotted`, default `solid`), `gridlines.vColor`, `gridlines.zeroLine` (on).
- `legend`: `show` (on), `position` (`top` | `bottom` | `right` | `left`, default `top`), `align` (`left` | `center` | `right`, default `left`), `showTitle`, `titleText`, `fontSize` (6–24, 9), `color`, `interactive` (on).
- `comparison`: `show` (on) ★, `stems` (on), `ghosts` (on), `colorByGap`, `higherIsBetter` (on), `positiveColor` (#2E7D4F), `negativeColor` (#C0392B), `stemWidth` (0.5–6, 1.5).
- `highlight`: `search.show` ★, `names` ★, `color`, `othersOpacity` (5–100, 22), `labels` (on).
- `play` ★ (card « Lecture ★ » / "Playback ★"): `start` (`last` | `first`, default `last`), `speed` (100–10000, 1000), `loop`, `autoPlay`, `transition` (on), `controls` (on), `position` (`bottom` | `top`, default `bottom`), `ticks` (`auto` | `all` | `none`, default `auto`), `tickLabels` (on), `stepButtons` (on), `speedButton` (on), `showLabel` (on), `labelSize` (12–160, 44), `labelPosition` (`bottomRight` | `topRight` | `topLeft` | `bottomLeft` | `center`, default `bottomRight`), `trail` (`none` | `selected` ★ | `highlighted` ★, default `none`).
- `smallMultiples`: `columns` (0–12, 0), `minHeight` (50–600, 110), `gap` (0–60, 12), `titleSize` (6–24, 10), `border`.
- `images`: `imageSize` (6–120, 22), `imageBorder` (on).
- `reference` (Analytics pane; lines 1 to 3 with suffix 1, 2, 3, then the band): `show1`, `kind1` (`constant` | `average` | `median` | `min` | `max` | `percentile` | `measure`, default `average`), `value1` (–, 0), `pct1` (1–99, 90), `label1`, `showValue1` (on), `color1`, `style1` (`solid` | `dashed` | `dotted`, default `dashed`), `width1` (0.5–6, 1.5), `labelPos1` (`end` | `start` | `none`, default `end`), `band`, `bandFrom` (–, 0), `bandTo` (–, 0), `bandLabel`, `bandColor`, `bandOpacity` (2–60, 12).
- `interaction`: `hover` (on), `dim` (5–80, 25), `brush` (on), `rank` (on).

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. Booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes.

```json
{
  "visualType": "plumeBeeswarm2C62844BD5AB404A8D59CCCC7D73C0DF",
  "query": {
    "queryState": {
      "details": { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Stores" } }, "Property": "Store" } }, "queryRef": "Stores.Store", "nativeQueryRef": "Store" } ] },
      "group":   { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Stores" } }, "Property": "Region" } }, "queryRef": "Stores.Region", "nativeQueryRef": "Region" } ] },
      "value":   { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Stores" } }, "Property": "Total sales" } }, "queryRef": "Stores.Total sales", "nativeQueryRef": "Total sales" } ] }
    }
  },
  "objects": {
    "swarm":   [ { "properties": { "side": { "expr": { "Literal": { "Value": "'positive'" } } } } } ],
    "stats":   [ { "properties": { "quartiles": { "expr": { "Literal": { "Value": "true" } } }, "violin": { "expr": { "Literal": { "Value": "true" } } } } } ],
    "labels":  [ { "properties": { "show": { "expr": { "Literal": { "Value": "true" } } }, "which": { "expr": { "Literal": { "Value": "'top'" } } }, "n": { "expr": { "Literal": { "Value": "3D" } } } } } ],
    "license": [ { "properties": { "key": { "expr": { "Literal": { "Value": "'PLUM1.…'" } } } } } ]
  }
}
```

The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from the `.pbiviz` file).

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`. Style adjustments in Beeswarm Plume (on settings left at their default): Minimal removes the gridlines and the lines between groups, Journal (`press`) uses dotted gridlines, Black and white turns on one shape per legend category, Unknown Pleasures and the "outlined" fill use hollow dots, the "glass" fill lowers the opacity, glowing styles add a glow to the dots.
- `style.themeJson` (Theme JSON ★): a JSON theme as plain text (format v2 with optional `extends` and groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`). Full reference: https://plumevisuals.com/ai/tutorials/en/themes-json.md.

### Common pitfalls

- A single dot, or one per group: nothing in Details.
- Fewer dots than rows: blank values, or two items with the same name (add a code as a second Details field).
- Tiny dots: too many dots for the band; enlarge the visual, use fewer groups, or use the jitter layout.
- "Nothing to place": the Value measure is blank for every item.
- Log scale message: zero or negative values are not placed.
- Small multiples taller than the visual: the area scrolls (set `smallMultiples.minHeight` lower).
- Watermark visible: a filled Play axis field, quartiles, groups sorted by median, placement by size (with Size), outlier labels, sieve, a ★ shape, box plot, violin, gradient, Compare with field, search, highlight list or field, history trails, small multiples, images, reference lines, a ★ style or a theme JSON, without a valid key.
- The visual makes no network request: data, images and license key stay in the report; no R or Python.

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

Force-directed (random) layout, lasso selection, a second value axis, connecting lines between dots of the same item within a frame, readers saving their search or highlights in the report, exporting the chart as an image, loading images from web addresses, more than 36 small multiples, more than 200,000 rows.

## Beeswarm Plume: data fields

- `details` Details (one dot each) / Détails (un point par valeur) (column, 2 max): One dot per value (customer, product, store…); two fields are combined.
- `value` Value / Valeur (measure, 1 max): Places each dot along the value axis.
- `group` Group (one band each) / Groupe (une bande par valeur) (column, 1 max): One swarm per value, to compare groups.
- `legend` Legend (color) / Légende (couleur) (column, 1 max): Colors the dots by category.
- `size` Size / Taille (measure, 1 max): Dot area proportional to this measure.
- `play` Play axis ★ / Axe de lecture ★ ★ (column, 1 max): Premium: a date, a year or an ordered category; the dots glide from one value to the next (play button).
- `compare` Compare with ★ / Comparer à ★ ★ (measure, 1 max): A reference value per dot (last year, target): a stem shows the gap.
- `multiples` Small multiples ★ / Petits multiples ★ ★ (column, 1 max): One small swarm per value, sharing the same value axis.
- `image` Image ★ ★ (measure, 1 max): An embedded image per dot (data:image/…;base64 or raw base64); web addresses are never loaded.
- `highlight` Highlight ★ / Mise en avant ★ ★ (measure, 1 max): Not blank and not 0: the dot stands out, the others fade.
- `reference` Reference value / Valeur de référence (measure, 1 max): Target or benchmark for the reference lines (Analytics pane).
- `tooltips` Tooltips / Infobulles (measure, several max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Beeswarm Plume: Format pane options (236)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Data colors / Couleurs des données (`dataColors`, one entry per item with a selector)
- `dataColors.mode` Coloring / Coloration: dropdown, default `auto`; values: `auto` Palette (by legend, else by group); `single` Single color; `gradient` Gradient by a value ★
- `dataColors.single` Color / Couleur: color, default (empty); values: hex color
- `dataColors.fill` Color / Couleur: color, default (empty); values: hex color
- `dataColors.gradientBy` Gradient value / Valeur du dégradé: dropdown, default `value`; values: `value` Value (position); `size` Size; `delta` Gap to the reference

### Swarm / Essaim (`swarm`)
- `swarm.mode` Layout / Disposition: dropdown, default `swarm`; values: `swarm` Swarm (no overlap); `jitter` Random jitter; `strip` Strip (dots on one line); `sieve` Sieve (dot columns) ★. Swarm: each dot at its exact value, pushed aside just enough not to cover another one (the same picture every time). Sieve: dots stacked in columns, like a histogram made of dots.
- `swarm.orientation` Orientation: dropdown, default `horizontal`; values: `horizontal` Horizontal (values at the bottom); `vertical` Vertical (values on the left)
- `swarm.side` Side / Côté: dropdown, default `both`; values: `both` Both sides (symmetric); `positive` One side (above or right); `negative` One side (below or left). One side with the violin ★ gives a raincloud plot: half violin on one side, dots on the other.
- `swarm.order` Placement order / Ordre de placement: dropdown, default `value`; values: `value` By value (classic swarm); `size` By size (large dots in the middle) ★. Visible when `swarm.mode` = `swarm`
- `swarm.jitterWidth` Jitter width (% of the band) / Largeur de la dispersion (% de la bande): number, default `70`; values: 5 to 100. Visible when `swarm.mode` = `jitter`
- `swarm.shape` Shape / Forme: dropdown, default `circle`; values: `circle` Circle; `square` Square; `roundedSquare` Rounded square; `rectangle` Rectangle; `triangle` Triangle; `diamond` Diamond; `hexagon` Hexagon; `star` Star; `heart` Heart; `ellipse` Ellipse ★; `pentagon` Pentagon ★; `octagon` Octagon ★; `rightTriangle` Right triangle ★; `parallelogram` Parallelogram ★; `trapezoid` Trapezoid ★; `ring` Ring ★; `semicircle` Semicircle ★; `arch` Arch ★; `capsule` Pill ★; `star6` Six-pointed star ★; `seal` Seal ★; `cross` Cross ★; `arrow` Arrow; `arrowUp` Arrow up ★; `arrowDown` Arrow down ★; `arrowLeft` Arrow left ★; `doubleArrow` Double arrow ★; `chevron` Chevron ★; `check` Check mark ★; `close` Close (X) ★; `plus` Plus ★; `minus` Minus ★; `warning` Warning ★; `info` Information ★; `playButton` Play button ★; `bubble` Speech bubble; `thought` Thought bubble ★; `flag` Flag ★; `bookmark` Bookmark ★; `tag` Tag ★; `bolt` Lightning bolt ★; `shield` Shield ★; `award` Award ★; `puzzle` Puzzle piece ★; `gear` Gear ★; `lock` Lock ★; `key` Key ★; `bell` Bell ★; `eye` Eye ★; `cloud` Cloud; `drop` Drop; `sun` Sun ★; `moon` Moon ★; `snowflake` Snowflake ★; `leaf` Leaf ★; `pine` Pine tree ★; `tree` Tree ★; `flower` Flower ★; `mountain` Mountain ★; `wave` Wave ★; `flame` Flame ★; `umbrella` Umbrella ★; `apple` Apple ★; `fish` Fish ★; `paw` Paw print ★; `rain` Rain ★; `sprout` Sprout ★; `person` Person; `man` Man ★; `woman` Woman ★; `child` Child ★; `people` Group of people ★; `bust` User bust ★; `house` House; `building` Office building ★; `factory` Factory ★; `castle` Castle ★; `shop` Shop ★; `bank` Bank ★; `hospital` Hospital ★; `book` Book ★; `envelope` Envelope ★; `phone` Phone ★; `laptop` Laptop ★; `monitor` Monitor ★; `gift` Gift ★; `clock` Clock ★; `calendar` Calendar ★; `pencil` Pencil ★; `lightbulb` Light bulb ★; `cup` Trophy ★; `crown` Crown ★; `trashCan` Trash can ★; `barrel` Barrel; `bottle` Bottle; `wineGlass` Wine glass; `glass` Glass; `mug` Mug ★; `jar` Jar ★; `bucket` Bucket ★; `battery` Battery; `batteryVertical` Vertical battery; `thermometer` Thermometer; `testTube` Test tube ★; `tank` Tank ★; `funnel` Funnel ★; `hourglass` Hourglass ★; `bag` Bag ★; `piggyBank` Piggy bank ★; `flask` Flask ★; `beaker` Beaker ★; `can` Can ★; `coffeeCup` Coffee cup ★; `vase` Vase ★; `milkCarton` Milk carton ★; `france` Metropolitan France ★; `africa` Africa ★; `australia` Australia ★; `southAmerica` South America ★; `pin` Map pin ★; `globe` Globe ★; `foldedMap` Folded map ★; `compass` Compass ★; `city` City skyline ★; `target` Target ★; `barChart` Bar chart ★; `pieChart` Pie chart ★; `trendUp` Trend up ★; `coin` Coin ★; `banknote` Banknote ★; `wallet` Wallet ★; `creditCard` Credit card ★; `cart` Shopping cart ★; `briefcase` Briefcase ★; `percent` Percent ★; `podium` Podium ★; `megaphone` Megaphone ★; `gem` Gem ★; `medal` Medal ★; `clipboard` Clipboard ★; `handshake` Handshake ★; `car` Car ★; `truck` Truck ★; `bus` Bus ★; `bicycle` Bicycle ★; `plane` Plane ★; `boat` Sailboat ★; `train` Train ★; `rocket` Rocket ★; `helicopter` Helicopter ★; `ship` Cargo ship ★; `fuel` Fuel pump ★; `scooter` Scooter ★. 22 free shapes; the others (★) show the watermark without a license. The space kept for each dot stays a circle: no shape spills onto its neighbor.
- `swarm.shapeByLegend` One shape per legend category / Une forme par catégorie de légende: toggle, default `false`; values: true / false. Circle, square, diamond, triangle, hexagon, star…: the category can be read without the colors (always on in high contrast).
- `swarm.size` Dot radius (px) / Rayon des points (px): number, default `5`; values: 0.5 to 40
- `swarm.autoFit` Shrink dots so that everything fits / Réduire les points pour que tout tienne: toggle, default `true`; values: true / false. When a band is too crowded, all dots get smaller (the same size in every band and every frame).
- `swarm.padding` Space between dots (px) / Espace entre les points (px): number, default `1`; values: 0 to 12
- `swarm.minSize` Smallest dot radius (Size field) / Rayon du plus petit point (champ Taille): number, default `3`; values: 0.5 to 40
- `swarm.maxSize` Largest dot radius (Size field) / Rayon du plus grand point (champ Taille): number, default `14`; values: 1 to 80
- `swarm.opacity` Opacity (%) / Opacité (%): number, default `88`; values: 10 to 100
- `swarm.hollow` Hollow dots / Points creux: toggle, default `false`; values: true / false
- `swarm.outline` Outline / Contour: toggle, default `true`; values: true / false
- `swarm.outlineColor` Outline color (empty = background) / Couleur du contour (vide = fond): color, default (empty); values: hex color. Visible when `swarm.outline` = `true`
- `swarm.bandLabels` Group names / Noms des groupes: toggle, default `true`; values: true / false
- `swarm.bandLabelSize` Name size / Taille des noms: number, default `10`; values: 6 to 24
- `swarm.bandLabelLines` Maximum lines per name / Lignes au plus par nom: number, default `2`; values: 1 to 4. Long names wrap to the next line (then “…”); the full name is in the tooltip of the name.
- `swarm.bandLabelWidth` Maximum room for names (% of the width) / Place maximale des noms (% de la largeur): number, default `32`; values: 10 to 60
- `swarm.showCount` Dot count under the name / Nombre de points sous le nom: toggle, default `true`; values: true / false
- `swarm.bandOrder` Group order / Ordre des groupes: dropdown, default `data`; values: `data` Data order (Power BI sort); `medianDesc` Median, descending ★; `medianAsc` Median, ascending ★; `count` Number of dots; `name` Name (A → Z)
- `swarm.separators` Lines between groups / Traits entre les groupes: toggle, default `true`; values: true / false
- `swarm.stripes` Alternate bands / Bandes alternées: toggle, default `false`; values: true / false
- `swarm.bandGap` Gap between groups (px) / Écart entre les groupes (px): number, default `6`; values: 0 to 60

### Statistics / Statistiques (`stats`)
- `stats.median` Median / Médiane: toggle, default `true`; values: true / false
- `stats.quartiles` Quartiles (Q1 and Q3) ★ / Quartiles (Q1 et Q3) ★ ★: toggle, default `false`; values: true / false
- `stats.mean` Mean / Moyenne: toggle, default `false`; values: true / false
- `stats.values` Write the marker values / Écrire les valeurs des repères: toggle, default `false`; values: true / false
- `stats.lineColor` Marker color (empty = text) / Couleur des repères (vide = texte): color, default (empty); values: hex color
- `stats.lineWidth` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `stats.box` Box plot ★ / Boîte à moustaches ★ ★: toggle, default `false`; values: true / false. Quartile box and whiskers drawn behind the dots of each group.
- `stats.whiskers` Whiskers / Moustaches: dropdown, default `iqr`; values: `iqr` 1.5 × interquartile range (Tukey); `minmax` Minimum and maximum; `p5` 5th and 95th percentiles; `p10` 10th and 90th percentiles
- `stats.outliers` Ring the outliers / Cercler les valeurs atypiques: toggle, default `true`; values: true / false. Dots beyond the whiskers get a ring in the unfavorable color.
- `stats.boxWidth` Box width (% of the band) / Largeur de la boîte (% de la bande): number, default `70`; values: 10 to 100
- `stats.violin` Violin (density) ★ / Violon (densité) ★ ★: toggle, default `false`; values: true / false. Smoothed density behind the dots. With Swarm › Side = one side, half a violin on the other side: a raincloud plot.
- `stats.bandwidth` Smoothing (0 = automatic) / Lissage (0 = automatique): number, default `0`; values: 0 to 1000000000. Kernel width in the unit of the value. Automatic: Silverman's rule.
- `stats.violinOpacity` Fill opacity (%) / Opacité du remplissage (%): number, default `16`; values: 0 to 80

### Data labels / Étiquettes de données (`labels`)
- `labels.show` Show / Afficher: toggle, default `false`; values: true / false
- `labels.content` Content / Contenu: dropdown, default `name`; values: `name` Name (Details); `nameValue` Name and value; `value` Value
- `labels.which` Labeled dots / Points étiquetés: dropdown, default `extremes`; values: `extremes` Minimum and maximum of each group; `top` The N largest; `bottom` The N smallest; `outliers` Outliers (1.5 × interquartile range) ★; `selected` Selected only; `all` All (no overlap). Selected and highlighted dots are always labeled.
- `labels.n` N: number, default `5`; values: 1 to 100. Visible when `labels.which` = `top` or `bottom`
- `labels.detailField` Name shown (two Details fields) / Nom affiché (deux champs Détails): dropdown, default `both`; values: `both` Both (A · B); `first` The first field; `second` The second field. With two fields in Details (e.g. Town and County): the name written in the labels and at the top of the tooltip. Both stay in the tooltip and the search.
- `labels.fontSize` Size / Taille: number, default `10`; values: 6 to 24
- `labels.color` Color (empty = automatic) / Couleur (vide = automatique): color, default (empty); values: hex color. Automatic: readable color depending on the background (inside bars: white or dark).
- `labels.bold` Bold / Gras: toggle, default `false`; values: true / false
- `labels.halo` Text halo / Halo autour du texte: toggle, default `true`; values: true / false
- `labels.declutter` Hide overlapping labels / Masquer les étiquettes qui se chevauchent: toggle, default `true`; values: true / false
- `labels.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `labels.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `labels.prefix` Prefix / Préfixe: text, default (empty)
- `labels.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)

### Value axis / Axe des valeurs (`valAxis`)
- `valAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `valAxis.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `valAxis.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `valAxis.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `valAxis.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `valAxis.prefix` Prefix / Préfixe: text, default (empty)
- `valAxis.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)
- `valAxis.line` Axis line / Trait de l'axe: toggle, default `false`; values: true / false
- `valAxis.scale` Scale / Échelle: dropdown, default `linear`; values: `linear` Linear; `log` Logarithmic
- `valAxis.min` Minimum: text, default (empty). Accepts a measure (Dynamic format field: valAxis.min, valAxis.max) to keep the same scale when another visual filters this one.
- `valAxis.max` Maximum: text, default (empty). Accepts a measure (Dynamic format field: valAxis.min, valAxis.max) to keep the same scale when another visual filters this one.
- `valAxis.zero` Always include zero / Toujours inclure zéro: toggle, default `false`; values: true / false. Visible when `valAxis.scale` = `linear`
- `valAxis.ticks` Number of ticks (approx.) / Nombre de graduations (environ): number, default `5`; values: 2 to 20
- `valAxis.invert` Invert axis / Inverser l'axe: toggle, default `false`; values: true / false
- `valAxis.round` Round range / Arrondir la plage: toggle, default `true`; values: true / false. Computed bounds rounded to a round tick. Off: the axis stops at the extreme values.
- `valAxis.showTitle` Show / Afficher: toggle, default `false`; values: true / false
- `valAxis.titleText` Text / Texte: text, default (empty). Visible when `valAxis.showTitle` = `true`

### Gridlines / Quadrillage (`gridlines`)
- `gridlines.vShow` Show / Afficher: toggle, default `true`; values: true / false
- `gridlines.vColor` Color (empty = style grid) / Couleur (vide = grille du style): color, default (empty); values: hex color
- `gridlines.vWidth` Width / Épaisseur: number, default `1`; values: 0.5 to 6
- `gridlines.vStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `gridlines.zeroLine` Zero line / Ligne du zéro: toggle, default `true`; values: true / false

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

### Comparison ★ / Comparaison ★ (`comparison`)
- `comparison.show` Show ★ / Afficher ★ ★: toggle, default `true`; values: true / false. Needs the “Compare with ★” field: a reference value per dot (last year, target, budget).
- `comparison.stems` Gap stem (from the reference to the dot) / Tige de l'écart (de la référence au point): toggle, default `true`; values: true / false
- `comparison.ghosts` Hollow dot at the reference / Point creux à la référence: toggle, default `true`; values: true / false
- `comparison.colorByGap` Color dots by their gap / Colorer les points selon l'écart: toggle, default `false`; values: true / false. Favorable, unfavorable or unchanged; the direction is also written in the tooltip (▲ ▼).
- `comparison.higherIsBetter` An increase is favorable / Une hausse est favorable: toggle, default `true`; values: true / false
- `comparison.positiveColor` Favorable color / Couleur favorable: color, default `#2E7D4F`; values: hex color
- `comparison.negativeColor` Unfavorable color / Couleur défavorable: color, default `#C0392B`; values: hex color
- `comparison.stemWidth` Stem width / Épaisseur de la tige: number, default `1.5`; values: 0.5 to 6

### Highlight ★ / Mise en avant ★ (`highlight`)
- `highlight.names` Highlighted dots ★ / Points mis en avant ★ ★: textarea, default (empty). Names of the Details field (case and accents ignored). The “Highlight ★” field does the same with a measure.
- `highlight.color` Color (empty = dot color) / Couleur (vide = couleur du point): color, default (empty); values: hex color
- `highlight.othersOpacity` Other dots opacity (%) / Opacité des autres points (%): number, default `22`; values: 5 to 100
- `highlight.labels` Label highlighted (and found) dots / Étiqueter les points mis en avant (et trouvés): toggle, default `true`; values: true / false

### Search ★ / Recherche ★ (`search`)
- `search.show` Search box in the visual ★ / Champ de recherche dans le visuel ★ ★: toggle, default `false`; values: true / false. Readers type a name: matching dots stand out and are labeled (Highlight card colors); Enter selects them.
- `search.hideInView` Hide in reading view / Masquer en mode lecture: toggle, default `false`; values: true / false. The box only appears in edit mode (published, exported or presented report: no box).
- `search.hideWhilePlaying` Hide while playing (play axis) / Masquer pendant la lecture (axe de lecture): toggle, default `true`; values: true / false. The box disappears during the animation (video, recording) and comes back on pause.
- `search.placeholder` Placeholder / Texte indicatif: text, default (empty)

### Zoom (`zoom`)
- `zoom.slider` Value axis zoom slider / Curseur de zoom de l'axe des valeurs: toggle, default `false`; values: true / false. Movable window and two handles below the axis (like the native zoom slider); double-click = full view. Not saved in the report.

### Images ★ (`images`)
- `images.imageSize` Minimum diameter of a dot with an image (px) / Diamètre minimal d'un point avec image (px): number, default `22`; values: 6 to 120. Dots that carry an image (“Image ★” field) are drawn at least this large so the image stays legible.
- `images.imageBorder` Border in the dot color / Bordure de la couleur du point: toggle, default `true`; values: true / false

### Small multiples ★ / Petits multiples ★ (`smallMultiples`)
- `smallMultiples.columns` Columns (0 = automatic) / Colonnes (0 = automatique): number, default `0`; values: 0 to 12
- `smallMultiples.minHeight` Minimum chart height (px) / Hauteur minimale d'un graphique (px): number, default `110`; values: 50 to 600
- `smallMultiples.gap` Spacing (px) / Espacement (px): number, default `12`; values: 0 to 60
- `smallMultiples.titleSize` Title size / Taille des titres: number, default `10`; values: 6 to 24
- `smallMultiples.border` Frame around each chart / Cadre autour de chaque graphique: toggle, default `false`; values: true / false

### Playback ★ / Lecture ★ (`play`)
- `play.start` Frame shown on opening / Image affichée à l'ouverture: dropdown, default `last`; values: `last` The last one (most recent); `first` The first one
- `play.speed` Duration of a frame (ms) / Durée d'une image (ms): number, default `1000`; values: 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, default `false`; values: true / false
- `play.autoPlay` Play automatically on opening / Lecture automatique à l'ouverture: toggle, default `false`; values: 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, default `true`; values: true / false. Values, positions and colors move smoothly from one frame to the next.
- `play.controls` Play bar / Barre de lecture: toggle, default `true`; values: true / false
- `play.position` Bar position / Position de la barre: dropdown, default `bottom`; values: `bottom` Bottom; `top` Top. Visible when `play.controls` = `true`
- `play.ticks` Tick marks / Graduations: dropdown, default `auto`; values: `auto` Automatic; `all` Every frame; `none` None. Visible when `play.controls` = `true`
- `play.tickLabels` Tick labels / Étiquettes des graduations: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.stepButtons` Start and end buttons / Boutons début et fin: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.speedButton` Speed button / Bouton de vitesse: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.showLabel` Current value in large type / Valeur en cours en grand: toggle, default `true`; values: true / false
- `play.labelSize` Large value size / Taille de la valeur en grand: number, default `44`; values: 12 to 160. Visible when `play.showLabel` = `true`
- `play.labelPosition` Large value position / Position de la valeur en grand: dropdown, default `bottomRight`; values: `bottomRight` Bottom right; `topRight` Top right; `topLeft` Top left; `bottomLeft` Bottom left; `center` Center. Visible when `play.showLabel` = `true`
- `play.trail` Dot history / Historique des points: dropdown, default `none`; values: `none` None; `selected` Selected dots ★; `highlighted` Highlighted dots ★. Earlier values of the dot (from the first frame to the current one), drawn as a trail along the value axis.

### Interactions (`interaction`)
- `interaction.hover` Highlight on hover / Mettre en avant au survol: toggle, default `true`; values: true / false
- `interaction.dim` Dimmed items opacity (%) / Opacité des éléments estompés (%): number, default `25`; values: 5 to 80
- `interaction.hlScale` Scale during cross-highlighting / Échelle pendant une surbrillance croisée: dropdown, default `all`; values: `all` All data (the scale stays); `highlighted` Refocus on the highlighted dots. When another visual sends a highlight (Format › Edit interactions › Highlight), the axis keeps all the data; a filter removes the dots: then set the axis minimum and maximum with a measure (Dynamic format).
- `interaction.brush` Select by drawing a rectangle / Sélection en traçant un rectangle: toggle, default `true`; values: true / false. Drag on the chart to select every dot inside the rectangle (Ctrl to add).
- `interaction.brushShape` Selection shape / Forme de la sélection: dropdown, default `rectangle`; values: `rectangle` Rectangle; `lasso` Lasso (freehand). Visible when `interaction.brush` = `true`
- `interaction.rank` Rank and percentile in the tooltip / Rang et centile dans l'infobulle: toggle, default `true`; values: true / false. Rank of the dot in its group (1 = largest value) and its percentile.

### Reference lines ★ / Lignes de référence ★ (`reference`, Analytics pane)
- `reference.show1` Show / Afficher: toggle, default `false`; values: true / false
- `reference.kind1` Value / Valeur: dropdown, default `average`; values: `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile; `measure` “Reference value” field
- `reference.value1` Constant value / Valeur constante: number, default `0`. Visible when `reference.kind1` = `constant`
- `reference.pct1` Percentile / Centile: number, default `90`; values: 1 to 99. Visible when `reference.kind1` = `percentile`
- `reference.label1` Label / Libellé: text, default (empty)
- `reference.showValue1` Show the value / Afficher la valeur: toggle, default `true`; values: true / false
- `reference.color1` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.style1` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `reference.width1` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `reference.labelPos1` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None
- `reference.show2` Show / Afficher: toggle, default `false`; values: true / false
- `reference.kind2` Value / Valeur: dropdown, default `constant`; values: `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile; `measure` “Reference value” field
- `reference.value2` Constant value / Valeur constante: number, default `0`. Visible when `reference.kind2` = `constant`
- `reference.pct2` Percentile / Centile: number, default `90`; values: 1 to 99. Visible when `reference.kind2` = `percentile`
- `reference.label2` Label / Libellé: text, default (empty)
- `reference.showValue2` Show the value / Afficher la valeur: toggle, default `true`; values: true / false
- `reference.color2` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.style2` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `reference.width2` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `reference.labelPos2` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None
- `reference.show3` Show / Afficher: toggle, default `false`; values: true / false
- `reference.kind3` Value / Valeur: dropdown, default `median`; values: `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile; `measure` “Reference value” field
- `reference.value3` Constant value / Valeur constante: number, default `0`. Visible when `reference.kind3` = `constant`
- `reference.pct3` Percentile / Centile: number, default `90`; values: 1 to 99. Visible when `reference.kind3` = `percentile`
- `reference.label3` Label / Libellé: text, default (empty)
- `reference.showValue3` Show the value / Afficher la valeur: toggle, default `true`; values: true / false
- `reference.color3` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.style3` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `reference.width3` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `reference.labelPos3` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None
- `reference.band` Show / Afficher: toggle, default `false`; values: true / false
- `reference.bandFrom` From / De: number, default `0`
- `reference.bandTo` To / À: number, default `0`
- `reference.bandLabel` Label / Libellé: text, default (empty)
- `reference.bandColor` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.bandOpacity` Opacity (%) / Opacité (%): number, default `12`; values: 2 to 60

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Hexbin Plume

- Too many points for a scatter chart? Group them into hexagons colored by count or average, then zoom in down to the points.
- Slug `hexbin` · version 1.1.0.0 · GUID (`visualType`) `plumeHexbinE30C7F7C4238475A8F1967FA03B31913` · page https://plumevisuals.com/en/visuals/hexbin

### What the visual does

Hexbin Plume (identifier `hexbin`) is a Power BI custom visual (version 1.1.0.0, installed from its `.pbiviz` file; AppSource submission in preparation) that draws a **hexagonal binning scatter chart**: points placed by two measures are grouped into bins colored by how many points they hold, or by an aggregate of a Value measure. Power BI has no native hexbin: the native scatter chart samples dense data (about 3,500 points, 10,000 at most) and shows shape, not density.

**New in version 1.1.0.0 (30/10/2026):** Free native-parity additions: X and Y **zoom sliders**, "Round the range", and a free **Symmetry and ratio** card in the Analytics pane (shading around y = x, total ratio or fixed slope line).

- **No sampling**: 30,000-row windows, then `fetchMoreData` up to **300,000 points**; every point is counted. 100,004 rows render in under a second in the test bench.
- **Bins**: hexagons (pointy or flat top) or squares; circles ★ and triangles ★. Automatic size (about one bin per 260 px², larger with few points), radius in px or number of columns; spacing, rounded corners, outline, grid of empty bins; a minimum number of points per bin, bins below it hidden or ★ drawn as points (isolated values).
- **Value of a bin**: number of points, share of points, or sum, average, median, minimum, maximum of the `value` measure (`bins.aggregate` = `auto` → average with a Value field, count otherwise).
- **Colors**: density-aware gradient of the style (small values take the shade closest to the background), one color by intensity, or the dominant category of the Legend field; linear or square root (default) scale, fixed bounds; ★ log scale, ★ diverging scale, ★ outliers ignored (2nd–98th percentile); ★ dominant category and its share, difference between two categories, change between frames, equal-count classes, custom thresholds.
- **Semantic zoom**: Shift + drag zooms into a rectangle; bins keep their screen size and are recomputed on the view; raw points appear when few remain (`points.show` = `zoom`). Double-click or ⟲ to zoom out; mouse wheel zoom is an option.
- **Play axis ★** with the shared Plume player: density changes from frame to frame with color and size transitions, a shared color scale (`colorScale.scope` = `all`) and an accumulate mode (`play.cumulative`).
- **Analytics ★**: contour lines (kernel density), marginal histograms aligned on the bins, least-squares trend on every point (per category, R², equation), reference lines; small multiples.

### 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 (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium**.
- Free in Hexbin Plume: hexagons and squares, every size and value setting (minimum points per bin with hidden bins), gradient, one color and dominant category coloring, linear and square root scales, fixed bounds, points, labels, axes (linear or log), legend, zoom and semantic zoom, cross-filtering, cross-highlighting, tooltips.
- Rebalanced on 10/22/2026 (visual never published before): the play axis, the log and diverging color scales, ignoring extreme values and drawing sparse bins as points became premium.
- Premium features of Hexbin Plume:
  - `dataColors.mode` = `purity` (dominant category and its share), `compare` (difference between two categories), `change` (change between frames) — only when the Legend (or Play axis for `change`) field is filled;
  - `bins.shape` = `circle` or `triangle`; `bins.sizeBy` = `count` or `value` (proportional size, bivariate hexbin);
  - the `play` role (Play axis ★, card « Playback ★ »): watermark as soon as the field is filled;
  - `colorScale.scale` = `quantile` or `thresholds`; `colorScale.scale` = `log`, `colorScale.diverging`, `colorScale.clip` — only when the gradient uses them (`dataColors.mode` = `gradient` or `single`);
  - `bins.sparse` = `points` — only when `bins.minCount` ≥ 2;
  - the `multiples` role (Small multiples ★); `marginals.show`; `contours.show`; `trend.show`; reference lines (`reference.*`).
- 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 `hexbin` 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, key accepted for 30 more days, reminders 30 and 7 days before the end). Prices: 39 € personal, 99 € SME, 299 € enterprise per year, or the catalog pack (199 € / 399 € / 1,199 € per year; tiers by number of users: personal 1–10, SME 11–200, enterprise more than 200).

### Expected data shape

One row per point: an ID in Details, two measures for the position.

| Details (`details`) | Legend (`legend`) | Play axis (`play`) | X axis (`x`) | Y axis (`y`) | Value (`value`) |
|---|---|---|---|---|---|
| L00001 | Bristol | 2023 | 48 | 212,000 | 760 |
| L00002 | York | 2021 | 95 | 218,000 | 1,090 |

- **Details (one point each)** (`details`, « Détails (un point par valeur) », one column): one point per value. Without it Power BI aggregates everything into one point (or one per legend value).
- **Legend (category)** (`legend`, « Légende (catégorie) », one column): category of each point; categories are sorted; beyond 12 the least frequent are grouped into "Others".
- **X axis**, **Y axis** (`x`, `y`, one measure each, required). Date-typed measures are shown as dates.
- **Value (per bin)** (`value`, « Valeur (par case) », one measure): aggregated in each bin with `bins.aggregate`.
- **Play axis ★** (`play`, « Axe de lecture ★ », one column): one frame per value; numbers and dates sorted. Premium: watermark without a key as soon as it holds data.
- **Small multiples ★** (`multiples`, one column): one chart per value, same axes, bins and colors (36 at most).
- **Tooltips** (`tooltips`): their average is added to a bin's tooltip; their value to a point's tooltip. **Dynamic format** (`format`, see below).
- The selection ID of a point is made of Details, Legend and Small multiples (not the play axis): clicking a bin selects all its items in every frame.

### DAX recipes

```dax
// One home per point (Details = Homes[Home]): an average returns the home's value
Average area = AVERAGE ( Homes[Area] )
Average price = AVERAGE ( Homes[Price] )
Average rent = AVERAGE ( Homes[Rent] )

// Dynamic title (renamed title.text in the Dynamic format well)
Density title = FORMAT ( CALCULATE ( COUNTROWS ( Homes ), ALLSELECTED () ), "#,0" ) & " homes: price vs area"

// 100,004-row test table
Points = ADDCOLUMNS ( GENERATESERIES ( 1, 100004, 1 ), "X", 40 + MOD ( [Value] * 7919, 120 ), "Y", 1500 + MOD ( [Value] * 104729, 2500 ) )
```

### Interactions with the report

- Click a bin: cross-filter on all its points (selection IDs of every point, deduplicated); Ctrl to add; clicking the only selected bin again clears. Drag: rectangle or lasso selection. Click a legend item: that category. Click an empty area: clear.
- Cross-highlighting from other visuals (`supportsHighlight`): each bin shows the highlighted share as an inner bin of proportional area; the selection is drawn the same way.
- Hover a bin: outline, its points (`points.show` = `hover`), Power BI tooltip: frame, panel, number of points and share, aggregate, X and Y ranges of the bin, dominant category and share, A / B shares and gap (compare), before and change (change), highlighted count, averages of the Tooltips measures; report-page tooltips receive up to 300 point identities.
- Context menu everywhere (bin = first point of the bin, point, empty area, axes, title, start screen). Keyboard: Tab, arrows from bin to bin, Enter selects, Esc clears; player keys (Space, arrows, Home, End) on the play bar. High contrast: bins drawn with the host colors and sized by count; French and English.
- Zoom, frame and speed are session state: nothing is saved with persistProperties.

### Dynamic formats

- **fx button** (Power BI conditional formatting) on colors and texts of the Format pane.
- **"Dynamic format" well** (`format`): measures renamed `card.setting` (e.g. `bins.radius`, `colorScale.scale`, `title.text`) drive any setting and win over the fixed value. Driving a ★ setting by DAX still shows the watermark without a key.

```dax
// renamed bins.sizeMode and bins.radius
Bin size mode = "radius"
Bin radius = IF ( COUNTROWS ( ALLSELECTED ( Homes ) ) > 20000, 10, 16 )
```

### Format pane: option IDs

- Card order: `license`, `style`, `dataColors`, `bins`, `colorScale`, `points`, `labels`, `xAxis`, `yAxis`, `legend`, `play`, `zoom`, `smallMultiples`, `marginals`, `contours`, `interaction`, then `title`, `source`, `container`, `texts`; Analytics pane: `reference`, `trend`. Format pane in version 1.1.0.0 (30/10/2026), top to bottom: `license`, `style`, `dataColors`, `bins`, `colorScale`, `points`, `labels`, `xAxis`, `yAxis`, `gridlines`, `legend`, `play`, `zoom`, `smallMultiples`, `marginals`, `contours`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`; Analytics pane: `reference`, `trend`, `symmetry`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- `dataColors`: `mode` (`gradient` | `single` | `category` | `purity` ★ | `compare` ★ | `change` ★), `single`, `fill` (per category), `compareA`, `compareB` (text; empty = most frequent / all the others), `changeRef` (`previous` | `first`).
- `bins`: `shape` (`hexagon` | `square` | `circle` ★ | `triangle` ★), `orientation` (`pointy` | `flat`), `sizeMode` (`auto` | `radius` | `columns`), `radius` (4–80, 14), `columns` (3–200, 24), `gap` (0–12, 1), `roundness` (0–100, 0), `aggregate` (`auto` | `count` | `percent` | `sum` | `average` | `median` | `min` | `max`), `minCount` (1–10,000, 1), `sparse` (`hide` | `points` ★), `sizeBy` (`none` | `count` ★ | `value` ★), `minSize` (5–100, 25), `opacity` (10–100, 100), `outline`, `outlineColor`, `outlineWidth` (0.5–6, 1), `emptyGrid`.
- `colorScale`: `scale` (`linear` | `sqrt` | `log` ★ | `quantile` ★ | `thresholds` ★), `classes` (2–9, 5), `thresholds` (text, `10; 50; 100`), `diverging` ★, `center` (`zero` | `average` | `median` | `constant`), `centerValue`, `min`, `max` (text, empty = auto), `clip` ★, `scope` (`all` | `frame`).
- `points`: `show` (`hover` | `zoom` | `always` | `none`), `threshold` (50–20,000, 1,500), `size` (1–12, 2.5), `color`, `opacity` (10–100, 70).
- `labels`: `show`, `content` (`value` | `count` | `percent` | `category`), `which` (`top` | `all`), `n` (10), `fontSize`, `color`, `bold`, `halo`, `declutter`, `units`, `decimals`, `prefix`, `suffix`.
- `xAxis`, `yAxis`: the shared value-axis settings (`scale` `linear` | `log`, `min`, `max`, `zero`, `ticks`, `invert`, titles, gridlines, `zeroLine`…).
- `play` ★: `start`, `speed`, `loop`, `autoPlay`, `transition`, `controls`, `position`, `ticks`, `tickLabels`, `stepButtons`, `speedButton`, `showLabel`, `labelSize`, `labelPosition`, `cumulative`.
- `zoom`: `rect` (on), `wheel` (off), `refine` (on). `smallMultiples`: `columns`, `minHeight`, `gap`, `titleSize`, `border`. `marginals` ★: `show`, `size` (40), `color`. `contours` ★: `show`, `levels` (5), `bandwidth` (0 = auto), `color`, `width`. `trend` ★: `show`, `perCategory`, `showR2`, `showEquation`, `color`, `style`, `width`. `interaction`: `hover`, `dim`, `brush`, `brushShape` (`rectangle` | `lasso`), `hoverOutline`.

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. Booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes.

```json
{
  "visualType": "plumeHexbinE30C7F7C4238475A8F1967FA03B31913",
  "query": {
    "queryState": {
      "details": { "projections": [ { "field": { "Column":  { "Expression": { "SourceRef": { "Entity": "Homes" } }, "Property": "Home" } }, "queryRef": "Homes.Home", "nativeQueryRef": "Home" } ] },
      "x":       { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Homes" } }, "Property": "Average area" } }, "queryRef": "Homes.Average area", "nativeQueryRef": "Average area" } ] },
      "y":       { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Homes" } }, "Property": "Average price" } }, "queryRef": "Homes.Average price", "nativeQueryRef": "Average price" } ] }
    }
  },
  "objects": {
    "bins":       [ { "properties": { "sizeMode": { "expr": { "Literal": { "Value": "'radius'" } } }, "radius": { "expr": { "Literal": { "Value": "16D" } } } } } ],
    "dataColors": [ { "properties": { "mode": { "expr": { "Literal": { "Value": "'gradient'" } } } } } ],
    "license":    [ { "properties": { "key": { "expr": { "Literal": { "Value": "'PLUM1.…'" } } } } } ]
  }
}
```

The custom visual package must also be embedded in the report (Power BI does this when the visual is imported from the `.pbiviz` file).

### Styles and theme JSON

- `style.preset` takes one of the 20 style IDs shared by every Plume visual: `none`, `minimal`, `blackWhite`, `press`, `vintage`, `earth`, `nordic`, `executive`, `accessible`, `pastel`, `bauhaus`, `climate`, `blueprint`, `unknownPleasures`, `dark`, `neon`, `terminal`, `infographic`, `cockpit`, `hologram`. The gradient follows the style's sequential palette, oriented so that small values are closest to the background; diverging modes use its diverging palette; categories use its categorical colors.
- `style.themeJson` (Theme JSON ★): a JSON theme as plain text (format v2 with optional `extends` and groups `colors`, `palettes`, `typography`, `shape`, `table`, `marks`, `effects`). Full reference: https://plumevisuals.com/ai/tutorials/en/themes-json.md.

### Common pitfalls

- A single bin: the Details field is empty, Power BI aggregates everything.
- "No point to show": X or Y holds no numbers.
- Every bin has the same color: one point per bin (bins too small or little data); use a larger radius.
- Coloring by category, difference or change does not apply, with a message in edit mode: the Legend (or Play axis) field is missing; the gradient applies, without watermark.
- Points missing with a log axis: zero or negative values are left out and reported in edit mode.
- A click on a very dense bin takes a second: it selects tens of thousands of points; zoom in first.
- Watermark visible: a Play axis field, a log or diverging color scale, extreme values ignored, sparse bins drawn as points, a ★ coloring, circles or triangles, proportional size, classes or thresholds, small multiples, marginal histograms, contour lines, trend, reference lines, a ★ style or a theme JSON, without a valid key.
- The visual makes no network request: data and license key stay in the report; no R or Python.

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

Geographic hexbins on a map (latitude / longitude with a basemap), 3D extruded bins, a mode or distinct count of a text column per bin, images per bin, annotations added by clicking, exporting the chart as an image, saving the zoom or the current frame in the report.

## Hexbin Plume: data fields

- `details` Details (one point each) / Détails (un point par valeur) (column, 1 max): One point per value (customer, order, sensor reading…). Without it, Power BI adds up the measures into one point per legend value.
- `legend` Legend (category) / Légende (catégorie) (column, 1 max): Category of each point: dominant category per bin, comparison of two groups ★
- `x` X axis / Axe X (measure, 1 max): 
- `y` Y axis / Axe Y (measure, 1 max): 
- `value` Value (per bin) / Valeur (par case) (measure, 1 max): Measure aggregated in each bin (sum, average, median, minimum, maximum). Empty = number of points.
- `play` Play axis ★ / Axe de lecture ★ ★ (column, 1 max): Premium: a date, a year or an ordered category; the density moves from one value to the next (play button).
- `multiples` Small multiples ★ / Petits multiples ★ ★ (column, 1 max): One small hexbin chart per value, sharing the same axes, bins and colors
- `tooltips` Tooltips / Infobulles (measure, several max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Hexbin Plume: Format pane options (272)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Data colors / Couleurs des données (`dataColors`, one entry per item with a selector)
- `dataColors.mode` Coloring / Coloration: dropdown, default `gradient`; values: `gradient` Gradient by value; `single` One color (intensity by value); `category` Dominant category (Legend field); `purity` Dominant category and its share ★; `compare` Difference between two categories ★; `change` Change between frames (play axis) ★
- `dataColors.single` Color / Couleur: color, default (empty); values: hex color
- `dataColors.fill` Color / Couleur: color, default (empty); values: hex color
- `dataColors.compareA` Category A (empty = most frequent) / Catégorie A (vide = la plus fréquente): text, default (empty). A value of the Legend field. Each bin shows which category is over-represented: its share of A minus its share of B.
- `dataColors.compareB` Category B (empty = all the others) / Catégorie B (vide = toutes les autres): text, default (empty)
- `dataColors.changeRef` Compare with / Comparer à: dropdown, default `previous`; values: `previous` The previous frame; `first` The first frame

### Bins / Cases (`bins`)
- `bins.shape` Shape / Forme: dropdown, default `hexagon`; values: `hexagon` Hexagons; `square` Squares; `circle` Circles ★; `triangle` Triangles ★
- `bins.orientation` Orientation: dropdown, default `pointy`; values: `pointy` Pointy top; `flat` Flat top. Visible when `bins.shape` = `hexagon` or `circle`
- `bins.sizeMode` Bin size / Taille des cases: dropdown, default `auto`; values: `auto` Automatic; `radius` Radius (px); `columns` Number of columns. Automatic: about one bin per 260 px² (450 on a medium visual), larger when there are few points. Radius stays the same when the visual is resized; columns follow its width.
- `bins.radius` Radius (px) / Rayon (px): number, default `14`; values: 4 to 80. Visible when `bins.sizeMode` = `radius`
- `bins.columns` Columns / Colonnes: number, default `24`; values: 3 to 200. Visible when `bins.sizeMode` = `columns`
- `bins.gap` Spacing (px) / Espacement (px): number, default `1`; values: 0 to 12
- `bins.roundness` Corner rounding (%) / Arrondi des angles (%): number, default `0`; values: 0 to 100
- `bins.aggregate` Calculation / Calcul: dropdown, default `auto`; values: `auto` Automatic; `count` Number of points; `percent` Share of points (%); `sum` Sum; `average` Average; `median` Median; `min` Minimum; `max` Maximum. Automatic: average of the Value field when it is filled, otherwise the number of points.
- `bins.minCount` Minimum points per bin / Points au minimum par case: number, default `1`; values: 1 to 10000. Bins with fewer points are hidden (or drawn as points, below).
- `bins.sparse` Bins under the minimum / Cases sous le minimum: dropdown, default `hide`; values: `hide` Hidden; `points` Drawn as points (isolated values) ★
- `bins.sizeBy` Bin size by / Taille des cases selon: dropdown, default `none`; values: `none` Nothing (full bins); `count` The number of points ★; `value` The bin value ★. Bivariate hexbin: with the Value field, the color shows its average (or sum…) and “The number of points” sizes the bins.
- `bins.minSize` Smallest bin size (%) / Taille de la plus petite case (%): number, default `25`; values: 5 to 100. Visible when `bins.sizeBy` = `count` or `value`
- `bins.opacity` Opacity (%) / Opacité (%): number, default `100`; values: 10 to 100
- `bins.outline` Outline / Contour: toggle, default `false`; values: true / false
- `bins.outlineColor` Outline color (empty = background) / Couleur du contour (vide = fond): color, default (empty); values: hex color. Visible when `bins.outline` = `true`
- `bins.outlineWidth` Outline width / Épaisseur du contour: number, default `1`; values: 0.5 to 6. Visible when `bins.outline` = `true`
- `bins.emptyGrid` Grid of empty bins / Grille des cases vides: toggle, default `false`; values: true / false. Draws the outline of every bin of the grid, even the empty ones.

### Color scale / Échelle de couleurs (`colorScale`)
- `colorScale.scale` Scale / Échelle: dropdown, default `sqrt`; values: `linear` Linear; `sqrt` Square root (more shades for small values); `log` Logarithmic ★; `quantile` Equal-count classes ★; `thresholds` Custom thresholds ★
- `colorScale.classes` Number of classes / Nombre de classes: number, default `5`; values: 2 to 9. Visible when `colorScale.scale` = `quantile`
- `colorScale.thresholds` Thresholds / Seuils: text, default (empty). Visible when `colorScale.scale` = `thresholds`. Values separated by semicolons: one color class between two thresholds.
- `colorScale.diverging` Diverging scale (around a center) ★ / Échelle divergente (autour d'un centre) ★ ★: toggle, default `false`; values: true / false. Uses the diverging palette of the style: below the center on one side, above it on the other (margins, gaps to a target).
- `colorScale.center` Center / Centre: dropdown, default `zero`; values: `zero` Zero; `average` Average of the bins; `median` Median of the bins; `constant` Fixed value. Visible when `colorScale.diverging` = `true`
- `colorScale.centerValue` Center value / Valeur du centre: number, default `0`. Visible when `colorScale.center` = `constant`
- `colorScale.min` Minimum: text, default (empty)
- `colorScale.max` Maximum: text, default (empty)
- `colorScale.clip` Ignore extreme values (2% on each side) ★ / Ignorer les valeurs extrêmes (2 % de chaque côté) ★ ★: toggle, default `false`; values: true / false. The gradient goes from the 2nd to the 98th percentile of the bins: one very dense bin no longer washes out the others.
- `colorScale.scope` Scale with a play axis / Échelle avec un axe de lecture: dropdown, default `all`; values: `all` Shared by all frames; `frame` Per frame. Shared: the same color means the same value in every frame (densities can be compared over time).

### Points (`points`)
- `points.show` Show points / Afficher les points: dropdown, default `hover`; values: `hover` Those of the hovered bin; `zoom` When few remain (zoom); `always` Always; `none` Never. When few: points appear over the bins as soon as the view holds fewer than the number below (zoom in to see them).
- `points.threshold` Maximum visible points / Nombre de points visibles au plus: number, default `1500`; values: 50 to 20000. Visible when `points.show` = `zoom`
- `points.size` Size (px) / Taille (px): number, default `2.5`; values: 1 to 12
- `points.color` Color (empty = text or category) / Couleur (vide = texte ou catégorie): color, default (empty); values: hex color
- `points.opacity` Opacity (%) / Opacité (%): number, default `70`; values: 10 to 100

### Data labels / Étiquettes de données (`labels`)
- `labels.show` Show / Afficher: toggle, default `false`; values: true / false
- `labels.content` Content / Contenu: dropdown, default `value`; values: `value` Bin value; `count` Number of points; `percent` Share of points; `category` Dominant category
- `labels.which` Labeled bins / Cases étiquetées: dropdown, default `top`; values: `top` Largest values (N); `all` All where the text fits
- `labels.n` N: number, default `10`; values: 1 to 500. Visible when `labels.which` = `top`
- `labels.fontSize` Size / Taille: number, default `10`; values: 6 to 24
- `labels.color` Color (empty = automatic) / Couleur (vide = automatique): color, default (empty); values: hex color. Automatic: readable color depending on the background (inside bars: white or dark).
- `labels.bold` Bold / Gras: toggle, default `false`; values: true / false
- `labels.halo` Text halo / Halo autour du texte: toggle, default `true`; values: true / false
- `labels.declutter` Hide overlapping labels / Masquer les étiquettes qui se chevauchent: toggle, default `true`; values: true / false
- `labels.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `labels.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `labels.prefix` Prefix / Préfixe: text, default (empty)
- `labels.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)

### X axis / Axe X (`xAxis`)
- `xAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `xAxis.position` Position: dropdown, default `bottom`; values: `bottom` Bottom; `top` Top
- `xAxis.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `xAxis.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `xAxis.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `xAxis.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `xAxis.prefix` Prefix / Préfixe: text, default (empty)
- `xAxis.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)
- `xAxis.line` Axis line / Trait de l'axe: toggle, default `false`; values: true / false
- `xAxis.scale` Scale / Échelle: dropdown, default `linear`; values: `linear` Linear; `log` Logarithmic
- `xAxis.min` Minimum: text, default (empty). Minimum and maximum accept a measure (Dynamic format field: xAxis.min, xAxis.max, yAxis.min, yAxis.max) to keep the same scale when another visual filters this one.
- `xAxis.max` Maximum: text, default (empty). Minimum and maximum accept a measure (Dynamic format field: xAxis.min, xAxis.max, yAxis.min, yAxis.max) to keep the same scale when another visual filters this one.
- `xAxis.zero` Always include zero / Toujours inclure zéro: toggle, default `false`; values: true / false. Visible when `xAxis.scale` = `linear`
- `xAxis.ticks` Number of ticks (approx.) / Nombre de graduations (environ): number, default `5`; values: 2 to 20
- `xAxis.invert` Invert axis / Inverser l'axe: toggle, default `false`; values: true / false
- `xAxis.round` Round range / Arrondir la plage: toggle, default `true`; values: true / false. Computed bounds rounded to a round tick. Off: the axis stops at the extreme values.
- `xAxis.showTitle` Show / Afficher: toggle, default `false`; values: true / false
- `xAxis.titleText` Text / Texte: text, default (empty). Visible when `xAxis.showTitle` = `true`

### Y axis / Axe Y (`yAxis`)
- `yAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `yAxis.position` Position: dropdown, default `left`; values: `left` Left; `right` Right
- `yAxis.fontSize` Size / Taille: number, default `9`; values: 6 to 24
- `yAxis.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `yAxis.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `yAxis.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `yAxis.prefix` Prefix / Préfixe: text, default (empty)
- `yAxis.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)
- `yAxis.line` Axis line / Trait de l'axe: toggle, default `false`; values: true / false
- `yAxis.scale` Scale / Échelle: dropdown, default `linear`; values: `linear` Linear; `log` Logarithmic
- `yAxis.min` Minimum: text, default (empty). Minimum and maximum accept a measure (Dynamic format field: xAxis.min, xAxis.max, yAxis.min, yAxis.max) to keep the same scale when another visual filters this one.
- `yAxis.max` Maximum: text, default (empty). Minimum and maximum accept a measure (Dynamic format field: xAxis.min, xAxis.max, yAxis.min, yAxis.max) to keep the same scale when another visual filters this one.
- `yAxis.zero` Always include zero / Toujours inclure zéro: toggle, default `false`; values: true / false. Visible when `yAxis.scale` = `linear`
- `yAxis.ticks` Number of ticks (approx.) / Nombre de graduations (environ): number, default `5`; values: 2 to 20
- `yAxis.invert` Invert axis / Inverser l'axe: toggle, default `false`; values: true / false
- `yAxis.round` Round range / Arrondir la plage: toggle, default `true`; values: true / false. Computed bounds rounded to a round tick. Off: the axis stops at the extreme values.
- `yAxis.showTitle` Show / Afficher: toggle, default `false`; values: true / false
- `yAxis.titleText` Text / Texte: text, default (empty). Visible when `yAxis.showTitle` = `true`

### Gridlines / Quadrillage (`gridlines`)
- `gridlines.hShow` Show / Afficher: toggle, default `true`; values: true / false
- `gridlines.hColor` Color (empty = style grid) / Couleur (vide = grille du style): color, default (empty); values: hex color
- `gridlines.hWidth` Width / Épaisseur: number, default `1`; values: 0.5 to 6
- `gridlines.hStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `gridlines.zeroLine` Zero line / Ligne du zéro: toggle, default `true`; values: true / false
- `gridlines.vShow` Show / Afficher: toggle, default `false`; values: true / false
- `gridlines.vColor` Color (empty = style grid) / Couleur (vide = grille du style): color, default (empty); values: hex color
- `gridlines.vWidth` Width / Épaisseur: number, default `1`; values: 0.5 to 6
- `gridlines.vStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `gridlines.plotColor` Background color (empty = none) / Couleur d'arrière-plan (vide = aucune): color, default (empty); values: hex color
- `gridlines.plotTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100

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

### Zoom (`zoom`)
- `zoom.x` X axis zoom slider / Curseur de zoom de l'axe X: toggle, default `false`; values: true / false
- `zoom.y` Y axis zoom slider / Curseur de zoom de l'axe Y: toggle, default `false`; values: true / false
- `zoom.rect` Shift + drag: zoom into a rectangle / Maj + glisser : zoomer sur un rectangle: toggle, default `true`; values: true / false. Double-click the chart, or the ⟲ button, to zoom out.
- `zoom.wheel` Mouse wheel: zoom / Molette : zoomer: toggle, default `false`; values: true / false. Off by default so that the report page keeps scrolling.
- `zoom.refine` Semantic zoom: refine the bins / Zoom sémantique : affiner les cases: toggle, default `true`; values: true / false. Zooming in keeps the bins the same size on screen, so each covers a smaller range of values: the detail appears.

### Marginal histograms ★ / Histogrammes en marge ★ (`marginals`)
- `marginals.show` Show ★ / Afficher ★ ★: toggle, default `false`; values: true / false. Distribution of X above the chart and of Y on its right, with the same classes as the bins.
- `marginals.size` Height (px) / Hauteur (px): number, default `40`; values: 16 to 160
- `marginals.color` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color

### Contour lines ★ / Lignes de niveau ★ (`contours`)
- `contours.show` Show ★ / Afficher ★ ★: toggle, default `false`; values: true / false. Smoothed density of the points drawn as contour lines over the bins.
- `contours.levels` Number of lines / Nombre de lignes: number, default `5`; values: 2 to 15
- `contours.bandwidth` Smoothing (px, 0 = automatic) / Lissage (px, 0 = automatique): number, default `0`; values: 0 to 120
- `contours.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `contours.width` Width / Épaisseur: number, default `1.2`; values: 0.5 to 4

### Small multiples ★ / Petits multiples ★ (`smallMultiples`)
- `smallMultiples.columns` Columns (0 = automatic) / Colonnes (0 = automatique): number, default `0`; values: 0 to 12
- `smallMultiples.minHeight` Minimum chart height (px) / Hauteur minimale d'un graphique (px): number, default `120`; values: 60 to 600
- `smallMultiples.gap` Spacing (px) / Espacement (px): number, default `12`; values: 0 to 60
- `smallMultiples.titleSize` Title size / Taille des titres: number, default `10`; values: 6 to 24
- `smallMultiples.border` Frame around each chart / Cadre autour de chaque graphique: toggle, default `false`; values: true / false

### Playback ★ / Lecture ★ (`play`)
- `play.start` Frame shown on opening / Image affichée à l'ouverture: dropdown, default `last`; values: `last` The last one (most recent); `first` The first one
- `play.speed` Duration of a frame (ms) / Durée d'une image (ms): number, default `1000`; values: 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, default `false`; values: true / false
- `play.autoPlay` Play automatically on opening / Lecture automatique à l'ouverture: toggle, default `false`; values: 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, default `true`; values: true / false. Values, positions and colors move smoothly from one frame to the next.
- `play.controls` Play bar / Barre de lecture: toggle, default `true`; values: true / false
- `play.position` Bar position / Position de la barre: dropdown, default `bottom`; values: `bottom` Bottom; `top` Top. Visible when `play.controls` = `true`
- `play.ticks` Tick marks / Graduations: dropdown, default `auto`; values: `auto` Automatic; `all` Every frame; `none` None. Visible when `play.controls` = `true`
- `play.tickLabels` Tick labels / Étiquettes des graduations: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.stepButtons` Start and end buttons / Boutons début et fin: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.speedButton` Speed button / Bouton de vitesse: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.showLabel` Current value in large type / Valeur en cours en grand: toggle, default `true`; values: true / false
- `play.labelSize` Large value size / Taille de la valeur en grand: number, default `44`; values: 12 to 160. Visible when `play.showLabel` = `true`
- `play.labelPosition` Large value position / Position de la valeur en grand: dropdown, default `bottomRight`; values: `bottomRight` Bottom right; `topRight` Top right; `topLeft` Top left; `bottomLeft` Bottom left; `center` Center. Visible when `play.showLabel` = `true`
- `play.cumulative` Accumulate frames / Cumuler les images: toggle, default `false`; values: true / false. Each frame shows every point up to it (the density builds up over time).

### Interactions (`interaction`)
- `interaction.hover` Highlight on hover / Mettre en avant au survol: toggle, default `true`; values: true / false
- `interaction.dim` Dimmed items opacity (%) / Opacité des éléments estompés (%): number, default `25`; values: 5 to 80
- `interaction.hlScale` Scale during cross-highlighting / Échelle pendant une surbrillance croisée: dropdown, default `all`; values: `all` All data (the scale stays); `highlighted` Refocus on the highlighted points. When another visual sends a highlight (Format › Edit interactions › Highlight), the axes and colors keep all the data; a filter removes the points: then set the axis minimum and maximum with a measure (Dynamic format).
- `interaction.brush` Select by drawing a rectangle / Sélection en traçant un rectangle: toggle, default `true`; values: true / false. Drag on the chart to select every point inside (Ctrl to add). A click on a bin selects all its points.
- `interaction.brushShape` Selection shape / Forme de la sélection: dropdown, default `rectangle`; values: `rectangle` Rectangle; `lasso` Lasso (freehand). Visible when `interaction.brush` = `true`
- `interaction.hoverOutline` Outline the hovered bin / Souligner la case survolée: toggle, default `true`; values: true / false

### Reference lines ★ / Lignes de référence ★ (`reference`, Analytics pane)
- `reference.show1` Show / Afficher: toggle, default `false`; values: true / false
- `reference.axis1` Axis / Axe: dropdown, default `y`; values: `y` Y axis (horizontal); `x` X axis (vertical)
- `reference.kind1` Value / Valeur: dropdown, default `average`; values: `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile
- `reference.value1` Constant value / Valeur constante: number, default `0`. Visible when `reference.kind1` = `constant`
- `reference.pct1` Percentile / Centile: number, default `90`; values: 1 to 99. Visible when `reference.kind1` = `percentile`
- `reference.label1` Label / Libellé: text, default (empty)
- `reference.showValue1` Show the value / Afficher la valeur: toggle, default `true`; values: true / false
- `reference.color1` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.style1` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `reference.width1` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `reference.labelPos1` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None
- `reference.show2` Show / Afficher: toggle, default `false`; values: true / false
- `reference.axis2` Axis / Axe: dropdown, default `y`; values: `y` Y axis (horizontal); `x` X axis (vertical)
- `reference.kind2` Value / Valeur: dropdown, default `constant`; values: `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile
- `reference.value2` Constant value / Valeur constante: number, default `0`. Visible when `reference.kind2` = `constant`
- `reference.pct2` Percentile / Centile: number, default `90`; values: 1 to 99. Visible when `reference.kind2` = `percentile`
- `reference.label2` Label / Libellé: text, default (empty)
- `reference.showValue2` Show the value / Afficher la valeur: toggle, default `true`; values: true / false
- `reference.color2` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.style2` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `reference.width2` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `reference.labelPos2` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None
- `reference.show3` Show / Afficher: toggle, default `false`; values: true / false
- `reference.axis3` Axis / Axe: dropdown, default `y`; values: `y` Y axis (horizontal); `x` X axis (vertical)
- `reference.kind3` Value / Valeur: dropdown, default `median`; values: `constant` Constant; `average` Average; `median` Median; `min` Minimum; `max` Maximum; `percentile` Percentile
- `reference.value3` Constant value / Valeur constante: number, default `0`. Visible when `reference.kind3` = `constant`
- `reference.pct3` Percentile / Centile: number, default `90`; values: 1 to 99. Visible when `reference.kind3` = `percentile`
- `reference.label3` Label / Libellé: text, default (empty)
- `reference.showValue3` Show the value / Afficher la valeur: toggle, default `true`; values: true / false
- `reference.color3` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.style3` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `reference.width3` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `reference.labelPos3` Label position / Position du libellé: dropdown, default `end`; values: `end` End; `start` Start; `none` None
- `reference.band` Show / Afficher: toggle, default `false`; values: true / false
- `reference.bandAxis` Axis / Axe: dropdown, default `y`; values: `y` Y axis; `x` X axis
- `reference.bandFrom` From / De: number, default `0`
- `reference.bandTo` To / À: number, default `0`
- `reference.bandLabel` Label / Libellé: text, default (empty)
- `reference.bandColor` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `reference.bandOpacity` Opacity (%) / Opacité (%): number, default `12`; values: 2 to 60

### Trend ★ / Tendance ★ (`trend`, Analytics pane)
- `trend.show` Show / Afficher: toggle, default `false`; values: true / false. Least-squares line computed on every point (not on the bins).
- `trend.perCategory` One trend per category / Une tendance par catégorie: toggle, default `false`; values: true / false
- `trend.showR2` Show R² / Afficher le R²: toggle, default `true`; values: true / false
- `trend.showEquation` Show the equation / Afficher l'équation: toggle, default `false`; values: true / false
- `trend.color` Color (empty = text or category) / Couleur (vide = texte ou catégorie): color, default (empty); values: hex color
- `trend.style` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `trend.width` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6

### Symmetry and ratio / Symétrie et ratio (`symmetry`, Analytics pane)
- `symmetry.show` Show / Afficher: toggle, default `false`; values: true / false. Shades the areas where Y is above and below X, around the y = x diagonal (X and Y in the same unit).
- `symmetry.colorAbove` Color where Y > X (empty = favorable) / Couleur où Y > X (vide = favorable): color, default (empty); values: hex color
- `symmetry.colorBelow` Color where Y < X (empty = unfavorable) / Couleur où Y < X (vide = défavorable): color, default (empty); values: hex color
- `symmetry.opacity` Opacity (%) / Opacité (%): number, default `8`; values: 2 to 40
- `symmetry.diagonal` y = x diagonal / Diagonale y = x: toggle, default `true`; values: true / false
- `symmetry.ratio` Show / Afficher: toggle, default `false`; values: true / false. A line from the origin whose slope is the overall ratio Y ÷ X of the points (like Power BI), or a fixed slope.
- `symmetry.ratioMode` Slope / Pente: dropdown, default `total`; values: `total` Total Y ÷ total X; `constant` Fixed value
- `symmetry.ratioValue` Fixed slope / Pente fixe: number, default `1`. Visible when `symmetry.ratioMode` = `constant`
- `symmetry.ratioColor` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color
- `symmetry.ratioStyle` Line style / Style de trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `symmetry.ratioLabel` Show the slope / Afficher la pente: toggle, default `true`; values: true / false

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Heatmap Plume

- A grid, a calendar or peak hours: the color of each cell shows where values concentrate.
- Slug `heatmap` · version 1.1.0.0 · GUID (`visualType`) `plumeHeatmap1EF5C05AB0CA4FB0A57FFFF734DE95DF` · page https://plumevisuals.com/en/visuals/heatmap

### What the visual does

Heatmap Plume (identifier `heatmap`) is a Power BI custom visual (version 1.1.0.0, installed from its `.pbiviz` file; not yet on AppSource) that draws **heatmaps**: cells colored by a value. Power BI Desktop has no native heatmap (the usual workaround is a matrix with background-color conditional formatting).

**New in version 1.1.0.0 (30/10/2026):** Format pane reorganized (`heatmap.*` → `layout.*`, `compare` → `comparison`); free **class colors** (equal classes; quantiles and thresholds ★) and cell outline width.

- **Three heatmaps in one** (`layout.mode`, « Type », `auto` by default):
  - **Grid** (`grid`): `rows` ("Rows") × `columns` ("Columns"), one cell per combination;
  - **Calendar** (`calendar`): a single `date` field with days; one strip per year with weeks as columns (GitHub style) or one block per month; separated months; whole years or the data period;
  - **Day of week × hour** (`weekHour`): a single `date` field with date-times; the visual computes the weekday (first day of the week from the language or `calendar.weekStart`) and the hour itself (no DAX column needed).
  - Automatic rules: Rows or Columns → grid; a date alone → calendar (days), day × hour (date-times), year × month grid (dates on the 1st of each month, or a date hierarchy without the day); Rows + Date → one column per day, month or year (with a Play axis as well, monthly dates become the 12 months of the year).
- **Date hierarchy accepted**: Year / Quarter / Month / Day levels (French, English and other languages) are rebuilt into dates; no need to switch to the date column. Dates sent as ISO text are read as local dates.
- **Color scale** (`scale`): single hue from light to dark (default, base color `scale.color` or the style palette's key color), the style's gradient palette, or diverging ★ with a midpoint (`zero`, `mean`, `median`, `center`, fixed `value`); continuous or equal classes; square root ★; min / max; robust range ★ (2nd–98th percentile). A blank value is **never** shown as zero: hatched cells (grayed in the calendar), "Blank" in the legend and tooltip.
- **Values in the cells** with automatic white / dark text; value or day number, or % of row, % of column, % of total ★; **all or nothing** (if one label does not fit, none is written, unless `labels.fit` is off).
- Sorting rows by model order, name, total or the value in a named column; columns by model order, name or total; first N rows; margin totals as values or bars ★.
- Selection of a cell, a row name, a column name (in the calendar: a month, a weekday, a year) cross-filters the report; cross-highlighting from other visuals dims the other cells; Ctrl + click adds.
- Large grids scroll; only the visible cells are drawn (at most 40,000 at a time); 100,000 rows render in about 1.5 s.
- **Play axis ★** (`play`): the cells change color from one frame to the next with a transition; same scale for every frame by default.

### 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 (including Gradient: start / middle / end) are **free**; every other `style.preset`, the other gradient palettes (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium**.
- Free in Heatmap Plume: grid, calendar, day × hour, year × month; single hue and palette scales; continuous and equal classes; linear scale; min / max; empty cell styles; labels with the value or the day number; cell shapes, spacing, square cells, min / max size; sorting (model, name, total, column value), first N rows; legend and class emphasis; weekdays, months, years, weekends; hour range and format.
- Rebalanced on 22/10/2026 (moved from free to premium): play axis, diverging gradient, square root scale, ignore extreme values, margin totals as values, labels in %.
- Premium features of Heatmap Plume (watermark only where they are actually applied):
  - the `play` role ("Play axis ★") with data;
  - `scale.kind` = `diverging` (outside a comparison); `scale.method` = `quantiles` or `thresholds` (with at least one threshold); `scale.transform` = `sqrt` or `log`; `scale.robust` (unless both min and max are set); `scale.scope` = `row` or `column` (grids);
  - `layout.shape` = `radial` (grids and day × hour);
  - `cells.sizeBy` = `value`, or `field` with the `size` role filled;
  - `sort.rowsBy` / `sort.colsBy` = `similarity` (hierarchical clustering, average linkage on standardized profiles, 400 items at most, dendrogram `sort.dendrogram`);
  - `margins.rows` / `margins.cols` = `values`, `bars` or `barsValues` (grids);
  - `labels.content` = `pctRow`, `pctCol` or `pctTotal`;
  - `calendar.holidays` (`fr`, `be`, `ch`, `ca`, `de`, `gb`, `us`; calendar only);
  - the `note` role ("Annotation ★") with at least one text; the `reference` role ("Reference ★"); the `multiples` role ("Small multiples ★").
- 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 `heatmap` or the whole catalog. 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

| Rows (`rows`) | Columns (`columns`) | Value (`values`) |
|---|---|---|
| Drinks | Jan | 228,000 |
| Drinks | Feb | 205,000 |
| Dairy | Jan | 44,000 |

- **Rows** (`rows`, « Lignes », one column) and **Columns** (`columns`, « Colonnes », one column): model order (Power BI "Sort by column" respected); numbers and dates ascending.
- **Date (calendar, day × hour)** (`date`, « Date (calendrier, jour × heure) », one column or a date hierarchy).
- **Value (color)** (`values`, « Valeur (couleur) », one measure). Without it but with a Date, each cell counts its rows. Several rows in one cell are combined by `layout.aggregate` (`sum`, `average`, `min`, `max`, `count`).
- **Size ★** (`size`, one measure), **Reference ★** (`reference`, one measure: last year, target), **Annotation ★** (`note`, a text measure or column), **Play axis** (`play`), **Small multiples ★** (`multiples`), **Tooltips** (`tooltips`), **Dynamic format** (`format`).
- Volume: windows of 30,000 rows, more fetched with `fetchMoreData` up to 100,000 rows.

### DAX recipes

```dax
Total revenue = SUM ( Sales[Revenue] )
// Reference ★: last year (date table marked as date table)
Revenue LY = CALCULATE ( [Total revenue], SAMEPERIODLASTYEAR ( Dates[Date] ) )
// Annotation ★: the event of the day
Event of the day = SELECTEDVALUE ( Attendance[Event] )   // a measure cannot share a column name of its own table
// Dynamic title (renamed title.text in the Dynamic format well)
Title = "Revenue 2025 · total " & FORMAT ( CALCULATE ( [Total revenue], ALLSELECTED () ), "#,0" )
```

### Interactions with the report

- Click a cell: cross-filter on every row of the cell (all play-axis frames); Ctrl to add; click a row or column name (calendar: a month, weekday or year name) to select it all (`interaction.headers`). Click an empty area to clear. Context menu everywhere, including on names and on the landing page.
- Hover: outline of the cell, row and column names in the accent color (`interaction.crosshair`), Power BI tooltip (row, column or date and holiday, value, reference and difference, size, % if shown, annotation, Tooltips measures, count of rows); report-page tooltips are supported.
- Legend with classes: click a class to emphasize its cells (`legend.interactive`, no filter).
- Keyboard: Tab to the heatmap, arrows move in two dimensions (calendar: days and weeks), Home / End, Enter selects, Esc clears; announcements in French and English. High contrast: five density patterns instead of colors.
- The visual never saves anything itself (no `persistProperties`).

### Format pane: option IDs

- Card order: `license`, `style`, `scale`, `layout`, `cells`, `labels`, `legend`, `rowAxis`, `colAxis`, `sort`, `margins`, `calendar`, `comparison`, `annotations`, `play`, `smallMultiples`, `interaction`, then `title`, `source`, `container`, `texts`. Format pane in version 1.1.0.0 (30/10/2026), top to bottom: `license`, `style`, `layout`, `scale`, `cells`, `labels`, `rowAxis`, `colAxis`, `legend`, `sort`, `margins`, `calendar`, `comparison`, `annotations`, `smallMultiples`, `play`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- `scale`: `kind` (`auto` | `mono` | `palette` | `diverging` ★), `color`, `mid` (`zero` | `mean` | `median` | `center` | `value`), `midValue`, `empty` (`auto` | `hatch` | `light` | `hide`), `method` (`continuous` | `classes` | `quantiles` ★ | `thresholds` ★), `classes` (2–12, 5), `thresholds` (text `10; 50; 100`), `transform` (`linear` | `sqrt` ★ | `log` ★), `scope` (`all` | `row` ★ | `column` ★), `min`, `max` (text), `robust` ★.
- `layout`: `mode` (`auto` | `grid` | `calendar` | `weekHour`), `shape` (`grid` | `radial` ★), `inner` (0–80 %, 28), `aggregate` (`sum` | `average` | `min` | `max` | `count`).
- `cells`: `shape` (`square` | `rounded` | `circle`), `radius` (0–20, 3), `gap` (0–20, 2), `square`, `minSize` (2–80, 14), `maxSize` (0–400, 0 = fill), `sizeBy` (`none` | `value` ★ | `field` ★), `border`, `borderColor`.
- `labels`: `show`, `content` (`value` | `pctRow` ★ | `pctCol` ★ | `pctTotal` ★ | `day`), `fontSize` (10), `color`, `bold`, `fit`, `units`, `decimals`, `prefix`, `suffix`.
- `legend`: `show`, `position` (`top` | `bottom` | `right` | `left`), `align`, `showTitle`, `titleText`, `fontSize` (9), `color`, `length` (60–600, 160), `interactive`.
- `rowAxis`: `show`, `fontSize`, `color`, `bold`, `maxSize`, `showTitle`, `titleText`. `colAxis`: same plus `position` (`top` | `bottom`) and `labelMode` (`auto` | `wrap` | `rotate45` | `rotate90` | `truncate`).
- `sort`: `rowsBy` (`model` | `name` | `total` | `column` | `similarity` ★), `rowsOrder` (`desc` | `asc`), `rowsColumn` (column name; empty = last), `rowsTop` (0 = all), `colsBy` (`model` | `name` | `total` | `similarity` ★), `colsOrder`, `dendrogram`, `treeSize` (16–160, 40).
- `margins` ★: `rows`, `cols` (`none` | `values` ★ | `bars` ★ | `barsValues` ★), `agg` (`sum` | `average` | `max` | `min`), `size` (5–40 %, 12), `color`, `fontSize`.
- `calendar`: `weekStart` (`auto` | `monday` | `sunday` | `saturday`), `dayLabels` (`alternate` | `all` | `none`), `weekends`, `layout` (`weeks` | `months`), `range` (`years` | `data`), `monthGaps`, `monthLabels`, `yearLabels`, `maxYears` (1–50, 10), `holidays` (`none` | `fr` ★ | `be` ★ | `ch` ★ | `ca` ★ | `de` ★ | `gb` ★ | `us` ★), `markColor`, `hourStart` (0), `hourEnd` (23), `hourFormat` (`auto` | `h24` | `h12`).
- `comparison`: `mode` (`difference` | `percent`), `lowerIsBetter`, `arrows`. `annotations`: `marker` (`corner` | `dot` | `outline`), `color`.
- `play` ★ (shared player): `start` (`last` | `first`), `speed` (ms, 1000), `loop`, `autoPlay`, `transition`, `controls`, `position`, `ticks`, `tickLabels`, `stepButtons`, `speedButton`, `showLabel`, `labelSize`, `labelPosition`, `sameScale`.
- `smallMultiples`: `columns`, `minWidth`, `gap`, `titleSize`, `border`. `interaction`: `hover`, `dim` (5–80, 25), `crosshair`, `headers`.

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID `plumeHeatmap1EF5C05AB0CA4FB0A57FFFF734DE95DF`, `queryState` keys are the data role names (`rows`, `columns`, `date`, `values`, `size`, `reference`, `note`, `play`, `multiples`, `tooltips`, `format`), `objects` keys are the option IDs above. Booleans `true` / `false`, numbers suffixed with `D`, strings and enumeration values in single quotes.

```json
"objects": {
  "scale":   [ { "properties": { "kind": { "expr": { "Literal": { "Value": "'diverging'" } } }, "mid": { "expr": { "Literal": { "Value": "'zero'" } } } } } ],
  "margins": [ { "properties": { "rows": { "expr": { "Literal": { "Value": "'values'" } } } } } ]
}
```

### Common pitfalls

- A calendar appears instead of a grid: only a date is in the fields (add Rows / Columns or set `layout.mode` = `grid`).
- Months out of alphabetical order: sort the text month column by the month number in the model, or use a date.
- Hatched cells: no data for that combination (not a zero); `scale.empty` changes the look.
- No labels: one value does not fit (all or nothing); reduce `labels.fontSize`, use `labels.units`, or turn off `labels.fit`.
- The grid scrolls: `cells.minSize` keeps cells readable; lower it or use `sort.rowsTop`.
- Similarity sort falls back to total: more than 400 rows or columns.
- Watermark visible: one of the ★ settings listed above actually applied, a ★ style, palette or theme JSON, without a valid key.

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

Row hierarchies with expandable subtotals (use Matrix Plume), regional holidays (Alsace-Moselle, Swiss cantons, US states), fiscal-year calendars, dragging to select a date range, lines or reference bands, exporting the heatmap as an image, any network call (data and license key stay in the report).

## Heatmap Plume: data fields

- `rows` Rows / Lignes (column, 1 max): One row of cells per value (product, region, day of week…)
- `columns` Columns / Colonnes (column, 1 max): One column of cells per value (month, hour, year…)
- `date` Date (calendar, day × hour) / Date (calendrier, jour × heure) (column, 4 max): Alone: a calendar (dates), a day of week × hour grid (date-times) or a year × month grid. With Rows: the dates become the columns
- `values` Value (color) / Valeur (couleur) (measure, 1 max): The measure that colors the cells; without a measure, each cell counts its rows
- `size` Size ★ / Taille ★ ★ (measure, 1 max): A second measure shown by the size of the cells (number of orders behind an average, for example)
- `reference` Reference ★ / Référence ★ ★ (measure, 1 max): Last year, target or average: the cells are colored by their gap to it
- `note` Annotation ★ ★ (measure, 1 max): A text per cell (event, comment): a marker in the cell and the text in the tooltip
- `play` Play axis ★ / Axe de lecture ★ ★ (column, 1 max): A date, a year or an ordered category: the cells change color from one value to the next (play button) ★
- `multiples` Small multiples ★ / Petits multiples ★ ★ (column, 1 max): One small heatmap per value, with the same scale and the same order
- `tooltips` Tooltips / Infobulles (measure, several max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Heatmap Plume: Format pane options (189)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Layout / Disposition (`layout`)
- `layout.mode` Type: dropdown, default `auto`; values: `auto` Automatic (from the fields); `grid` Grid: rows × columns; `calendar` Calendar (a Date field); `weekHour` Day of week × hour (date-time). Automatic: Rows / Columns give a grid; a Date alone gives a calendar (days), a day × hour grid (date-times) or a year × month grid (months).
- `layout.shape` Shape / Forme: dropdown, default `grid`; values: `grid` Grid; `radial` Radial (columns around a circle) ★. Radial: the columns (hours, months) go around the circle and the rows become rings.
- `layout.inner` Center hole (% of the radius) / Trou central (% du rayon): number, default `28`; values: 0 to 80. Visible when `layout.shape` = `radial`
- `layout.aggregate` Several values in a cell / Plusieurs valeurs dans une case: dropdown, default `sum`; values: `sum` Sum; `average` Average; `min` Minimum; `max` Maximum; `count` Count of rows. Day × hour and calendar: how the rows of the same cell are combined (sum of sales, average temperature…).

### Color scale / Échelle de couleurs (`scale`)
- `scale.kind` Gradient / Dégradé: dropdown, default `auto`; values: `auto` Automatic (single hue, or the style palette); `mono` Single hue: light to dark; `palette` Gradient palette (Style card); `diverging` Diverging: two hues and a midpoint ★. The palettes (Viridis, Magma, Blues…) and the start / middle / end colors are chosen in Style › Custom colors.
- `scale.color` Hue (empty = style color) / Teinte (vide = couleur du style): color, default (empty); values: hex color. Visible when `scale.kind` = `auto` or `mono`
- `scale.mid` Scale midpoint / Milieu de l'échelle: dropdown, default `zero`; values: `zero` Zero; `mean` Average; `median` Median; `center` Center of the range; `value` Fixed value. Visible when `scale.kind` = `diverging`
- `scale.midValue` Midpoint value / Valeur du milieu: number, default `0`. Visible when `scale.kind` = `diverging`
- `scale.empty` Empty cells / Cases vides: dropdown, default `auto`; values: `auto` Automatic (hatched; grayed in the calendar); `hatch` Hatched; `light` Grayed; `hide` Hidden. A blank value is never shown as zero: a zero takes the color of the scale.
- `scale.method` Color distribution / Répartition des couleurs: dropdown, default `continuous`; values: `continuous` Continuous; `classes` Equal classes; `quantiles` Quantiles (same number of cells per class) ★; `thresholds` Custom thresholds ★
- `scale.classes` Number of classes / Nombre de classes: number, default `5`; values: 2 to 12. Visible when `scale.method` = `classes` or `quantiles`
- `scale.thresholds` Thresholds (separated by ;) / Seuils (séparés par ;): text, default (empty). Visible when `scale.method` = `thresholds`
- `scale.classColors` Class colors (empty = gradient) / Couleurs des classes (vide = dégradé): text, default (empty). Visible when `scale.method` = `classes` or `quantiles` or `thresholds`. Like the Rules of the native conditional formatting: one color per class, from the lowest to the highest, separated by ; (#RRGGBB or a color name). Missing colors come from the gradient.
- `scale.transform` Scale / Échelle: dropdown, default `linear`; values: `linear` Linear; `sqrt` Square root ★; `log` Logarithmic ★. Square root and logarithmic scales spread out small values when a few cells are very large.
- `scale.scope` Scale computed over / Échelle calculée sur: dropdown, default `all`; values: `all` All cells; `row` Each row ★; `column` Each column ★. Per row: each row has its own lightest and darkest cell (rows with different units or sizes).
- `scale.min` Minimum: text, default (empty)
- `scale.max` Maximum: text, default (empty)
- `scale.robust` Ignore extreme values (2% on each side) ★ / Ignorer les valeurs extrêmes (2 % de chaque côté) ★ ★: toggle, default `false`; values: true / false. The colors are spread between the 2nd and 98th percentiles: one huge cell no longer flattens all the others.

### Cells / Cases (`cells`)
- `cells.shape` Cell shape / Forme des cases: dropdown, default `rounded`; values: `square` Square; `rounded` Rounded corners; `circle` Circles
- `cells.radius` Corner radius (px) / Arrondi (px): number, default `3`; values: 0 to 20. Visible when `cells.shape` = `rounded`
- `cells.gap` Spacing (px) / Espacement (px): number, default `2`; values: 0 to 20
- `cells.square` Square cells in the grid / Cases carrées dans la grille: toggle, default `false`; values: true / false. The calendar always uses square cells.
- `cells.minSize` Minimum size before scrolling (px) / Taille minimale avant défilement (px): number, default `14`; values: 2 to 80. Large grids scroll (only the visible cells are drawn) instead of shrinking below this size.
- `cells.maxSize` Maximum size (px, 0 = fill) / Taille maximale (px, 0 = remplir): number, default `0`; values: 0 to 400
- `cells.sizeBy` Cell size / Taille des cases: dropdown, default `none`; values: `none` All full; `value` By value ★; `field` By the "Size" field ★. The color shows the value, the size shows how much data is behind it (or the value itself).
- `cells.border` Outline / Contour: toggle, default `false`; values: true / false
- `cells.borderColor` Outline color (empty = grid) / Couleur du contour (vide = grille): color, default (empty); values: hex color. Visible when `cells.border` = `true`
- `cells.borderWidth` Outline width (px) / Épaisseur du contour (px): number, default `1`; values: 0.5 to 6. Visible when `cells.border` = `true`

### Data labels / Étiquettes de données (`labels`)
- `labels.show` Show / Afficher: toggle, default `true`; values: true / false. Values are written in the cells that are large enough.
- `labels.content` Content / Contenu: dropdown, default `value`; values: `value` Value; `pctRow` % of row ★; `pctCol` % of column ★; `pctTotal` % of total ★; `day` Day number (calendar)
- `labels.fontSize` Text size / Taille du texte: number, default `10`; values: 6 to 32
- `labels.color` Color (empty = automatic) / Couleur (vide = automatique): color, default (empty); values: hex color. Automatic: white or dark text depending on each cell.
- `labels.bold` Bold / Gras: toggle, default `false`; values: true / false
- `labels.fit` Hide the labels when they do not all fit / Masquer les étiquettes quand elles ne tiennent pas toutes: toggle, default `true`; values: true / false. All or nothing: never a grid with labels in some cells only. Off: each label that fits is written.
- `labels.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `labels.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `labels.prefix` Prefix / Préfixe: text, default (empty)
- `labels.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)

### Row labels / Étiquettes des lignes (`rowAxis`)
- `rowAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `rowAxis.fontSize` Text size / Taille du texte: number, default `9`; values: 6 to 24
- `rowAxis.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `rowAxis.bold` Bold / Gras: toggle, default `false`; values: true / false
- `rowAxis.maxSize` Maximum room (% of the visual) / Place maximale (% du visuel): number, default `30`; values: 5 to 60
- `rowAxis.showTitle` Row title / Titre des lignes: toggle, default `false`; values: true / false
- `rowAxis.titleText` Title text / Texte du titre: text, default (empty). Visible when `rowAxis.showTitle` = `true`

### Column labels / Étiquettes des colonnes (`colAxis`)
- `colAxis.show` Show / Afficher: toggle, default `true`; values: true / false
- `colAxis.position` Position: dropdown, default `top`; values: `top` Top; `bottom` Bottom
- `colAxis.fontSize` Text size / Taille du texte: number, default `9`; values: 6 to 24
- `colAxis.color` Color (empty = secondary) / Couleur (vide = secondaire): color, default (empty); values: hex color
- `colAxis.bold` Bold / Gras: toggle, default `false`; values: true / false
- `colAxis.labelMode` Long labels / Étiquettes longues: dropdown, default `auto`; values: `auto` Automatic; `wrap` Two lines; `rotate45` Tilted (45°); `rotate90` Vertical; `truncate` Truncated (…)
- `colAxis.maxSize` Maximum room (% of the visual) / Place maximale (% du visuel): number, default `30`; values: 5 to 60
- `colAxis.showTitle` Column title / Titre des colonnes: toggle, default `false`; values: true / false
- `colAxis.titleText` Title text / Texte du titre: text, default (empty). Visible when `colAxis.showTitle` = `true`

### Legend / Légende (`legend`)
- `legend.show` Show / Afficher: toggle, default `true`; values: true / false
- `legend.position` Position: dropdown, default `top`; values: `top` Top; `bottom` Bottom; `right` Right; `left` Left
- `legend.align` Alignment / Alignement: dropdown, default `right`; values: `left` Start; `center` Center; `right` End. Visible when `legend.position` = `top` or `bottom`
- `legend.showTitle` Legend title / Titre de la légende: toggle, default `false`; values: true / false
- `legend.titleText` Title text / Texte du titre: text, default (empty). Visible when `legend.showTitle` = `true`
- `legend.fontSize` Text size / Taille du texte: number, default `9`; values: 6 to 24
- `legend.color` Color (empty = secondary) / Couleur (vide = secondaire): color, default (empty); values: hex color
- `legend.length` Gradient length (px) / Longueur du dégradé (px): number, default `160`; values: 60 to 600
- `legend.interactive` Click a class = highlight its cells / Clic sur une classe = mettre ses cases en avant: toggle, default `true`; values: true / false

### Sort / Tri (`sort`)
- `sort.rowsBy` Sort rows by / Trier les lignes par: dropdown, default `model`; values: `model` Model order (as in Power BI); `name` Name; `total` Row total; `column` Value in a column; `similarity` Similarity (clustering) ★. Similarity: rows that look alike are placed side by side (hierarchical clustering, computed in the visual).
- `sort.rowsOrder` Order / Ordre: dropdown, default `desc`; values: `desc` Largest first (names A to Z); `asc` Smallest first (names Z to A). Visible when `sort.rowsBy` = `name` or `total` or `column`
- `sort.rowsColumn` Column name / Nom de la colonne: text, default (empty). Visible when `sort.rowsBy` = `column`. Empty: the last column.
- `sort.rowsTop` Show the first N rows (0 = all) / Afficher les N premières lignes (0 = toutes): number, default `0`; values: 0 to 5000
- `sort.colsBy` Sort columns by / Trier les colonnes par: dropdown, default `model`; values: `model` Model order (as in Power BI); `name` Name; `total` Column total; `similarity` Similarity (clustering) ★
- `sort.colsOrder` Order / Ordre: dropdown, default `desc`; values: `desc` Largest first (names A to Z); `asc` Smallest first (names Z to A). Visible when `sort.colsBy` = `name` or `total`
- `sort.dendrogram` Draw the clustering tree / Dessiner l'arbre du regroupement: toggle, default `true`; values: true / false. With a similarity sort: the tree shows which rows (columns) are closest.
- `sort.treeSize` Tree size (px) / Taille de l'arbre (px): number, default `40`; values: 16 to 160. Visible when `sort.dendrogram` = `true`

### Margin totals ★ / Totaux en marge ★ (`margins`)
- `margins.rows` Row totals (right) / Total des lignes (à droite): dropdown, default `none`; values: `none` None; `values` Values ★; `bars` Bars ★; `barsValues` Bars and values ★
- `margins.cols` Column totals / Total des colonnes: dropdown, default `none`; values: `none` None; `values` Values ★; `bars` Bars ★; `barsValues` Bars and values ★. Drawn on the side opposite the column labels.
- `margins.agg` Calculation / Calcul: dropdown, default `sum`; values: `sum` Sum; `average` Average; `max` Maximum; `min` Minimum
- `margins.size` Bar room (% of the visual) / Place des barres (% du visuel): number, default `12`; values: 5 to 40
- `margins.color` Bar color (empty = scale color) / Couleur des barres (vide = couleur de l'échelle): color, default (empty); values: hex color
- `margins.fontSize` Text size / Taille du texte: number, default `9`; values: 6 to 24

### Calendar and hours / Calendrier et heures (`calendar`)
- `calendar.weekStart` First day of the week / Premier jour de la semaine: dropdown, default `auto`; values: `auto` From the language (Sunday in US English); `monday` Monday; `sunday` Sunday; `saturday` Saturday
- `calendar.dayLabels` Day names / Noms des jours: dropdown, default `alternate`; values: `alternate` Every other day; `all` All; `none` None
- `calendar.weekends` Mark weekends / Souligner les week-ends: toggle, default `false`; values: true / false
- `calendar.layout` Layout / Disposition: dropdown, default `weeks`; values: `weeks` Weeks as columns (GitHub style); `months` One block per month
- `calendar.range` Period shown / Période affichée: dropdown, default `years`; values: `years` Whole years; `data` From the first to the last day of the data
- `calendar.monthGaps` Separate the months / Séparer les mois: toggle, default `true`; values: true / false
- `calendar.monthLabels` Month names / Noms des mois: toggle, default `true`; values: true / false
- `calendar.yearLabels` Years / Années: toggle, default `true`; values: true / false
- `calendar.maxYears` Maximum number of years (most recent) / Nombre d'années au plus (les plus récentes): number, default `10`; values: 1 to 50
- `calendar.holidays` Public holidays / Jours fériés: dropdown, default `none`; values: `none` None; `fr` France ★; `be` Belgium ★; `ch` Switzerland (federal) ★; `ca` Canada (federal) ★; `de` Germany (national) ★; `gb` United Kingdom (England) ★; `us` United States (federal) ★. Computed in the visual (Easter included), outlined in the calendar and named in the tooltip.
- `calendar.markColor` Marker color (empty = accent) / Couleur des repères (vide = accent): color, default (empty); values: hex color
- `calendar.hourStart` First hour / Première heure: number, default `0`; values: 0 to 23
- `calendar.hourEnd` Last hour / Dernière heure: number, default `23`; values: 0 to 23
- `calendar.hourFormat` Hour format / Format des heures: dropdown, default `auto`; values: `auto` From the language; `h24` 24-hour (0 to 23); `h12` 12-hour (AM / PM)

### Comparison ★ / Comparaison ★ (`comparison`)
- `comparison.mode` Color by / Couleur selon: dropdown, default `difference`; values: `difference` Difference (value − reference); `percent` Difference in % of the reference. With a measure in "Reference": each cell is colored by its gap to the reference (last year, target, average), on a diverging scale centered on zero.
- `comparison.lowerIsBetter` A decrease is favorable / Une baisse est favorable: toggle, default `false`; values: true / false
- `comparison.arrows` ▲▼ arrows in the labels / Flèches ▲▼ dans les étiquettes: toggle, default `true`; values: true / false

### Annotations ★ (`annotations`)
- `annotations.marker` Marker / Repère: dropdown, default `corner`; values: `corner` Cell corner; `dot` Dot; `outline` Outline. Cells with a text in the "Annotation" field get a marker; the text is in the tooltip.
- `annotations.color` Color (empty = accent) / Couleur (vide = accent): color, default (empty); values: hex color

### Small multiples ★ / Petits multiples ★ (`smallMultiples`)
- `smallMultiples.columns` Columns (0 = automatic) / Colonnes (0 = automatique): number, default `0`; values: 0 to 12
- `smallMultiples.minWidth` Minimum chart width (px) / Largeur minimale d'un graphique (px): number, default `220`; values: 80 to 800
- `smallMultiples.gap` Spacing (px) / Espacement (px): number, default `14`; values: 0 to 60
- `smallMultiples.titleSize` Title size / Taille des titres: number, default `10`; values: 6 to 24
- `smallMultiples.border` Frame around each chart / Cadre autour de chaque graphique: toggle, default `false`; values: true / false

### Playback ★ / Lecture ★ (`play`)
- `play.start` Frame shown on opening / Image affichée à l'ouverture: dropdown, default `last`; values: `last` The last one (most recent); `first` The first one
- `play.speed` Duration of a frame (ms) / Durée d'une image (ms): number, default `1000`; values: 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, default `false`; values: true / false
- `play.autoPlay` Play automatically on opening / Lecture automatique à l'ouverture: toggle, default `false`; values: 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, default `true`; values: true / false. Values, positions and colors move smoothly from one frame to the next.
- `play.controls` Play bar / Barre de lecture: toggle, default `true`; values: true / false
- `play.position` Bar position / Position de la barre: dropdown, default `bottom`; values: `bottom` Bottom; `top` Top. Visible when `play.controls` = `true`
- `play.ticks` Tick marks / Graduations: dropdown, default `auto`; values: `auto` Automatic; `all` Every frame; `none` None. Visible when `play.controls` = `true`
- `play.tickLabels` Tick labels / Étiquettes des graduations: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.stepButtons` Start and end buttons / Boutons début et fin: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.speedButton` Speed button / Bouton de vitesse: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.showLabel` Current value in large type / Valeur en cours en grand: toggle, default `true`; values: true / false
- `play.labelSize` Large value size / Taille de la valeur en grand: number, default `44`; values: 12 to 160. Visible when `play.showLabel` = `true`
- `play.labelPosition` Large value position / Position de la valeur en grand: dropdown, default `bottomRight`; values: `bottomRight` Bottom right; `topRight` Top right; `topLeft` Top left; `bottomLeft` Bottom left; `center` Center. Visible when `play.showLabel` = `true`
- `play.sameScale` Same scale for every frame / Même échelle pour toutes les images: toggle, default `true`; values: true / false. The colors keep the same meaning from one frame to the next (recommended). Off: each frame uses its own lightest and darkest cell.

### Interactions (`interaction`)
- `interaction.hover` Highlight on hover / Mettre en avant au survol: toggle, default `true`; values: true / false
- `interaction.dim` Dimmed items opacity (%) / Opacité des éléments estompés (%): number, default `25`; values: 5 to 80
- `interaction.crosshair` Hover: emphasize the row and the column / Survol : souligner la ligne et la colonne: toggle, default `true`; values: true / false
- `interaction.headers` Click a name = select the row or the column / Clic sur un nom = sélectionner la ligne ou la colonne: toggle, default `true`; values: true / false. Also month, day and year names in the calendar.

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.

---

# Radar Plume

- Compare profiles across several criteria, each on its own scale: players, products, teams, stores.
- Slug `radar` · version 1.1.0.0 · GUID (`visualType`) `plumeRadarC4CFD44A07A54CEF8806718E4F113927` · page https://plumevisuals.com/en/visuals/radar

### What the visual does

Radar Plume (identifier `radar`) is a Power BI custom visual (base range, version 1.1.0.0, installed from its `.pbiviz` file; AppSource submission in preparation) that draws **radar (spider) charts**. Power BI Desktop has no native radar; Microsoft's free Radar Chart has a single common scale, no maximum and needs one measure per series.

**New in version 1.1.0.0 (30/10/2026):** Format pane reorganized (`radar.type` / `grid` / angles → **Layout**, `gridLines` → `gridlines`, `compare` → `comparison`); free gridline width and polygon line style.

- **Two ways to give the axes**: without the `axis` role ("Axes (category)"), **each measure of Values is an axis** (statistics or KPIs with different units); with `axis`, **each value of the category is an axis** and the measure gives the value.
- **Series**: the `legend` role ("Series (one polygon each)") draws one polygon per value from a single measure (one player, product, team). With `axis` and no `legend`, several measures in Values give one polygon each.
- **Scales** (`scale.mode`): `auto` (common with an Axes field; one per axis when measures have different formats or a size ratio above 4), `common`, `perAxis` (each axis its own round range, written under its name: "0 – 120"), `normalized` ★ (0–100 % of each axis maximum; `scale.normFrom` = `zero` or `min`). `scale.zero` (start at zero), `scale.min` / `scale.max` for the common scale. Level values are round: ratings up to 4.6 give 0 to 5 in 5 levels.
- **Per-axis settings ★** (dynamic card `axes`, "Apply settings to" All axes or one axis): `min`, `max`, `invert` ("Lower is better", the best value at the edge, "↓" after the name), `weight` (score). Stored with the measure selector (`{ metadata: queryName }`) or the category selector.
- Polygon or circular grid, levels, alternating bands, spokes, level values written between the first and the last axis, rotation, direction, center hole ★, fill opacity (automatically lighter beyond 3 series), markers (circle, square, diamond, one shape per series), value labels (value, % of the axis maximum ★, series and value), axis order (model, name, value ★, custom list ★).
- **Play axis ★** (`play` role, shared Plume player): play / pause, start / end, slider, speed ×0.5 to ×4, loop, autoplay, value in large type; **polygons morph from one frame to the next**; scales stay fixed over all frames.
- Interactions: click a point (axis + series), a polygon (series), an axis name (category, `axisLabels.click`) or the legend to cross-filter; hover = the series stands out; highlighting from other visuals dims series without highlighted values.

### Free vs premium (★)

- Every feature works without a key and nothing is ever blocked. Free features never show a watermark, and the default settings use no premium feature.
- 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 (`style.palette`) and `style.themeJson` ("Theme JSON ★") are **premium**.
- Free in Radar Plume: both axis modes, Series, the scale modes auto, common and per axis, min / max of the common scale, grid, fills, markers, value labels, axis order by model or name (the model order follows Power BI's Sort by column), rotation, legend, interactions, high contrast, dynamic formats.
- Rebalanced on 22/10/2026 (moved from free to premium): play axis, normalized scale, axis order by value or custom, labels in % of the axis maximum, center hole.
- Premium features of Radar Plume (the watermark appears only when they actually apply):
  - the `play` role ("Play axis ★") with data; `scale.mode` = `normalized`; `sort.by` = `value`, or `custom` with at least one name; `labels.content` = `percent` with labels shown; `layout.inner` > 0;
  - `layout.type` = `polar` (polar rose, radial bars) and `radar.curve` = `smooth`;
  - per-axis settings: any `axes.min`, `axes.max`, `axes.invert` (weights only matter with a score);
  - the **Target ★** field (`target`, with Axes), `benchmark.series` (a series name that exists), `benchmark.average`, `benchmark.band` = `minmax` or `quartiles`;
  - `comparison.with` = `target`, `reference`, `previous` (with a play axis) or `first`; `score.method` = `mean` or `area`; `extremes.show` ≠ `none`;
  - the **Small multiples ★** field (`multiples`) or `smallMultiples.bySeries`.
- 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.
- Accepted keys: only keys starting with `PLUM1.` shown in the buyer's account on plumevisuals.com, checked offline (Ed25519 signature), covering `radar` or the whole catalog. 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

**Measures mode** (one measure per criterion), one row per compared item:

| Player (`legend`) | Speed (`values`) | Stamina (`values`) | Passes completed (`values`) | Goals (`values`) |
|---|---|---|---|---|
| Léa | 31.5 | 88 | 86% | 14 |
| Marc | 33.8 | 72 | 78% | 19 |

**Category mode** (long format), one row per item and per criterion:

| Team (`legend`) | Skill (`axis`) | Rating (`values`) | Target (`target`) |
|---|---|---|---|
| North team | Communication | 4.2 | 4.0 |
| North team | Technical skills | 3.1 | 4.0 |

- **Axes (category)** (`axis`, « Axes (catégorie) », one column): one axis per value; Power BI sorts text alphabetically, so sort the month column by its number in the model (Sort by column, free) or use `sort.by` = `custom` ★.
- **Series** (`legend`, « Séries (un polygone par valeur) », one column): up to 60 series drawn.
- **Values** (`values`, « Valeurs », 1 to 24 measures).
- **Target ★** (`target`, « Cible ★ », one measure, with Axes): dashed outline, compared with `comparison.with` = `target`.
- **Play axis ★** (`play`, « Axe de lecture ★ »), **Small multiples ★** (`multiples`, « Petits multiples ★ »), **Tooltips** (`tooltips`), **Dynamic format** (`format`).
- At most 60 axes are drawn (message in edit mode); 30,000-row windows, more with `fetchMoreData` up to 100,000 rows; 100,004 rows render in about 1.3 s.

### DAX recipes

```dax
// Measures mode: choose the aggregation of each criterion
Speed = AVERAGE ( Players[Speed km/h] )       // a measure cannot share a column name of its own table
Goals = SUM ( Players[Goals scored] )
Salary = AVERAGE ( Players[Annual salary] )          // then Per-axis settings ★ › Salary › Lower is better

// Category mode
Average rating = AVERAGE ( Assessments[Rating] )
Target = AVERAGE ( Assessments[Target score] )      // one target per skill (Target ★ field)
```

### Format pane: option IDs

- Card order: `license`, `style`, `dataColors`, `radar`, `scale`, `axes` (dynamic, ★), `gridlines`, `axisLabels`, `labels`, `legend`, `sort`, `benchmark`, `comparison`, `score`, `extremes`, `play`, `smallMultiples`, `interaction`, then `title`, `source`, `container`, `texts`. Format pane in version 1.1.0.0 (30/10/2026), top to bottom: `license`, `style`, `layout`, `dataColors`, `radar`, `scale`, `axes`, `axisLabels`, `labels`, `gridlines`, `legend`, `sort`, `benchmark`, `comparison`, `score`, `extremes`, `smallMultiples`, `play`, `interaction`, `tooltip`, `title`, `source`, `container`, `texts`. Settings moved or renamed in this version keep working in older reports (the old names are still read).
- `dataColors`: `mode` (`series` | `single`), `single`, `fill` (per series).
- `radar`: `layout.type` (`radar` | `polar` ★), `layout.grid` (`polygon` | `circle`), `layout.startAngle` (−360–360, 0), `layout.clockwise`, `layout.size` (40–100, 92), `layout.inner` ★ (0–60, 0), `fillOpacity` (0–100, 16), `width` (0–10, 2), `curve` (`linear` | `smooth` ★), `markers`, `markerSize` (2–20, 6), `markerShape` (`circle` | `square` | `diamond` | `series`), `barPadding` (0–80, 12), `polarLayout` (`grouped` | `overlap`).
- `scale`: `mode` (`auto` | `common` | `perAxis` | `normalized` ★), `zero`, `min`, `max` (text), `normFrom` (`zero` | `min`).
- `axes` ★: `min`, `max` (text), `invert`, `weight` (0–100, 1).
- `gridlines`: `levels` (1–12, 4), `bands`, `spokes`, `style` (`solid` | `dashed` | `dotted`), `color`, `levelLabels`, `levelSize` (9).
- `axisLabels`: `show`, `fontSize` (10), `color`, `bold`, `wrap`, `range`, `click`.
- `labels`: `show`, `content` (`value` | `percent` ★ | `seriesValue`), `which` (`all` | `first` | `last` | `single`), `fontSize`, `color`, `bold`, `halo`, `declutter`, `units`, `decimals`, `prefix`, `suffix`.
- `sort`: `by` (`data` | `name` | `value` ★ | `custom` ★), `order` (`desc` | `asc`), `custom` (names, one per line or `;`).
- `benchmark`: `targetColor`, `targetStyle`, `targetWidth`, `series` ★ (name), `average` ★, `band` (`none` | `minmax` ★ | `quartiles` ★), `bandColor`, `bandOpacity` (3–70, 14).
- `comparison`: `with` (`none` | `target` ★ | `reference` ★ | `previous` ★ | `first` ★), `focus` (series name), `arrows`, `ghost`, `pct`.
- `score`: `method` (`none` | `mean` ★ | `area` ★), `inLegend`, `center`, `decimals` (0–2).
- `extremes`: `show` (`none` | `both` ★ | `best` ★ | `worst` ★).
- `play` ★ (shared player): `start` (`last` | `first`), `speed` (ms), `loop`, `autoPlay`, `transition`, `controls`, `position`, `ticks`, `tickLabels`, `stepButtons`, `speedButton`, `showLabel`, `labelSize`, `labelPosition`.
- `smallMultiples`: `bySeries` ★, `others`, `sortByScore`, `columns`, `minWidth` (170), `gap`, `titleSize`, `border`. `interaction`: `hover`, `dim` (5–80, 25).

### Editing a PBIP report (visual.json)

`visualType` is the visual GUID, `queryState` keys are the data role names, `objects` keys are the option IDs. A per-axis setting uses a `metadata` selector with the measure's query name.

```json
{
  "visualType": "plumeRadarC4CFD44A07A54CEF8806718E4F113927",
  "query": { "queryState": {
    "values": { "projections": [
      { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Players" } }, "Property": "Speed" } }, "queryRef": "Players.Speed", "nativeQueryRef": "Speed" },
      { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "Players" } }, "Property": "Salary" } }, "queryRef": "Players.Salary", "nativeQueryRef": "Salary" } ] },
    "legend": { "projections": [ { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "Players" } }, "Property": "Player" } }, "queryRef": "Players.Player", "nativeQueryRef": "Player" } ] } } },
  "objects": {
    "scale": [ { "properties": { "mode": { "expr": { "Literal": { "Value": "'perAxis'" } } } } } ],
    "axes":  [ { "properties": { "invert": { "expr": { "Literal": { "Value": "true" } } } }, "selector": { "metadata": "Players.Salary" } } ],
    "score": [ { "properties": { "method": { "expr": { "Literal": { "Value": "'mean'" } } } } } ]
  }
}
```

### Dynamic formats

- **fx button** on colors and texts of the Format pane; **"Dynamic format" well**: measures renamed `card.setting` (e.g. `title.text`, `radar.fillOpacity`, `scale.max`, `axes.invert` for all axes). Driving a ★ setting by DAX still shows the watermark without a key.

### Common pitfalls

- One or two lines instead of a polygon: fewer than 3 axes.
- Polygons squashed except on one axis: common scale with different units; use `perAxis` (or `normalized` ★).
- Doubled values: a `SUM` measure over several rows per item; use `AVERAGE`.
- Months in alphabetical order: sort the month column by the month number in the model (Sort by column), or `sort.by` = `custom` ★ with the month list.
- Reference series not drawn: the name in `benchmark.series` does not match a value of Series (message in edit mode).
- Watermark visible: a ★ setting listed above, a ★ style or a theme JSON, without a valid key.

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

Images in points or at the end of axes, a logarithmic scale, mixing bars and lines per series, drill-down on the axes, free annotations, more than 60 axes or 60 series drawn, exporting the chart as an image. The visual makes no network request.

## Radar Plume: data fields

- `axis` Axes (category) / Axes (catégorie) (column, 1 max): One axis per value (skills, criteria, months…). Leave empty to get one axis per measure of the Values field
- `legend` Series (one polygon each) / Séries (un polygone par valeur) (column, 1 max): A product, a player, a team, a scenario: one polygon per value
- `values` Values / Valeurs (measure, 24 max): Without Axes: each measure is an axis (each with its own scale if needed). With Axes: the value of each axis; several measures without Series give one polygon each
- `target` Target ★ / Cible ★ ★ (measure, 1 max): With Axes: a target value per axis, drawn as a dashed outline and compared with each series
- `play` Play axis ★ / Axe de lecture ★ ★ (column, 1 max): A date, a year or an ordered category: the polygons morph from one value to the next (play button) ★
- `multiples` Small multiples ★ / Petits multiples ★ ★ (column, 1 max): One small radar per value, with the same scales
- `tooltips` Tooltips / Infobulles (measure, several max): 
- `format` Dynamic format / Format dynamique (measure, several max): Measures named card.setting (e.g. title.fontSize): drive any Format option with DAX

## Radar Plume: Format pane options (176)

### Plume Studio License / Licence Plume Studio (`license`)
- `license.buy` Get a license / Obtenir une licence: info, default `plumevisuals.com`
- `license.key` License key / Clé de licence: text, default (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, default `true`; values: true / false

### Style (`style`)
- `style.preset` Style: dropdown, default `none`; values: `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, default (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, default `false`; values: 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, default `false`; values: true / false
- `style.customColors` Customize colors / Personnaliser les couleurs: toggle, default `false`; values: 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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorText` Text / Texte: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorMuted` Secondary text / Texte secondaire: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorGrid` Lines and grid / Traits et grille: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorAccent` Accent: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorPositive` Favorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.colorNegative` Unfavorable / Défavorable: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series1` Series 1 / Série 1: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series2` Series 2 / Série 2: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series3` Series 3 / Série 3: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series4` Series 4 / Série 4: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series5` Series 5 / Série 5: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series6` Series 6 / Série 6: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series7` Series 7 / Série 7: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.series8` Series 8 / Série 8: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.palette` Gradient palette / Palette du dégradé: dropdown, default `auto`; values: `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, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleMid` Gradient: middle (diverging) / Dégradé : milieu (écarts): color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.scaleHigh` Gradient: end / Dégradé : fin: color, default (empty); values: hex color. Visible when `style.customColors` = `true`
- `style.fontFamily` Font / Police: font, default `Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif`. Used by every text of the visual (title, axes, labels, cells).
- `style.animate` Animations: toggle, default `true`; values: true / false. Smooth transitions when data changes. Automatically disabled when the system asks to reduce motion.

### Layout / Disposition (`layout`)
- `layout.type` Type: dropdown, default `radar`; values: `radar` Radar (polygons); `polar` Polar rose (radial bars) ★
- `layout.grid` Grid shape / Forme de la grille: dropdown, default `polygon`; values: `polygon` Polygonal; `circle` Circular
- `layout.startAngle` First axis angle (degrees, 0 = top) / Angle du premier axe (degrés, 0 = en haut): number, default `0`; values: -360 to 360
- `layout.clockwise` Clockwise / Sens des aiguilles d'une montre: toggle, default `true`; values: true / false
- `layout.size` Radar size (% of the room) / Taille du radar (% de la place): number, default `92`; values: 40 to 100
- `layout.inner` Center hole (%) ★ / Trou central (%) ★ ★: number, default `0`; values: 0 to 60. Leaves an empty disc in the center: small values stay visible.

### Data colors / Couleurs des données (`dataColors`, one entry per item with a selector)
- `dataColors.mode` Coloring / Coloration: dropdown, default `series`; values: `series` One color per series; `single` Single color
- `dataColors.single` Color / Couleur: color, default (empty); values: hex color
- `dataColors.fill` Color / Couleur: color, default (empty); values: hex color

### Radar (`radar`)
- `radar.fillOpacity` Fill opacity (%) / Opacité du remplissage (%): number, default `16`; values: 0 to 100
- `radar.width` Line width (px) / Épaisseur du trait (px): number, default `2`; values: 0 to 10
- `radar.lineStyle` Line style / Style du trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `radar.curve` Line / Tracé: dropdown, default `linear`; values: `linear` Straight; `smooth` Smooth curves ★
- `radar.markers` Markers / Marqueurs: toggle, default `true`; values: true / false
- `radar.markerSize` Marker size (px) / Taille des marqueurs (px): number, default `6`; values: 2 to 20. Visible when `radar.markers` = `true`
- `radar.markerShape` Marker shape / Forme des marqueurs: dropdown, default `circle`; values: `circle` Circle; `square` Square; `diamond` Diamond; `series` One shape per series. Visible when `radar.markers` = `true`. One shape per series helps when colors are hard to tell apart.
- `radar.barPadding` Space between sectors (%) / Espace entre les secteurs (%): number, default `12`; values: 0 to 80
- `radar.polarLayout` Several series / Plusieurs séries: dropdown, default `grouped`; values: `grouped` Side by side; `overlap` Overlapping

### Scale / Échelle (`scale`)
- `scale.mode` Axis scale / Échelle des axes: dropdown, default `auto`; values: `auto` Automatic; `common` Common to all axes; `perAxis` One scale per axis; `normalized` Normalized (0–100 % of the axis maximum) ★. Automatic: common scale for a category; one scale per axis when the measures have different units or sizes.
- `scale.zero` Start at zero / Partir de zéro: toggle, default `true`; values: true / false. Off: each scale starts near the smallest value (differences stand out; say it in the title).
- `scale.min` Minimum (common scale) / Minimum (échelle commune): text, default (empty)
- `scale.max` Maximum (common scale) / Maximum (échelle commune): text, default (empty). E.g. 100 for scores out of 100 or 5 for ratings out of 5.
- `scale.normFrom` Normalization: 0 % / Normalisation : 0 %: dropdown, default `zero`; values: `zero` = zero; `min` = smallest value of the axis. Visible when `scale.mode` = `normalized`

### Per-axis settings ★ / Réglages par axe ★ (`axes`, one entry per item with a selector)
- `axes.min` Axis minimum ★ / Minimum de l'axe ★ ★: text, default (empty)
- `axes.max` Axis maximum ★ / Maximum de l'axe ★ ★: text, default (empty). Choose “All axes” or one axis in “Apply settings to” above. Empty = automatic.
- `axes.invert` Lower is better (inverted axis) ★ / Plus bas = mieux (axe inversé) ★ ★: toggle, default `false`; values: true / false. Costs, delays, weight: the best value is drawn at the edge, the axis name gets a ↓ mark.
- `axes.weight` Weight in the score ★ / Poids dans le score ★ ★: number, default `1`; values: 0 to 100

### Axis names / Noms des axes (`axisLabels`)
- `axisLabels.show` Show / Afficher: toggle, default `true`; values: true / false
- `axisLabels.fontSize` Text size / Taille du texte: number, default `10`; values: 6 to 24
- `axisLabels.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `axisLabels.bold` Bold / Gras: toggle, default `false`; values: true / false
- `axisLabels.wrap` Long names on two lines / Noms longs sur deux lignes: toggle, default `true`; values: true / false
- `axisLabels.range` Scale under the name (one scale per axis) / Échelle sous le nom (échelle par axe): toggle, default `true`; values: true / false. With one scale per axis: “0 – 120” under each axis name.
- `axisLabels.click` Click on a name = select the axis / Clic sur un nom = sélectionner l'axe: toggle, default `true`; values: true / false. With an Axes field: filters the other visuals of the page.

### Data labels / Étiquettes de données (`labels`)
- `labels.show` Show / Afficher: toggle, default `false`; values: true / false
- `labels.content` Content / Contenu: dropdown, default `value`; values: `value` Value; `percent` % of the axis maximum ★; `seriesValue` Series and value
- `labels.which` Labeled series / Séries étiquetées: dropdown, default `all`; values: `all` All; `first` The first one; `last` The last one; `single` Only when there is one
- `labels.fontSize` Size / Taille: number, default `10`; values: 6 to 24
- `labels.color` Color (empty = automatic) / Couleur (vide = automatique): color, default (empty); values: hex color. Automatic: readable color depending on the background (inside bars: white or dark).
- `labels.bold` Bold / Gras: toggle, default `false`; values: true / false
- `labels.halo` Text halo / Halo autour du texte: toggle, default `true`; values: true / false
- `labels.declutter` Hide overlapping labels / Masquer les étiquettes qui se chevauchent: toggle, default `true`; values: true / false
- `labels.units` Display units / Unités d'affichage: dropdown, default `auto`; values: `auto` Auto; `none` None; `k` Thousands; `m` Millions; `b` Billions
- `labels.decimals` Decimals (-1 = auto) / Décimales (-1 = auto): number, default `-1`; values: -1 to 6
- `labels.prefix` Prefix / Préfixe: text, default (empty)
- `labels.suffix` Suffix (e.g. €) / Suffixe (ex. €): text, default (empty)

### Gridlines / Quadrillage (`gridlines`)
- `gridlines.levels` Number of levels / Nombre de niveaux: number, default `4`; values: 1 to 12
- `gridlines.bands` Alternating level bands / Niveaux en bandes alternées: toggle, default `true`; values: true / false
- `gridlines.spokes` Spokes (one line per axis) / Rayons (un trait par axe): toggle, default `true`; values: true / false
- `gridlines.style` Line style / Style du trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `gridlines.width` Width (px) / Épaisseur (px): number, default `1`; values: 0.5 to 6
- `gridlines.color` Color (empty = style grid) / Couleur (vide = grille du style): color, default (empty); values: hex color
- `gridlines.levelLabels` Level values / Valeurs des niveaux: toggle, default `true`; values: true / false. Written along the first axis (common or normalized scale).
- `gridlines.levelSize` Level values size / Taille des valeurs des niveaux: number, default `9`; values: 6 to 20. Visible when `gridlines.levelLabels` = `true`

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

### Sort / Tri (`sort`)
- `sort.by` Axis order / Ordre des axes: dropdown, default `data`; values: `data` Model order (as in Power BI); `name` Axis name; `value` Value (average of the series) ★; `custom` Custom ★
- `sort.order` Direction / Sens: dropdown, default `desc`; values: `desc` Descending (names A to Z); `asc` Ascending (names Z to A). Visible when `sort.by` = `name` or `value`
- `sort.custom` Custom order / Ordre personnalisé: textarea, default (empty). Visible when `sort.by` = `custom`. Axes not listed follow in the model order. Case and accents are ignored.

### Reference ★ / Référence ★ (`benchmark`)
- `benchmark.targetColor` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `benchmark.targetStyle` Line style / Style du trait: dropdown, default `dashed`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted
- `benchmark.targetWidth` Width / Épaisseur: number, default `1.5`; values: 0.5 to 6
- `benchmark.series` Reference series (name) ★ / Série de référence (nom) ★ ★: text, default (empty). A value of the Series field drawn as a gray dashed outline, without fill (benchmark, last year, competitor).
- `benchmark.average` Average of all series ★ / Moyenne de toutes les séries ★ ★: toggle, default `false`; values: true / false
- `benchmark.band` Band per axis / Bande par axe: dropdown, default `none`; values: `none` None; `minmax` From the minimum to the maximum of the series ★; `quartiles` Quartiles of the series (25 % to 75 %) ★. The range covered by the group on each axis: the eye sees at once where a series stands out.
- `benchmark.bandColor` Band color (empty = secondary text) / Couleur de la bande (vide = texte secondaire): color, default (empty); values: hex color
- `benchmark.bandOpacity` Band opacity (%) / Opacité de la bande (%): number, default `14`; values: 3 to 70

### Comparison ★ / Comparaison ★ (`comparison`)
- `comparison.with` Compare with / Comparer à: dropdown, default `none`; values: `none` Nothing; `target` The target ★; `reference` The reference series (or the average) ★; `previous` The previous frame (play axis) ★; `first` The first series ★
- `comparison.focus` Compared series (empty = automatic) / Série comparée (vide = automatique): text, default (empty). A value of the Series field. Empty: the first series (the second one when comparing with the first series).
- `comparison.arrows` ▲▼ gap under each axis name / ▲▼ écart sous chaque nom d'axe: toggle, default `true`; values: true / false
- `comparison.ghost` Dashed comparison outline / Contour de comparaison en pointillé: toggle, default `true`; values: true / false
- `comparison.pct` Gap in % / Écart en %: toggle, default `false`; values: true / false

### Overall score ★ / Score global ★ (`score`)
- `score.method` Method / Calcul: dropdown, default `none`; values: `none` None; `mean` Weighted mean of the axes (0–100) ★; `area` Polygon area (% of the full radar) ★. Each axis counts as 0 at its minimum and 100 at its maximum (inverted axes and weights of “Per-axis settings” included).
- `score.inLegend` Score in the legend (ranking) / Score dans la légende (classement): toggle, default `true`; values: true / false
- `score.center` Score in the center (single series or small multiples) / Score au centre (une seule série ou petits multiples): toggle, default `true`; values: true / false
- `score.decimals` Decimals / Décimales: number, default `0`; values: 0 to 2

### Best and worst axis ★ / Meilleur et pire axe ★ (`extremes`)
- `extremes.show` Highlight / Mettre en avant: dropdown, default `none`; values: `none` Nothing; `both` The best and the worst axis ★; `best` The best axis ★; `worst` The worst axis ★. Of the compared series (Comparison card), relative to each axis scale; “lower is better” axes included.

### Small multiples ★ / Petits multiples ★ (`smallMultiples`)
- `smallMultiples.bySeries` One radar per series ★ / Un radar par série ★ ★: toggle, default `false`; values: true / false. Without the Small multiples field: each series gets its own radar (profiles side by side).
- `smallMultiples.others` Other series in gray in each radar / Autres séries en gris dans chaque radar: toggle, default `true`; values: true / false
- `smallMultiples.sortByScore` Rank by score / Classer par score: toggle, default `false`; values: true / false
- `smallMultiples.columns` Columns (0 = automatic) / Colonnes (0 = automatique): number, default `0`; values: 0 to 12
- `smallMultiples.minWidth` Minimum radar width (px) / Largeur minimale d'un radar (px): number, default `170`; values: 80 to 800
- `smallMultiples.gap` Spacing (px) / Espacement (px): number, default `12`; values: 0 to 60
- `smallMultiples.titleSize` Title size / Taille des titres: number, default `10`; values: 6 to 24
- `smallMultiples.border` Frame around each radar / Cadre autour de chaque radar: toggle, default `false`; values: true / false

### Playback ★ / Lecture ★ (`play`)
- `play.start` Frame shown on opening / Image affichée à l'ouverture: dropdown, default `last`; values: `last` The last one (most recent); `first` The first one
- `play.speed` Duration of a frame (ms) / Durée d'une image (ms): number, default `1000`; values: 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, default `false`; values: true / false
- `play.autoPlay` Play automatically on opening / Lecture automatique à l'ouverture: toggle, default `false`; values: 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, default `true`; values: true / false. Values, positions and colors move smoothly from one frame to the next.
- `play.controls` Play bar / Barre de lecture: toggle, default `true`; values: true / false
- `play.position` Bar position / Position de la barre: dropdown, default `bottom`; values: `bottom` Bottom; `top` Top. Visible when `play.controls` = `true`
- `play.ticks` Tick marks / Graduations: dropdown, default `auto`; values: `auto` Automatic; `all` Every frame; `none` None. Visible when `play.controls` = `true`
- `play.tickLabels` Tick labels / Étiquettes des graduations: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.stepButtons` Start and end buttons / Boutons début et fin: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.speedButton` Speed button / Bouton de vitesse: toggle, default `true`; values: true / false. Visible when `play.controls` = `true`
- `play.showLabel` Current value in large type / Valeur en cours en grand: toggle, default `true`; values: true / false
- `play.labelSize` Large value size / Taille de la valeur en grand: number, default `44`; values: 12 to 160. Visible when `play.showLabel` = `true`
- `play.labelPosition` Large value position / Position de la valeur en grand: dropdown, default `bottomRight`; values: `bottomRight` Bottom right; `topRight` Top right; `topLeft` Top left; `bottomLeft` Bottom left; `center` Center. Visible when `play.showLabel` = `true`

### Interactions (`interaction`)
- `interaction.hover` Highlight on hover / Mettre en avant au survol: toggle, default `true`; values: true / false
- `interaction.dim` Dimmed items opacity (%) / Opacité des éléments estompés (%): number, default `25`; values: 5 to 80

### Tooltips / Infobulles (`tooltip`)
- `tooltip.show` Show / Afficher: toggle, default `true`; values: true / false. Tooltip on hover (with the fields of the "Tooltips" well and report page tooltips).

### Title / Titre (`title`)
- `title.show` Show / Afficher: toggle, default `true`; values: true / false
- `title.text` Text / Texte: text, default (empty). Leave empty for an automatic title built from the fields.
- `title.fontSize` Size / Taille: number, default `14`; values: 7 to 40
- `title.bold` Bold / Gras: toggle, default `true`; values: true / false
- `title.italic` Italic / Italique: toggle, default `false`; values: true / false
- `title.underline` Underline / Souligné: toggle, default `false`; values: true / false
- `title.color` Color (empty = text) / Couleur (vide = texte): color, default (empty); values: hex color
- `title.bgColor` Background color / Couleur d'arrière-plan: color, default (empty); values: hex color
- `title.align` Horizontal alignment / Alignement horizontal: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right
- `title.wrap` Text wrap / Retour automatique à la ligne: toggle, default `true`; values: true / false
- `title.subtitle` Subtitle / Sous-titre: text, default (empty). Several lines allowed: type \n to go to the next line.
- `title.subFontSize` Size / Taille: number, default `11`; values: 7 to 30. Visible when `title.subtitle` = 
- `title.subColor` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color. Visible when `title.subtitle` = 
- `title.subItalic` Italic / Italique: toggle, default `false`; values: true / false. Visible when `title.subtitle` = 
- `title.divider` Show divider / Afficher le séparateur: toggle, default `false`; values: true / false
- `title.dividerColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `title.divider` = `true`
- `title.dividerStyle` Line style / Style de trait: dropdown, default `solid`; values: `solid` Solid; `dashed` Dashed; `dotted` Dotted. Visible when `title.divider` = `true`
- `title.dividerWidth` Width / Épaisseur: number, default `1`; values: 1 to 6. Visible when `title.divider` = `true`
- `title.spaceBelow` Space below the title (px) / Espace sous le titre (px): number, default `4`; values: 0 to 40

### Source note / Note de source (`source`)
- `source.show` Show / Afficher: toggle, default `false`; values: true / false
- `source.text` Text / Texte: text, default (empty)
- `source.fontSize` Size / Taille: number, default `9`; values: 6 to 20
- `source.italic` Italic / Italique: toggle, default `false`; values: true / false
- `source.color` Color (empty = secondary text) / Couleur (vide = texte secondaire): color, default (empty); values: hex color
- `source.align` Alignment / Alignement: dropdown, default `left`; values: `left` Left; `center` Center; `right` Right

### Frame / Cadre (`container`)
- `container.bgShow` Background / Arrière-plan: toggle, default `false`; values: true / false
- `container.bgColor` Color / Couleur: color, default `#FFFFFF`; values: hex color. Visible when `container.bgShow` = `true`
- `container.bgColor2` Gradient end (optional) / Fin du dégradé (optionnel): color, default (empty); values: hex color. Visible when `container.bgShow` = `true`
- `container.bgTransparency` Transparency (%) / Transparence (%): slider, default `0`; values: 0 to 100. Visible when `container.bgShow` = `true`
- `container.border` Border / Bordure: toggle, default `false`; values: true / false
- `container.borderColor` Color (empty = lines) / Couleur (vide = traits): color, default (empty); values: hex color. Visible when `container.border` = `true`
- `container.borderWidth` Width / Épaisseur: number, default `1`; values: 0 to 6. Visible when `container.border` = `true`
- `container.radius` Rounded corners / Coins arrondis: number, default `8`; values: 0 to 24
- `container.shadow` Shadow / Ombre: toggle, default `false`; values: true / false
- `container.shadowColor` Color (empty = soft) / Couleur (vide = douce): color, default (empty); values: hex color. Visible when `container.shadow` = `true`
- `container.shadowSize` Blur (px) / Flou (px): number, default `12`; values: 0 to 40. Visible when `container.shadow` = `true`
- `container.padding` Inner padding / Marge intérieure: number, default `8`; values: 0 to 40

### Language and numbers / Langue et nombres (`texts`)
- `texts.language` Interface language / Langue de l'interface: dropdown, default `auto`; values: `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, default (empty). Thousands and decimal separators. Empty: same as Power BI.
