Skip to content
CodeAtlas UI

Charts

Charts overview

Apache ECharts wrapped by the design system. Pass data only; themes, animation and glass tooltips are automatic.

<script>
  import { LineChart } from "@codeatlasdev/ui/charts";
</script>

<LineChart series={[{ name: "Revenue", data: [42, 58, 51, 74] }]} categories={["Jan", "Feb", "Mar", "Apr"]} />

Charts live in the @codeatlasdev/ui/charts subpath and need the optional peer dependency echarts (bun add echarts, version 6). Every chart takes data and a few semantic props. There is no style or font prop on purpose: the palette follows the active preset, axes, legend and tooltips read the --ca-* tokens, and charts re-theme when the color scheme, preset or surface style changes. Series can take an explicit color; use hex or rgb, because ECharts paints on a canvas and cannot parse oklch(). Charts render on the client, so hydrate them with client:visible in Astro.

Component Use for
LineChart Trends over time, areas, live streams
BarChart Vertical, horizontal, stacked and grouped bars
PieChart Pie, donut and rose proportions
ScatterChart Correlations and bubble sizing
RadarChart Multi-dimension profiles
GaugeChart KPI gauges and progress rings
HeatmapChart Calendar and matrix density
Sparkline Inline micro charts

All chart components also accept height (CSS length, each chart has its own default) and class.

Dashboard

Every chart type together inside glass cards.

Revenue

$118k
↑+23.4%

Users

94.2k
↑+8.1%

Growth

34%
↑+5.6%

Uptime

99.9%
↑+0.1%
Code
svelte
<script lang="ts">
  import { Card, Grid, KpiCard, KpiGrid, Stack } from '@codeatlasdev/ui';
  import { LineChart, BarChart, PieChart, ScatterChart, HeatmapChart, GaugeChart, RadarChart, type CalendarHeatmapPoint } from '@codeatlasdev/ui/charts';
  import { TrendingUp, Users, DollarSign, Activity } from '@lucide/svelte';

  const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep'];
  const revenue = [42000, 58000, 51000, 74000, 68000, 89000, 95000, 102000, 118000];
  const expenses = [31000, 39000, 36000, 48000, 52000, 58000, 61000, 66000, 72000];
  const fmt = (v: number) => `$${(v / 1000).toFixed(0)}k`;

  const calDays: CalendarHeatmapPoint[] = Array.from({ length: 200 }, (_, i) => {
    const d = new Date(Date.UTC(2026, 2, 1 + i));
    return [d.toISOString().slice(0, 10), Math.round(10 + 8 * Math.sin(i * 0.17) * Math.cos(i * 0.05))];
  });

  const scatter = Array.from({ length: 60 }, (_, i): [number, number] => [
    Math.round(500 + 9500 * (0.5 + 0.5 * Math.sin(i * 0.37 + 0.4))),
    parseFloat((0.5 + 11.5 * (0.5 + 0.5 * Math.cos(i * 0.29 + 1.1))).toFixed(2)),
  ]);
</script>

<Stack gap="4">
  <KpiGrid>
    <KpiCard title="Revenue" value="$118k" trend={23.4} icon={DollarSign} />
    <KpiCard title="Users" value="94.2k" trend={8.1} icon={Users} />
    <KpiCard title="Growth" value="34%" trend={5.6} icon={TrendingUp} />
    <KpiCard title="Uptime" value="99.9%" trend={0.1} icon={Activity} />
  </KpiGrid>

  <Card material="glass" full>
    <LineChart series={[{ name: 'Revenue', data: revenue }, { name: 'Expenses', data: expenses }]} categories={months} valueFormatter={fmt} area height="280px" />
  </Card>

  <Grid class="grid-auto-280" gap="4">
    <Card material="glass">
      <BarChart
        series={[
          { name: 'Organic', data: [12400, 18200, 22600, 28800] },
          { name: 'Paid', data: [8200, 11600, 14800, 19200] },
          { name: 'Referral', data: [4800, 6200, 8400, 11600] },
          { name: 'Direct', data: [3200, 4800, 6200, 8400] },
        ]}
        categories={['Q1', 'Q2', 'Q3', 'Q4']}
        valueFormatter={(v) => `${(v / 1000).toFixed(0)}k`}
        stacked
        height="260px"
      />
    </Card>
    <Card material="glass">
      <PieChart
        data={[
          { value: 38, name: 'Product A' },
          { value: 27, name: 'Product B' },
          { value: 19, name: 'Product C' },
          { value: 10, name: 'Product D' },
          { value: 6, name: 'Other' },
        ]}
        donut
        height="260px"
      />
    </Card>
  </Grid>

  <Card material="glass" full>
    <ScatterChart series={[{ name: 'Accounts', data: scatter }]} yName="Conversion %" yFormatter={(v) => `${v.toFixed(1)}%`} height="260px" />
  </Card>

  <Grid class="grid-auto-280" gap="4">
    <Card material="glass">
      <HeatmapChart variant="calendar" data={calDays} range={['2026-03-01', '2026-09-18']} height="140px" />
    </Card>
    <Card material="glass">
      <GaugeChart value={84} label="Score" height="220px" />
    </Card>
  </Grid>

  <Card material="glass" full>
    <RadarChart
      indicators={['Speed', 'Quality', 'Reliability', 'Innovation', 'Support'].map((name) => ({ name, max: 100 }))}
      series={[
        { name: 'Team A', values: [88, 92, 76, 85, 94] },
        { name: 'Team B', values: [74, 68, 90, 72, 81] },
      ]}
      height="280px"
    />
  </Card>
</Stack>

<style>
  :global(.grid-auto-280) { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
</style>

Shared props

PropTypeDefaultDescription
heightstring–CSS height of the chart. Defaults differ per chart (320px for line, bar and scatter; 300px for pie; 340px for radar; 280px for gauge; 240px for heatmap; 48px for sparkline).
classstring''Extra class names on the chart container.