Lab 22 / the parked decision comes back
The chart engine.
Charts were parked in Lab 11 with the form work done: sixteen measures matched to forms, six popular charts rejected with reasons, the palette validated. What stayed open was the engine and the ambition. The brief now has three tiers: the easy data (bars and lines), the shaped data (the RSS radar), and the instruments (a heat map of where sales come from, the globe, and more like it). Four candidates were benched: your three, ApexCharts, AG Charts and MUI X Charts, and one challenger this lab proposes. Performance and security were scored as hard criteria, from verified sources, not marketing pages.
The recommendation: Apache ECharts, one engine for all three tiers. It is the only candidate that covers the whole brief in its free, governed core, and the only one whose accessibility layer natively draws the system's own hatched fills.
Seeing beats reading: the live annex renders every tier in the browser with the engine itself, on the system's theme: the hatched open month, the RSS radar against the average, the destination heat map on our own topology, the money flow with its shares, and the service tickets month.
4Candidates benched
8Hard criteria
3Tiers covered
EChartsRecommendation
1Decision superseded
01 / the brief
Three tiers, one engine wanted.
TierExamplesWhat it demands of the engine
1 · The easy databar, line, areaThe sixteen form mappings from Lab 11 stand. Demands: our marks (thin bars, 3px data ends, hairline grid), the validated palette, tabular mono figures, a table view behind every chart (L12), no default animation (M1).
2 · The shaped dataRSS radar, heatmap, aged matrixForms where the shape is the reading. The RSS radar has six fixed axes worn as a signature (Lab 20's glyph, now full-size); the calendar heatmap already has its component. Demands: radar and heatmap in the core catalog, axes order fixed platform wide.
3 · The instrumentsdestination heat map, money flow, moreWhere sales come from and where they go, with spend per destination; how revenue becomes margin. Demands: geographic series, flow (sankey) series, and room to grow without changing engine.
02 / the bench
Four engines against eight hard criteria.
Facts below are verified against each library's own documentation, npm records and the CVE databases, current to this week.
CriterionApexChartsAG ChartsMUI X ChartsECharts (proposed)
Tier 1 coverageyesyes (Community)yesyes
RadaryesEnterprise onlyyes, youngyes, core
Geo and globenonemaps, Enterprise, 2Dnonegeo core · globe via GL
Flow (sankey), chordnoneEnterprise onlynonecore, chord new in 6.0
Performance modelSVG, DOM-boundcanvasSVG, WebGL heatmap is Premiumcanvas, progressive render, LTTB sampling
Security recordXSS CVE-2021-23327, regressed in 3.26.0clean recordclean recordASF governance, risky APIs documented, policy below
Licence for our catalogMIT but catalog missingcommercial per developerPro / Premium per developerApache-2.0, everything free
Theming fitconfig objects, HTML tooltipstheme APIMaterial and Emotion runtimeone theme JSON from our tokens, dynamic light and dark in 6.0, decals draw our hatching
Why each shortlisted engine falls short
ApexChartsThe friendliest to start and the hardest to defend. Tier 3 does not exist in its catalog at all, its SVG rendering hits a ceiling exactly where the ledger's data begins, and its tooltip and legend layer has already produced a cross-site scripting CVE that then regressed back in a later release. The chart layer sits under figures we owe SOC 2 evidence for; a charting library with an XSS history in its label pipeline is the wrong neighbour for it.
AG ChartsThe strongest engineering of the three, and the honest second place. Canvas performance is real and the company is serious. But the brief's whole second and third tier, radar, maps, sankey, sits behind the Enterprise licence, per developer, and there is still no globe at the end of it. Cost is not the constraint; buying into a gated catalog that ends below the ambition is.
MUI X ChartsYoung catalog, no geographic series, and the deepest mismatch: it ships Material's styling system, an Emotion CSS-in-JS runtime the platform does not have, to style charts a token JSON should style. Its best charts (heatmap, WebGL rendering) sit in Pro and Premium tiers. Choosing it means adopting a second design system to power the first one's charts.
03 / the pick
Apache ECharts, and why it is not close.
ECharts 6.0 shipped July 2025 under the Apache Software Foundation: canvas rendering with progressive drawing for large series, largest-triangle-three-buckets sampling for long lines, the full catalog in core (bar, line, area, scatter, radar, heatmap, calendar, geo maps, sankey, chord, gauge, candlestick), dynamic theme switching for our authored light and dark, and server-side rendering for share pages. The 3D globe comes from the GL extension when wanted; the 2D geo series in core already draws the destination heat map.
One engine, three tiersEvery form in the brief, and every form Lab 11 mapped, renders from one dependency with one theme. No second library when the ambition grows: chord for intercompany flows and matrix layouts are already in the box.
The decal alignmentECharts' accessibility layer draws decal patterns, hatched fills, on any series. The design system's fill rule (solid settled, hatched open) and its CVD texture requirement are not a customisation here; they are a supported first-class feature. No other candidate has this.
GovernanceAn Apache Foundation project: public security process, documented risky APIs, no vendor to outgrow, no per-developer licence to audit. The library is a dependency, not a relationship.
Motion under our lawanimation: false is one line in the base theme, which satisfies M1 globally; the intelligence layer then re-enables exactly the signals I1 permits, per series, deliberately.
Decision superseded
Lab 11 adopted Recharts for the simple forms. This recommendation retires that: the sixteen form mappings, the palette and the token work all carry over unchanged, but the renderer becomes ECharts so the platform runs one chart engine, not two. The Recharts decision was right for the brief it had; the brief grew.
One engineering check before the globe
The GL extension (BSD licensed, last published this year) is verified compatible with ECharts 5.x; its compatibility with 6.0 must be proven in a spike before the 3D globe ships. The heat map does not wait for it: the 2D geo series is core. If the spike fails, the globe waits on GL, not the platform on the globe.
04 / security
The engine is safe the way it is used. So the use is law.
ECharts' own security guidelines name its two risky APIs: tooltip.formatter accepts raw HTML, and title.link follows URLs unsanitised. Customer names, supplier names and narrative strings flow into charts, and some of those strings originate outside the platform. So the integration carries five rules, enforced in one wrapper module nobody bypasses:
No HTML from data, everEvery formatter returns plain text rendered in richText mode. A customer named <script> charts as a customer named <script>. The wrapper owns the formatters; pages pass data, never markup.
title.link is bannedCharts never navigate through the engine. Every figure opens its report through the platform's own router, which is already the Board archetype's law.
Self-hosted, pinned, offlineThe library and the GL extension are bundled from the lockfile, never a CDN. Map topology is our own file shipped with the app; no tile servers, no external fetches at runtime, which also keeps the strict CSP intact.
Canvas under CSPCanvas rendering needs no inline script, no eval, no foreignObject HTML in SVG. The chart surface adds nothing to the CSP allowlist.
Advisories watchedThe dependency rides the platform's existing audit pipeline; ASF publishes CVEs through the standard channels the pipeline already reads.
05 / performance
Budgets, not hopes.
Modular importcore + used seriesECharts tree-shakes by series and component. The dashboard bundle carries bar, line and the theme; geo and sankey load with the surfaces that use them.
GL loads on demandglobe surfaces onlyThe GL extension is heavy and loads only on the route that draws the globe, never in the shared bundle.
Large seriesprogressive + LTTBLedger-scale series render progressively; long lines downsample by largest-triangle-three-buckets, which keeps the shape truthful, not just smaller.
Frame budget16ms interactionHover, crosshair and range changes stay inside one frame at dashboard density; the spike that proves GL also measures the globe against this budget on the reference machine.
No animation cost0ms defaultM1's animation: false is also the cheapest render path; the intelligence layer pays for motion only where a signal earns it.
06 / the instruments
The heat map, the money flow, and the radar, under the laws.
The destination heat map
Where customers are booking, as heat (refined on team review, 20 Aug): a country's shade deepens with its revenue on the sequential ramp, and the mark on it scales the same way, so a destination with more revenue visibly outweighs the rest even when its geography is a dot. The ranked list beside it is the reading, every figure carries its share of the total, and every figure opens its report. The projected map is the working instrument and ships first; the globe follows once GL is proven, in the same home for this use (ruled: Sales Analytics).
The destination heat map · schematic · shade and mark scale with revenue, the list is the truth
Destinations · revenue · share · Q3
Maldives$1,204,300 · 33.5%
Dubai$851,900 · 23.7%
Paris$556,410 · 15.5%
Rome$338,275 · 9.4%
Tokyo$232,860 · 6.5%
Shade is revenue, twiceThe country fills from the sequential ramp and its mark scales with the same figure, so the Maldives, a dot of geography carrying a third of the revenue, is never hidden by its own size. The scale prints under the map in mono.
Still by default, alive by lawNothing rotates and no trail runs on its own (M1). When a booking confirms while the surface is open, its country pulses once and settles: I1's motion-as-report, the intelligence layer's first shipped signal.
The list is the table viewL12 is satisfied on the surface itself: the ranked list is the readable, exportable truth, each figure with its share of the total, and each row opens Sales Analytics filtered to the destination.
Our geography, our themeTopology ships with the app, drawn in theme tokens, no tiles, no labels except where a mark earns one. The map is an instrument of ours, not an embedded product of someone else's.
The money flow
Revenue to cost to margin, by segment, as a sankey: the first instrument the accounting side has asked for by shape. Flows are the platform's own ledger figures; every band opens the report that proves it. Chord joins later for intercompany, when consolidation C1 wakes.
The share rule · ruled 20 Aug
Wherever a revenue renders on a chart, its percentage of the total renders beside it: on the node, in the tooltip, in the ranked list. A figure without its share answers "how much" and dodges "how much of what". Counts are exempt; the rule is for money.
The RSS radar, finished
Lab 11 rejected the radar as a comparative chart and that rejection stands for customers against customers. The RSS radar is a different job: six fixed axes worn as a signature, drawn against the one comparison that is the score's own definition (refined on team review, 20 Aug): the average across all customers, as a dashed resting-grey baseline, never filled. Where the blue leaves the grey is the relationship. Rules: the six axes and their order are fixed platform wide, one customer per chart, the average is the only other line that may ever share the axes, the profile fills at 12% ours-blue with a 1.5px stroke, values print at the vertices in mono, and the table view lists both sets of figures.
Ruled · 20 Aug 2026
The engine is Apache ECharts.
- The engine: approved. Apache ECharts for all three tiers, superseding the Lab 11 Recharts adoption. The form mappings, palette and tokens carry over unchanged.
- The instrument plan: approved. Origin map first on core geo, the 3D globe behind the GL compatibility spike, money flow sankey next, RSS radar under the signature rules.
- Refined on team review, same day: the geographic instrument is a heat map (shade and mark scale with revenue), the RSS radar carries the all-customers average as its baseline, the share rule applies wherever revenue charts, and a service tickets status example joined the live annex.
- The globe's home, refined in the ruling: the globe is an instrument with different uses depending on where it lives. For this use, sales origins and destinations, both the origin map and the proven globe live in Sales Analytics. The Board-opener idea was not adopted; future uses of the globe name their own homes when they arrive.