Skip to content

Graph Panel

GraphPreview
ANZASBFoodSaveRent

Force-directed graph visualization of money flows between accounts and categories. Nodes represent accounts and expense categories; edges represent transaction flows between them.

Chart Type

PropertyValue
LibraryApache ECharts (raw echarts.init())
Series typegraph with layout: 'force'
RenderingCanvas, direct init (NOT BaseChart)
Resize handlingManual ResizeObserver on container
Source filesrc/components/panels/GraphPanel.tsx

The panel bypasses BaseChart intentionally to avoid re-mount issues with the force layout. A raw echarts.init() call is made on a container div, with a dedicated ResizeObserver wired for responsive resizing.

What It Shows

  • Nodes -- bank accounts and spending categories, sized by transaction volume
  • Edges -- transaction flows between accounts and categories, width scaled by flow amount
  • Adjacency highlighting -- hovering a node highlights its connected edges in that node's color

Node Coloring

Account TypeColor
CHECKINGAccent (#00d4aa)
SAVINGSAccent (#00d4aa)
CREDITDanger (red)
INVESTMENTWarning (amber)
CategoriesPer-category color from CATEGORY_COLORS

Custom color groups override the defaults when a node name matches the group's search query.

Interactivity

Full-Canvas Pan and Zoom

ECharts' built-in roam is disabled. Instead, custom mouse handlers provide unbounded navigation:

  • Drag-pan -- click and drag anywhere on the canvas to pan
  • Scroll-wheel zoom -- zooms toward the mouse cursor position (range: 0.1x to 15x)
  • Fit-to-bounds -- auto-fits the graph on initial load; re-center via the header button

Manual Adjacency Highlight

The built-in focus: 'adjacency' emphasis is supplemented with a manual implementation that:

  1. Builds an adjacency map of node-to-edge indices on each option update
  2. On mouseover, dispatches highlight actions for the hovered node, its neighbors, and connected edges
  3. Overrides edge stroke color to match the hovered node's color
  4. On mouseout, dispatches downplay and forces a zrender refresh

Node Dragging

Individual nodes are draggable (draggable: true) within the force layout. The force simulation runs with animation: false for instant layout.

Settings Sidebar

A 220px collapsible sidebar (toggled via the gear icon in the header) with 5 sections:

1. Filters

ControlDescription
Text filterFilters nodes by name substring match
Accounts toggleShow/hide account nodes
Categories toggleShow/hide category nodes
Orphans toggleShow/hide nodes with no connections

2. Groups

ControlOptions
Grouping modeBy Type, By Bank, By Category Type, None
Color groupsCustom search-query-to-color mappings with add/remove

3. Display

ControlRange
LabelsOn/Off
ArrowsOn/Off (edge arrow symbols)
Node Size5 -- 80
Link Thickness1 -- 10
Label Size6 -- 18
Label Opacity0% -- 100%
Node Opacity0.1 -- 1.0
Link StyleStraight, Curved, Dashed
Node ShapeCircle, Square, Rounded Square, Diamond

4. Forces

ControlRange
Center Force (gravity)0 -- 0.5
Repel Force5 -- 500
Link Distance Min1 -- 200
Link Distance Max5 -- 400
Friction0 -- 1

5. Restore Defaults

Resets all settings to their initial values via useGraphStore.resetToDefaults().

Data Source

StoreFields
useFinanceStoreaccounts, transactions, categories
useGraphStoreAll layout/display/force settings, settingsOpen
useChartThemeTheme colors for tooltips, labels, borders

Empty State

Displays "No transaction data" centered in the panel when transactions.length === 0.