All use cases
Build this app

An analytics dashboard or admin console

Charts, stat bands and tables over live data — the internal surface every product grows whether it was planned or not.

The problem

Every product eventually grows an internal console, and it is usually the ugliest surface in the codebase because it was never anyone's project. It is also the one your team looks at daily, and the one where a wrong number does the most damage: a dashboard nobody trusts gets replaced by someone exporting to a spreadsheet.

The technical trap is charts. A charting library that owns its own DOM will fight your framework about who re-renders, and the usual outcome is a panel that flickers or goes stale without saying so.

What you are building

Live surfaces, not screenshots — every one composed from the same components you would install. ECharts behind a React wrapper that keeps the option object declarative, so a chart is data rather than an imperative instance you have to remember to update.

Analytics dashboard

fancy-echarts with a stat band above it; the chart is the real ECharts, not an image.

The code

A chart is an option object, not an instancetsx
// The wrapper diffs and applies the option, so the chart follows state the way
// any other component does -- no ref, no imperative setOption, nothing to forget
// on update.
<EChart
  style={{ height: 240 }}
  option={{
    xAxis: { type: "category", data: months },
    yAxis: { type: "value" },
    series: [{ type: "bar", data: revenue }],
  }}
/>
Live without a refresh buttontsx
// Hydrate from the Inertia payload so the first paint is server data rather than
// a spinner, then invalidate on a broadcast event. Polling is a tax you pay
// forever; invalidation updates the panel that changed, when it changed.
const { data } = useHydratedQuery({
  queryKey: ["revenue", period],
  initialData: page.props.revenue,
});

useEchoInvalidation("orders", ["revenue"]);
Measure the console itselfphp
// An internal tool nobody opens is worth deleting, and you cannot tell without
// measuring. fancy-heuristics records interaction server-side, with no
// third-party pixel on an authenticated admin surface.
Heuristics::record('dashboard.viewed', [
    'panel'  => 'revenue',
    'period' => $period,
]);

How to solve it

  1. Install the chart wrapper

    ECharts is the engine; the wrapper makes it declarative. Register only the chart types you use so the bundle carries only those.

    Run thisbash
    npm i @particle-academy/fancy-echarts
  2. Lead with the numbers, not the chart

    The figures people came for should be readable before anything renders. Tabular numerals line up in a band; the chart is the explanation underneath.

  3. Hydrate from the server payload

    First paint should be real data. A console that opens on skeletons trains people to distrust it.

  4. Invalidate on events, not on a timer

    Broadcast invalidation refreshes the panel whose data actually changed, instead of re-fetching everything on a schedule.