
These composed blocks preserve the original EvilCharts dashboard designs while using the Svelte 5 chart API.

## Market Share

### Market Share

```svelte
<script lang="ts">
	import { EvilPieChart } from '$lib/components/evilcharts/charts/layerchart-pie-chart/index.js';
	import { type ChartConfig } from '$lib/components/evilcharts/ui/layerchart-chart/index.js';

	const series = [
		{ key: 'skyline', label: 'Skyline', value: 27, color: '#0a0a0a' },
		{ key: 'datawell', label: 'Datawell', value: 21, color: '#343434' },
		{ key: 'cloudpeak', label: 'Cloudpeak', value: 13, color: '#555555' },
		{ key: 'taskbridge', label: 'Taskbridge', value: 21, color: '#777777' },
		{ key: 'insightloop', label: 'Insightloop', value: 6, color: '#999999' },
		{ key: 'streamforge', label: 'Streamforge', value: 12, color: '#b9b9b9' }
	] as const;

	const data = [...series].reverse().map(({ key, value }) => ({
		product: key,
		value,
		share: `${value}%`
	}));

	const config = Object.fromEntries(
		series.map(({ key, label, color }) => [
			key,
			{ label, colors: { light: [color], dark: [color === '#0a0a0a' ? '#ffffff' : color] } }
		])
	) satisfies ChartConfig;

	const total = series.reduce((sum, { value }) => sum + value, 0);
	let selected = $state<string | null>(null);
	let revision = $state(0);

	function select(key: string) {
		selected = selected === key ? null : key;
		revision += 1;
	}
</script>

<div class="@container flex h-full w-full min-w-0 flex-col overflow-hidden p-3 sm:p-4">
	<div class="relative min-h-0 w-full flex-1">
		{#key revision}
			<EvilPieChart
				{data}
				{config}
				dataKey="value"
				nameKey="product"
				class="h-full w-full"
				defaultSelectedSector={selected}
				onSelectionChange={(selection) => (selected = selection?.dataKey ?? null)}
			>
				<EvilPieChart.Tooltip />
				<EvilPieChart.Pie
					isClickable
					innerRadius="52%"
					outerRadius="94%"
					paddingAngle={3}
					startAngle={90}
					endAngle={-270}
				>
					<EvilPieChart.Label dataKey="share" />
				</EvilPieChart.Pie>
			</EvilPieChart>
		{/key}

		<div
			class="pointer-events-none absolute inset-0 flex flex-col items-center justify-center gap-0.5"
		>
			<span class="text-xl font-semibold tracking-tight text-primary @xl:text-3xl">${total}B</span>
			<span class="text-[10px] text-muted-foreground @xl:text-xs">Ecosystem value</span>
		</div>
	</div>

	<div
		class="mt-2 grid shrink-0 grid-cols-2 gap-x-3 gap-y-1.5 border-t pt-2 sm:mt-3 sm:pt-3 @md:grid-flow-col @md:grid-rows-3 @md:gap-x-6"
	>
		{#each series as item (item.key)}
			<button
				type="button"
				aria-pressed={selected === item.key}
				onclick={() => select(item.key)}
				class="flex min-w-0 cursor-pointer items-center gap-1.5 text-left text-[10px] transition-opacity sm:gap-2 sm:text-xs"
				class:opacity-40={selected !== null && selected !== item.key}
			>
				<span class="size-2.5 shrink-0 rounded-[3px]" style:background={item.color}></span>
				<span class="truncate font-medium text-primary">{item.label}</span>
				<span class="ml-auto shrink-0 text-muted-foreground">${item.value}B</span>
			</button>
		{/each}
	</div>
</div>
```
### npm

```bash
npx shadcn-svelte@latest add @evilcharts/market-share-pie-chart
```

### yarn

```bash
yarn dlx shadcn-svelte@latest add @evilcharts/market-share-pie-chart
```

### bun

```bash
bunx --bun shadcn-svelte@latest add @evilcharts/market-share-pie-chart
```

### pnpm

```bash
pnpm dlx shadcn-svelte@latest add @evilcharts/market-share-pie-chart
```

## Progress Rings

### Progress Rings

