Themes
A theme seeds a coordinated set of visual defaults in one option, so a diagram does not need eight colors set by hand to look deliberate.
Built-in themes
const sankey = new ApexSankey(document.getElementById('chart'), {
theme: 'midnight',
})
sankey.render(data)
| Theme | Appearance |
|---|---|
'light' | The default light look |
'dark' | Dark canvas, light labels |
'midnight' | Deep blue canvas with a cool palette |
'mint' | Light canvas with a green-leaning palette |
'sunset' | Warm palette on a soft background |
What a theme sets
A theme is a bundle of the ordinary options:
| Field | Type | Description |
|---|---|---|
nodePalette | string[] | Ordered node fill colors, cycled across nodes without their own color |
fontColor | string | Node label color |
edgeOpacity | number | Ribbon opacity, 0 to 1 |
edgeGradientFill | boolean | Fill ribbons with a source-to-target gradient |
nodeBorderColor | string | null | Node border color; null disables it |
canvasStyle | string | CSS on the SVG root, typically background and border |
tooltipTheme | 'dark' | 'light' | Tooltip color preset |
Precedence
Options you set explicitly always win over the theme. That makes a theme a baseline rather than a straitjacket:
const sankey = new ApexSankey(el, {
theme: 'sunset', // seeds palette, canvas, label color
edgeOpacity: 0.6, // but this specific value wins
})
Inline themes
theme also accepts an object directly, which is convenient for a one-off:
const sankey = new ApexSankey(el, {
theme: {
nodePalette: ['#0ea5e9', '#6366f1', '#a855f7'],
fontColor: '#0f172a',
edgeOpacity: 0.45,
canvasStyle: 'background: #f8fafc; box-sizing: border-box;',
tooltipTheme: 'light',
},
})
Brand presets
For a theme reused across an app, register it once by name and reference it everywhere. This keeps the palette in one place instead of copied into every chart:
import { ApexSankey } from 'apexsankey'
ApexSankey.registerTheme('acme', {
nodePalette: ['#ff5a5f', '#087f8c', '#5d2e8c'],
fontColor: '#1a1a1a',
canvasStyle: 'background: #faf7f2; box-sizing: border-box;',
})
// anywhere afterwards
new ApexSankey(el, { theme: 'acme' }).render(data)
Register before constructing any instance that names the theme. Registering an existing name overrides it, which is how you would re-theme a whole app at runtime.
Palette only
If all you want is a different set of node colors, skip themes and set nodePalette:
const sankey = new ApexSankey(el, {
nodePalette: ['#2563eb', '#16a34a', '#f59e0b', '#dc2626'],
})
The palette cycles across nodes in order. A node that sets its own color in the data keeps it and is skipped in the cycle. See Node and Edge Styling.
CSS variables
Themes cover the SVG's own paint. For the surrounding chrome, and for anything you would rather drive from a stylesheet, the diagram also honours CSS custom properties. That path is useful when the colors already live in a design system, or when they need to respond to a prefers-color-scheme media query; the variables are re-read on the next render.
Family root tokens
Declare the --apx-* tokens once on :root and the ApexCharts-family visuals on the page pick them up: charts, sankey diagrams, trees and gantt charts. On apexsankey 1.12.2 a diagram honours two of them, --apx-fore for the node label fill and --apx-grid for the node rect stroke. Its canvas background comes from the canvasStyle option and its node fills from nodePalette, so --apx-surface and --apx-series-N do not reach a Sankey.
:root {
--apx-accent: #4f46e5; /* primary accent */
--apx-fore: #1f2937; /* text and labels; the node label fill here */
--apx-grid: #e5e7eb; /* gridlines, borders and separators; the node stroke here */
--apx-surface: #ffffff; /* background surface; not read by a Sankey */
/* ordered palette for multi-series visuals; not read by a Sankey */
--apx-series-1: #4f46e5;
--apx-series-2: #06b6d4;
}
The tokens are resolved on each render, so a token change lands on the next draw. After an OS light/dark flip or a design-system swap, call update() to repaint.
They resolve below the options you set on the diagram itself. A diagram already styled through its own options, or through the --apex-sankey-* variables, is untouched. Measured on apexsankey 1.12.2, the order is: your options, then --apex-sankey-*, then these family tokens, then a registered theme, then the built-in default. The family tokens override a registered theme per key rather than wholesale: with only --apx-grid declared, the node stroke takes the CSS value while the label fill keeps the theme's. For --apx-surface and --apx-series-N the chain never reaches the Sankey at all, so it terminates at the built-in default.
The point is that these are not this library's variables. They are the family's, so a design system declares its palette once rather than once per product.