Flutter docs
Default skin

CashFlowChart Composition

Money in and out per period, with the running balance over them. BalanceCurve shows that cash dips; this shows why — which week's bills pull it under and which receipt brings it back. It is the shape cash-forecast dashboards converge on: inflow bars up, outflow bars down, the balance as a line across both.

Usage

Cash, next six weeks

Below the line from Oct 12 — lowest −10M, 1 period(s) under.

Cash flow by period
PeriodInOutBalance
Sep 28Rp 12.000.000Rp 18.500.000Rp 33.500.000
Oct 5Rp 0Rp 26.000.000Rp 7.500.000
Oct 12Rp 4.000.000Rp 21.000.000-Rp 9.500.000
Oct 19Rp 95.000.000Rp 14.000.000Rp 71.500.000
Oct 26Rp 8.000.000Rp 19.000.000Rp 60.500.000
Nov 2Rp 30.000.000Rp 12.000.000Rp 78.500.000

Press a week to list what is behind it.

Start from the real balance

opening is the balance before the first period — today's cash for a forecast, or the opening of a historical window. The line starts there and runs through each period's close. Starting from zero draws a projection of change, which reads like a projection of cash and is not one.

What it states

Above the plot, one sentence gives the two figures a decision needs: the first period below the threshold and the lowest balance. The period selector marks a dip, including one hidden inside a period that later closes above the threshold. A dot marks the lowest point on the plot; the sentence supplies its exact figure. Lightweight Charts draws the bars, line, threshold, grid and numeric axis. Hover a period on the plot to read its exact inflow, outflow and closing balance without interpreting the compact axis labels. If the period's intra-period low differs from its close, the detail shows that too.

Periods are the consumer's

The chart does not bucket. Pass days, weeks or months, each with its start day, inflow and outflow (positive; a negative outflow is read as the same amount). A period bucketed from finer figures can dip and recover inside itself — a week that is overdrawn on Wednesday and paid on Friday closes above zero. Pass its low (the lowest balance within it) and the chart reads that against the threshold, marks its period and plots the dip, so a mid-period shortfall is never hidden by the close. formatPeriod names a period on the chart's axis and in the selector; by default it is its start day in the document's language. The axis chooses which labels fit at the available width. An optional signed adjustment changes the running balance without creating an inflow/outflow bar. It appears separately in exact details and the table; use adjustmentLabel to name it. Never disguise a balance adjustment as a receipt or payment.

Interaction contract

Read-only unless onSelectPeriod is given. Then each period is a button named with its date and all three exact figures, aria-pressed for selectedPeriod, so the consumer can list what is behind it beside the chart. Keyboard focus on any period reveals the same exact-value detail as hover. Without an action callback, periods remain focusable labelled images, not buttons that promise an unavailable action. The detail follows the active period near the pointer, or its balance point during keyboard focus. It flips and stays within the chart bounds near an edge rather than jumping to the opposite chart edge. Pass periodControlsLabel to put the exact-value table in an initially closed native disclosure. This leaves only the plot's date axis visible in a compact overview. Enter or Space on the summary opens rows with the period, inflow, outflow, optional adjustment and closing balance. Numbers use formatExact, not the abbreviated axis format. Read-only period labels are plain row headings; when onSelectPeriod is provided they retain their selection buttons and keyboard detail. Use periodLabel to translate the period column heading. Do not label a date-only selector as an exact-amount table. For a read-only overview where hover details are sufficient, omit periodControlsLabel and pass compact. Period controls stay visually hidden until keyboard focus, while exact values remain available in the screen-reader table. Do not add a second visible table merely to repeat the plot.

Accessibility

A visually hidden table gives every period's in, out and balance by default. With periodControlsLabel, the same table is visible when the disclosure is opened; there is no duplicate hidden table or date selector. The canvas is aria-hidden because the table is the exact accessible rendering. Under forced-colors: active the canvas is replaced by an always-visible table, even with a disclosure label. Pass formatExact when format abbreviates the axis; the library has no currency assumption. The chart has no entry animation, including under reduced motion.

Do

Use it for a forecast where the reader has to see which flows cause a dip.

Don't

Use it for a plain balance with no flows to explain — that is BalanceCurve.

Props

PropTypeDefaultNotes
labelstring—Visible title and accessible name. Required.
openingnumber—The balance before the first period. Required.
periodsCashFlowPeriod[]—`{ id, start, inflow, outflow, adjustment?, low? }` in order; adjustments affect balance, not flow bars; `low` is the lowest balance within the period.
format(value: number) => string—How a value is written. The product owns this.
formatExact(value: number) => stringformatFull-precision values for hover, focused period buttons and the accessible table.
formatPeriod(start: string) => string—How a period is named. Defaults to its start day.
threshold{ value: number; label?: string }{ value: 0 }The line the balance is read against.
onSelectPeriod(id: string) => void—Makes each period a button.
selectedPeriodstring—The period whose detail the consumer is showing.
heightnumber240Plot height in pixels.
inflowLabel / outflowLabel / balanceLabelstring'In' / 'Out' / 'Balance'Legend, table and button words.
lowestLabelstring'Low'Hover label when the lowest intra-period balance differs from the closing balance.
adjustmentLabelstring'Adjustment'Exact detail and table label for non-flow balance changes.
periodLabelstring'Period'Heading for the exact table's period column.
belowLabel(from, lowest, periods) => string—The sentence when the balance goes below the line.
clearLabel(lowest) => string—The sentence when it never does.
tableLabelstring'Cash flow by period'Caption of the exact-value table.
periodControlsLabelstring—Optional label for an initially collapsed visible exact-value table. Omit to keep expanded period controls and a screen-reader table.
compactbooleanfalseVisually hide undisclosed period controls until keyboard focus; keep the exact screen-reader table and forced-colors fallback.
emptyLabelstring'Nothing to project yet.'Shown when there are no periods.
localestring—Language for default period names; the document's `lang` when omitted.
classNamestring—Added to the root element.

Tokens

--cb-tone-success fills inflows, --cb-tone-danger fills outflows and marks a period below the threshold, --cb-tone-brand draws the balance and low point, --cb-border draws the grid and selector separator, --cb-fg-muted the axis text, --cb-focus-width the focus ring, and the existing --cb-radius-*, --cb-space-*, and --cb-text-* Tokens size the component.