ApexCharts Dark/Light Theme Toggle with PNG, SVG and CSV Export — Free Snippet

ApexCharts Dark/Light Theme Toggle with PNG, SVG and CSV Export · Charts · Plain HTML, CSS & JS · Live preview

CategoryCharts

What's included

Features

In-place theme switch
updateOptions merges only the theme differences.
Theme-aware palette
Lighter series colours in dark mode.
Transparent chart background
Card colours come from CSS variables.
High-DPI PNG
dataURI with scale: 2.
Native SVG export
The chart's own vector markup.
Exact CSV export
Built from the plotted arrays.
Blob URL cleanup
Object URLs revoked after download.
Announced actions
A polite live region reports downloads.

About this UI Snippet

ApexCharts Theming and Export — One Chart, Two Themes, Three Downloads

Screenshot of the ApexCharts Dark/Light Theme Toggle with PNG, SVG and CSV Export snippet rendered live

Charts are rarely looked at only in the dashboard. They get pasted into slides, dropped into reports and viewed in dark mode. This snippet covers both needs in one place: a theme switch that restyles the chart without recreating it, and three export buttons for the formats people actually ask for.

Theme switching with updateOptions

themeOptions(dark) returns only the settings that differ between themes: theme.mode, chart.foreColor (axis and legend text), grid colour, series colours and tooltip theme. The page uses CSS custom properties for its own colours; the chart receives the matching values through chart.updateOptions(), which merges into the existing config and redraws once. chart.background: 'transparent' lets the card's background show through in both themes.

Brighter series colours in dark mode

The same indigo that works on white looks muddy on navy. The dark palette uses lighter tints of the same hues, so each series keeps its identity across themes.

PNG through dataURI

chart.dataURI({ scale: 2 }) returns a promise with a PNG data URL rendered at twice the size, so the image stays crisp in presentations. A temporary link with the download attribute saves it.

SVG straight from the DOM

ApexCharts draws SVG, so the vector export is the chart's own markup, cloned, given an xmlns, serialised and saved as a Blob.

CSV from the source data

The CSV is built from the arrays that were plotted, not scraped from the chart. That keeps the file exact and independent of formatting.

Feedback for every action

A polite live region announces each download for screen reader users.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Paste this snippet into an AI assistant like Claude and ask it to explain what theme.mode changes by itself and what the snippet still sets manually. Ask it to follow the operating-system preference with matchMedia('(prefers-color-scheme: dark)'), to add an XLSX export, or to include a title and date in exported images. It can also check whether the dark palette keeps enough contrast between the three series.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a themeable, exportable stacked area chart with ApexCharts (loaded from a CDN) in plain HTML, CSS and JavaScript.

Requirements:
- Show three signup channels over 14 weeks as a stacked area chart with a gradient fill.
- Style the page with CSS custom properties for light and dark themes and a toggle button with aria-pressed.
- On toggle, update the chart in place with only the theme-dependent options: theme mode, foreground text colour, grid colour, a lighter series palette for dark mode and tooltip theme, keeping the chart background transparent.
- Add a PNG export at 2x scale using the chart's dataURI method.
- Add an SVG export that serialises the chart's own SVG element.
- Add a CSV export built from the source data arrays with a header row.
- Announce each download in a polite live region and revoke object URLs after use.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Source Code

Requires
<div class="ath-page" id="athPage" data-theme="light">
  <div class="ath-card">
    <div class="ath-head">
      <div>
        <div class="ath-title">Signups by Channel</div>
        <div class="ath-sub">Stacked area · last 14 weeks</div>
      </div>
      <div class="ath-actions">
        <button type="button" class="ath-btn" id="athTheme" aria-pressed="false">🌙 Dark</button>
        <button type="button" class="ath-btn" id="athPng">PNG</button>
        <button type="button" class="ath-btn" id="athSvg">SVG</button>
        <button type="button" class="ath-btn" id="athCsv">CSV</button>
      </div>
    </div>
    <div id="athChart"></div>
    <div class="ath-status" id="athStatus" role="status" aria-live="polite"></div>
  </div>
</div>

Step by step

How to Use

  1. 1
    Load ApexChartsInclude apexcharts.min.js from the CDN.
  2. 2
    Paste the snippetA stacked area chart renders in a light card.
  3. 3
    Switch themeClick Dark; page and chart restyle without re-creating the chart.
  4. 4
    ExportDownload a PNG, the SVG, or the data as CSV.
  5. 5
    Reuse the patternPut your theme differences in themeOptions() and call updateOptions.

Real-world uses

Common Use Cases

Dashboards with dark mode
Keep charts consistent with the app theme.
Reporting tools
Let users take charts into slides and docs.
Analytics products
Offer raw data next to the visual.
Internal tools
Quick exports without a reporting backend.
Learning ApexCharts
A reference for theme.mode and dataURI.
Related: Color Mode Toggle
Pair it with a site-wide Color Mode Toggle.
Related: SheetJS Excel export
For spreadsheet downloads see SheetJS Table to Excel Export and Import.

Got questions?

Frequently Asked Questions

Call chart.updateOptions({ theme: { mode: 'dark' } }). theme.mode adjusts text, grid and tooltip defaults. For full control also update chart.foreColor, grid.borderColor and colors, and set chart.background to 'transparent' so your page background shows through.

Call chart.dataURI(), which returns a promise resolving to an object with imgURI, a PNG data URL. Pass { scale: 2 } for a higher-resolution image, then trigger a download with a temporary link element.

The chart is rendered as an inline SVG element. Clone it, set the xmlns attribute, serialise it with XMLSerializer and save it as a Blob with type image/svg+xml.

The toolbar menu can export CSV too. Building it from your own data gives you control over column names, number formatting and extra columns, and guarantees the file matches the source data exactly.

No. updateOptions merges the new options into the existing configuration and redraws once, keeping the instance, its event handlers and its state.