```svelte
<script lang="ts">
	import { EvilPieChart } from '$lib/components/evilcharts/charts/layerchart-pie-chart/index.js';
	import { type ChartConfig } from '$lib/components/evilcharts/ui/layerchart-chart/index.js';

	const dotCount = 40;
	const sectorCount = dotCount * 2;
	const stats = [
		{ id: 'support', value: 48, caption: 'Additional support requests from users.' },
		{ id: 'forecast', value: 67, caption: 'Inaccurate forecasts disrupt planning.' }
	] as const;

	const dataFor = (id: string) =>
		Array.from({ length: sectorCount }, (_, index) => ({ dot: `${id}-${index}`, value: 1 }));

	function configFor(id: string, value: number): ChartConfig {
		const filled = Math.round((dotCount * value) / 100);
		return Object.fromEntries(
			Array.from({ length: sectorCount }, (_, index) => {
				const color = index % 2 ? 'transparent' : index / 2 < filled ? '#e43861' : '#404040';
				return [`${id}-${index}`, { label: '', colors: { light: [color], dark: [color] } }];
			})
		);
	}
</script>

<div class="@container flex h-full w-full min-w-0 flex-col overflow-hidden p-3 sm:p-4">
	<div class="flex shrink-0 items-start justify-between gap-3">
		<div class="flex min-w-0 flex-col gap-0.5">
			<span class="text-[10px] tracking-wide text-muted-foreground uppercase">User research</span>
			<span
				class="truncate text-base leading-tight font-medium tracking-tight text-primary sm:text-xl"
				>Where the workday leaks</span
			>
		</div>
		<span class="shrink-0 text-[10px] text-muted-foreground sm:text-xs">1,240 responses</span>
	</div>

	<div class="mt-2 grid min-h-0 flex-1 grid-cols-2 gap-2 sm:mt-3 sm:gap-4">
		{#each stats as stat (stat.id)}
			<div class="relative min-h-0 min-w-0">
				<EvilPieChart
					data={dataFor(stat.id)}
					config={configFor(stat.id, stat.value)}
					dataKey="value"
					nameKey="dot"
					class="h-full w-full"
				>
					<EvilPieChart.Pie innerRadius="85%" outerRadius="92%" cornerRadius={6} />
				</EvilPieChart>

				<div
					class="pointer-events-none absolute inset-0 flex flex-col items-center justify-center gap-1 px-[22%] text-center"
				>
					<span class="text-2xl leading-none font-medium tracking-tight text-primary sm:text-4xl"
						>{stat.value}%</span
					>
					<span class="text-[9px] leading-snug text-balance text-muted-foreground sm:text-xs"
						>{stat.caption}</span
					>
				</div>
			</div>
		{/each}
	</div>
</div>
```
### npm

```bash
npx shadcn-svelte@latest add @evilcharts/progress-rings-pie-chart
```

### yarn

```bash
yarn dlx shadcn-svelte@latest add @evilcharts/progress-rings-pie-chart
```

### bun

```bash
bunx --bun shadcn-svelte@latest add @evilcharts/progress-rings-pie-chart
```

### pnpm

```bash
pnpm dlx shadcn-svelte@latest add @evilcharts/progress-rings-pie-chart
```

## Revenue Mix

### Revenue Mix

```svelte
<script lang="ts">
	import { EvilPieChart } from '$lib/components/evilcharts/charts/layerchart-pie-chart/index.js';
	import { type ChartConfig } from '$lib/components/evilcharts/ui/layerchart-chart/index.js';

	const data = [
		{ channel: 'direct', label: 'Direct', value: 52400, color: '#7c3aed' },
		{ channel: 'marketplace', label: 'Marketplace', value: 38900, color: '#4f46e5' },
		{ channel: 'wholesale', label: 'Wholesale', value: 24150, color: '#0284c7' },
		{ channel: 'affiliate', label: 'Affiliate', value: 16300, color: '#059669' }
	];

	const config = Object.fromEntries(
		data.map(({ channel, label, color }) => [
			channel,
			{ label, colors: { light: [color], dark: [color] } }
		])
	) satisfies ChartConfig;
	const orders = 1284;
	const money = (value: number) => value.toLocaleString('en-US');
</script>

<div
	class="@container flex h-full w-full min-w-0 items-center gap-2 overflow-hidden p-3 sm:p-4 @sm:gap-4"
>
	<div class="relative aspect-square w-[43%] max-w-72 shrink-0">
		<EvilPieChart {data} {config} dataKey="value" nameKey="channel" class="h-full w-full">
			<EvilPieChart.Tooltip />
			<EvilPieChart.Pie innerRadius="62%" outerRadius="92%" paddingAngle={6} cornerRadius={12} />
		</EvilPieChart>

		<div class="pointer-events-none absolute inset-0 flex items-center justify-center">
			<div
				class="flex aspect-square w-[56%] flex-col items-center justify-center rounded-full border border-dashed"
			>
				<span class="text-base leading-none font-semibold tracking-tight text-primary @sm:text-2xl"
					>{money(orders)}</span
				>
				<span class="mt-1 text-center text-[9px] text-muted-foreground @sm:text-xs"
					>Total orders</span
				>
			</div>
		</div>
	</div>

	<div class="flex min-h-0 min-w-0 flex-1 flex-col justify-center">
		{#each data as item (item.channel)}
			<div class="flex min-w-0 items-center gap-1.5 py-1.5 @sm:gap-2 @sm:py-2">
				<span class="size-2.5 shrink-0 rounded-[3px]" style:background={item.color}></span>
				<span class="truncate text-[10px] text-muted-foreground @sm:text-xs">{item.label}</span>
				<span class="ml-auto shrink-0 text-[10px] font-semibold text-primary @sm:text-xs"
					>${money(item.value)}</span
				>
			</div>
		{/each}
	</div>
</div>
```
### npm

