npm apexcharts 6.0.0
💎 Version 6.0.0

5 hours ago

ApexCharts 6.0.0

The largest release in the library's history. Version 6 turns a chart from a picture you look at into a surface you investigate, author, and share. Most of what follows is opt-in and tree-shakeable; existing configs keep working unchanged, and the zero-dependency, SVG-first identity is intact.

Two behaviors change by default (both respect prefers-reduced-motion and the existing dynamicAnimation.enabled escape hatch): data updates that add or remove points now animate coherently, and mobile pinch/pan gestures are on. See Fixes for the details.

✨ Features

Weave: public plugin platform

Publish reusable chart plugins to npm against a stable, versioned API. A plugin draws into its own sandboxed layer and subscribes to lifecycle hooks; it never touches raw internal state.

import ApexCharts from 'apexcharts'
import 'apexcharts/features/weave'

ApexCharts.registerPlugin({
  name: 'watermark',
  apiVersion: 1,
  setup(api) {
    api.on('draw', ({ layer, scales }) => {
      layer.text({ x: 10, y: 20, text: 'ACME', size: '12px' })
    })
  },
})

// activate per chart
const options = { plugins: [{ name: 'watermark' }] }
  • api.layer is a plugin-owned drawing surface (path/line/rect/circle/text); api.scales converts data to pixels; api.data, api.theme, and api.store round out the facade.
  • apiVersion gates the contract so raw internals can keep changing safely. ApexCharts.unregisterPlugin(name) exists for tests and hot reload.

Strata: hybrid SVG + canvas renderer

Break the SVG node ceiling without leaving SVG behind. Below a threshold the output is identical SVG; above it, only the series layer becomes a <canvas> while axes, grid, tooltips, annotations, and exports stay SVG.

import ApexCharts from 'apexcharts'
import 'apexcharts/features/renderer-canvas'

const options = {
  chart: { renderer: 'auto', rendererThreshold: 8000 }, // 'svg' | 'canvas' | 'auto'
}
// chart.getActiveRenderer() reports what is in use
  • Canvas is live for line, area, bar, column, scatter, and candlestick, with shared tooltip, crosshair, zoom, pan, hover and legend dimming, and PNG/SVG export all working.
  • Falls back to SVG automatically for canvas-unsupported features (pattern/image fills, color-matrix state filters). Per-point selection visuals and keyboard traversal on canvas remain SVG-only for now.

Marks: composable custom series types

Register a renderItem(datum, scales, api) function and get a first-class series: events, shared tooltip, legend, and keyboard navigation all work with no extra wiring.

import ApexCharts from 'apexcharts'
import 'apexcharts/features/marks'

ApexCharts.registerSeriesType('lollipop', {
  renderItem({ x, y, api, color }) {
    api.line({ x1: x, y1: api.zeroY, x2: x, y2: y, stroke: color })
    api.circle({ cx: x, cy: y, r: 5, fill: color })
  },
})

const options = { series: [{ type: 'lollipop', data: [[0, 3], [1, 6], [2, 4]] }] }

Dumbbell, lollipop, and bullet ship as samples. Built-in type names are guarded against shadowing.

Rewind: history and undo/redo

Generic Ctrl-Z over a command journal. Zooms, series toggles, option changes, and annotation edits are recorded; high-frequency gestures coalesce into a single step.

import ApexCharts from 'apexcharts'
import 'apexcharts/features/history'

const options = { chart: { history: { enabled: true, maxDepth: 100, coalesceMs: 250 } } }
// chart.history.undo(), .redo(), .jump(id), .transaction(fn, { label })

Perspectives: shareable view state

Serialize the exact view (zoom window, hidden series, selection, annotations, theme) into a compact token you can put in a URL and restore anywhere.

import ApexCharts from 'apexcharts'
import 'apexcharts/features/perspectives'

const token = chart.perspectives.capture()
const url = chart.perspectives.toURL()      // href with #apex=<token>
chart.perspectives.apply(token, { animate: true })
// also: .save(name), .list(); static ApexCharts.perspectives.fromURL(href)

Facet: design tokens and OS-aware themes

Charts read --apx-* CSS custom properties from the cascade, follow the operating system's light/dark and contrast preferences with no JS, and can reference named brand themes.

import ApexCharts from 'apexcharts'
import 'apexcharts/features/facet'

ApexCharts.registerTheme('brand', { palette: ['#4f46e5', '#0ea5e9'], tokens: { accent: '#4f46e5' } })

