Migrating from ApexCharts 4.x

Switching an existing app: what is identical, what is new, what behaves differently.

View .md Agent setup

WestCoast Charts started from the MIT-licensed ApexCharts 4.7.0 source and keeps an ApexCharts-style configuration model for familiar options, methods and events. This is not a guarantee of unchanged behaviour for every application. Review the differences in themes, accessibility, text escaping, sanitization and validation below, then test your actual charts before switching.

ApexCharts is a trademark of its owner. WestCoast Charts is an independent project by West Coast Software and is not affiliated with, sponsored or endorsed by the owner of ApexCharts. The name is used here only to describe compatibility and to credit the origin of the code (see LICENSE and NOTICE).

Which versions? This guide is written for code that targets ApexCharts 4.x (4.0 to 4.7). Options that first appeared in later ApexCharts versions are not part of WestCoast Charts.

The switch in three steps

1. Replace the package.

sh
npm uninstall apexcharts
npm install west-coast-charts@1.1.5

2. Change the import. The default export is the chart class. It is also exported under the name ApexCharts, so the rest of your code can keep the old identifier:

js
// before: import ApexCharts from 'apexcharts'
import { ApexCharts } from 'west-coast-charts'

const chart = new ApexCharts(document.querySelector('#chart'), {
  chart: { type: 'area', height: 300 },
  series: [{ name: 'Sign-ups', data: [31, 40, 28, 51, 42, 109, 100] }],
  xaxis: { categories: ['W1', 'W2', 'W3', 'W4', 'W5', 'W6', 'W7'] },
})
await chart.render()

With script tags, swap the file. The bundle defines the global WestCoastCharts and also window.ApexCharts when that global is still free, so inline code that says new ApexCharts(...) keeps working:

html
<!-- before: <script src=".../apexcharts.min.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/west-coast-charts@1.1.5/dist/west-coast-charts.min.js"></script>
<div id="chart"></div>
<script>
  new ApexCharts(document.querySelector('#chart'), {
    chart: { type: 'bar', height: 260 },
    series: [{ name: 'Tickets', data: [8, 13, 5, 21] }],
    xaxis: { categories: ['Mon', 'Tue', 'Wed', 'Thu'] },
  }).render()
</script>

3. Decide about the look. Charts use the new coastal theme preset by default (palette, typography, spacing). To keep the 4.7.0 appearance pixel for pixel, select the classic preset, either per chart or for every chart through the window.Apex global defaults, which work as before:

js
import WestCoastCharts from 'west-coast-charts'

// every chart on the page
window.Apex = { theme: { preset: 'classic' } }

// or one chart
const chart = new WestCoastCharts(document.querySelector('#chart'), {
  theme: { preset: 'classic' },
  chart: { type: 'line', height: 260 },
  series: [{ name: 'Errors', data: [3, 1, 4, 1, 5] }],
})
await chart.render()
console.log(chart.w.globals.colors[0]) // '#008FFB', the 4.7.0 palette

Then run your test suite and go through What behaves differently.

What stays the same

Area Status
Options Familiar 4.7.0 option names and structure; review the behaviour and default changes documented below
Chart types All 4.7.0 types are in the core: line, area, bar/column, rangeBar, rangeArea, candlestick, boxPlot, scatter, bubble, heatmap, treemap, pie, donut, polarArea, radar, radialBar, mixed charts
Methods render, updateOptions, updateSeries, appendSeries, appendData, toggleSeries, showSeries, hideSeries, resetSeries, zoomX, toggleDataPointSelection, addXaxisAnnotation and the other annotation methods, dataURI, destroy, and the static exec, getChartByID, merge, initOnLoad
Events chart.events.* callbacks with the same arguments
Global defaults window.Apex
Locales The same locale objects and chart.locales / chart.defaultLocale
CSS Every apexcharts-* class name stays, so your style overrides and test selectors keep matching. The root element also gets the class wcc
TypeScript ApexOptions and all Apex* types are still exported

The complete, generated list is in the options reference and the methods reference.

What behaves differently

These changes are deliberate: they fix security issues or crashes, or they add accessibility. Each one names the setting that restores the 4.7.0 behaviour where one exists.

1. Default theme

New charts use the coastal preset. Use theme: { preset: 'classic' } for the old look (step 3). Explicit colours, fonts and theme.palette settings are applied on top of either preset, as before. See docs/THEMING.md (library repository).

2. HTML in labels, legends and tooltips

  • Strings from data and configuration (series names, categories, labels, titles, annotation text, locale strings) are always drawn as text. A series named <b>EU</b> shows those characters instead of bold text.
  • HTML returned by your functions (formatters, tooltip.custom, legend.markers.customHTML) and explicit markup options (toolbar icons, customSVG) is still allowed, but it passes through a sanitizer first. Event-handler attributes, javascript: URLs and scripts are removed.
  • chart.sanitizeHtml controls this: true (default, built-in allow-list), a function (html, { svg }) => string | Node to plug in your own sanitizer such as DOMPurify, or false for raw innerHTML as in 4.7.0 (only for output you fully trust).
  • When you build HTML from data in a formatter, escape the data with WestCoastCharts.escapeHtml().
js
import WestCoastCharts from 'west-coast-charts'

const chart = new WestCoastCharts(document.querySelector('#chart'), {
  chart: { type: 'line', height: 260 },
  series: [
    { name: 'eu-west', data: [12, 18, 15] },
    { name: 'us-east', data: [20, 14, 22] },
  ],
  legend: {
    show: true,
    // escape the data, keep your own markup; the onerror handler is stripped by the sanitizer
    formatter: (name) => `<b>${WestCoastCharts.escapeHtml(name)}</b><img src="x" onerror="alert(1)">`,
  },
})
await chart.render()