```bash
npx shadcn-svelte@latest add @evilcharts/revenue-mix-pie-chart
```

### yarn

```bash
yarn dlx shadcn-svelte@latest add @evilcharts/revenue-mix-pie-chart
```

### bun

```bash
bunx --bun shadcn-svelte@latest add @evilcharts/revenue-mix-pie-chart
```

### pnpm

```bash
pnpm dlx shadcn-svelte@latest add @evilcharts/revenue-mix-pie-chart
```

## Reliability Score

### Reliability Score

```svelte
<script lang="ts">
	import { EvilPieChart } from '$lib/components/evilcharts/charts/layerchart-pie-chart/index.js';
	import { type ChartConfig } from '$lib/components/evilcharts/ui/layerchart-chart/index.js';

	const max = 1000;
	const score = 842;
	const data = [
		{ band: 'atrisk', label: 'At risk', from: 0, value: 450, color: '#e11d48' },
		{ band: 'fair', label: 'Fair', from: 450, value: 200, color: '#f59e0b' },
		{ band: 'good', label: 'Good', from: 650, value: 170, color: '#84cc16' },
		{ band: 'excellent', label: 'Excellent', from: 820, value: 180, color: '#059669' }
	];
	const config = Object.fromEntries(
		data.map(({ band, label, color }) => [
			band,
			{ label, colors: { light: [color], dark: [color] } }
		])
	) satisfies ChartConfig;
	const scoreBand = [...data].reverse().find(({ from }) => score >= from) ?? data[0];
</script>

<div class="flex h-full w-full min-w-0 flex-col overflow-hidden p-3 sm:p-4">
	<span class="shrink-0 text-base font-medium tracking-tight text-primary sm:text-lg"
		>Delivery Reliability</span
	>

	<div class="relative mx-auto mt-1 aspect-square min-h-0 w-full max-w-50 flex-1">
		<EvilPieChart
			data={[...data].reverse()}
			{config}
			dataKey="value"
			nameKey="band"
			class="h-full w-full"
		>
			<EvilPieChart.Pie
				innerRadius="74%"
				outerRadius="94%"
				paddingAngle={6}
				cornerRadius={10}
				startAngle={-30}
				endAngle={210}
			/>
		</EvilPieChart>
		<div class="pointer-events-none absolute inset-0 flex items-center justify-center">
			<span class="text-3xl font-semibold tracking-tight text-primary sm:text-4xl">{score}</span>
		</div>
	</div>

	<div class="-mt-5 shrink-0 text-center">
		<p class="text-xs font-medium text-primary sm:text-sm">
			Reliability is {scoreBand.label.toLowerCase()}
		</p>
		<p class="text-[10px] text-muted-foreground sm:text-xs">Updated 12 Mar 2026</p>
	</div>

	<div class="mt-auto shrink-0 pt-2">
		<div class="flex text-[9px] text-muted-foreground sm:text-[10px]">
			{#each data as item (item.band)}
				<span style:flex-grow={item.value} style:flex-basis="0">{item.from}</span>
			{/each}
			<span>{max}</span>
		</div>
		<div class="mt-1 flex gap-1">
			{#each data as item (item.band)}
				<span
					class="h-1.5 rounded-full"
					style:flex-grow={item.value}
					style:flex-basis="0"
					style:background={item.color}
				></span>
			{/each}
		</div>
	</div>
</div>
```
### npm

```bash
npx shadcn-svelte@latest add @evilcharts/reliability-score-pie-chart
```

### yarn

```bash
yarn dlx shadcn-svelte@latest add @evilcharts/reliability-score-pie-chart
```

### bun

```bash
bunx --bun shadcn-svelte@latest add @evilcharts/reliability-score-pie-chart
```

### pnpm

```bash
pnpm dlx shadcn-svelte@latest add @evilcharts/reliability-score-pie-chart
```