const options = { theme: { follow: 'os', name: 'brand' } }
:root { --apx-accent: #4f46e5; --apx-grid: #e5e7eb; --apx-surface: #fff; }

chart.refreshTokens() re-reads the cascade after a runtime token change that does not itself trigger a render.

Cadence: pluggable easing

chart.animations.easing accepts a named curve, a cubic-bezier array, or a function. The default is unchanged, so existing charts animate exactly as before.

const options = { chart: { animations: { easing: 'easeOutBack' } } } // or [0.34, 1.56, 0.64, 1], or (t) => t*t
// ApexCharts.registerEasing('bounce', (t) => /* ... */)

A data-change override is available via chart.animations.dynamicAnimation.easing.

Linked Views: crossfilter and cross-chart coordination

Coordinate a group of charts without wiring. In highlight mode, brushing one chart dims the non-matching marks in the others (no redraw). A real crossfilter engine adds categorical click-filters, range brushes, a shared data-table, and a heatmap 2D matrix target.

import ApexCharts from 'apexcharts'
import 'apexcharts/features/link'

// highlight mode, per chart
const options = { chart: { group: 'sales', link: { enabled: true, mode: 'highlight', dimOpacity: 0.2 } } }

// or a shared crossfilter engine
const cf = ApexCharts.crossfilter({ id: 'sales', records })

Ink Layer: direct-manipulation annotation authoring

Annotations become draggable and resizable, with click-to-create, snap to gridlines, and a floating editor card (inline rename, recolor, bold, font size, marker size and shape, delete). Every edit is undoable when Rewind is enabled.

import ApexCharts from 'apexcharts'
import 'apexcharts/features/ink'

const options = { chart: { ink: { enabled: true, palette: true, snap: true } } }
// fires annotationDragged, annotationEdited, annotationStyled, annotationDeleted

Measure ruler

Hold a key and drag to read the change, percent, range, and slope between two points; on release the ruler pins as a data-anchored overlay that re-projects on zoom and resize.

import ApexCharts from 'apexcharts'
import 'apexcharts/features/measure'

const options = { chart: { measure: { enabled: true, mode: 'span', key: 'm', pinOnRelease: true } } }
// or drive it from code: chart.startMeasure(), chart.stopMeasure(), chart.clearMeasures()
// fires `measured`

mode: 'span' is the finance-style vertical band with a change/percent/range readout; mode: 'free' is a diagonal ruler between two arbitrary points. Styling resolves through --apx-measure-* tokens.

Context menu (Radial Actions)

Right-click or long-press a data point for verbs that act at that exact point rather than chart-wide.

import ApexCharts from 'apexcharts'
import 'apexcharts/features/context-menu'

const options = {
  chart: {
    contextMenu: {
      enabled: true,
      items: ['annotate', 'xline', 'yline', 'measure', {
        id: 'copy', label: 'Copy value',
        onClick: (ctx, { x, y, seriesIndex, dataPointIndex }) => {},
      }],
    },
  },
}

Built-in annotate / xline / yline items are ink-managed when the ink feature is bundled (they open the floating editor and undo via Rewind).

Storyboard: scroll-driven choreography (scrollytelling)

Pair prose sections with saved views. Scrolling a beat past the viewport trigger applies its view; scrolling back reverses it. Each beat can also merge an updateOptions payload so it can restyle or morph chart.type inside one animated transition.

import ApexCharts from 'apexcharts'
import 'apexcharts/features/storyboard' // includes Perspectives

chart.storyboard.bind({
  beats: [
    { selector: '[data-apex-beat="1"]', view: { window: { xaxis: { min: 0, max: 10 } } } },
    { selector: '[data-apex-beat="2"]', view: { collapsed: [1] }, options: { chart: { type: 'area' } } },
  ],
})
// chart.storyboard.goTo(beat), .current(), .unbind(); fires beatChange

Real-time streaming: constant-velocity scroll

Rolling-window updates now scroll at constant velocity instead of warping in place, and chart.streaming bounds memory for long-running feeds.

const options = { chart: { streaming: { enabled: true, maxPoints: 100000 } } }
// appendData() trims each series to maxPoints (or the visible xaxis.range window)

The scroll animation itself needs no opt-in: any update that continues the previous window (appendData, or a shifted fixed-length updateSeries) translates smoothly.

🔧 Behavior changes (on by default)

Coherent variable-length data transitions

Updates that change the number of data points now animate as one coordinated motion instead of popping. Appended bars grow from the baseline, removed bars shrink into ghosts and fade out, line and area fills reshape over the union of old and new points (so they can never tear), and markers, bubbles, and axis tick labels ride along on the same clock. This also gives scatter and bubble charts dynamic-update animations for the first time, and bubbles tween their radius on z changes. Zoom re-projections animate their marks and ticks too.

Disable per chart with chart.animations.dynamicAnimation.enabled: false. Skipped automatically above chart.animations.largeDatasetThreshold and when prefers-reduced-motion is set.

Native-feeling mobile gestures (Momentum)

Two-finger pinch-zoom around the centroid, two-finger pan, and kinetic inertia after a one-finger flick, with axis rails so a vertical swipe still scrolls the page. Configurable via chart.zoom.pinch and chart.pan.inertia.

🐛 Fixes

  • Scatter jitter zoom: zooming a jitter strip plot now snaps the window to whole bands, so x-axis labels no longer vanish on zoom-in and the first and last dot clouds are no longer half-cropped on zoom-out.
  • render() is idempotent: a repeated render() call (including a framework double-invoking an effect) returns the same promise instead of building a duplicate chart in the same element. destroy() clears it so an instance can render fresh; a rejected render clears itself so callers can retry.
  • Legend toggle: hideSeries / showSeries / toggleSeries no longer silently no-op under strict CSS selector engines (the series lookup no longer relies on an escaped-colon attribute selector).
  • Area morph: fixed a long-standing malformed pathFrom (double z) that fed the animation engine an invalid command list on area updates.

📦 Tree-shaking

Every feature above ships as a tree-shakeable entry (apexcharts/features/*) registered through the feature registry; the core stays lean. See the tree-shaking guide for the complete list of entry points.

TypeScript

Full type definitions ship with the package (no @types/* install). 6.0 adds types for every new config namespace and API, plus the SSR statics (renderToString, renderToHTML, hydrate, hydrateAll, isHydrated).

Don't miss a new apexcharts release

NewReleases is sending notifications on new releases.