Pie Charts
Pie chart examples: donut, labels, legend, stacked rings and more.
Each example is an iv-card with a chart inside. Copy the code under it. See Chart for the parts and the API.
import { IV_CHART_IMPORTS } from '@inlaylab/ivorie/chart';Interactive
import { ChangeDetectionStrategy, Component, computed, signal } from '@angular/core';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IV_SELECT_IMPORTS } from '@inlaylab/ivorie/select';
import { IV_CHART_IMPORTS, IvChartConfig, IvSectorShape, ivArc } from '@inlaylab/ivorie/chart';
@Component({
selector: 'demo-chart-pie-interactive',
imports: [IV_CARD_IMPORTS, IV_CHART_IMPORTS, IV_SELECT_IMPORTS],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-card class="w-full max-w-md flex flex-col">
<iv-card-header class="flex-row items-start space-y-0 pb-0">
<div class="grid gap-1">
<iv-card-title>Pie Chart - Interactive</iv-card-title>
<iv-card-description>January - June 2024</iv-card-description>
</div>
<iv-select [(value)]="month">
<iv-select-trigger
class="ml-auto h-7 w-[130px] rounded-lg pl-2.5"
aria-label="Select a value"
/>
<iv-select-content class="rounded-xl">
@for (key of months; track key) {
<iv-select-item [value]="key" class="rounded-lg">
<div class="flex items-center gap-2 text-xs">
<span
class="flex h-3 w-3 shrink-0 rounded-xs"
[style.background-color]="config[key].color"
></span>
{{ config[key].label }}
</div>
</iv-select-item>
}
</iv-select-content>
</iv-select>
</iv-card-header>
<iv-card-content class="flex flex-1 justify-center pb-0">
<iv-chart [config]="config" class="mx-auto aspect-square w-full max-w-[300px]">
<svg ivPieChart>
<g
ivPie
[data]="data"
dataKey="desktop"
nameKey="month"
[innerRadius]="60"
[strokeWidth]="5"
[activeIndex]="activeIndex()"
>
<ng-template ivActiveShape let-s>
<svg:path [attr.d]="grow(s)" [attr.fill]="s.fill" />
<svg:path [attr.d]="ring(s)" [attr.fill]="s.fill" />
</ng-template>
<ng-template ivChartLabel let-cx="cx" let-cy="cy">
<svg:text
[attr.x]="cx"
[attr.y]="cy"
text-anchor="middle"
dominant-baseline="middle"
>
<svg:tspan [attr.x]="cx" [attr.y]="cy" class="fill-foreground text-3xl font-bold">
{{ data[activeIndex()].desktop.toLocaleString() }}
</svg:tspan>
<svg:tspan [attr.x]="cx" [attr.y]="cy + 24" class="fill-muted-foreground">
Visitors
</svg:tspan>
</svg:text>
</ng-template>
</g>
</svg>
<iv-chart-tooltip [cursor]="false" hideLabel />
</iv-chart>
</iv-card-content>
</iv-card>
`,
})
export default class ChartPieInteractive {
protected readonly data = [
{ month: 'january', desktop: 186, fill: 'var(--color-january)' },
{ month: 'february', desktop: 305, fill: 'var(--color-february)' },
{ month: 'march', desktop: 237, fill: 'var(--color-march)' },
{ month: 'april', desktop: 173, fill: 'var(--color-april)' },
{ month: 'may', desktop: 209, fill: 'var(--color-may)' },
];
protected readonly config: IvChartConfig = {
visitors: { label: 'Visitors' },
desktop: { label: 'Desktop' },
mobile: { label: 'Mobile' },
january: { label: 'January', color: 'var(--chart-1)' },
february: { label: 'February', color: 'var(--chart-2)' },
march: { label: 'March', color: 'var(--chart-3)' },
april: { label: 'April', color: 'var(--chart-4)' },
may: { label: 'May', color: 'var(--chart-5)' },
};
protected readonly months = this.data.map((row) => row.month);
protected readonly month = signal<string | null>(this.months[0]);
protected readonly activeIndex = computed(() =>
Math.max(
0,
this.data.findIndex((row) => row.month === this.month()),
),
);
/** The active sector, 10px larger, and a ring around it. */
protected readonly grow = (s: IvSectorShape) => ivArc({ ...s, outerRadius: s.outerRadius + 10 });
protected readonly ring = (s: IvSectorShape) =>
ivArc({ ...s, innerRadius: s.outerRadius + 12, outerRadius: s.outerRadius + 25 });
}
Simple
Trending up by 5.2% this month
Showing total visitors for the last 6 months
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { NgIcon } from '@ng-icons/core';
import { lucideTrendingUp } from '@ng-icons/lucide';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IV_CHART_IMPORTS, IvChartConfig } from '@inlaylab/ivorie/chart';
@Component({
selector: 'demo-chart-pie-simple',
imports: [IV_CARD_IMPORTS, IV_CHART_IMPORTS, NgIcon],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-card class="w-full max-w-md flex flex-col">
<iv-card-header class="items-center pb-0">
<iv-card-title>Pie Chart</iv-card-title>
<iv-card-description>January - June 2024</iv-card-description>
</iv-card-header>
<iv-card-content class="flex-1 pb-0">
<iv-chart [config]="config" class="mx-auto aspect-square max-h-[250px]">
<svg ivPieChart>
<g ivPie [data]="data" dataKey="visitors" nameKey="browser" />
</svg>
<iv-chart-tooltip [cursor]="false" hideLabel />
</iv-chart>
</iv-card-content>
<iv-card-footer class="flex-col gap-2 text-sm">
<div class="flex items-center gap-2 leading-none font-medium">
Trending up by 5.2% this month <ng-icon [svg]="trendingUp" size="16" />
</div>
<div class="text-muted-foreground leading-none">
Showing total visitors for the last 6 months
</div>
</iv-card-footer>
</iv-card>
`,
})
export default class ChartPieSimple {
protected readonly data = [
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
{ browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' },
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
];
protected readonly config: IvChartConfig = {
visitors: { label: 'Visitors' },
chrome: { label: 'Chrome', color: 'var(--chart-1)' },
safari: { label: 'Safari', color: 'var(--chart-2)' },
firefox: { label: 'Firefox', color: 'var(--chart-3)' },
edge: { label: 'Edge', color: 'var(--chart-4)' },
other: { label: 'Other', color: 'var(--chart-5)' },
};
protected readonly trendingUp = lucideTrendingUp;
}
Separator None
Trending up by 5.2% this month
Showing total visitors for the last 6 months
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { NgIcon } from '@ng-icons/core';
import { lucideTrendingUp } from '@ng-icons/lucide';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IV_CHART_IMPORTS, IvChartConfig } from '@inlaylab/ivorie/chart';
@Component({
selector: 'demo-chart-pie-separator-none',
imports: [IV_CARD_IMPORTS, IV_CHART_IMPORTS, NgIcon],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-card class="w-full max-w-md flex flex-col">
<iv-card-header class="items-center pb-0">
<iv-card-title>Pie Chart - Separator None</iv-card-title>
<iv-card-description>January - June 2024</iv-card-description>
</iv-card-header>
<iv-card-content class="flex-1 pb-0">
<iv-chart [config]="config" class="mx-auto aspect-square max-h-[250px]">
<svg ivPieChart>
<g ivPie [data]="data" dataKey="visitors" nameKey="browser" stroke="0" />
</svg>
<iv-chart-tooltip [cursor]="false" hideLabel />
</iv-chart>
</iv-card-content>
<iv-card-footer class="flex-col gap-2 text-sm">
<div class="flex items-center gap-2 leading-none font-medium">
Trending up by 5.2% this month <ng-icon [svg]="trendingUp" size="16" />
</div>
<div class="text-muted-foreground leading-none">
Showing total visitors for the last 6 months
</div>
</iv-card-footer>
</iv-card>
`,
})
export default class ChartPieSeparatorNone {
protected readonly data = [
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
{ browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' },
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
];
protected readonly config: IvChartConfig = {
visitors: { label: 'Visitors' },
chrome: { label: 'Chrome', color: 'var(--chart-1)' },
safari: { label: 'Safari', color: 'var(--chart-2)' },
firefox: { label: 'Firefox', color: 'var(--chart-3)' },
edge: { label: 'Edge', color: 'var(--chart-4)' },
other: { label: 'Other', color: 'var(--chart-5)' },
};
protected readonly trendingUp = lucideTrendingUp;
}
Label
Trending up by 5.2% this month
Showing total visitors for the last 6 months
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { NgIcon } from '@ng-icons/core';
import { lucideTrendingUp } from '@ng-icons/lucide';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IV_CHART_IMPORTS, IvChartConfig } from '@inlaylab/ivorie/chart';
@Component({
selector: 'demo-chart-pie-label',
imports: [IV_CARD_IMPORTS, IV_CHART_IMPORTS, NgIcon],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-card class="w-full max-w-md flex flex-col">
<iv-card-header class="items-center pb-0">
<iv-card-title>Pie Chart - Label</iv-card-title>
<iv-card-description>January - June 2024</iv-card-description>
</iv-card-header>
<iv-card-content class="flex-1 pb-0">
<iv-chart
[config]="config"
class="mx-auto aspect-square max-h-[250px] pb-0 [&_[data-slot=chart-pie-label]]:fill-foreground"
>
<svg ivPieChart>
<g ivPie [data]="data" dataKey="visitors" label nameKey="browser" />
</svg>
<iv-chart-tooltip hideLabel />
</iv-chart>
</iv-card-content>
<iv-card-footer class="flex-col gap-2 text-sm">
<div class="flex items-center gap-2 leading-none font-medium">
Trending up by 5.2% this month <ng-icon [svg]="trendingUp" size="16" />
</div>
<div class="text-muted-foreground leading-none">
Showing total visitors for the last 6 months
</div>
</iv-card-footer>
</iv-card>
`,
})
export default class ChartPieLabel {
protected readonly data = [
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
{ browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' },
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
];
protected readonly config: IvChartConfig = {
visitors: { label: 'Visitors' },
chrome: { label: 'Chrome', color: 'var(--chart-1)' },
safari: { label: 'Safari', color: 'var(--chart-2)' },
firefox: { label: 'Firefox', color: 'var(--chart-3)' },
edge: { label: 'Edge', color: 'var(--chart-4)' },
other: { label: 'Other', color: 'var(--chart-5)' },
};
protected readonly trendingUp = lucideTrendingUp;
}
Custom Label
Trending up by 5.2% this month
Showing total visitors for the last 6 months
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { NgIcon } from '@ng-icons/core';
import { lucideTrendingUp } from '@ng-icons/lucide';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IV_CHART_IMPORTS, IvChartConfig } from '@inlaylab/ivorie/chart';
@Component({
selector: 'demo-chart-pie-label-custom',
imports: [IV_CARD_IMPORTS, IV_CHART_IMPORTS, NgIcon],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-card class="w-full max-w-md flex flex-col">
<iv-card-header class="items-center pb-0">
<iv-card-title>Pie Chart - Custom Label</iv-card-title>
<iv-card-description>January - June 2024</iv-card-description>
</iv-card-header>
<iv-card-content class="flex-1 pb-0">
<iv-chart [config]="config" class="mx-auto aspect-square max-h-[250px] px-0">
<svg ivPieChart>
<g
ivPie
[data]="data"
dataKey="visitors"
[labelLine]="false"
[label]="label"
nameKey="browser"
>
<ng-template #label let-l>
<svg:text
[attr.x]="l.x"
[attr.y]="l.y"
[attr.text-anchor]="l.textAnchor"
[attr.dominant-baseline]="l.dominantBaseline"
fill="var(--foreground)"
>
{{ l.value }}
</svg:text>
</ng-template>
</g>
</svg>
<iv-chart-tooltip nameKey="visitors" hideLabel />
</iv-chart>
</iv-card-content>
<iv-card-footer class="flex-col gap-2 text-sm">
<div class="flex items-center gap-2 leading-none font-medium">
Trending up by 5.2% this month <ng-icon [svg]="trendingUp" size="16" />
</div>
<div class="text-muted-foreground leading-none">
Showing total visitors for the last 6 months
</div>
</iv-card-footer>
</iv-card>
`,
})
export default class ChartPieLabelCustom {
protected readonly data = [
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
{ browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' },
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
];
protected readonly config: IvChartConfig = {
visitors: { label: 'Visitors' },
chrome: { label: 'Chrome', color: 'var(--chart-1)' },
safari: { label: 'Safari', color: 'var(--chart-2)' },
firefox: { label: 'Firefox', color: 'var(--chart-3)' },
edge: { label: 'Edge', color: 'var(--chart-4)' },
other: { label: 'Other', color: 'var(--chart-5)' },
};
protected readonly trendingUp = lucideTrendingUp;
}
Label List
Trending up by 5.2% this month
Showing total visitors for the last 6 months
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { NgIcon } from '@ng-icons/core';
import { lucideTrendingUp } from '@ng-icons/lucide';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IV_CHART_IMPORTS, IvChartConfig } from '@inlaylab/ivorie/chart';
@Component({
selector: 'demo-chart-pie-label-list',
imports: [IV_CARD_IMPORTS, IV_CHART_IMPORTS, NgIcon],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-card class="w-full max-w-md flex flex-col">
<iv-card-header class="items-center pb-0">
<iv-card-title>Pie Chart - Label List</iv-card-title>
<iv-card-description>January - June 2024</iv-card-description>
</iv-card-header>
<iv-card-content class="flex-1 pb-0">
<iv-chart [config]="config" class="mx-auto aspect-square max-h-[250px]">
<svg ivPieChart>
<g ivPie [data]="data" dataKey="visitors">
<g
ivLabelList
dataKey="browser"
class="fill-background text-xs"
[formatter]="label"
/>
</g>
</svg>
<iv-chart-tooltip nameKey="visitors" hideLabel />
</iv-chart>
</iv-card-content>
<iv-card-footer class="flex-col gap-2 text-sm">
<div class="flex items-center gap-2 leading-none font-medium">
Trending up by 5.2% this month <ng-icon [svg]="trendingUp" size="16" />
</div>
<div class="text-muted-foreground leading-none">
Showing total visitors for the last 6 months
</div>
</iv-card-footer>
</iv-card>
`,
})
export default class ChartPieLabelList {
protected readonly data = [
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
{ browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' },
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
];
protected readonly config: IvChartConfig = {
visitors: { label: 'Visitors' },
chrome: { label: 'Chrome', color: 'var(--chart-1)' },
safari: { label: 'Safari', color: 'var(--chart-2)' },
firefox: { label: 'Firefox', color: 'var(--chart-3)' },
edge: { label: 'Edge', color: 'var(--chart-4)' },
other: { label: 'Other', color: 'var(--chart-5)' },
};
protected readonly trendingUp = lucideTrendingUp;
/** The config label of a browser key. */
protected readonly label = (browser: string) => this.config[browser]?.label ?? browser;
}
Legend
Chrome
Safari
Firefox
Edge
Other
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IV_CHART_IMPORTS, IvChartConfig } from '@inlaylab/ivorie/chart';
@Component({
selector: 'demo-chart-pie-legend',
imports: [IV_CARD_IMPORTS, IV_CHART_IMPORTS],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-card class="w-full max-w-md flex flex-col">
<iv-card-header class="items-center pb-0">
<iv-card-title>Pie Chart - Legend</iv-card-title>
<iv-card-description>January - June 2024</iv-card-description>
</iv-card-header>
<iv-card-content class="flex-1 pb-0">
<iv-chart [config]="config" class="mx-auto aspect-square max-h-[300px]">
<svg ivPieChart>
<g ivPie [data]="data" dataKey="visitors" />
</svg>
<iv-chart-legend
nameKey="browser"
class="-translate-y-2 flex-wrap gap-2 *:basis-1/4 *:justify-center"
/>
</iv-chart>
</iv-card-content>
</iv-card>
`,
})
export default class ChartPieLegend {
protected readonly data = [
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
{ browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' },
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
];
protected readonly config: IvChartConfig = {
visitors: { label: 'Visitors' },
chrome: { label: 'Chrome', color: 'var(--chart-1)' },
safari: { label: 'Safari', color: 'var(--chart-2)' },
firefox: { label: 'Firefox', color: 'var(--chart-3)' },
edge: { label: 'Edge', color: 'var(--chart-4)' },
other: { label: 'Other', color: 'var(--chart-5)' },
};
}
Donut
Trending up by 5.2% this month
Showing total visitors for the last 6 months
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { NgIcon } from '@ng-icons/core';
import { lucideTrendingUp } from '@ng-icons/lucide';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IV_CHART_IMPORTS, IvChartConfig } from '@inlaylab/ivorie/chart';
@Component({
selector: 'demo-chart-pie-donut',
imports: [IV_CARD_IMPORTS, IV_CHART_IMPORTS, NgIcon],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-card class="w-full max-w-md flex flex-col">
<iv-card-header class="items-center pb-0">
<iv-card-title>Pie Chart - Donut</iv-card-title>
<iv-card-description>January - June 2024</iv-card-description>
</iv-card-header>
<iv-card-content class="flex-1 pb-0">
<iv-chart [config]="config" class="mx-auto aspect-square max-h-[250px]">
<svg ivPieChart>
<g ivPie [data]="data" dataKey="visitors" nameKey="browser" [innerRadius]="60" />
</svg>
<iv-chart-tooltip [cursor]="false" hideLabel />
</iv-chart>
</iv-card-content>
<iv-card-footer class="flex-col gap-2 text-sm">
<div class="flex items-center gap-2 leading-none font-medium">
Trending up by 5.2% this month <ng-icon [svg]="trendingUp" size="16" />
</div>
<div class="text-muted-foreground leading-none">
Showing total visitors for the last 6 months
</div>
</iv-card-footer>
</iv-card>
`,
})
export default class ChartPieDonut {
protected readonly data = [
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
{ browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' },
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
];
protected readonly config: IvChartConfig = {
visitors: { label: 'Visitors' },
chrome: { label: 'Chrome', color: 'var(--chart-1)' },
safari: { label: 'Safari', color: 'var(--chart-2)' },
firefox: { label: 'Firefox', color: 'var(--chart-3)' },
edge: { label: 'Edge', color: 'var(--chart-4)' },
other: { label: 'Other', color: 'var(--chart-5)' },
};
protected readonly trendingUp = lucideTrendingUp;
}
Donut Active
Trending up by 5.2% this month
Showing total visitors for the last 6 months
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { NgIcon } from '@ng-icons/core';
import { lucideTrendingUp } from '@ng-icons/lucide';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IV_CHART_IMPORTS, IvChartConfig, IvSectorShape, ivArc } from '@inlaylab/ivorie/chart';
@Component({
selector: 'demo-chart-pie-donut-active',
imports: [IV_CARD_IMPORTS, IV_CHART_IMPORTS, NgIcon],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-card class="w-full max-w-md flex flex-col">
<iv-card-header class="items-center pb-0">
<iv-card-title>Pie Chart - Donut Active</iv-card-title>
<iv-card-description>January - June 2024</iv-card-description>
</iv-card-header>
<iv-card-content class="flex-1 pb-0">
<iv-chart [config]="config" class="mx-auto aspect-square max-h-[250px]">
<svg ivPieChart>
<g
ivPie
[data]="data"
dataKey="visitors"
nameKey="browser"
[innerRadius]="60"
[strokeWidth]="5"
[activeIndex]="0"
>
<ng-template ivActiveShape let-s>
<svg:path [attr.d]="grow(s)" [attr.fill]="s.fill" />
</ng-template>
</g>
</svg>
<iv-chart-tooltip [cursor]="false" hideLabel />
</iv-chart>
</iv-card-content>
<iv-card-footer class="flex-col gap-2 text-sm">
<div class="flex items-center gap-2 leading-none font-medium">
Trending up by 5.2% this month <ng-icon [svg]="trendingUp" size="16" />
</div>
<div class="text-muted-foreground leading-none">
Showing total visitors for the last 6 months
</div>
</iv-card-footer>
</iv-card>
`,
})
export default class ChartPieDonutActive {
protected readonly data = [
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
{ browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' },
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
];
protected readonly config: IvChartConfig = {
visitors: { label: 'Visitors' },
chrome: { label: 'Chrome', color: 'var(--chart-1)' },
safari: { label: 'Safari', color: 'var(--chart-2)' },
firefox: { label: 'Firefox', color: 'var(--chart-3)' },
edge: { label: 'Edge', color: 'var(--chart-4)' },
other: { label: 'Other', color: 'var(--chart-5)' },
};
protected readonly trendingUp = lucideTrendingUp;
/** The active sector, 10px larger. */
protected readonly grow = (s: IvSectorShape) => ivArc({ ...s, outerRadius: s.outerRadius + 10 });
}
Donut with Text
Trending up by 5.2% this month
Showing total visitors for the last 6 months
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { NgIcon } from '@ng-icons/core';
import { lucideTrendingUp } from '@ng-icons/lucide';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IV_CHART_IMPORTS, IvChartConfig } from '@inlaylab/ivorie/chart';
@Component({
selector: 'demo-chart-pie-donut-text',
imports: [IV_CARD_IMPORTS, IV_CHART_IMPORTS, NgIcon],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-card class="w-full max-w-md flex flex-col">
<iv-card-header class="items-center pb-0">
<iv-card-title>Pie Chart - Donut with Text</iv-card-title>
<iv-card-description>January - June 2024</iv-card-description>
</iv-card-header>
<iv-card-content class="flex-1 pb-0">
<iv-chart [config]="config" class="mx-auto aspect-square max-h-[250px]">
<svg ivPieChart>
<g
ivPie
[data]="data"
dataKey="visitors"
nameKey="browser"
[innerRadius]="60"
[strokeWidth]="5"
>
<ng-template ivChartLabel let-cx="cx" let-cy="cy">
<svg:text
[attr.x]="cx"
[attr.y]="cy"
text-anchor="middle"
dominant-baseline="middle"
>
<svg:tspan [attr.x]="cx" [attr.y]="cy" class="fill-foreground text-3xl font-bold">
{{ total.toLocaleString() }}
</svg:tspan>
<svg:tspan [attr.x]="cx" [attr.y]="cy + 24" class="fill-muted-foreground">
Visitors
</svg:tspan>
</svg:text>
</ng-template>
</g>
</svg>
<iv-chart-tooltip [cursor]="false" hideLabel />
</iv-chart>
</iv-card-content>
<iv-card-footer class="flex-col gap-2 text-sm">
<div class="flex items-center gap-2 leading-none font-medium">
Trending up by 5.2% this month <ng-icon [svg]="trendingUp" size="16" />
</div>
<div class="text-muted-foreground leading-none">
Showing total visitors for the last 6 months
</div>
</iv-card-footer>
</iv-card>
`,
})
export default class ChartPieDonutText {
protected readonly data = [
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
{ browser: 'firefox', visitors: 287, fill: 'var(--color-firefox)' },
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
{ browser: 'other', visitors: 190, fill: 'var(--color-other)' },
];
protected readonly config: IvChartConfig = {
visitors: { label: 'Visitors' },
chrome: { label: 'Chrome', color: 'var(--chart-1)' },
safari: { label: 'Safari', color: 'var(--chart-2)' },
firefox: { label: 'Firefox', color: 'var(--chart-3)' },
edge: { label: 'Edge', color: 'var(--chart-4)' },
other: { label: 'Other', color: 'var(--chart-5)' },
};
protected readonly trendingUp = lucideTrendingUp;
protected readonly total = this.data.reduce((sum, row) => sum + row.visitors, 0);
}
Stacked
Trending up by 5.2% this month
Showing total visitors for the last 6 months
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { NgIcon } from '@ng-icons/core';
import { lucideTrendingUp } from '@ng-icons/lucide';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IV_CHART_IMPORTS, IvChartConfig, IvChartPayload } from '@inlaylab/ivorie/chart';
@Component({
selector: 'demo-chart-pie-stacked',
imports: [IV_CARD_IMPORTS, IV_CHART_IMPORTS, NgIcon],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-card class="w-full max-w-md flex flex-col">
<iv-card-header class="items-center pb-0">
<iv-card-title>Pie Chart - Stacked</iv-card-title>
<iv-card-description>January - June 2024</iv-card-description>
</iv-card-header>
<iv-card-content class="flex-1 pb-0">
<iv-chart [config]="config" class="mx-auto aspect-square max-h-[250px]">
<svg ivPieChart>
<g ivPie [data]="desktop" dataKey="desktop" [outerRadius]="60" />
<g ivPie [data]="mobile" dataKey="mobile" [innerRadius]="70" [outerRadius]="90" />
</svg>
<iv-chart-tooltip
labelKey="visitors"
nameKey="month"
indicator="line"
[labelFormatter]="series"
/>
</iv-chart>
</iv-card-content>
<iv-card-footer class="flex-col gap-2 text-sm">
<div class="flex items-center gap-2 leading-none font-medium">
Trending up by 5.2% this month <ng-icon [svg]="trendingUp" size="16" />
</div>
<div class="text-muted-foreground leading-none">
Showing total visitors for the last 6 months
</div>
</iv-card-footer>
</iv-card>
`,
})
export default class ChartPieStacked {
protected readonly config: IvChartConfig = {
visitors: { label: 'Visitors' },
desktop: { label: 'Desktop' },
mobile: { label: 'Mobile' },
january: { label: 'January', color: 'var(--chart-1)' },
february: { label: 'February', color: 'var(--chart-2)' },
march: { label: 'March', color: 'var(--chart-3)' },
april: { label: 'April', color: 'var(--chart-4)' },
may: { label: 'May', color: 'var(--chart-5)' },
};
protected readonly trendingUp = lucideTrendingUp;
protected readonly desktop = [
{ month: 'january', desktop: 186, fill: 'var(--color-january)' },
{ month: 'february', desktop: 305, fill: 'var(--color-february)' },
{ month: 'march', desktop: 237, fill: 'var(--color-march)' },
{ month: 'april', desktop: 173, fill: 'var(--color-april)' },
{ month: 'may', desktop: 209, fill: 'var(--color-may)' },
];
protected readonly mobile = [
{ month: 'january', mobile: 80, fill: 'var(--color-january)' },
{ month: 'february', mobile: 200, fill: 'var(--color-february)' },
{ month: 'march', mobile: 120, fill: 'var(--color-march)' },
{ month: 'april', mobile: 190, fill: 'var(--color-april)' },
{ month: 'may', mobile: 130, fill: 'var(--color-may)' },
];
/** The label names the ring: Desktop or Mobile. */
protected readonly series = (_: unknown, payload: IvChartPayload[]) =>
String(this.config[payload[0]?.key]?.label ?? '');
}