General
Chart
Usage#
import { WdsChartComponent } from '@wds/angular/chart';Examples#
Default#
type). config, data and the formatters are properties (in HTML set them from a script); series and x-key are attributes. Each series gets its name and color from config. The chart needs the echarts package: pnpm add echarts.
import { Component } from '@angular/core';
import { WdsChartComponent } from '@wds/angular/chart';
import { CONFIG, MONTHS, shortMonth } from './chart-data';
@Component({
selector: 'app-chart-default-demo',
host: { class: 'block w-full max-w-xl' },
imports: [WdsChartComponent],
template: `
<wds-chart
label="Visits: desktop and mobile"
[config]="config"
[data]="months"
[series]="['desktop', 'mobile']"
x-key="month"
[xFormatter]="shortMonth"
/>
`,
})
export class ChartDefaultDemo {
protected readonly config = CONFIG;
protected readonly months = MONTHS;
protected readonly shortMonth = shortMonth;
}import type { WdsChartConfig } from '@wds/core/chart';
export const MONTHS = [
{ month: 'January', desktop: 186, mobile: 80 },
{ month: 'February', desktop: 305, mobile: 200 },
{ month: 'March', desktop: 237, mobile: 120 },
{ month: 'April', desktop: 73, mobile: 190 },
{ month: 'May', desktop: 209, mobile: 130 },
{ month: 'June', desktop: 214, mobile: 140 },
];
/** Names and colors of the series; `month` and `date` name the category column of the data table. */
export const CONFIG: WdsChartConfig = {
month: { label: 'Month' },
date: { label: 'Day' },
desktop: { label: 'Desktop', color: 'var(--wds-chart-1)' },
mobile: { label: 'Mobile', color: 'var(--wds-chart-2)' },
};
export const BROWSERS = [
{ browser: 'chrome', visitors: 275 },
{ browser: 'safari', visitors: 200 },
{ browser: 'firefox', visitors: 187 },
{ browser: 'edge', visitors: 173 },
{ browser: 'other', visitors: 90 },
];
/** In `pie` and `radial` every category (row) has its own name and color. */
export const BROWSER_CONFIG: WdsChartConfig = {
browser: { label: 'Browser' },
visitors: { label: 'Visitors' },
chrome: { label: 'Chrome', color: 'var(--wds-chart-1)' },
safari: { label: 'Safari', color: 'var(--wds-chart-2)' },
firefox: { label: 'Firefox', color: 'var(--wds-chart-3)' },
edge: { label: 'Edge', color: 'var(--wds-chart-4)' },
other: { label: 'Other', color: 'var(--wds-chart-5)' },
};
/** 90 days of visits (computed, so it is the same on every render). */
export const DAILY = Array.from({ length: 90 }, (_, i) => {
const wave = Math.sin(i / 6) * 90 + Math.cos(i / 2.3) * 40;
return {
date: new Date(Date.UTC(2026, 3, 1 + i)).toISOString().slice(0, 10),
desktop: Math.round(260 + wave + (i % 7) * 12),
mobile: Math.round(180 + wave * 0.6 + ((i * 5) % 11) * 9),
};
});
/** `January` → `Jan`. */
export const shortMonth = (value: string) => value.slice(0, 3);
/** `2026-04-01` → `Apr 1`. */
export const shortDate = (value: string) =>
new Date(`${value}T00:00`).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });Horizontal#
horizontal turns the bars sideways, grid="none" hides the grid lines and value-labels writes the values next to the bars. With one series there is no legend: the chart label names it.
import { Component } from '@angular/core';
import { WdsChartComponent } from '@wds/angular/chart';
import { CONFIG, MONTHS } from './chart-data';
@Component({
selector: 'app-chart-horizontal-demo',
host: { class: 'block w-full max-w-xl' },
imports: [WdsChartComponent],
template: `
<wds-chart
label="Desktop visits"
[config]="config"
[data]="months"
[series]="['desktop']"
x-key="month"
horizontal
grid="none"
value-labels
/>
`,
})
export class ChartHorizontalDemo {
protected readonly config = CONFIG;
protected readonly months = MONTHS;
}import type { WdsChartConfig } from '@wds/core/chart';
export const MONTHS = [
{ month: 'January', desktop: 186, mobile: 80 },
{ month: 'February', desktop: 305, mobile: 200 },
{ month: 'March', desktop: 237, mobile: 120 },
{ month: 'April', desktop: 73, mobile: 190 },
{ month: 'May', desktop: 209, mobile: 130 },
{ month: 'June', desktop: 214, mobile: 140 },
];
/** Names and colors of the series; `month` and `date` name the category column of the data table. */
export const CONFIG: WdsChartConfig = {
month: { label: 'Month' },
date: { label: 'Day' },
desktop: { label: 'Desktop', color: 'var(--wds-chart-1)' },
mobile: { label: 'Mobile', color: 'var(--wds-chart-2)' },
};
export const BROWSERS = [
{ browser: 'chrome', visitors: 275 },
{ browser: 'safari', visitors: 200 },
{ browser: 'firefox', visitors: 187 },
{ browser: 'edge', visitors: 173 },
{ browser: 'other', visitors: 90 },
];
/** In `pie` and `radial` every category (row) has its own name and color. */
export const BROWSER_CONFIG: WdsChartConfig = {
browser: { label: 'Browser' },
visitors: { label: 'Visitors' },
chrome: { label: 'Chrome', color: 'var(--wds-chart-1)' },
safari: { label: 'Safari', color: 'var(--wds-chart-2)' },
firefox: { label: 'Firefox', color: 'var(--wds-chart-3)' },
edge: { label: 'Edge', color: 'var(--wds-chart-4)' },
other: { label: 'Other', color: 'var(--wds-chart-5)' },
};
/** 90 days of visits (computed, so it is the same on every render). */
export const DAILY = Array.from({ length: 90 }, (_, i) => {
const wave = Math.sin(i / 6) * 90 + Math.cos(i / 2.3) * 40;
return {
date: new Date(Date.UTC(2026, 3, 1 + i)).toISOString().slice(0, 10),
desktop: Math.round(260 + wave + (i % 7) * 12),
mobile: Math.round(180 + wave * 0.6 + ((i * 5) % 11) * 9),
};
});
/** `January` → `Jan`. */
export const shortMonth = (value: string) => value.slice(0, 3);
/** `2026-04-01` → `Apr 1`. */
export const shortDate = (value: string) =>
new Date(`${value}T00:00`).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });Stacked#
stacked puts the series on top of each other. tooltip sets the series indicator in the tooltip: dot (default), line or dashed.
import { Component } from '@angular/core';
import { WdsChartComponent } from '@wds/angular/chart';
import { CONFIG, MONTHS, shortMonth } from './chart-data';
@Component({
selector: 'app-chart-stacked-demo',
host: { class: 'block w-full max-w-xl' },
imports: [WdsChartComponent],
template: `
<wds-chart
label="Visits, stacked"
[config]="config"
[data]="months"
[series]="['desktop', 'mobile']"
x-key="month"
[xFormatter]="shortMonth"
stacked
tooltip="line"
/>
`,
})
export class ChartStackedDemo {
protected readonly config = CONFIG;
protected readonly months = MONTHS;
protected readonly shortMonth = shortMonth;
}import type { WdsChartConfig } from '@wds/core/chart';
export const MONTHS = [
{ month: 'January', desktop: 186, mobile: 80 },
{ month: 'February', desktop: 305, mobile: 200 },
{ month: 'March', desktop: 237, mobile: 120 },
{ month: 'April', desktop: 73, mobile: 190 },
{ month: 'May', desktop: 209, mobile: 130 },
{ month: 'June', desktop: 214, mobile: 140 },
];
/** Names and colors of the series; `month` and `date` name the category column of the data table. */
export const CONFIG: WdsChartConfig = {
month: { label: 'Month' },
date: { label: 'Day' },
desktop: { label: 'Desktop', color: 'var(--wds-chart-1)' },
mobile: { label: 'Mobile', color: 'var(--wds-chart-2)' },
};
export const BROWSERS = [
{ browser: 'chrome', visitors: 275 },
{ browser: 'safari', visitors: 200 },
{ browser: 'firefox', visitors: 187 },
{ browser: 'edge', visitors: 173 },
{ browser: 'other', visitors: 90 },
];
/** In `pie` and `radial` every category (row) has its own name and color. */
export const BROWSER_CONFIG: WdsChartConfig = {
browser: { label: 'Browser' },
visitors: { label: 'Visitors' },
chrome: { label: 'Chrome', color: 'var(--wds-chart-1)' },
safari: { label: 'Safari', color: 'var(--wds-chart-2)' },
firefox: { label: 'Firefox', color: 'var(--wds-chart-3)' },
edge: { label: 'Edge', color: 'var(--wds-chart-4)' },
other: { label: 'Other', color: 'var(--wds-chart-5)' },
};
/** 90 days of visits (computed, so it is the same on every render). */
export const DAILY = Array.from({ length: 90 }, (_, i) => {
const wave = Math.sin(i / 6) * 90 + Math.cos(i / 2.3) * 40;
return {
date: new Date(Date.UTC(2026, 3, 1 + i)).toISOString().slice(0, 10),
desktop: Math.round(260 + wave + (i % 7) * 12),
mobile: Math.round(180 + wave * 0.6 + ((i * 5) % 11) * 9),
};
});
/** `January` → `Jan`. */
export const shortMonth = (value: string) => value.slice(0, 3);
/** `2026-04-01` → `Apr 1`. */
export const shortDate = (value: string) =>
new Date(`${value}T00:00`).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });Percentage#
stack-offset="expand" shows each stack as shares of 100%. y-axis shows the value axis labels.
import { Component } from '@angular/core';
import { WdsChartComponent } from '@wds/angular/chart';
import { CONFIG, MONTHS, shortMonth } from './chart-data';
@Component({
selector: 'app-chart-percentage-demo',
host: { class: 'block w-full max-w-xl' },
imports: [WdsChartComponent],
template: `
<wds-chart
label="Share of visits by device"
[config]="config"
[data]="months"
[series]="['desktop', 'mobile']"
x-key="month"
[xFormatter]="shortMonth"
stacked
stack-offset="expand"
y-axis
/>
`,
})
export class ChartPercentageDemo {
protected readonly config = CONFIG;
protected readonly months = MONTHS;
protected readonly shortMonth = shortMonth;
}import type { WdsChartConfig } from '@wds/core/chart';
export const MONTHS = [
{ month: 'January', desktop: 186, mobile: 80 },
{ month: 'February', desktop: 305, mobile: 200 },
{ month: 'March', desktop: 237, mobile: 120 },
{ month: 'April', desktop: 73, mobile: 190 },
{ month: 'May', desktop: 209, mobile: 130 },
{ month: 'June', desktop: 214, mobile: 140 },
];
/** Names and colors of the series; `month` and `date` name the category column of the data table. */
export const CONFIG: WdsChartConfig = {
month: { label: 'Month' },
date: { label: 'Day' },
desktop: { label: 'Desktop', color: 'var(--wds-chart-1)' },
mobile: { label: 'Mobile', color: 'var(--wds-chart-2)' },
};
export const BROWSERS = [
{ browser: 'chrome', visitors: 275 },
{ browser: 'safari', visitors: 200 },
{ browser: 'firefox', visitors: 187 },
{ browser: 'edge', visitors: 173 },
{ browser: 'other', visitors: 90 },
];
/** In `pie` and `radial` every category (row) has its own name and color. */
export const BROWSER_CONFIG: WdsChartConfig = {
browser: { label: 'Browser' },
visitors: { label: 'Visitors' },
chrome: { label: 'Chrome', color: 'var(--wds-chart-1)' },
safari: { label: 'Safari', color: 'var(--wds-chart-2)' },
firefox: { label: 'Firefox', color: 'var(--wds-chart-3)' },
edge: { label: 'Edge', color: 'var(--wds-chart-4)' },
other: { label: 'Other', color: 'var(--wds-chart-5)' },
};
/** 90 days of visits (computed, so it is the same on every render). */
export const DAILY = Array.from({ length: 90 }, (_, i) => {
const wave = Math.sin(i / 6) * 90 + Math.cos(i / 2.3) * 40;
return {
date: new Date(Date.UTC(2026, 3, 1 + i)).toISOString().slice(0, 10),
desktop: Math.round(260 + wave + (i % 7) * 12),
mobile: Math.round(180 + wave * 0.6 + ((i * 5) % 11) * 9),
};
});
/** `January` → `Jan`. */
export const shortMonth = (value: string) => value.slice(0, 3);
/** `2026-04-01` → `Apr 1`. */
export const shortDate = (value: string) =>
new Date(`${value}T00:00`).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });Line#
type="line". curve is linear, smooth or step; value-labels puts the last value at the end of each line.
import { Component } from '@angular/core';
import { WdsChartComponent } from '@wds/angular/chart';
import { CONFIG, MONTHS, shortMonth } from './chart-data';
@Component({
selector: 'app-chart-line-demo',
host: { class: 'block w-full max-w-xl' },
imports: [WdsChartComponent],
template: `
<wds-chart
label="Monthly visits"
type="line"
curve="smooth"
y-axis
value-labels
[config]="config"
[data]="months"
[series]="['desktop', 'mobile']"
x-key="month"
[xFormatter]="shortMonth"
/>
`,
})
export class ChartLineDemo {
protected readonly config = CONFIG;
protected readonly months = MONTHS;
protected readonly shortMonth = shortMonth;
}import type { WdsChartConfig } from '@wds/core/chart';
export const MONTHS = [
{ month: 'January', desktop: 186, mobile: 80 },
{ month: 'February', desktop: 305, mobile: 200 },
{ month: 'March', desktop: 237, mobile: 120 },
{ month: 'April', desktop: 73, mobile: 190 },
{ month: 'May', desktop: 209, mobile: 130 },
{ month: 'June', desktop: 214, mobile: 140 },
];
/** Names and colors of the series; `month` and `date` name the category column of the data table. */
export const CONFIG: WdsChartConfig = {
month: { label: 'Month' },
date: { label: 'Day' },
desktop: { label: 'Desktop', color: 'var(--wds-chart-1)' },
mobile: { label: 'Mobile', color: 'var(--wds-chart-2)' },
};
export const BROWSERS = [
{ browser: 'chrome', visitors: 275 },
{ browser: 'safari', visitors: 200 },
{ browser: 'firefox', visitors: 187 },
{ browser: 'edge', visitors: 173 },
{ browser: 'other', visitors: 90 },
];
/** In `pie` and `radial` every category (row) has its own name and color. */
export const BROWSER_CONFIG: WdsChartConfig = {
browser: { label: 'Browser' },
visitors: { label: 'Visitors' },
chrome: { label: 'Chrome', color: 'var(--wds-chart-1)' },
safari: { label: 'Safari', color: 'var(--wds-chart-2)' },
firefox: { label: 'Firefox', color: 'var(--wds-chart-3)' },
edge: { label: 'Edge', color: 'var(--wds-chart-4)' },
other: { label: 'Other', color: 'var(--wds-chart-5)' },
};
/** 90 days of visits (computed, so it is the same on every render). */
export const DAILY = Array.from({ length: 90 }, (_, i) => {
const wave = Math.sin(i / 6) * 90 + Math.cos(i / 2.3) * 40;
return {
date: new Date(Date.UTC(2026, 3, 1 + i)).toISOString().slice(0, 10),
desktop: Math.round(260 + wave + (i % 7) * 12),
mobile: Math.round(180 + wave * 0.6 + ((i * 5) % 11) * 9),
};
});
/** `January` → `Jan`. */
export const shortMonth = (value: string) => value.slice(0, 3);
/** `2026-04-01` → `Apr 1`. */
export const shortDate = (value: string) =>
new Date(`${value}T00:00`).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });Area#
type="area" with gradient fills and a stack.
import { Component } from '@angular/core';
import { WdsChartComponent } from '@wds/angular/chart';
import { CONFIG, MONTHS, shortMonth } from './chart-data';
@Component({
selector: 'app-chart-area-demo',
host: { class: 'block w-full max-w-xl' },
imports: [WdsChartComponent],
template: `
<wds-chart
label="Visits, area"
type="area"
curve="smooth"
gradient
stacked
tooltip="dashed"
[config]="config"
[data]="months"
[series]="['mobile', 'desktop']"
x-key="month"
[xFormatter]="shortMonth"
/>
`,
})
export class ChartAreaDemo {
protected readonly config = CONFIG;
protected readonly months = MONTHS;
protected readonly shortMonth = shortMonth;
}import type { WdsChartConfig } from '@wds/core/chart';
export const MONTHS = [
{ month: 'January', desktop: 186, mobile: 80 },
{ month: 'February', desktop: 305, mobile: 200 },
{ month: 'March', desktop: 237, mobile: 120 },
{ month: 'April', desktop: 73, mobile: 190 },
{ month: 'May', desktop: 209, mobile: 130 },
{ month: 'June', desktop: 214, mobile: 140 },
];
/** Names and colors of the series; `month` and `date` name the category column of the data table. */
export const CONFIG: WdsChartConfig = {
month: { label: 'Month' },
date: { label: 'Day' },
desktop: { label: 'Desktop', color: 'var(--wds-chart-1)' },
mobile: { label: 'Mobile', color: 'var(--wds-chart-2)' },
};
export const BROWSERS = [
{ browser: 'chrome', visitors: 275 },
{ browser: 'safari', visitors: 200 },
{ browser: 'firefox', visitors: 187 },
{ browser: 'edge', visitors: 173 },
{ browser: 'other', visitors: 90 },
];
/** In `pie` and `radial` every category (row) has its own name and color. */
export const BROWSER_CONFIG: WdsChartConfig = {
browser: { label: 'Browser' },
visitors: { label: 'Visitors' },
chrome: { label: 'Chrome', color: 'var(--wds-chart-1)' },
safari: { label: 'Safari', color: 'var(--wds-chart-2)' },
firefox: { label: 'Firefox', color: 'var(--wds-chart-3)' },
edge: { label: 'Edge', color: 'var(--wds-chart-4)' },
other: { label: 'Other', color: 'var(--wds-chart-5)' },
};
/** 90 days of visits (computed, so it is the same on every render). */
export const DAILY = Array.from({ length: 90 }, (_, i) => {
const wave = Math.sin(i / 6) * 90 + Math.cos(i / 2.3) * 40;
return {
date: new Date(Date.UTC(2026, 3, 1 + i)).toISOString().slice(0, 10),
desktop: Math.round(260 + wave + (i % 7) * 12),
mobile: Math.round(180 + wave * 0.6 + ((i * 5) % 11) * 9),
};
});
/** `January` → `Jan`. */
export const shortMonth = (value: string) => value.slice(0, 3);
/** `2026-04-01` → `Apr 1`. */
export const shortDate = (value: string) =>
new Date(`${value}T00:00`).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });Series options#
WdsChartSeries object with its own curve, showSymbol, color, stack or fillOpacity.
import { Component } from '@angular/core';
import { WdsChartComponent } from '@wds/angular/chart';
import type { WdsChartSeriesInput } from '@wds/core/chart';
import { CONFIG, MONTHS, shortMonth } from './chart-data';
@Component({
selector: 'app-chart-series-options-demo',
host: { class: 'block w-full max-w-xl' },
imports: [WdsChartComponent],
template: `
<wds-chart
label="Visits, step line"
type="line"
[config]="config"
[data]="months"
[series]="series"
x-key="month"
[xFormatter]="shortMonth"
/>
`,
})
export class ChartSeriesOptionsDemo {
protected readonly config = CONFIG;
protected readonly months = MONTHS;
protected readonly shortMonth = shortMonth;
protected readonly series: WdsChartSeriesInput = [
{ key: 'desktop', curve: 'step' },
{ key: 'mobile', curve: 'linear', showSymbol: true },
];
}import type { WdsChartConfig } from '@wds/core/chart';
export const MONTHS = [
{ month: 'January', desktop: 186, mobile: 80 },
{ month: 'February', desktop: 305, mobile: 200 },
{ month: 'March', desktop: 237, mobile: 120 },
{ month: 'April', desktop: 73, mobile: 190 },
{ month: 'May', desktop: 209, mobile: 130 },
{ month: 'June', desktop: 214, mobile: 140 },
];
/** Names and colors of the series; `month` and `date` name the category column of the data table. */
export const CONFIG: WdsChartConfig = {
month: { label: 'Month' },
date: { label: 'Day' },
desktop: { label: 'Desktop', color: 'var(--wds-chart-1)' },
mobile: { label: 'Mobile', color: 'var(--wds-chart-2)' },
};
export const BROWSERS = [
{ browser: 'chrome', visitors: 275 },
{ browser: 'safari', visitors: 200 },
{ browser: 'firefox', visitors: 187 },
{ browser: 'edge', visitors: 173 },
{ browser: 'other', visitors: 90 },
];
/** In `pie` and `radial` every category (row) has its own name and color. */
export const BROWSER_CONFIG: WdsChartConfig = {
browser: { label: 'Browser' },
visitors: { label: 'Visitors' },
chrome: { label: 'Chrome', color: 'var(--wds-chart-1)' },
safari: { label: 'Safari', color: 'var(--wds-chart-2)' },
firefox: { label: 'Firefox', color: 'var(--wds-chart-3)' },
edge: { label: 'Edge', color: 'var(--wds-chart-4)' },
other: { label: 'Other', color: 'var(--wds-chart-5)' },
};
/** 90 days of visits (computed, so it is the same on every render). */
export const DAILY = Array.from({ length: 90 }, (_, i) => {
const wave = Math.sin(i / 6) * 90 + Math.cos(i / 2.3) * 40;
return {
date: new Date(Date.UTC(2026, 3, 1 + i)).toISOString().slice(0, 10),
desktop: Math.round(260 + wave + (i % 7) * 12),
mobile: Math.round(180 + wave * 0.6 + ((i * 5) % 11) * 9),
};
});
/** `January` → `Jan`. */
export const shortMonth = (value: string) => value.slice(0, 3);
/** `2026-04-01` → `Apr 1`. */
export const shortDate = (value: string) =>
new Date(`${value}T00:00`).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });Bars and a line#
type: 'line' is drawn as a line on a bar chart.
import { Component } from '@angular/core';
import { WdsChartComponent } from '@wds/angular/chart';
import type { WdsChartSeriesInput } from '@wds/core/chart';
import { CONFIG, MONTHS, shortMonth } from './chart-data';
@Component({
selector: 'app-chart-mixed-demo',
host: { class: 'block w-full max-w-xl' },
imports: [WdsChartComponent],
template: `
<wds-chart
label="Desktop (bars) and mobile (line)"
[config]="config"
[data]="months"
[series]="series"
x-key="month"
[xFormatter]="shortMonth"
/>
`,
})
export class ChartMixedDemo {
protected readonly config = CONFIG;
protected readonly months = MONTHS;
protected readonly shortMonth = shortMonth;
protected readonly series: WdsChartSeriesInput = ['desktop', { key: 'mobile', type: 'line', curve: 'smooth' }];
}import type { WdsChartConfig } from '@wds/core/chart';
export const MONTHS = [
{ month: 'January', desktop: 186, mobile: 80 },
{ month: 'February', desktop: 305, mobile: 200 },
{ month: 'March', desktop: 237, mobile: 120 },
{ month: 'April', desktop: 73, mobile: 190 },
{ month: 'May', desktop: 209, mobile: 130 },
{ month: 'June', desktop: 214, mobile: 140 },
];
/** Names and colors of the series; `month` and `date` name the category column of the data table. */
export const CONFIG: WdsChartConfig = {
month: { label: 'Month' },
date: { label: 'Day' },
desktop: { label: 'Desktop', color: 'var(--wds-chart-1)' },
mobile: { label: 'Mobile', color: 'var(--wds-chart-2)' },
};
export const BROWSERS = [
{ browser: 'chrome', visitors: 275 },
{ browser: 'safari', visitors: 200 },
{ browser: 'firefox', visitors: 187 },
{ browser: 'edge', visitors: 173 },
{ browser: 'other', visitors: 90 },
];
/** In `pie` and `radial` every category (row) has its own name and color. */
export const BROWSER_CONFIG: WdsChartConfig = {
browser: { label: 'Browser' },
visitors: { label: 'Visitors' },
chrome: { label: 'Chrome', color: 'var(--wds-chart-1)' },
safari: { label: 'Safari', color: 'var(--wds-chart-2)' },
firefox: { label: 'Firefox', color: 'var(--wds-chart-3)' },
edge: { label: 'Edge', color: 'var(--wds-chart-4)' },
other: { label: 'Other', color: 'var(--wds-chart-5)' },
};
/** 90 days of visits (computed, so it is the same on every render). */
export const DAILY = Array.from({ length: 90 }, (_, i) => {
const wave = Math.sin(i / 6) * 90 + Math.cos(i / 2.3) * 40;
return {
date: new Date(Date.UTC(2026, 3, 1 + i)).toISOString().slice(0, 10),
desktop: Math.round(260 + wave + (i % 7) * 12),
mobile: Math.round(180 + wave * 0.6 + ((i * 5) % 11) * 9),
};
});
/** `January` → `Jan`. */
export const shortMonth = (value: string) => value.slice(0, 3);
/** `2026-04-01` → `Apr 1`. */
export const shortDate = (value: string) =>
new Date(`${value}T00:00`).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });Donut#
pie and radial the categories are the rows (x-key) and the value is the first series; config names and colors the categories (or fill in a row). inner-radius makes a donut, pad-angle separates the slices, and center-value with center-label fill the middle.
import { Component } from '@angular/core';
import { WdsChartComponent } from '@wds/angular/chart';
import { BROWSERS, BROWSER_CONFIG } from './chart-data';
@Component({
selector: 'app-chart-donut-demo',
host: { class: 'block w-full max-w-xs' },
imports: [WdsChartComponent],
template: `
<wds-chart
label="Visitors by browser"
type="pie"
inner-radius="58%"
pad-angle="2"
center-value="925"
center-label="visitors"
[config]="browserConfig"
[data]="browsers"
[series]="['visitors']"
x-key="browser"
class="[--wds-chart-aspect-ratio:1]"
/>
`,
})
export class ChartDonutDemo {
protected readonly browsers = BROWSERS;
protected readonly browserConfig = BROWSER_CONFIG;
}import type { WdsChartConfig } from '@wds/core/chart';
export const MONTHS = [
{ month: 'January', desktop: 186, mobile: 80 },
{ month: 'February', desktop: 305, mobile: 200 },
{ month: 'March', desktop: 237, mobile: 120 },
{ month: 'April', desktop: 73, mobile: 190 },
{ month: 'May', desktop: 209, mobile: 130 },
{ month: 'June', desktop: 214, mobile: 140 },
];
/** Names and colors of the series; `month` and `date` name the category column of the data table. */
export const CONFIG: WdsChartConfig = {
month: { label: 'Month' },
date: { label: 'Day' },
desktop: { label: 'Desktop', color: 'var(--wds-chart-1)' },
mobile: { label: 'Mobile', color: 'var(--wds-chart-2)' },
};
export const BROWSERS = [
{ browser: 'chrome', visitors: 275 },
{ browser: 'safari', visitors: 200 },
{ browser: 'firefox', visitors: 187 },
{ browser: 'edge', visitors: 173 },
{ browser: 'other', visitors: 90 },
];
/** In `pie` and `radial` every category (row) has its own name and color. */
export const BROWSER_CONFIG: WdsChartConfig = {
browser: { label: 'Browser' },
visitors: { label: 'Visitors' },
chrome: { label: 'Chrome', color: 'var(--wds-chart-1)' },
safari: { label: 'Safari', color: 'var(--wds-chart-2)' },
firefox: { label: 'Firefox', color: 'var(--wds-chart-3)' },
edge: { label: 'Edge', color: 'var(--wds-chart-4)' },
other: { label: 'Other', color: 'var(--wds-chart-5)' },
};
/** 90 days of visits (computed, so it is the same on every render). */
export const DAILY = Array.from({ length: 90 }, (_, i) => {
const wave = Math.sin(i / 6) * 90 + Math.cos(i / 2.3) * 40;
return {
date: new Date(Date.UTC(2026, 3, 1 + i)).toISOString().slice(0, 10),
desktop: Math.round(260 + wave + (i % 7) * 12),
mobile: Math.round(180 + wave * 0.6 + ((i * 5) % 11) * 9),
};
});
/** `January` → `Jan`. */
export const shortMonth = (value: string) => value.slice(0, 3);
/** `2026-04-01` → `Apr 1`. */
export const shortDate = (value: string) =>
new Date(`${value}T00:00`).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });Radar#
type="radar": one polygon per series, radar-shape="circle" for a round grid.
import { Component } from '@angular/core';
import { WdsChartComponent } from '@wds/angular/chart';
import { CONFIG, MONTHS, shortMonth } from './chart-data';
@Component({
selector: 'app-chart-radar-demo',
host: { class: 'block w-full max-w-xs' },
imports: [WdsChartComponent],
template: `
<wds-chart
label="Visits on a radar"
type="radar"
[config]="config"
[data]="months"
[series]="['desktop', 'mobile']"
x-key="month"
[xFormatter]="shortMonth"
class="[--wds-chart-aspect-ratio:1]"
/>
`,
})
export class ChartRadarDemo {
protected readonly config = CONFIG;
protected readonly months = MONTHS;
protected readonly shortMonth = shortMonth;
}import type { WdsChartConfig } from '@wds/core/chart';
export const MONTHS = [
{ month: 'January', desktop: 186, mobile: 80 },
{ month: 'February', desktop: 305, mobile: 200 },
{ month: 'March', desktop: 237, mobile: 120 },
{ month: 'April', desktop: 73, mobile: 190 },
{ month: 'May', desktop: 209, mobile: 130 },
{ month: 'June', desktop: 214, mobile: 140 },
];
/** Names and colors of the series; `month` and `date` name the category column of the data table. */
export const CONFIG: WdsChartConfig = {
month: { label: 'Month' },
date: { label: 'Day' },
desktop: { label: 'Desktop', color: 'var(--wds-chart-1)' },
mobile: { label: 'Mobile', color: 'var(--wds-chart-2)' },
};
export const BROWSERS = [
{ browser: 'chrome', visitors: 275 },
{ browser: 'safari', visitors: 200 },
{ browser: 'firefox', visitors: 187 },
{ browser: 'edge', visitors: 173 },
{ browser: 'other', visitors: 90 },
];
/** In `pie` and `radial` every category (row) has its own name and color. */
export const BROWSER_CONFIG: WdsChartConfig = {
browser: { label: 'Browser' },
visitors: { label: 'Visitors' },
chrome: { label: 'Chrome', color: 'var(--wds-chart-1)' },
safari: { label: 'Safari', color: 'var(--wds-chart-2)' },
firefox: { label: 'Firefox', color: 'var(--wds-chart-3)' },
edge: { label: 'Edge', color: 'var(--wds-chart-4)' },
other: { label: 'Other', color: 'var(--wds-chart-5)' },
};
/** 90 days of visits (computed, so it is the same on every render). */
export const DAILY = Array.from({ length: 90 }, (_, i) => {
const wave = Math.sin(i / 6) * 90 + Math.cos(i / 2.3) * 40;
return {
date: new Date(Date.UTC(2026, 3, 1 + i)).toISOString().slice(0, 10),
desktop: Math.round(260 + wave + (i % 7) * 12),
mobile: Math.round(180 + wave * 0.6 + ((i * 5) % 11) * 9),
};
});
/** `January` → `Jan`. */
export const shortMonth = (value: string) => value.slice(0, 3);
/** `2026-04-01` → `Apr 1`. */
export const shortDate = (value: string) =>
new Date(`${value}T00:00`).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });Radial#
type="radial": one ring per category; a full ring is the largest value. hide-track hides the ring background.
import { Component } from '@angular/core';
import { WdsChartComponent } from '@wds/angular/chart';
import { BROWSERS, BROWSER_CONFIG } from './chart-data';
@Component({
selector: 'app-chart-radial-demo',
host: { class: 'block w-full max-w-xs' },
imports: [WdsChartComponent],
template: `
<wds-chart
label="Visitors by browser, rings"
type="radial"
inner-radius="24%"
[config]="browserConfig"
[data]="browsers"
[series]="['visitors']"
x-key="browser"
class="[--wds-chart-aspect-ratio:1]"
/>
`,
})
export class ChartRadialDemo {
protected readonly browsers = BROWSERS;
protected readonly browserConfig = BROWSER_CONFIG;
}import type { WdsChartConfig } from '@wds/core/chart';
export const MONTHS = [
{ month: 'January', desktop: 186, mobile: 80 },
{ month: 'February', desktop: 305, mobile: 200 },
{ month: 'March', desktop: 237, mobile: 120 },
{ month: 'April', desktop: 73, mobile: 190 },
{ month: 'May', desktop: 209, mobile: 130 },
{ month: 'June', desktop: 214, mobile: 140 },
];
/** Names and colors of the series; `month` and `date` name the category column of the data table. */
export const CONFIG: WdsChartConfig = {
month: { label: 'Month' },
date: { label: 'Day' },
desktop: { label: 'Desktop', color: 'var(--wds-chart-1)' },
mobile: { label: 'Mobile', color: 'var(--wds-chart-2)' },
};
export const BROWSERS = [
{ browser: 'chrome', visitors: 275 },
{ browser: 'safari', visitors: 200 },
{ browser: 'firefox', visitors: 187 },
{ browser: 'edge', visitors: 173 },
{ browser: 'other', visitors: 90 },
];
/** In `pie` and `radial` every category (row) has its own name and color. */
export const BROWSER_CONFIG: WdsChartConfig = {
browser: { label: 'Browser' },
visitors: { label: 'Visitors' },
chrome: { label: 'Chrome', color: 'var(--wds-chart-1)' },
safari: { label: 'Safari', color: 'var(--wds-chart-2)' },
firefox: { label: 'Firefox', color: 'var(--wds-chart-3)' },
edge: { label: 'Edge', color: 'var(--wds-chart-4)' },
other: { label: 'Other', color: 'var(--wds-chart-5)' },
};
/** 90 days of visits (computed, so it is the same on every render). */
export const DAILY = Array.from({ length: 90 }, (_, i) => {
const wave = Math.sin(i / 6) * 90 + Math.cos(i / 2.3) * 40;
return {
date: new Date(Date.UTC(2026, 3, 1 + i)).toISOString().slice(0, 10),
desktop: Math.round(260 + wave + (i % 7) * 12),
mobile: Math.round(180 + wave * 0.6 + ((i * 5) % 11) * 9),
};
});
/** `January` → `Jan`. */
export const shortMonth = (value: string) => value.slice(0, 3);
/** `2026-04-01` → `Apr 1`. */
export const shortDate = (value: string) =>
new Date(`${value}T00:00`).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });Custom colors#
--wds-chart-1…5 tokens in a fixed order, so a series keeps its color when another one is hidden. color in config sets any CSS color, and theme sets separate colors for light and dark backgrounds.
import { Component } from '@angular/core';
import { WdsChartComponent } from '@wds/angular/chart';
import type { WdsChartConfig } from '@wds/core/chart';
import { MONTHS, shortMonth } from './chart-data';
@Component({
selector: 'app-chart-custom-colors-demo',
host: { class: 'block w-full max-w-xl' },
imports: [WdsChartComponent],
template: `
<wds-chart
label="Visits in custom colors"
[config]="colors"
[data]="months"
[series]="['desktop', 'mobile']"
x-key="month"
[xFormatter]="shortMonth"
/>
`,
})
export class ChartCustomColorsDemo {
protected readonly months = MONTHS;
protected readonly shortMonth = shortMonth;
protected readonly colors: WdsChartConfig = {
month: { label: 'Month' },
desktop: { label: 'Desktop', color: '#0d9488' },
mobile: { label: 'Mobile', theme: { light: '#c2410c', dark: '#fb923c' } },
};
}import type { WdsChartConfig } from '@wds/core/chart';
export const MONTHS = [
{ month: 'January', desktop: 186, mobile: 80 },
{ month: 'February', desktop: 305, mobile: 200 },
{ month: 'March', desktop: 237, mobile: 120 },
{ month: 'April', desktop: 73, mobile: 190 },
{ month: 'May', desktop: 209, mobile: 130 },
{ month: 'June', desktop: 214, mobile: 140 },
];
/** Names and colors of the series; `month` and `date` name the category column of the data table. */
export const CONFIG: WdsChartConfig = {
month: { label: 'Month' },
date: { label: 'Day' },
desktop: { label: 'Desktop', color: 'var(--wds-chart-1)' },
mobile: { label: 'Mobile', color: 'var(--wds-chart-2)' },
};
export const BROWSERS = [
{ browser: 'chrome', visitors: 275 },
{ browser: 'safari', visitors: 200 },
{ browser: 'firefox', visitors: 187 },
{ browser: 'edge', visitors: 173 },
{ browser: 'other', visitors: 90 },
];
/** In `pie` and `radial` every category (row) has its own name and color. */
export const BROWSER_CONFIG: WdsChartConfig = {
browser: { label: 'Browser' },
visitors: { label: 'Visitors' },
chrome: { label: 'Chrome', color: 'var(--wds-chart-1)' },
safari: { label: 'Safari', color: 'var(--wds-chart-2)' },
firefox: { label: 'Firefox', color: 'var(--wds-chart-3)' },
edge: { label: 'Edge', color: 'var(--wds-chart-4)' },
other: { label: 'Other', color: 'var(--wds-chart-5)' },
};
/** 90 days of visits (computed, so it is the same on every render). */
export const DAILY = Array.from({ length: 90 }, (_, i) => {
const wave = Math.sin(i / 6) * 90 + Math.cos(i / 2.3) * 40;
return {
date: new Date(Date.UTC(2026, 3, 1 + i)).toISOString().slice(0, 10),
desktop: Math.round(260 + wave + (i % 7) * 12),
mobile: Math.round(180 + wave * 0.6 + ((i * 5) % 11) * 9),
};
});
/** `January` → `Jan`. */
export const shortMonth = (value: string) => value.slice(0, 3);
/** `2026-04-01` → `Apr 1`. */
export const shortDate = (value: string) =>
new Date(`${value}T00:00`).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });Interactive#
zoom adds zooming (wheel, gesture and a slider), wds-chart-click returns the clicked point, and show-table shows the data as a table. Changing type redraws the chart with the same data.
Clicked: none
import { Component, signal } from '@angular/core';
import { WdsChartComponent } from '@wds/angular/chart';
import { WDS_SELECT } from '@wds/angular/select';
import { WdsSwitchComponent } from '@wds/angular/switch';
import type { WdsChartClickDetail } from '@wds/core/chart';
import { CONFIG, DAILY, shortDate } from './chart-data';
@Component({
selector: 'app-chart-interactive-demo',
host: { class: 'flex w-full max-w-2xl flex-col gap-3' },
imports: [WdsChartComponent, ...WDS_SELECT, WdsSwitchComponent],
template: `
<div class="flex flex-wrap items-center gap-4">
<wds-select class="w-36" aria-label="Chart type" [value]="type()" (wdsChange)="type.set($any($event.value))">
<wds-select-item value="area">Area</wds-select-item>
<wds-select-item value="line">Line</wds-select-item>
<wds-select-item value="bar">Bar</wds-select-item>
</wds-select>
<wds-switch class="text-sm" [checked]="table()" (wdsChange)="table.set($event.checked)">Table</wds-switch>
</div>
<wds-chart
label="Daily visits"
[type]="type()"
zoom
y-axis
gradient
stacked
curve="smooth"
[showTable]="table()"
[config]="config"
[data]="daily"
[series]="['mobile', 'desktop']"
x-key="date"
[xFormatter]="shortDate"
class="[--wds-chart-height:300px] [&::part(table)]:mt-2"
(wdsChartClick)="onClick($event)"
/>
<p class="m-0 text-sm text-muted-foreground">Clicked: {{ clicked() || 'none' }}</p>
`,
})
export class ChartInteractiveDemo {
protected readonly config = CONFIG;
protected readonly daily = DAILY;
protected readonly shortDate = shortDate;
protected readonly type = signal<'area' | 'line' | 'bar'>('area');
protected readonly table = signal(false);
protected readonly clicked = signal('');
protected onClick({ key, name, value }: WdsChartClickDetail): void {
this.clicked.set(`${CONFIG[key]?.label ?? key}, ${shortDate(name)}: ${value}`);
}
}import type { WdsChartConfig } from '@wds/core/chart';
export const MONTHS = [
{ month: 'January', desktop: 186, mobile: 80 },
{ month: 'February', desktop: 305, mobile: 200 },
{ month: 'March', desktop: 237, mobile: 120 },
{ month: 'April', desktop: 73, mobile: 190 },
{ month: 'May', desktop: 209, mobile: 130 },
{ month: 'June', desktop: 214, mobile: 140 },
];
/** Names and colors of the series; `month` and `date` name the category column of the data table. */
export const CONFIG: WdsChartConfig = {
month: { label: 'Month' },
date: { label: 'Day' },
desktop: { label: 'Desktop', color: 'var(--wds-chart-1)' },
mobile: { label: 'Mobile', color: 'var(--wds-chart-2)' },
};
export const BROWSERS = [
{ browser: 'chrome', visitors: 275 },
{ browser: 'safari', visitors: 200 },
{ browser: 'firefox', visitors: 187 },
{ browser: 'edge', visitors: 173 },
{ browser: 'other', visitors: 90 },
];
/** In `pie` and `radial` every category (row) has its own name and color. */
export const BROWSER_CONFIG: WdsChartConfig = {
browser: { label: 'Browser' },
visitors: { label: 'Visitors' },
chrome: { label: 'Chrome', color: 'var(--wds-chart-1)' },
safari: { label: 'Safari', color: 'var(--wds-chart-2)' },
firefox: { label: 'Firefox', color: 'var(--wds-chart-3)' },
edge: { label: 'Edge', color: 'var(--wds-chart-4)' },
other: { label: 'Other', color: 'var(--wds-chart-5)' },
};
/** 90 days of visits (computed, so it is the same on every render). */
export const DAILY = Array.from({ length: 90 }, (_, i) => {
const wave = Math.sin(i / 6) * 90 + Math.cos(i / 2.3) * 40;
return {
date: new Date(Date.UTC(2026, 3, 1 + i)).toISOString().slice(0, 10),
desktop: Math.round(260 + wave + (i % 7) * 12),
mobile: Math.round(180 + wave * 0.6 + ((i * 5) % 11) * 9),
};
});
/** `January` → `Jan`. */
export const shortMonth = (value: string) => value.slice(0, 3);
/** `2026-04-01` → `Apr 1`. */
export const shortDate = (value: string) =>
new Date(`${value}T00:00`).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });API References#
wds-chart#
bar, line, area, pie, radar, radial.
Series colors are the --wds-chart-1…5 tokens (in a fixed order); config sets names and colors.
The legend toggles series, the tooltip shows every series at a point, and the data is also in a table
(always for screen readers, on screen with show-table).
Requires the echarts package (an optional dependency of @wds/core, loaded only by @wds/core/chart).
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
| type | WdsChartType | 'bar' | |
| series | WdsChartSeriesInput | [] | series="desktop, mobile") or full WdsChartSeries objects. In pie/radial the first series is the value. |
| x-key.xKey | string | '' | |
| stacked | boolean | false | |
| stack-offset.stackOffset | WdsChartStackOffset | 'none' | expand: the stack as a percentage share (0–100%). |
| horizontal | boolean | false | |
| grid | WdsChartGrid | 'horizontal' | |
| hide-x-axis.hideXAxis | boolean | false | |
| y-axis.yAxis | boolean | false | |
| curve | WdsChartCurve | 'linear' | line/area (a series can override it). |
| gradient | boolean | false | area fill. |
| value-labels.valueLabels | boolean | false | |
| legend | WdsChartLegend | 'auto' | auto (from 2 series), top, bottom, none. |
| tooltip | WdsChartTooltipIndicator | 'none' | 'dot' | none turns the tooltip off. |
| inner-radius.innerRadius | string | undefined | pie (donut) and radial, e.g. 60%. | |
| outer-radius.outerRadius | string | undefined | pie and radial. | |
| start-angle.startAngle | number | undefined | pie/radial in degrees (default 90, i.e. 12 o'clock). | |
| end-angle.endAngle | number | undefined | pie/radial in degrees. | |
| pad-angle.padAngle | number | 0 | pie slices in degrees. |
| center-value.centerValue | string | '' | |
| center-label.centerLabel | string | '' | |
| radar-shape.radarShape | 'polygon' | 'circle' | 'polygon' | |
| hide-track.hideTrack | boolean | false | radial rings. |
| zoom | boolean | false | |
| disable-animation.disableAnimation | boolean | false | prefers-reduced-motion). |
| renderer | 'svg' | 'canvas' | 'svg' | svg (sharp text, print) or canvas (many points). |
| label | string | '' | |
| show-table.showTable | boolean | false | |
| locale | string | undefined |
Properties
| Property | Description |
|---|---|
| configWdsChartConfig | pie/radial). |
| dataWdsChartDatum[] | |
| xFormatter(value: string) => string | undefined | |
| yFormatter(value: number) => string | undefined | |
| valueFormatter(value: number, key: string) => string | undefined | |
| optionRecord<string, unknown> | undefined | markLine). |
Events
| Event | Description |
|---|---|
| wds-chart-clickCustomEvent<WdsChartClickDetail> | |
| wds-legend-changeCustomEvent<WdsChartLegendChangeDetail> |
Methods
| Method | Description |
|---|---|
| getInstance() | dispatchAction. |
| resize() |
CSS parts (::part)
| Part | Description |
|---|---|
| plot | |
| legend | |
| table |
CSS custom properties
| Property | Description |
|---|---|
| --wds-chart-height | |
| --wds-chart-aspect-ratio |
Accessibility#
Screen reader#
role="figure" and label as its accessible name. The drawing itself is hidden from screen readers (aria-hidden); instead the data is in a table with the label as its caption, visually hidden unless show-table is set.
aria-pressed; a hidden series stays in the table. The legend name and the fallback table caption are built in and are in Polish for now (Legenda, Dane wykresu).
Keyboard support#
| Key | Function |
|---|---|