[PR #7682] [WIP] Various sankey improvements and bugfixes #77309

Open
opened 2026-05-16 19:09:59 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/actualbudget/actual/pull/7682
Author: @emiltb
Created: 5/2/2026
Status: 🔄 Open

Base: masterHead: sankey-fixes


📝 Commits (10+)

  • 69178ef Point Overbudgeted node to Budget instead of Available funds
  • 9503fb8 Extract hidden node handling to separate function
  • 48a20a8 Fix income without payee placement and Overspent - Budgeted value
  • 2c8563d Fix TopN. Handle negative budgeting differently.
  • 8a3925b Better handling of negative budgeting and spending
  • 2a48b38 Disclaimer for negative budgeting
  • 5e6eb7f Add account grouping in Spent view
  • c0232bc Fix Options menu closing on toggle
  • aa8ae9d Fix graph title not saved when changed
  • f861229 [AI] Add unit tests for spreadsheet code

📊 Changes

6 files changed (+1343 additions, -274 deletions)

View changed files

📝 packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx (+1 -1)
📝 packages/desktop-client/src/components/reports/reports/Sankey.tsx (+148 -42)
📝 packages/desktop-client/src/components/reports/reports/SankeyCard.tsx (+66 -18)
packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.test.ts (+717 -0)
📝 packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts (+410 -213)
📝 packages/loot-core/src/types/models/dashboard.ts (+1 -0)

📄 Description

Description

This PR addresses a number of issues discovered in the Sankey chart.

  • Changes placement of 'Overspent' node
  • Refactors addition of hidden nodes for more robust layer placement
  • Better handling of net deposits in categories in Spent mode
  • Better handling of categories with negative amounts budgeted in Budget mode (i.e. covering overspending from a Savings category)
  • Added a disclaimer to the graph description, describing the challenge in representing negative numbers, and why they Sankey chart there might in some cases provide a slightly different view on the budget than other places in the app.
  • Fixes an issue where the 'Show N' value did not result in N categories being shown.
  • Add option to group all accounts in Spent view to a single Income node.
  • Fix issue with report title not being saved.
  • Add unit tests for spreadsheet code (mostly AI-generated).
  • Modify handling of too many nodes in a layer. The user can now select a max number of nodes (or All) and the chart will show up to that number of nodes - however if the view height is too small to properly display that, nodes are automatically grouped into Other nodes, to avoid displaying a broken graph. This adjusts dynamically as the window size changes. Data fetching and preparation of the graph data was separated, to ensure that only the necessary steps are reprocessed, when the size changes.
  • Modified the color-assignment algorithm. It now uses the first three letters of the key (which in most cases is a uuid) as a random value, that is mapped to a color. This ensures that the same link/node gets a random color, but in a stable way, so the same color is always assigned to the same category. This also ensures that colors for a given category are the same for Spent/Budgeted views.

Relates to #1919.

Testing

Manual testing with various test budgets. Added unit tests for core spreadsheet functionality.

Checklist

  • Release notes added (see link above)
  • No obvious regressions in affected areas
  • Self-review has been performed - I understand what each change in the code does and why it is needed

Bundle Stats

Bundle Files count Total bundle size % Changed
desktop-client 33 13.95 MB → 13.95 MB (-5.08 kB) -0.04%
loot-core 1 5.31 MB 0%
api 2 3.94 MB 0%
cli 1 7.97 MB 0%
crdt 1 11.12 kB 0%
View detailed bundle stats

desktop-client

Total

Files count Total bundle size % Changed
33 13.95 MB → 13.95 MB (-5.08 kB) -0.04%
Changeset
File Δ Size
src/components/reports/spreadsheets/sankey-spreadsheet.ts 📈 +3.51 kB (+14.43%) 24.31 kB → 27.82 kB
src/components/reports/reports/CustomReport.tsx 📉 -4 B (-0.01%) 41.84 kB → 41.84 kB
src/components/reports/graphs/SankeyGraph.tsx 📉 -1 B (-0.01%) 7.09 kB → 7.08 kB
src/components/reports/reports/NetWorth.tsx 📉 -2 B (-0.01%) 14.16 kB → 14.16 kB
src/components/reports/SaveReport.tsx 📉 -2 B (-0.02%) 12.91 kB → 12.91 kB
src/components/reports/graphs/DonutGraph.tsx 📉 -4 B (-0.02%) 22.7 kB → 22.7 kB
src/components/reports/reports/NetWorthCard.tsx 📉 -2 B (-0.02%) 7.87 kB → 7.87 kB
src/components/reports/spreadsheets/net-worth-spreadsheet.ts 📉 -2 B (-0.03%) 5.69 kB → 5.69 kB
src/components/reports/graphs/NetWorthGraph.tsx 📉 -8 B (-0.04%) 21.25 kB → 21.24 kB
src/components/reports/reports/Sankey.tsx 📉 -5.5 kB (-14.87%) 36.95 kB → 31.45 kB
src/components/reports/reports/SankeyCard.tsx 📉 -3.07 kB (-36.99%) 8.3 kB → 5.23 kB
View detailed bundle breakdown

Added
No assets were added

Removed
No assets were removed

Bigger
No assets were bigger

Smaller

Asset File Size % Changed
static/js/ReportRouter.js 1.22 MB → 1.22 MB (-5.08 kB) -0.41%

Unchanged

Asset File Size % Changed
static/js/index.js 2.01 MB 0%
static/js/BackgroundImage.js 121.09 kB 0%
static/js/FormulaEditor.js 962.55 kB 0%
static/js/ScheduleEditForm.js 146.45 kB 0%
static/js/TransactionEdit.js 190.43 kB 0%
static/js/TransactionList.js 85.81 kB 0%
static/js/Value.js 4.96 MB 0%
static/js/bankSyncUtils.js 54.15 kB 0%
static/js/ca.js 187.72 kB 0%
static/js/chart-theme.js 800.08 kB 0%
static/js/client.js 451.37 kB 0%
static/js/da.js 101.28 kB 0%
static/js/de.js 170.38 kB 0%
static/js/en-GB.js 10.01 kB 0%
static/js/en.js 193.42 kB 0%
static/js/es.js 178.83 kB 0%
static/js/extends.js 519.29 kB 0%
static/js/fr.js 178.71 kB 0%
static/js/indexeddb-main-thread-worker-e59fee74.js 13.46 kB 0%
static/js/it.js 165.13 kB 0%
static/js/narrow.js 364.2 kB 0%
static/js/nb-NO.js 148.19 kB 0%
static/js/nl.js 106.34 kB 0%
static/js/pt-BR.js 189.39 kB 0%
static/js/resize-observer.js 18.06 kB 0%
static/js/th.js 174.62 kB 0%
static/js/theme.js 31.67 kB 0%
static/js/uk.js 207.56 kB 0%
static/js/useFormatList.js 4.96 kB 0%
static/js/wide.js 453 B 0%
static/js/workbox-window.prod.es5.js 7.33 kB 0%
static/js/zh-Hans.js 117.75 kB 0%

loot-core

Total

Files count Total bundle size % Changed
1 5.31 MB 0%
View detailed bundle breakdown

Added
No assets were added

Removed
No assets were removed

Bigger
No assets were bigger

Smaller
No assets were smaller

Unchanged

Asset File Size % Changed
kcab.worker.jUVFVkaN.js 5.31 MB 0%

api

Total

Files count Total bundle size % Changed
2 3.94 MB 0%
View detailed bundle breakdown

Added
No assets were added

Removed
No assets were removed

Bigger
No assets were bigger

Smaller
No assets were smaller

Unchanged

Asset File Size % Changed
index.js 3.94 MB 0%
models.js 0 B 0%

cli

Total

Files count Total bundle size % Changed
1 7.97 MB 0%
View detailed bundle breakdown

Added
No assets were added

Removed
No assets were removed

Bigger
No assets were bigger

Smaller
No assets were smaller

Unchanged

Asset File Size % Changed
cli.js 7.97 MB 0%

crdt

Total

Files count Total bundle size % Changed
1 11.12 kB 0%
View detailed bundle breakdown

Added
No assets were added

Removed
No assets were removed

Bigger
No assets were bigger

Smaller
No assets were smaller

Unchanged

Asset File Size % Changed
index.js 11.12 kB 0%

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/actualbudget/actual/pull/7682 **Author:** [@emiltb](https://github.com/emiltb) **Created:** 5/2/2026 **Status:** 🔄 Open **Base:** `master` ← **Head:** `sankey-fixes` --- ### 📝 Commits (10+) - [`69178ef`](https://github.com/actualbudget/actual/commit/69178ef46a671b14eb6b91a8339308cb26870ada) Point Overbudgeted node to Budget instead of Available funds - [`9503fb8`](https://github.com/actualbudget/actual/commit/9503fb8c81ec93471b540c182ce3ae16d41a866b) Extract hidden node handling to separate function - [`48a20a8`](https://github.com/actualbudget/actual/commit/48a20a8ff2d1837babfec8ccfd20d6f1305c4ad2) Fix income without payee placement and Overspent - Budgeted value - [`2c8563d`](https://github.com/actualbudget/actual/commit/2c8563d72d2d5d05463853c360ae167376e61a72) Fix TopN. Handle negative budgeting differently. - [`8a3925b`](https://github.com/actualbudget/actual/commit/8a3925bc1e1ba20387eb3df621123bc56dfa612b) Better handling of negative budgeting and spending - [`2a48b38`](https://github.com/actualbudget/actual/commit/2a48b384764c0f8dee76461aa616c3fb8fa31db6) Disclaimer for negative budgeting - [`5e6eb7f`](https://github.com/actualbudget/actual/commit/5e6eb7f61117dfce35efb368cb9892db15b5727c) Add account grouping in Spent view - [`c0232bc`](https://github.com/actualbudget/actual/commit/c0232bc58d3f78386e49a0ef62d4f7c98aa11295) Fix Options menu closing on toggle - [`aa8ae9d`](https://github.com/actualbudget/actual/commit/aa8ae9dcd8902e570fa052dd8b9dd9b1f641bb28) Fix graph title not saved when changed - [`f861229`](https://github.com/actualbudget/actual/commit/f861229f317c1457eb8be366b45e3a068d8c476b) [AI] Add unit tests for spreadsheet code ### 📊 Changes **6 files changed** (+1343 additions, -274 deletions) <details> <summary>View changed files</summary> 📝 `packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx` (+1 -1) 📝 `packages/desktop-client/src/components/reports/reports/Sankey.tsx` (+148 -42) 📝 `packages/desktop-client/src/components/reports/reports/SankeyCard.tsx` (+66 -18) ➕ `packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.test.ts` (+717 -0) 📝 `packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts` (+410 -213) 📝 `packages/loot-core/src/types/models/dashboard.ts` (+1 -0) </details> ### 📄 Description ## Description This PR addresses a number of issues discovered in the Sankey chart. * Changes placement of 'Overspent' node * Refactors addition of hidden nodes for more robust layer placement * Better handling of net deposits in categories in Spent mode * Better handling of categories with negative amounts budgeted in Budget mode (i.e. covering overspending from a Savings category) * Added a disclaimer to the graph description, describing the challenge in representing negative numbers, and why they Sankey chart there might in some cases provide a slightly different view on the budget than other places in the app. * Fixes an issue where the 'Show N' value did not result in N categories being shown. * Add option to group all accounts in Spent view to a single Income node. * Fix issue with report title not being saved. * Add unit tests for spreadsheet code (mostly AI-generated). * Modify handling of too many nodes in a layer. The user can now select a max number of nodes (or All) and the chart will show up to that number of nodes - however if the view height is too small to properly display that, nodes are automatically grouped into Other nodes, to avoid displaying a broken graph. This adjusts dynamically as the window size changes. Data fetching and preparation of the graph data was separated, to ensure that only the necessary steps are reprocessed, when the size changes. * Modified the color-assignment algorithm. It now uses the first three letters of the key (which in most cases is a uuid) as a random value, that is mapped to a color. This ensures that the same link/node gets a random color, but in a stable way, so the same color is always assigned to the same category. This also ensures that colors for a given category are the same for Spent/Budgeted views. ## Related issue(s) Relates to #1919. ## Testing Manual testing with various test budgets. Added unit tests for core spreadsheet functionality. ## Checklist - [ ] Release notes added (see link above) - [x] No obvious regressions in affected areas - [x] Self-review has been performed - I understand what each change in the code does and why it is needed <!--- actual-bot-sections ---> <!--- bundlestats-action-comment key:combined start ---> ### Bundle Stats Bundle | Files count | Total bundle size | % Changed ------ | ----------- | ----------------- | --------- desktop-client | 33 | 13.95 MB → 13.95 MB (-5.08 kB) | -0.04% loot-core | 1 | 5.31 MB | 0% api | 2 | 3.94 MB | 0% cli | 1 | 7.97 MB | 0% crdt | 1 | 11.12 kB | 0% <details> <summary>View detailed bundle stats</summary> #### desktop-client **Total** Files count | Total bundle size | % Changed ----------- | ----------------- | --------- 33 | 13.95 MB → 13.95 MB (-5.08 kB) | -0.04% <details> <summary>Changeset</summary> File | Δ | Size ---- | - | ---- `src/components/reports/spreadsheets/sankey-spreadsheet.ts` | 📈 +3.51 kB (+14.43%) | 24.31 kB → 27.82 kB `src/components/reports/reports/CustomReport.tsx` | 📉 -4 B (-0.01%) | 41.84 kB → 41.84 kB `src/components/reports/graphs/SankeyGraph.tsx` | 📉 -1 B (-0.01%) | 7.09 kB → 7.08 kB `src/components/reports/reports/NetWorth.tsx` | 📉 -2 B (-0.01%) | 14.16 kB → 14.16 kB `src/components/reports/SaveReport.tsx` | 📉 -2 B (-0.02%) | 12.91 kB → 12.91 kB `src/components/reports/graphs/DonutGraph.tsx` | 📉 -4 B (-0.02%) | 22.7 kB → 22.7 kB `src/components/reports/reports/NetWorthCard.tsx` | 📉 -2 B (-0.02%) | 7.87 kB → 7.87 kB `src/components/reports/spreadsheets/net-worth-spreadsheet.ts` | 📉 -2 B (-0.03%) | 5.69 kB → 5.69 kB `src/components/reports/graphs/NetWorthGraph.tsx` | 📉 -8 B (-0.04%) | 21.25 kB → 21.24 kB `src/components/reports/reports/Sankey.tsx` | 📉 -5.5 kB (-14.87%) | 36.95 kB → 31.45 kB `src/components/reports/reports/SankeyCard.tsx` | 📉 -3.07 kB (-36.99%) | 8.3 kB → 5.23 kB </details> <details> <summary>View detailed bundle breakdown</summary> <div> **Added** No assets were added **Removed** No assets were removed **Bigger** No assets were bigger **Smaller** Asset | File Size | % Changed ----- | --------- | --------- static/js/ReportRouter.js | 1.22 MB → 1.22 MB (-5.08 kB) | -0.41% **Unchanged** Asset | File Size | % Changed ----- | --------- | --------- static/js/index.js | 2.01 MB | 0% static/js/BackgroundImage.js | 121.09 kB | 0% static/js/FormulaEditor.js | 962.55 kB | 0% static/js/ScheduleEditForm.js | 146.45 kB | 0% static/js/TransactionEdit.js | 190.43 kB | 0% static/js/TransactionList.js | 85.81 kB | 0% static/js/Value.js | 4.96 MB | 0% static/js/bankSyncUtils.js | 54.15 kB | 0% static/js/ca.js | 187.72 kB | 0% static/js/chart-theme.js | 800.08 kB | 0% static/js/client.js | 451.37 kB | 0% static/js/da.js | 101.28 kB | 0% static/js/de.js | 170.38 kB | 0% static/js/en-GB.js | 10.01 kB | 0% static/js/en.js | 193.42 kB | 0% static/js/es.js | 178.83 kB | 0% static/js/extends.js | 519.29 kB | 0% static/js/fr.js | 178.71 kB | 0% static/js/indexeddb-main-thread-worker-e59fee74.js | 13.46 kB | 0% static/js/it.js | 165.13 kB | 0% static/js/narrow.js | 364.2 kB | 0% static/js/nb-NO.js | 148.19 kB | 0% static/js/nl.js | 106.34 kB | 0% static/js/pt-BR.js | 189.39 kB | 0% static/js/resize-observer.js | 18.06 kB | 0% static/js/th.js | 174.62 kB | 0% static/js/theme.js | 31.67 kB | 0% static/js/uk.js | 207.56 kB | 0% static/js/useFormatList.js | 4.96 kB | 0% static/js/wide.js | 453 B | 0% static/js/workbox-window.prod.es5.js | 7.33 kB | 0% static/js/zh-Hans.js | 117.75 kB | 0% </div> </details> --- #### loot-core **Total** Files count | Total bundle size | % Changed ----------- | ----------------- | --------- 1 | 5.31 MB | 0% <details> <summary>View detailed bundle breakdown</summary> <div> **Added** No assets were added **Removed** No assets were removed **Bigger** No assets were bigger **Smaller** No assets were smaller **Unchanged** Asset | File Size | % Changed ----- | --------- | --------- kcab.worker.jUVFVkaN.js | 5.31 MB | 0% </div> </details> --- #### api **Total** Files count | Total bundle size | % Changed ----------- | ----------------- | --------- 2 | 3.94 MB | 0% <details> <summary>View detailed bundle breakdown</summary> <div> **Added** No assets were added **Removed** No assets were removed **Bigger** No assets were bigger **Smaller** No assets were smaller **Unchanged** Asset | File Size | % Changed ----- | --------- | --------- index.js | 3.94 MB | 0% models.js | 0 B | 0% </div> </details> --- #### cli **Total** Files count | Total bundle size | % Changed ----------- | ----------------- | --------- 1 | 7.97 MB | 0% <details> <summary>View detailed bundle breakdown</summary> <div> **Added** No assets were added **Removed** No assets were removed **Bigger** No assets were bigger **Smaller** No assets were smaller **Unchanged** Asset | File Size | % Changed ----- | --------- | --------- cli.js | 7.97 MB | 0% </div> </details> --- #### crdt **Total** Files count | Total bundle size | % Changed ----------- | ----------------- | --------- 1 | 11.12 kB | 0% <details> <summary>View detailed bundle breakdown</summary> <div> **Added** No assets were added **Removed** No assets were removed **Bigger** No assets were bigger **Smaller** No assets were smaller **Unchanged** Asset | File Size | % Changed ----- | --------- | --------- index.js | 11.12 kB | 0% </div> </details> </details> <!--- bundlestats-action-comment key:combined end ---> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-05-16 19:09:59 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/actual#77309