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–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 without re-rendering the chart.
Family root tokens
Declare the --apx-* tokens once on :root and every ApexCharts-family visual on the page follows: charts, sankey diagrams, trees and gantt charts.
:root {
--apx-accent: #4f46e5; /* primary accent */
--apx-fore: #1f2937; /* text and labels */
--apx-grid: #e5e7eb; /* gridlines, borders and separators */
--apx-surface: #ffffff; /* background surface */
/* ordered palette for multi-series visuals */
--apx-series-1: #4f46e5;
--apx-series-2: #06b6d4;
}
They are read live, so a token change is picked up without re-rendering, which is what makes an OS light/dark flip or a host app swapping its design system work on its own.
They resolve below anything you set explicitly. A diagram already themed through its own options, or through the --apex-sankey-* variables, is untouched. The order is: your options, then --apex-sankey-*, then a registered theme, then these family tokens, then 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.