
These compositions pair bars and lines with the metrics they explain. Their data comes from the
original EvilCharts composed and benchmark examples.

## Revenue and profit

### Revenue and profit

```svelte
<script lang="ts">
	import { EvilComposedChart } from '../../charts/layerchart-composed-chart/index.js';
	import type { ChartConfig } from '../../ui/layerchart-chart/index.js';

	const data = [
		{ month: 'January', revenue: 4200, profit: 1800 },
		{ month: 'February', revenue: 5800, profit: 2400 },
		{ month: 'March', revenue: 4100, profit: 1600 },
		{ month: 'April', revenue: 6200, profit: 2800 },
		{ month: 'May', revenue: 5400, profit: 2200 },
		{ month: 'June', revenue: 7800, profit: 3400 },
		{ month: 'July', revenue: 6100, profit: 2600 },
		{ month: 'August', revenue: 8200, profit: 3800 },
		{ month: 'September', revenue: 5900, profit: 2500 },
		{ month: 'October', revenue: 6800, profit: 3000 },
		{ month: 'November', revenue: 7200, profit: 3200 },
		{ month: 'December', revenue: 9100, profit: 4200 }
	];
	const config = {
		revenue: { label: 'Revenue', colors: { light: ['#3b82f6'], dark: ['#6a5acd'] } },
		profit: { label: 'Profit', colors: { light: ['#10b981'], dark: ['#34d399'] } }
	} satisfies ChartConfig;
	const latest = data.at(-1)!;
	const annualRevenue = data.reduce((sum, row) => sum + row.revenue, 0);
	const annualProfit = data.reduce((sum, row) => sum + row.profit, 0);
	const compactMoney = (value: number) => `$${(value / 1000).toFixed(1)}k`;
</script>

<section
	class="@container/block flex size-full min-h-0 flex-col overflow-hidden p-3 sm:p-4"
	data-block="revenue-composed-chart"
>
	<header
		class="grid shrink-0 grid-cols-[1fr_auto_auto] items-end gap-3 border-b pb-2 @sm/block:gap-6 @sm/block:pb-3"
	>
		<div class="min-w-0">
			<span class="block truncate text-[10px] tracking-[0.16em] text-muted-foreground uppercase"
				>Revenue and profit</span
			>
			<strong class="text-xl tracking-tight @sm/block:text-3xl"
				>{compactMoney(annualRevenue)}</strong
			>
			<span class="ml-1 text-[10px] text-muted-foreground @sm/block:text-xs">this year</span>
		</div>
		<div class="text-right">
			<span class="block text-[9px] text-muted-foreground @sm/block:text-[11px]"
				>December revenue</span
			>
			<strong class="text-sm @sm/block:text-lg">{compactMoney(latest.revenue)}</strong>
		</div>
		<div class="text-right">
			<span class="block text-[9px] text-muted-foreground @sm/block:text-[11px]"
				>December profit</span
			>
			<strong class="text-sm text-emerald-500 @sm/block:text-lg"
				>{compactMoney(latest.profit)}</strong
			>
		</div>
	</header>
	<div class="mt-2 min-h-0 flex-1 overflow-hidden">
		<EvilComposedChart {data} {config} xDataKey="month" class="size-full" curveType="monotone">
			<EvilComposedChart.Grid />
			<EvilComposedChart.XAxis
				dataKey="month"
				tickFormatter={(value) => String(value).slice(0, 3)}
			/>
			<EvilComposedChart.YAxis />
			<EvilComposedChart.Tooltip />
			<EvilComposedChart.Bar dataKey="revenue" variant="gradient" radius={3} isClickable />
			<EvilComposedChart.Line dataKey="profit" strokeVariant="solid" glow isClickable>
				<EvilComposedChart.ActiveDot variant="colored-border" />
			</EvilComposedChart.Line>
		</EvilComposedChart>
	</div>
	<footer
		class="flex shrink-0 justify-end gap-3 pt-1 text-[9px] text-muted-foreground @sm/block:text-[11px]"
	>
		<span
			>Annual profit <b class="font-medium text-foreground">{compactMoney(annualProfit)}</b></span
		>
		<span
			>Margin <b class="font-medium text-emerald-500"
				>{((annualProfit / annualRevenue) * 100).toFixed(1)}%</b
			></span
		>
	</footer>
</section>
```
### npm

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