3. CSV export

exportToCSV neutralises spreadsheet formulas: text cells that start with =, +, -, @, tab or carriage return get a leading '. Real numbers such as -12.5 are left alone. Cells containing the delimiter, quotes or line breaks are quoted (RFC 4180) instead of having characters removed. There is no switch back; this closes a formula-injection hole.

4. Malformed options no longer throw

Inputs that made 4.7.0 throw a TypeError, for example series: null, null entries in series, data: null, xaxis.categories: null or annotations: null, are treated as empty, in the constructor and in every update method. If your code relied on a throw to detect bad data, validate the data yourself instead. Valid options are passed through untouched.

js
import WestCoastCharts from 'west-coast-charts'

const chart = new WestCoastCharts(document.querySelector('#chart'), {
  chart: { type: 'bar', height: 240 },
  series: null, // data not loaded yet: an empty chart instead of an exception
})
await chart.render()
await chart.updateSeries([{ name: 'Orders', data: [5, null, 9] }, null])

5. Accessibility is on by default

Every chart now adds:

  • tabindex="0", an ARIA accessible name and <desc> on the chart SVG, plus keyboard navigation (arrow keys, Home/End, Enter/Space, zoom and pan keys). Tab is never captured.
  • a polite live region that announces the focused point, selection and zoom,
  • a visually hidden data table for screen readers,
  • prefers-reduced-motion support: animations are skipped for users who ask for less motion.

This changes the DOM: snapshot tests and selectors that count elements inside the chart container, or tests of the page's tab order, can need an update. You can switch the parts off individually, but please only do so when you provide the same information another way:

js
import WestCoastCharts from 'west-coast-charts'

const chart = new WestCoastCharts(document.querySelector('#chart'), {
  chart: {
    type: 'line',
    height: 240,
    accessibility: {
      enabled: true,                      // master switch
      keyboard: { enabled: true },
      announcements: { enabled: true },
    },
    animations: { respectReducedMotion: true },
  },
  wcc: { a11y: { dataTable: false } },   // 'hidden' (default) | 'details' (visible) | false
  series: [{ name: 'Queue depth', data: [4, 9, 6, 12] }],
})
await chart.render()

Details: docs/ACCESSIBILITY.md (library repository).

6. Bundle size

The core is larger than ApexCharts 4.7.0 because the accessibility, security, theming and robustness work above lives in it: 192,030 B against 152,686 B for apexcharts.min.js 4.7.0 (gzip level 9, measured on integrate/v1 d03e23b2). Where the bytes go is documented in docs/architecture/size-ledger.md (library repository). New chart types and features live in separate entries, so they cost nothing unless you import them.

7. Unknown chart types fail loudly

If chart.type names a WestCoast Charts type whose entry is not loaded (for example funnel without west-coast-charts/types), render() rejects with a message naming the import to add, and logs the same hint. Types that existed in 4.7.0 are never affected.

8. Toolbar size in the new presets

The coastal preset (and the presets from west-coast-charts/types/themes) uses 28 × 28 px toolbar buttons to meet the WCAG 2.5.8 target size. classic keeps the 4.7.0 20 px icons.

9. Browser support

The core still targets ES2018 engines (Chrome 60+, Edge 79+, Firefox 55+, Safari 11.1+). Optional feature bundles and the premium bundle need ES2020; see Getting started and the browser table in the repository README.

What is new

Everything below is optional; none of it changes a 4.7.0 configuration.

Addition Where Docs
Theme presets coastal and classic in the core; midnight, paper, accessible and colour-vision palettes (theme.accessibility.colorBlindMode) core, west-coast-charts/types/themes THEMING.md (library repository)
14 additional chart types: gauge, funnel/pyramid, waterfall, dumbbell, histogram, violin/raincloud, sunburst, icicle, streamgraph, unit/waffle, barRace, calendar, slope, beeswarm (plus nested treemaps and box plots from raw samples) west-coast-charts/types or west-coast-charts/types/<name> options reference
Keyboard navigation, announcements, data table, focus ring core ACCESSIBILITY.md (library repository)
Large-data rendering: dense-mark paths and line/area decimation (wcc.performance), optional canvas renderer core (dense marks), west-coast-charts/types/decimate, west-coast-charts/features/renderer-canvas Performance and security
Label readability (halo, pill, auto contrast) west-coast-charts/features/readability docs/features/readability.md (library repository)
Drill-down, linked charts, highlight and filter, undo history, narrative captions, perspectives, storyboards, trellis small multiples west-coast-charts/features/<name> docs/features/
Plugin API: WestCoastCharts.use(plugin) core docs/architecture/plugins.md (library repository)
WestCoastCharts.escapeHtml, chart.sanitizeHtml, Trusted Types policy west-coast-charts core Performance and security
Premium types: sankey, chord, gantt, tree, stock, map, marimekko, network, radialColumn west-coast-charts/premium (licence key) Premium and licensing

Checklist

  • apexcharts replaced by west-coast-charts in package.json and in all imports or script tags
  • Look decided: coastal (new default) or theme: { preset: 'classic' }
  • Formatters that return HTML built from data use WestCoastCharts.escapeHtml()
  • Series names or labels that contained intended HTML moved into a formatter
  • Snapshot and DOM tests updated for the accessibility elements
  • CSV consumers are fine with the ' prefix on formula-like cells
  • Code that relied on exceptions for bad configs now validates its data
  • Content Security Policy checked (Getting started)

WestCoast Charts 1.1.5 · generated from the library guide at commit 95f093ba. Code examples in the guide are executed by the library's docs check.