ariel-sofi opened a new pull request, #42477:
URL: https://github.com/apache/superset/pull/42477
### SUMMARY
The Sankey chart accepts exactly one source and one target column, so a flow
spanning three or more dimensions (for example `Country → Product → Channel →
Outcome`) cannot be built. The ECharts sankey series already lays out an
arbitrary number of levels from chained links, so the limitation lives only in
the plugin's control panel and query — `buildQuery.ts` hard-codes `groupby =
[source, target]` and both controls are `multi: false`.
This adds an optional ordered **Intermediate levels** column control between
the existing Source and Target. When set, `buildQuery` groups by `[source,
...intermediateLevels, target]` in a single query, and `transformProps` emits
links for each adjacent pair, aggregating the metric.
Long-standing requests for this: #3059, #20887, and discussion #38713 (where
the only suggested workaround is a `UNION ALL` virtual dataset of stacked
source/target pairs).
**Design notes**
- **Backward compatible.** `intermediate_levels` is a new optional form-data
key, so existing saved charts are untouched and no migration is needed. With it
unset, the link/node output is identical to today.
- **Node identity.** In multi-level mode node names carry their level index
internally (NUL-delimited) and each node is pinned to its column via `depth`.
This is what makes the feature safe: without it, a value appearing in two
levels (say `Other` at level 1 and level 3) silently merges into one node, and
the resulting back-edge makes ECharts throw `Sankey is a DAG, the original data
has cycle!`, which aborts the render. Labels and tooltips strip the prefix, so
it is invisible to users.
- **Two-column mode keeps raw node names** rather than prefixing, so
edge-list datasets that intentionally chain flows across rows (`A→B`, `B→C`)
still connect. This is the one behavioral tension in the change and the reason
prefixing is conditional.
- **Missing values** at any level become `NULL_STRING` instead of dropping
the row, which keeps per-level totals equal (a dropped row would remove its
value from every level).
**Rendering fixes needed to make deep charts usable**
- `nodeGap` is left at the ECharts default. It is a fixed pixel budget per
column: once `nodeGap × nodes` exceeds the plot height ECharts drops **every**
node in that column. Measured with 33 first-level nodes at 900×600, a `nodeGap`
of 20 rendered 0 of 34 node rects while the default of 8 rendered all of them.
- Node labels are truncated to a fixed width, because long category values
otherwise push the flow area off the canvas. The full value remains in the
tooltip.
- Adds a **roaming** control (pan/zoom), defaulting to `true` to match the
existing Graph and Tree charts, so a dense diagram stays explorable inside a
dashboard tile.
- The series also picks up gradient links and `emphasis: { focus:
'adjacency' }` on hover, which makes an individual path traceable through
several levels. Note this applies to two-column charts too — it is a visual
refresh, not a data change.
**Dashboard integration**
Sankey no longer has a two-dimension limit, so its entry is removed from
`CHART_TYPE_LIMITATIONS` (which previously warned that extra columns "will be
ignored"), and the dynamic-groupby mapping in `getFormDataWithExtraFilters` now
assigns the first column to source, the last to target, and everything between
to intermediate levels.
### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
Skipped — the only datasets available on the machine used for development
are private. Happy to add screenshots from the examples data if a reviewer
would like them; the testing instructions below reproduce the behavior in a
couple of minutes.
### TESTING INSTRUCTIONS
Unit tests (17 new for Sankey, plus 2 added to the dashboard util suite):
```bash
cd superset-frontend
npm run test -- plugins/plugin-chart-echarts/test/Sankey
npm run test -- src/dashboard/util/getFormDataWithExtraFilters.test.ts
```
Manual, on any dataset with three or more categorical columns and a numeric
measure:
1. Create a Sankey chart. Set **Source**, **Target**, and a `SUM(...)`
metric — confirm it behaves exactly as before.
2. Add one column to **Intermediate levels** → three columns of nodes
appear, chained through the middle level. Add a second → four levels.
3. Hover a node: it and its adjacent links highlight while the rest dims.
Hover a link: the tooltip shows the metric plus each endpoint's share.
4. Use a dataset where the *same value occurs in two different levels* (e.g.
the same column as both Source and Target). Confirm two distinct nodes render
and no "Sankey is a DAG" error appears.
5. Confirm labels show plain values (no level prefix) and long values are
truncated with an ellipsis.
6. Set **Node alignment** to Left/Right and confirm it re-renders without
re-querying; scroll-zoom and drag to confirm roaming.
7. Verify totals: for each level boundary, the sum of link values should
equal the metric total — nulls and duplicate pairs must not change it.
8. Open an existing saved two-column Sankey and confirm identical topology;
on a dashboard, drive it with a dimension-selector control and confirm
first/middle/last mapping.
### ADDITIONAL INFORMATION
- [x] Has associated issue: #3059, #20887, discussion #38713
- [ ] Required feature flags:
- [x] Changes UI
- [ ] Includes DB Migration (follow approval process in
[SIP-59](https://github.com/apache/superset/issues/13351))
- [ ] Migration is atomic, supports rollback & is backwards-compatible
- [ ] Confirm DB migration upgrade and downgrade tested
- [ ] Runtime estimates and downtime expectations provided
- [x] Introduces new feature or API
- [ ] Removes existing feature or API
Known gaps, deliberately out of scope: cross-filtering is still
unimplemented for this chart (pre-existing `TODO` in `Sankey/index.ts`), and
per-level styling via the ECharts `levels` option is a natural follow-up.
Cyclic data in two-column mode still surfaces the ECharts DAG error, as it does
today.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]