# Sankey Plume: technical reference for AI assistants

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

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

- Product page: https://plumevisuals.com/en/visuals/alluvial-shift (French: https://plumevisuals.com/fr/visuels/alluvial-shift)
- Summary: Sankey diagram: flows from a source to a destination over several levels, or customers changing segment from one year to the next.
- Power BI visual GUID (`visualType`): `plumeAlluvialShift7C4F119D60FF4086BE549F8CECDC03B9`
- Power BI visuals API: 5.11.1
- Support: https://plumevisuals.com/support · contact@plumevisuals.com
- Index of everything on the site for AI assistants: https://plumevisuals.com/llms.txt

## What the visual does

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.

## Data fields (wells)

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

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

Data view: categorical, categories = `period` + `stages` + `entity` + `source` + `destination` (one row per combination), 30,000 rows per data window (more fetched automatically); measures = `value`, `linkColor`, `tooltips`, `format`.
Capabilities: supportsHighlight, supportsKeyboardFocus, supportsMultiVisualSelection, supportsLandingPage, supportsEmptyDataView.
Network access: none (no privileges requested, no external request).

## Format pane options (132)

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

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

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

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

**Style**

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

**Custom colors / Couleurs personnalisées**

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

**Text / Texte**

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

**Animations**

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

### Layout / Disposition (`layout`, Format pane)

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `layout.orientation` | Orientation | Orientation | dropdown | enumeration | `horizontal` | `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 | Source → Destination | dropdown | enumeration | `chain` | `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 | enumeration | `justify` | `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 | enumeration | `loop` | `loop` Loops under the chart; `hide` Hide | Visible when `layout.structure` = `chain` |

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

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

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `dataColors.mode` | Coloring | Coloration | dropdown | enumeration | `auto` | `auto` Palette (one color per category); `single` Single color |  |
| `dataColors.single` | Color | Couleur | color | fill | (empty) | hex color |  |
| `dataColors.fill` | Color | Couleur | color | fill | (empty) | hex color |  |

### Categories (nodes) / Catégories (nœuds) (`nodes`, Format pane)

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `nodes.width` | Node width | Largeur des nœuds | number | integer | `12` | 3 to 40 |  |
| `nodes.padding` | Space between nodes | Espace entre les nœuds | number | integer | `10` | 0 to 40 |  |
| `nodes.order` | Category order | Ordre des catégories | dropdown | enumeration | `auto` | `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 | text | (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 | integer | `12` | 2 to 40 |  |
| `nodes.minHeight` | Minimum node height (px, 0 = none) | Hauteur minimale des nœuds (px, 0 = aucune) | number | integer | `0` | 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`, Format pane)

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `flows.colorBy` | Flow color | Couleur des flux | dropdown | enumeration | `source` | `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 | integer | `45` | 5 to 100 |  |
| `flows.render` | Flow drawing | Dessin des flux | dropdown | enumeration | `ribbons` | `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 | numeric | `0` | 0 to 4 | Visible when `flows.render` = `threads` |
| `flows.curvature` | Curvature (%) | Courbure (%) | number | integer | `50` | 0 to 100 |  |
| `flows.changesOnly` | Emphasize category changes ★ | Faire ressortir les changements de catégorie ★ | toggle | bool | `false` | 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 | text | (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 | text | (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 | enumeration | `flow` | `flow` Flow color; `distinct` One color per highlighted name |  |
| `flows.dimOpacity` | Dimmed flows: opacity (% of opacity) | Flux en retrait : opacité (% de l'opacité) | number | integer | `45` | 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 | numeric | `0` | 0 to 20 |  |
| `flows.outline` | Flow outline | Contour des flux | toggle | bool | `false` | true / false |  |
| `flows.outlineColor` | Outline color (empty = flow color) | Couleur du contour (vide = couleur du flux) | color | fill | (empty) | hex color | Visible when `flows.outline` = `true` |
| `flows.outlineWidth` | Outline width | Épaisseur du contour | number | numeric | `1` | 0.5 to 4 | Visible when `flows.outline` = `true` |

### Entries, exits and retention / Entrées, sorties et maintien (`migration`, Format pane)

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `migration.showMissing` | Show entries and exits | Afficher les entrées et les sorties | toggle | bool | `true` | 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 | text | (empty) |  |  |
| `migration.lostLabel` | Exits label | Libellé des sorties | text | text | (empty) |  |  |
| `migration.retention` | Retention rate between columns ★ | Taux de maintien entre les colonnes ★ | toggle | bool | `false` | true / false |  |
| `migration.retentionKind` | Retention = | Maintien = | dropdown | enumeration | `same` | `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`, Format pane)

The card header toggle is `categoryLabels.show`.

**Labels / Étiquettes**

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `categoryLabels.show` | Show | Afficher | toggle | bool | `true` | true / false |  |
| `categoryLabels.content` | Content | Contenu | dropdown | enumeration | `nameValue` | `name` Name; `nameValue` Name and value; `namePct` Name and % of the column; `all` Name, value and % |  |
| `categoryLabels.pctOf` | Percentage of | Pourcentage calculé sur | dropdown | enumeration | `column` | `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 | formatting | `10` | 6 to 24 |  |
| `categoryLabels.color` | Color (empty = text) | Couleur (vide = texte) | color | fill | (empty) | hex color |  |
| `categoryLabels.halo` | Text halo | Halo autour du texte | toggle | bool | `true` | true / false |  |
| `categoryLabels.bold` | Bold (name) | Gras (nom) | toggle | bool | `true` | true / false |  |
| `categoryLabels.italic` | Italic | Italique | toggle | bool | `false` | true / false |  |
| `categoryLabels.wrap` | Two lines if needed | Sur deux lignes si besoin | toggle | bool | `true` | 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 | bool | `false` | true / false | On: labels are written even in tight columns (they may touch). Off: a label that does not fit is left out. |

**Numbers / Nombres**

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

### Flow labels / Étiquettes des flux (`linkLabels`, Format pane)

The card header toggle is `linkLabels.show`.

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `linkLabels.show` | Show | Afficher | toggle | bool | `false` | true / false |  |
| `linkLabels.content` | Content | Contenu | dropdown | enumeration | `value` | `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 | formatting | `9` | 6 to 20 |  |
| `linkLabels.color` | Color (empty = text) | Couleur (vide = texte) | color | fill | (empty) | hex color |  |
| `linkLabels.bold` | Bold | Gras | toggle | bool | `true` | true / false |  |
| `linkLabels.italic` | Italic | Italique | toggle | bool | `false` | true / false |  |
| `linkLabels.force` | Force display | Afficher même sans place | toggle | bool | `false` | 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 | integer | `0` | 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`, Format pane)

