Chart components are built on ECharts. Install it as a dependency:

npm install echarts

For optimal bundle size, import only the ECharts components you need. The examples below show the minimum required imports for our use cases.

import * as echarts from 'echarts/core';import {  BarChart,  LineChart,  MapChart,  PieChart,  ScatterChart} from 'echarts/charts';import {  AriaComponent,  AxisPointerComponent,  BrushComponent,  GeoComponent,  GridComponent,  TooltipComponent} from 'echarts/components';import { CanvasRenderer } from 'echarts/renderers';echarts.use([  BarChart,  LineChart,  PieChart,  MapChart,  ScatterChart,  AxisPointerComponent,  BrushComponent,  GeoComponent,  GridComponent,  TooltipComponent,  CanvasRenderer,  AriaComponent]);

Available Charts

Timeseries Chart
A specialized chart for displaying time-based data.
Bubble Map
Plot proportional bubbles over a GeoJSON map.
Custom Chart
Examples like pie charts.

Color System

Color Palette
Information about our color system.

Legend

Use LegendItem to display chart series information with color indicators.

LargeItem

Active State

Requests
1,234 req/s
Storage
56 GB
Warnings
128

Inactive State

Requests
1,234 req/s
Storage
56 GB
Warnings
128
<script lang="ts">
  import { onMount } from 'svelte';
  import { ChartLegend, ChartPalette } from 'kumo-svelte';
  import { getIsDarkMode } from './chart-color-demo-data';

  let isDarkMode = $state(false);

  onMount(() => {
    const update = () => {
      isDarkMode = getIsDarkMode();
    };
    const observer = new MutationObserver(update);

    update();
    [document.documentElement, document.body].forEach((node) => {
      observer.observe(node, { attributes: true, attributeFilter: ['data-mode', 'class'] });
    });

    const mediaQuery = window.matchMedia?.('(prefers-color-scheme: dark)');
    mediaQuery?.addEventListener('change', update);

    return () => {
      observer.disconnect();
      mediaQuery?.removeEventListener('change', update);
    };
  });
</script>

<div class="space-y-4">
  <h3 class="text-sm font-medium">Active State</h3>

  <div class="flex flex-wrap gap-4 divide-x divide-kumo-hairline">
    <ChartLegend
      variant="large"
      name="Requests"
      color={ChartPalette.semantic('Neutral', isDarkMode)}
      value="1,234"
      unit="req/s"
    />
    <ChartLegend
      variant="large"
      name="Storage"
      color={ChartPalette.semantic('Attention', isDarkMode)}
      value="56"
      unit="GB"
    />
    <ChartLegend
      variant="large"
      name="Warnings"
      color={ChartPalette.semantic('Warning', isDarkMode)}
      value="128"
    />
  </div>

  <h3 class="mt-12 text-sm font-medium">Inactive State</h3>

  <div class="flex flex-wrap gap-4 divide-x divide-kumo-hairline">
    <ChartLegend
      variant="large"
      name="Requests"
      color={ChartPalette.semantic('Neutral', isDarkMode)}
      value="1,234"
      unit="req/s"
      inactive
    />
    <ChartLegend
      variant="large"
      name="Storage"
      color={ChartPalette.semantic('Attention', isDarkMode)}
      value="56"
      unit="GB"
      inactive
    />
    <ChartLegend
      variant="large"
      name="Warnings"
      color={ChartPalette.semantic('Warning', isDarkMode)}
      value="128"
      inactive
    />
  </div>
</div>

SmallItem

Active State

Requests 1,234 req/s
Storage 56 GB
Warnings 128

Inactive State

Requests 1,234 req/s
Storage 56 GB
Warnings 128
<script lang="ts">
  import { onMount } from 'svelte';
  import { ChartLegend, ChartPalette } from 'kumo-svelte';
  import { getIsDarkMode } from './chart-color-demo-data';

  let isDarkMode = $state(false);

  onMount(() => {
    const update = () => {
      isDarkMode = getIsDarkMode();
    };
    const observer = new MutationObserver(update);

    update();
    [document.documentElement, document.body].forEach((node) => {
      observer.observe(node, { attributes: true, attributeFilter: ['data-mode', 'class'] });
    });

    const mediaQuery = window.matchMedia?.('(prefers-color-scheme: dark)');
    mediaQuery?.addEventListener('change', update);

    return () => {
      observer.disconnect();
      mediaQuery?.removeEventListener('change', update);
    };
  });
</script>

<div class="space-y-4">
  <h3 class="text-sm font-medium">Active State</h3>
  <div class="flex flex-wrap gap-4">
    <ChartLegend
      name="Requests"
      color={ChartPalette.semantic('Neutral', isDarkMode)}
      value="1,234"
      unit="req/s"
    />
    <ChartLegend
      name="Storage"
      color={ChartPalette.semantic('Attention', isDarkMode)}
      value="56"
      unit="GB"
    />
    <ChartLegend name="Warnings" color={ChartPalette.semantic('Warning', isDarkMode)} value="128" />
  </div>

  <h3 class="mt-12 text-sm font-medium">Inactive State</h3>
  <div class="flex flex-wrap gap-4">
    <ChartLegend
      name="Requests"
      color={ChartPalette.semantic('Neutral', isDarkMode)}
      value="1,234"
      unit="req/s"
      inactive
    />
    <ChartLegend
      name="Storage"
      color={ChartPalette.semantic('Attention', isDarkMode)}
      value="56"
      unit="GB"
      inactive
    />
    <ChartLegend
      name="Warnings"
      color={ChartPalette.semantic('Warning', isDarkMode)}
      value="128"
      inactive
    />
  </div>
</div>
Read latency
P99
124 ms
P95
76 ms
P75
32 ms
P50
10 ms