BESBanking Experience System
Docs Components Journey Showcase
Draft — not yet human-verified. Every gate passing here is automated. No screen-reader, Arabic native-speaker or usability testing has been carried out yet, and all Arabic UI copy is machine-drafted. What has and hasn't been verified
Cross-cutting systems

26 — Financial Data Visualization System

Banking Experience System (BES) · v2.0.0-draft

Live example

Spending breakdown — August
Balance trend — 6 months

Every chart ships a "View as table" equivalent (expand under each) — data is never conveyed by color alone.

Code
<div class="demo-stack">
  <div class="grid2" style="display:grid;grid-template-columns:1fr 1fr;gap:20px">
    <div>
      <div style="font-size:13px;font-weight:600;margin-bottom:6px">Spending breakdown — August</div>
      <div class="bes-chart" data-bes-chart='{"type":"donut","data":[{"label":"Groceries","value":2340},{"label":"Dining","value":1240},{"label":"Transport","value":860},{"label":"Utilities","value":1590},{"label":"Other","value":2890}],"opts":{"center":"AED 8.9K","centerSub":"August","label":"Spending by category, August","colLabel":"Category","colValue":"AED"}}'></div>
    </div>
    <div>
      <div style="font-size:13px;font-weight:600;margin-bottom:6px">Balance trend — 6 months</div>
      <div class="bes-chart" data-bes-chart='{"type":"line","data":[{"label":"Mar","value":21000},{"label":"Apr","value":19400},{"label":"May","value":24100},{"label":"Jun","value":22800},{"label":"Jul","value":26500},{"label":"Aug","value":25000}],"opts":{"label":"Balance trend over six months","colLabel":"Month","colValue":"AED"}}'></div>
    </div>
  </div>
  <p style="font-size:13px;color:var(--bes-text-secondary);margin:4px 0 0">Every chart ships a "View as table" equivalent (expand under each) — data is never conveyed by color alone.</p>
</div>

Charts in BES answer financial questions; they are information, not decoration. Every chart must remain understandable without color, and every chart has a text/table equivalent.


1. Chart components

Component Question it answers Form
Balance Chart "How has my balance moved?" Line/area, time axis
Cash-flow Chart "What came in vs went out?" Paired columns (in/out) per period + net line
Spending Breakdown "Where did it go?" Donut (≤6 slices + Other) or horizontal bars (preferred ≥5 categories)
Category Trend "Is dining growing?" Small-multiple lines or bars per category
Budget Progress "How much is left?" Progress bar + remaining figure
Goal Progress "How close am I?" Progress + projection marker (est.)
Income vs Expenses "Am I ahead?" Grouped columns + net annotation
Portfolio Chart "How is my portfolio doing?" Line with period selector, basis toggle
Asset Allocation "What am I holding?" Donut/stacked bar + table legend
Loan Repayment "How does my balance amortize?" Stacked area (principal/profit split) + schedule table
Interest/Profit Breakdown "What does this cost over time?" Stacked columns per period
Credit Score Display "Where do I stand?" Sourced gauge + band label + factors list (real bureau data only)
Financial Health "Am I okay?" Composite indicators with plain-language basis (P-49)
Transaction Heatmap "When do I spend?" Calendar heat grid (with value labels on focus)
FX Rate History "Is this a good rate?" Line + current-rate marker + period high/low

2. Chart selection rules

  • Time → line/area. Composition → donut (≤6) or bars. Comparison → bars (never pie). Flow → paired columns. Single value vs target → progress.
  • Sparklines (in cards/rows) show shape only — no axis implied precision; always paired with the actual current figure.
  • 3D, gauges-as-decoration, dual-y-axes (except FX pair contexts with explicit labeling) are banned.

3. Color & accessibility

  • Categorical palette (dedicated, ordered for adjacent distinguishability): chart.cat1 #1F52C4 · cat2 #0F6974 · cat3 #8F5F0E · cat4 #5A3DA0 · cat5 #0B7A45 · cat6 #A82E1F · cat7 #55617A — plus pattern fills (dots/hatch) engaged automatically in high-contrast mode and print.
  • Status colors (success/error) are not chart categories; performance charts may use financial.income/financial.negative for gain/loss areas only.
  • Every series distinguishable by ≥2 channels (color + marker shape/pattern/direct label). Direct labeling preferred over legends where space allows.
  • Text equivalent mandatory: "View as table" on every chart; screen readers get a summary sentence ("Spending by category, August: Groceries AED 2,340 highest, seven categories, total AED 8,920") + the table.
  • Interactive points keyboard-reachable; tooltips on focus; touch targets ≥44px via invisible hit areas.

4. Financial data rules

  • Axes honesty: y-axis starts at zero for amounts; non-zero baselines (rate charts) show a break indicator + baseline label.
  • Negative values plotted below a marked zero line, labeled with true minus; never clipped.
  • Zero values render (a zero-spend month is data); missing data renders as a labeled gap ("No data") — never interpolated silently.
  • Rounding: chart labels may abbreviate (AED 2.3K) but tooltips/tables carry full precision.
  • Time periods labeled unambiguously ("Aug 2026", not "08/26"); comparison periods explicit ("vs Jul 2026").
  • Projections/estimates: dashed + "estimated" label; never same treatment as actuals.
  • Currency: single-currency per chart; multi-currency data converted with the conversion note ("All values in AED, converted at today's rate").

5. RTL behavior

  • Time axes stay LTR (chronology reads left→right universally in charts; flipping time confuses more than it localizes) — documented as the deliberate exception; axis labels localize.
  • Bar/column category axes mirror (first category at inline-start); donut rotation order mirrors; legends and labels mirror; numerals per locale policy.
  • Heatmap weekday order follows locale week start.

6. Empty, loading, error

Loading: skeleton chart shape (no fake data motion). Empty: explanation + enablement ("Your spending breakdown appears after your first month of transactions"). Error: inline retry, cached-with-timestamp where available. Insufficient data (<3 points for a trend): show the table instead of a misleading line — the component downgrades itself.


All components in this family — live

Every component from this specification, rendered by the coded library. Expand "Code" to copy the markup.

Bar chart & budget progress

Dining budget — August
AED 1,240.00 spentAED 240.00 left
Code
<div class="demo-stack" style="max-width:520px">
  <div class="bes-chart" data-bes-chart='{"type":"bar","data":[{"label":"Apr","value":18500},{"label":"May","value":18500},{"label":"Jun","value":21300},{"label":"Jul","value":18500},{"label":"Aug","value":18500}],"opts":{"label":"Income by month in dirhams","colLabel":"Month","colValue":"AED"}}'></div>
  <div class="bes-limit">
    <div style="font-size:13.5px;font-weight:600;margin-bottom:6px">Dining budget — August</div>
    <div class="bes-progress bes-progress--warn"><div class="fill" style="inline-size:84%"></div></div>
    <div class="figures"><span class="used"><bdi class="bes-amount">AED 1,240.00</bdi> spent</span><span><bdi class="bes-amount">AED 240.00</bdi> left</span></div>
  </div>
</div>