### yarn

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

### bun

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

### pnpm

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

## Signups against target

### Signups against target

```svelte
<script lang="ts">
	import { EvilComposedChart } from '../../charts/layerchart-composed-chart/index.js';
	import type { ChartConfig } from '../../ui/layerchart-chart/index.js';

	const data = [
		{ date: 'Jan 1', actual: 240, target: 125 },
		{ date: 'Jan 8', actual: 240, target: 125 },
		{ date: 'Jan 15', actual: 175, target: 200 },
		{ date: 'Jan 22', actual: 175, target: 200 },
		{ date: 'Feb 1', actual: 175, target: 200 },
		{ date: 'Feb 8', actual: 260, target: 125 },
		{ date: 'Feb 15', actual: 260, target: 125 },
		{ date: 'Feb 22', actual: 260, target: 125 },
		{ date: 'Mar 1', actual: 260, target: 190 },
		{ date: 'Mar 8', actual: 335, target: 190 },
		{ date: 'Mar 15', actual: 335, target: 190 },
		{ date: 'Mar 22', actual: 335, target: 390 },
		{ date: 'Apr 1', actual: 335, target: 390 },
		{ date: 'Apr 8', actual: 335, target: 390 },
		{ date: 'Apr 15', actual: 190, target: 390 },
		{ date: 'Apr 22', actual: 215, target: 305 },
		{ date: 'May 1', actual: 215, target: 305 },
		{ date: 'May 8', actual: 215, target: 175 },
		{ date: 'May 15', actual: 215, target: 175 },
		{ date: 'May 22', actual: 275, target: 175 },
		{ date: 'Jun 1', actual: 275, target: 245 }
	];
	const config = {
		actual: { label: 'Actual', colors: { light: ['#ff3e00'], dark: ['#ff5a1f'] } },
		target: { label: 'Target', colors: { light: ['#737373'], dark: ['#a3a3a3'] } }
	} satisfies ChartConfig;
	const latest = data.at(-1)!;
	const delta = ((latest.actual - latest.target) / latest.target) * 100;
</script>

<section
	class="flex size-full min-h-0 flex-col overflow-hidden p-3 sm:p-4"
	data-block="signups-composed-chart"
>
	<header class="flex shrink-0 items-start justify-between gap-4">
		<div>
			<span class="block text-[11px] text-muted-foreground">Weekly signups</span>
			<strong class="text-2xl tracking-tight sm:text-3xl">{latest.actual}</strong>
			<span class="ml-2 text-[11px] font-medium text-[#ff3e00] sm:text-sm"
				>+{delta.toFixed(1)}% vs target</span
			>
		</div>
		<div class="rounded-md border px-2.5 py-1.5 text-right">
			<span class="block text-[9px] tracking-wider text-muted-foreground uppercase">Target</span>
			<strong class="text-base">{latest.target}</strong>
		</div>
	</header>
	<div class="mt-2 min-h-0 flex-1 overflow-hidden sm:mt-3">
		<EvilComposedChart {data} {config} xDataKey="date" class="size-full" curveType="step">
			<EvilComposedChart.Grid />
			<EvilComposedChart.XAxis
				dataKey="date"
				tickFormatter={(value) => (String(value).endsWith(' 1') ? String(value).split(' ')[0] : '')}
			/>
			<EvilComposedChart.YAxis />
			<EvilComposedChart.Tooltip />
			<EvilComposedChart.Bar dataKey="actual" variant="gradient" radius={2} />
			<EvilComposedChart.Line dataKey="target" strokeVariant="dashed">
				<EvilComposedChart.ActiveDot variant="border" />
			</EvilComposedChart.Line>
		</EvilComposedChart>
	</div>
</section>
```
### npm

```bash
npx shadcn-svelte@latest add @evilcharts/signups-composed-chart
```

### yarn

```bash
yarn dlx shadcn-svelte@latest add @evilcharts/signups-composed-chart
```

### bun

```bash
bunx --bun shadcn-svelte@latest add @evilcharts/signups-composed-chart
```

### pnpm

```bash
pnpm dlx shadcn-svelte@latest add @evilcharts/signups-composed-chart
```
