The Future of Web Dev
The Future of Web Dev
Evil Charts for Svelte: Animated Chart Components for Svelte 5
Animated Svelte 5 chart components with LayerChart SVG or Apache ECharts Canvas/SVG, installed as editable source through shadcn-svelte.

Evil Charts for Svelte is a Svelte chart component library for creating animated area, line, bar, composed, radar, pie, radial, and Sankey visualizations.
Install charts as editable source through shadcn-svelte and choose LayerChart for Svelte-rendered SVG or Apache ECharts for Canvas with optional SVG rendering.
Features
- Eight chart families for area, line, bar, composed, radar, pie, radial, and Sankey charts.
- LayerChart SVG and Apache ECharts Canvas or SVG renderers.
- Compound chart roots with axes, grids, series, tooltips, legends, dots, and brushes.
- Light and dark series colors through
ChartConfig. - Click selection, clickable legends, loading states, and animated reveals.
- Ordered-dither rendering for area, line, bar, composed, pie, and radar charts.
- Dashboard blocks built from the chart components.
How To Use It
Choose LayerChart or ECharts
Provider choice is made per chart. Every child inside a compound chart root must come from that root’s provider. One Svelte application can render charts from both providers.
| Provider | Renderer | Best Match |
|---|---|---|
| LayerChart | SVG | Svelte-rendered SVG, CSS styling, DOM inspection, and design-led dashboards. |
| Apache ECharts | Canvas or SVG | Dense datasets, frequent updates, and existing ECharts option workflows. |
Install the Chart Engine
Install LayerChart when you plan to use layerchart-* registry items:
npm install layerchartInstall Apache ECharts for echarts-* items:
npm install echartsSet Up shadcn-svelte
Registry installation uses the shadcn-svelte CLI. Skip initialization when the project already has its shadcn-svelte configuration.
npx shadcn-svelte@latest initChoose a Registry Item
Each chart family has a LayerChart item and an ECharts item.
| Chart | LayerChart Registry Item | ECharts Registry Item |
|---|---|---|
| Area | layerchart-area-chart | echarts-area-chart |
| Line | layerchart-line-chart | echarts-line-chart |
| Bar | layerchart-bar-chart | echarts-bar-chart |
| Composed | layerchart-composed-chart | echarts-composed-chart |
| Radar | layerchart-radar-chart | echarts-radar-chart |
| Pie | layerchart-pie-chart | echarts-pie-chart |
| Radial | layerchart-radial-chart | echarts-radial-chart |
| Sankey | layerchart-sankey-chart | echarts-sankey-chart |
Install the LayerChart area chart:
npx shadcn-svelte@latest add https://evilcharts-sv.vercel.app/r/layerchart-area-chart.jsonInstall its ECharts counterpart:
npx shadcn-svelte@latest add https://evilcharts-sv.vercel.app/r/echarts-area-chart.jsonBasic Usage
Each chart root owns the dataset, chart configuration, selection state, and other shared settings. Child components define the visible chart parts.
A series dataKey must exist in the dataset and in chartConfig.
<script lang="ts">
import { EvilAreaChart } from '$lib/components/evilcharts/charts/layerchart-area-chart/index.js';
import type { ChartConfig } from '$lib/components/evilcharts/ui/layerchart-chart/index.js';
const data = [
{ month: 'January', revenue: 42000 },
{ month: 'February', revenue: 51000 },
{ month: 'March', revenue: 47000 },
{ month: 'April', revenue: 63000 }
];
const chartConfig = {
revenue: {
label: 'Revenue',
colors: {
light: ['#047857'],
dark: ['#10b981']
}
}
} satisfies ChartConfig;
</script>
<EvilAreaChart
{data}
config={chartConfig}
accessibility={{ label: 'Monthly revenue' }}
>
<EvilAreaChart.Grid />
<EvilAreaChart.XAxis dataKey="month" />
<EvilAreaChart.Tooltip />
<EvilAreaChart.Area dataKey="revenue" variant="gradient" />
</EvilAreaChart>Configure Labels, Colors, and Icons
ChartConfig maps each series key to the content used by chart series, legends, and tooltips.
| Property | Purpose |
|---|---|
label | String or Svelte Snippet displayed for the series. |
colors.light | CSS color array for the light theme. |
colors.dark | CSS color array for the dark theme. |
icon | Optional Svelte component used in legends and tooltips. |
A single color creates a solid series color. Multiple values become gradient stops. At least one theme key must exist when colors is present.
const chartConfig = {
visitors: {
label: 'Visitors',
colors: {
light: ['#0284c7', '#6366f1', '#9333ea'],
dark: ['#38bdf8', '#818cf8', '#c084fc']
}
}
} satisfies ChartConfig;Add Clickable Series Selection
Set isClickable on a series or legend when another part of the page needs to react to the selected metric. Use selectedDataKey for controlled state or defaultSelectedDataKey when the chart owns its initial selection.
<script lang="ts">
let selectedMetric = $state<string | null>(null);
</script>
<EvilAreaChart
{data}
config={chartConfig}
selectedDataKey={selectedMetric}
onSelectionChange={(key) => {
selectedMetric = key;
}}
>
<EvilAreaChart.XAxis dataKey="month" />
<EvilAreaChart.Legend isClickable />
<EvilAreaChart.Tooltip />
<EvilAreaChart.Area
dataKey="revenue"
isClickable
/>
</EvilAreaChart>Use Ordered-Dither Rendering
Area, line, bar, composed, pie, and radar charts accept renderStyle="dither". Available textures are gradient, dotted, hatched, and solid.
<EvilAreaChart
{data}
config={chartConfig}
renderStyle="dither"
ditherVariant="hatched"
ditherCellSize={2}
>
<EvilAreaChart.XAxis dataKey="month" />
<EvilAreaChart.Tooltip />
<EvilAreaChart.Area dataKey="revenue" />
</EvilAreaChart>Use the Apache ECharts Provider
ECharts roots render to Canvas by default. Pass renderer="svg" for an SVG chart surface.
The ECharts compound API follows the LayerChart composition model. chartOptions accepts lower-level ECharts options, and <EChartsAreaChart.Brush /> adds the provider’s dataZoom-based range selector.
<script lang="ts">
import {
EChartsAreaChart,
type ChartConfig
} from '$lib/components/evilcharts/charts/echarts-area-chart/index.js';
</script>
<EChartsAreaChart
renderer="svg"
{data}
config={chartConfig}
>
<EChartsAreaChart.Grid />
<EChartsAreaChart.XAxis dataKey="month" />
<EChartsAreaChart.Brush />
<EChartsAreaChart.Legend isClickable />
<EChartsAreaChart.Tooltip />
<EChartsAreaChart.Area dataKey="revenue" isClickable />
</EChartsAreaChart>Styling and Customization
Registry installs place the chart source under $lib/components/evilcharts, where the Svelte and TypeScript files become part of the application codebase.
ChartConfig controls labels, icons, and theme colors. Root and series props control fills, strokes, curves, selection, loading behavior, and dither textures.
LayerChart roots expose chartProps for lower-level LayerChart configuration. ECharts roots expose chartOptions, which is deep-merged into the generated ECharts option object.
Accessibility
Give each chart an accessible name with accessibility.label. Use labelledBy when visible page content already names the chart.
<h2 id="traffic-title">Monthly Traffic</h2>
<EvilAreaChart
{data}
config={chartConfig}
accessibility={{
labelledBy: 'traffic-title',
description: 'Desktop and mobile traffic for the current quarter.'
}}
>
<EvilAreaChart.Legend isClickable />
<EvilAreaChart.Area dataKey="desktop" isClickable />
<EvilAreaChart.Area dataKey="mobile" isClickable />
</EvilAreaChart>