The card header toggle is `headers.show`.

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `headers.show` | Show | Afficher | toggle | bool | `true` | true / false |  |
| `headers.names` | Column names (separated by ;) | Noms des colonnes (séparés par ;) | text | text | (empty) |  | Leave empty for the field names (stages) or the period values. |
| `headers.fontSize` | Text size | Taille du texte | number | formatting | `10` | 6 to 24 |  |
| `headers.color` | Color (empty = text) | Couleur (vide = texte) | color | fill | (empty) | hex color |  |
| `headers.showTotal` | Total under the name | Total sous le nom | toggle | bool | `false` | true / false |  |

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

| Option ID | Label (EN) | Label (FR) | Control | Type | Default | Allowed values | Notes |
|---|---|---|---|---|---|---|---|
| `interaction.hover` | Highlight on hover | Mettre en avant au survol | toggle | bool | `true` | true / false |  |
| `interaction.dim` | Dimmed items opacity (%) | Opacité des éléments estompés (%) | number | integer | `25` | 5 to 80 |  |
| `interaction.trace` | Trace paths on hover | Suivre les parcours au survol | toggle | bool | `true` | 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 | bool | `true` | 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`, Format pane)

The card header toggle is `tooltip.show`.

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

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

The card header toggle is `title.show`.

**Title / Titre**

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

**Subtitle / Sous-titre**

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

**Divider / Séparateur**

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

**Spacing / Espacement**

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

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

The card header toggle is `source.show`.

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

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

**Background / Arrière-plan**

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

**Border / Bordure**

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

**Shadow / Ombre**

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

**Spacing / Marges**

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

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

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

### Other objects (not in the Format pane cards above)

- `labels`: `labels.show` (bool), `labels.content` (enumeration), `labels.pctOf` (enumeration), `labels.fontSize` (formatting), `labels.color` (fill), `labels.halo` (bool), `labels.units` (enumeration), `labels.decimals` (integer), `labels.prefix` (text), `labels.suffix` (text).
