Chart
SVG charts built from small parts. Line, area, bar, pie, radar and radial.
import { … } from '@inlaylab/ivorie/chart'import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_CHART_IMPORTS, IvChartConfig } from '@inlaylab/ivorie/chart';
@Component({
selector: 'demo-chart',
imports: [IV_CHART_IMPORTS],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-chart [config]="config" class="min-h-[200px] w-full">
<svg ivBarChart [data]="data">
<g ivBar dataKey="desktop" [radius]="4" />
<g ivBar dataKey="mobile" [radius]="4" />
</svg>
</iv-chart>
`,
})
export default class ChartDemo {
protected readonly data = [
{ 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 },
];
protected readonly config: IvChartConfig = {
desktop: { label: 'Desktop', color: '#2563eb' },
mobile: { label: 'Mobile', color: '#60a5fa' },
};
}
Installation
npx ivorie add chartimport { … } from '@inlaylab/ivorie/chart'Charts are made of parts: a container, a chart root, then grid, axes, series, tooltip and legend. You add only the parts you need. The parts and their inputs follow Recharts, so shadcn's chart examples port almost line by line.
Browse ready-made cards in Area Charts, Bar Charts, Line Charts, Pie Charts, Radar Charts, Radial Charts and Tooltips.
Usage
import { IV_CHART_IMPORTS, IvChartConfig } from '@inlaylab/ivorie/chart';<iv-chart [config]="config" class="min-h-[200px] w-full">
<svg ivBarChart [data]="data">
<g ivCartesianGrid [vertical]="false" />
<g ivXAxis dataKey="month" />
<g ivBar dataKey="desktop" [radius]="4" />
</svg>
<iv-chart-tooltip />
<iv-chart-legend />
</iv-chart>The svg root and its g parts are real SVG elements. Angular renders them on the server too.
Your first chart
Build the bar chart at the top of this page, one step at a time.
1. Define your data
Any array of objects works. Each key is a column you can draw.
protected readonly data = [
{ 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 },
];2. Define your config
The config names and colors each series. It holds no data, so many charts can share one.
protected readonly config: IvChartConfig = {
desktop: { label: 'Desktop', color: '#2563eb' },
mobile: { label: 'Mobile', color: '#60a5fa' },
};3. Build your chart
Put a chart root inside iv-chart, and a series per data key. Give the container a height: a min-h-*, an h-* or an aspect-* class. Its default is aspect-video.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_CHART_IMPORTS, IvChartConfig } from '@inlaylab/ivorie/chart';
@Component({
selector: 'demo-chart',
imports: [IV_CHART_IMPORTS],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-chart [config]="config" class="min-h-[200px] w-full">
<svg ivBarChart [data]="data">
<g ivBar dataKey="desktop" [radius]="4" />
<g ivBar dataKey="mobile" [radius]="4" />
</svg>
</iv-chart>
`,
})
export default class ChartDemo {
protected readonly data = [
{ 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 },
];
protected readonly config: IvChartConfig = {
desktop: { label: 'Desktop', color: '#2563eb' },
mobile: { label: 'Mobile', color: '#60a5fa' },
};
}
4. Add a grid
g[ivCartesianGrid] draws the lines. [vertical]="false" keeps only the horizontal ones.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_CHART_IMPORTS, IvChartConfig } from '@inlaylab/ivorie/chart';
@Component({
selector: 'demo-chart-bar-demo-grid',
imports: [IV_CHART_IMPORTS],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-chart [config]="config" class="min-h-[200px] w-full">
<svg ivBarChart [data]="data">
<g ivCartesianGrid [vertical]="false" />
<g ivBar dataKey="desktop" [radius]="4" />
<g ivBar dataKey="mobile" [radius]="4" />
</svg>
</iv-chart>
`,
})
export default class ChartBarDemoGrid {
protected readonly data = [
{ 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 },
];
protected readonly config: IvChartConfig = {
desktop: { label: 'Desktop', color: '#2563eb' },
mobile: { label: 'Mobile', color: '#60a5fa' },
};
}
5. Add an axis
g[ivXAxis] labels each row with its dataKey. tickFormatter shortens the labels.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_CHART_IMPORTS, IvChartConfig } from '@inlaylab/ivorie/chart';
@Component({
selector: 'demo-chart-bar-demo-axis',
imports: [IV_CHART_IMPORTS],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-chart [config]="config" class="min-h-[200px] w-full">
<svg ivBarChart [data]="data">
<g ivCartesianGrid [vertical]="false" />
<g
ivXAxis
dataKey="month"
[tickLine]="false"
[tickMargin]="10"
[axisLine]="false"
[tickFormatter]="short"
/>
<g ivBar dataKey="desktop" [radius]="4" />
<g ivBar dataKey="mobile" [radius]="4" />
</svg>
</iv-chart>
`,
})
export default class ChartBarDemoAxis {
protected readonly data = [
{ 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 },
];
protected readonly config: IvChartConfig = {
desktop: { label: 'Desktop', color: '#2563eb' },
mobile: { label: 'Mobile', color: '#60a5fa' },
};
protected readonly short = (month: string) => month.slice(0, 3);
}
6. Add a tooltip
Put iv-chart-tooltip inside iv-chart, after the chart root. Hover a bar. Labels and colors come from the config.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_CHART_IMPORTS, IvChartConfig } from '@inlaylab/ivorie/chart';
@Component({
selector: 'demo-chart-bar-demo-tooltip',
imports: [IV_CHART_IMPORTS],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-chart [config]="config" class="min-h-[200px] w-full">
<svg ivBarChart [data]="data">
<g ivCartesianGrid [vertical]="false" />
<g
ivXAxis
dataKey="month"
[tickLine]="false"
[tickMargin]="10"
[axisLine]="false"
[tickFormatter]="short"
/>
<g ivBar dataKey="desktop" [radius]="4" />
<g ivBar dataKey="mobile" [radius]="4" />
</svg>
<iv-chart-tooltip />
</iv-chart>
`,
})
export default class ChartBarDemoTooltip {
protected readonly data = [
{ 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 },
];
protected readonly config: IvChartConfig = {
desktop: { label: 'Desktop', color: '#2563eb' },
mobile: { label: 'Mobile', color: '#60a5fa' },
};
protected readonly short = (month: string) => month.slice(0, 3);
}
7. Add a legend
iv-chart-legend lists each series with its config label. The chart makes room for it.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_CHART_IMPORTS, IvChartConfig } from '@inlaylab/ivorie/chart';
@Component({
selector: 'demo-chart-bar-demo-legend',
imports: [IV_CHART_IMPORTS],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-chart [config]="config" class="min-h-[200px] w-full">
<svg ivBarChart [data]="data">
<g ivCartesianGrid [vertical]="false" />
<g
ivXAxis
dataKey="month"
[tickLine]="false"
[tickMargin]="10"
[axisLine]="false"
[tickFormatter]="short"
/>
<g ivBar dataKey="desktop" [radius]="4" />
<g ivBar dataKey="mobile" [radius]="4" />
</svg>
<iv-chart-tooltip />
<iv-chart-legend />
</iv-chart>
`,
})
export default class ChartBarDemoLegend {
protected readonly data = [
{ 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 },
];
protected readonly config: IvChartConfig = {
desktop: { label: 'Desktop', color: '#2563eb' },
mobile: { label: 'Mobile', color: '#60a5fa' },
};
protected readonly short = (month: string) => month.slice(0, 3);
}
That is your first chart. Next, browse the gallery pages or read the API below.
Config
The config maps each data key to a label, an optional icon, and a color or a theme.
import { IvChartConfig } from '@inlaylab/ivorie/chart';
protected readonly config: IvChartConfig = {
desktop: {
label: 'Desktop',
icon: MonitorIcon,
// A color...
color: '#2563eb',
},
mobile: {
label: 'Mobile',
// ...or a light and a dark color.
theme: { light: '#60a5fa', dark: '#93c5fd' },
},
};labelnames the series in the tooltip and the legend.iconis any component. The tooltip and the legend draw it in place of the swatch. To use an<ng-icon>, wrap it in a small component.- Each key becomes a CSS custom property,
--color-<key>, oniv-chart. Use simple identifiers as keys: letters, digits,-and_, no spaces. - One
dataKeynames one series. Two series with the samedataKeyin one chart collide (tooltip rows, legend, stacks and the active point mix them up). Give each its own key.
Theming
Use CSS variables (recommended), or any color: hex, hsl, oklch.
CSS variables
The theme defines --chart-1 to --chart-5, for light and dark mode. Point the config at them:
protected readonly config: IvChartConfig = {
desktop: { label: 'Desktop', color: 'var(--chart-1)' },
mobile: { label: 'Mobile', color: 'var(--chart-2)' },
};Change them in your styles to recolor every chart:
:root {
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
}
.dark {
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
}A theme per series
theme sets a light and a dark color for one series. Dark applies under a .dark ancestor.
protected readonly config: IvChartConfig = {
desktop: { label: 'Desktop', theme: { light: '#2563eb', dark: '#60a5fa' } },
};Using the colors
A series uses var(--color-<dataKey>) by default. Use the same variable anywhere inside iv-chart:
- In an input:
<g ivBar dataKey="desktop" fill="var(--color-mobile)" />. - In data:
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }. A row'sfillcolors its bar, sector or tooltip row. - In a class:
<g ivLabelList class="fill-(--color-desktop)" />. - In a gradient:
<linearGradient id="fillDesktop">ids are page-wide. If a component that draws a chart renders more than once on a page, make the id unique per instance (for example withIvIdGenerator.next('fill')from@inlaylab/ivorie/core) and use it infill="url(#…)".
Tooltip
A tooltip shows a label, a name, an indicator and a value per series.
import {
ChangeDetectionStrategy,
Component,
booleanAttribute,
computed,
input,
} from '@angular/core';
import { cn } from '@inlaylab/ivorie/core';
interface Row {
name: string;
value: number;
fill: string;
}
/** A still copy of the tooltip card, to show its parts. */
@Component({
selector: 'demo-tooltip-card',
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'contents' },
template: `
<div [class]="classes()">
@if (!nest() && !hideLabel()) {
<div class="font-medium">{{ label() }}</div>
}
<div class="grid gap-1.5">
@for (item of payload(); track item.name) {
<div class="flex w-full items-stretch gap-2" [class.items-center]="indicator() === 'dot'">
<div
[class]="indicatorClass()"
[style.--color-bg]="item.fill"
[style.--color-border]="item.fill"
></div>
<div
class="flex flex-1 justify-between leading-none"
[class]="nest() ? 'items-end' : 'items-center'"
>
<div class="grid gap-1.5">
@if (nest() && !hideLabel()) {
<div class="font-medium">{{ label() }}</div>
}
<span class="text-muted-foreground">{{ item.name }}</span>
</div>
<span class="text-foreground font-mono font-medium tabular-nums">{{
item.value.toLocaleString('en-US')
}}</span>
</div>
</div>
}
</div>
</div>
`,
})
class TooltipCard {
readonly label = input('');
readonly hideLabel = input(false, { transform: booleanAttribute });
readonly indicator = input<'dot' | 'line' | 'dashed'>('dot');
readonly payload = input.required<Row[]>();
readonly class = input('');
protected readonly nest = computed(
() => this.payload().length === 1 && this.indicator() !== 'dot',
);
protected readonly classes = computed(() =>
cn(
'cn-chart-tooltip grid min-w-32 items-start transition-all ease-in-out hover:-translate-y-0.5',
this.class(),
),
);
protected readonly indicatorClass = computed(() => {
const indicator = this.indicator();
return cn(
'shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)',
indicator === 'dot' && 'h-2.5 w-2.5',
indicator === 'line' && 'w-1',
indicator === 'dashed' && 'w-0 border-[1.5px] border-dashed bg-transparent',
this.nest() && indicator === 'dashed' && 'my-0.5',
);
});
}
@Component({
selector: 'demo-chart-tooltip-demo',
imports: [TooltipCard],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div
class="text-foreground grid aspect-video w-full max-w-md justify-center md:grid-cols-2 [&>div]:relative [&>div]:flex [&>div]:h-[137px] [&>div]:w-[224px] [&>div]:items-center [&>div]:justify-center [&>div]:p-4"
>
<div>
<div class="absolute top-[45px] left-[-35px] z-10 text-sm font-medium">Label</div>
<svg
viewBox="0 0 193 40"
width="50"
height="12"
fill="none"
class="absolute top-[50px] left-[5px] z-10"
aria-hidden="true"
>
<path
fill="currentColor"
d="M173.928 21.13C115.811 44.938 58.751 45.773 0 26.141c4.227-4.386 7.82-2.715 10.567-1.88 21.133 5.64 42.9 6.266 64.457 7.101 31.066 1.253 60.441-5.848 89.183-17.335 1.268-.418 2.325-1.253 4.861-2.924-14.582-2.924-29.165 2.089-41.845-3.76.212-.835.212-1.879.423-2.714 9.51-.627 19.231-1.253 28.742-2.089 9.51-.835 18.808-1.88 28.318-2.506 6.974-.418 9.933 2.924 7.397 9.19-3.17 8.145-7.608 15.664-11.623 23.391-.423.836-1.057 1.88-1.902 2.298-2.325.835-4.65 1.044-7.186 1.67-.422-2.088-1.479-4.386-1.268-6.265.423-2.506 1.902-4.595 3.804-9.19Z"
/>
</svg>
<demo-tooltip-card label="Page Views" [payload]="pageViews" class="w-[8rem]" />
</div>
<div class="items-end">
<div class="absolute top-[0px] left-[122px] z-10 text-sm font-medium">Name</div>
<svg
width="35"
height="42"
fill="none"
viewBox="0 0 122 148"
class="absolute top-[10px] left-[85px] z-10 -scale-x-100"
aria-hidden="true"
>
<path
fill="currentColor"
d="M0 2.65c6.15-4.024 12.299-2.753 17.812-.847a115.56 115.56 0 0 1 21.84 10.59C70.4 32.727 88.849 61.744 96.483 97.54c1.908 9.108 2.544 18.639 3.817 29.017 8.481-4.871 12.934-14.402 21.416-19.909 1.061 4.236-1.06 6.989-2.756 9.319-6.998 9.531-14.207 19.062-21.63 28.382-3.604 4.448-6.36 4.871-10.177 1.059-8.058-7.837-12.935-17.368-14.42-28.382 0-.424.636-1.059 1.485-2.118 9.118 2.33 6.997 13.979 14.843 18.215 3.393-14.614.848-28.593-2.969-42.149-4.029-14.19-9.33-27.746-17.812-39.82-8.27-11.86-18.66-21.392-30.11-30.287C26.93 11.758 14.207 6.039 0 2.65Z"
/>
</svg>
<demo-tooltip-card
label="Browser"
hideLabel
indicator="dashed"
[payload]="browsers"
class="w-[8rem]"
/>
</div>
<div class="hidden! md:flex!">
<demo-tooltip-card
label="Page Views"
indicator="line"
[payload]="desktop"
class="w-[9rem]"
/>
</div>
<div class="items-start! justify-start!">
<div class="absolute top-[60px] left-[50px] z-10 text-sm font-medium">Indicator</div>
<demo-tooltip-card
label="Browser"
hideLabel
indicator="dot"
[payload]="chrome"
class="w-[8rem]"
/>
<svg
width="15"
height="34"
fill="none"
viewBox="0 0 75 175"
class="absolute top-[38px] left-[30px] z-10 rotate-[-40deg]"
aria-hidden="true"
>
<path
fill="currentColor"
d="M20.187 175c-4.439-2.109-7.186-2.531-8.032-4.008-3.17-5.484-6.763-10.968-8.454-17.084-5.073-16.242-4.439-32.694-1.057-49.146 5.707-28.053 18.388-52.942 34.24-76.565 1.692-2.531 3.171-5.063 4.862-7.805 0-.21-.211-.632-.634-1.265-4.65 1.265-9.511 2.53-14.161 3.585-2.537.422-5.496.422-8.032-.421-1.48-.422-3.593-2.742-3.593-4.219 0-1.898 1.48-4.218 2.747-5.906 1.057-1.054 2.96-1.265 4.65-1.687C35.406 7.315 48.088 3.729 60.98.776c10.99-2.53 14.584 1.055 13.95 11.812-.634 11.18-.846 22.358-1.268 33.326-.212 3.375-.846 6.96-1.268 10.757-8.878-4.007-8.878-4.007-12.048-38.177C47.03 33.259 38.153 49.289 29.91 65.741 21.667 82.193 16.17 99.49 13.212 117.84c-2.959 18.984.634 36.912 6.975 57.161Z"
/>
</svg>
</div>
</div>
`,
})
export default class ChartTooltipDemo {
protected readonly pageViews: Row[] = [
{ name: 'Desktop', value: 186, fill: 'var(--chart-1)' },
{ name: 'Mobile', value: 80, fill: 'var(--chart-2)' },
];
protected readonly browsers: Row[] = [
{ name: 'Chrome', value: 1286, fill: 'var(--chart-3)' },
{ name: 'Firefox', value: 1000, fill: 'var(--chart-4)' },
];
protected readonly desktop: Row[] = [{ name: 'Desktop', value: 12486, fill: 'var(--chart-3)' }];
protected readonly chrome: Row[] = [{ name: 'Chrome', value: 1286, fill: 'var(--chart-1)' }];
}
Pick the indicator with indicator: dot, line or dashed. Hide parts with hideLabel and hideIndicator. Add [cursor]="false" to drop the band or line under the active row.
<iv-chart-tooltip indicator="line" hideLabel [cursor]="false" />Names come from the config. nameKey and labelKey pick other config entries:
protected readonly data = [
{ browser: 'chrome', visitors: 187, fill: 'var(--color-chrome)' },
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
];
protected readonly config: IvChartConfig = {
visitors: { label: 'Total Visitors' },
chrome: { label: 'Chrome', color: 'var(--chart-1)' },
safari: { label: 'Safari', color: 'var(--chart-2)' },
};<!-- Label "Total Visitors", rows named "Chrome" and "Safari". -->
<iv-chart-tooltip labelKey="visitors" nameKey="browser" />For your own markup, put an ivChartTooltipContent template inside. It gets the rows and the label:
<iv-chart-tooltip hideLabel>
<ng-template ivChartTooltipContent let-payload>
@for (item of payload; track item.key) {
<div class="flex items-center gap-2">
{{ config[item.key]?.label }}
<span class="ml-auto font-mono tabular-nums">{{ item.value }} kcal</span>
</div>
}
</ng-template>
</iv-chart-tooltip>To change only the rows and keep the card and label, use an ivChartTooltipItem template. It replaces the indicator, name and value of each row (Recharts' formatter returning markup):
<iv-chart-tooltip hideLabel>
<ng-template ivChartTooltipItem let-item let-label="label">
{{ label }}
<span class="ml-auto font-mono tabular-nums">{{ item.value }} kcal</span>
</ng-template>
</iv-chart-tooltip>Legend
Put iv-chart-legend inside iv-chart. It shows a swatch, or the config icon, and the label per series. verticalAlign="top" puts it above the chart.
<iv-chart-legend verticalAlign="top" />Like the tooltip, nameKey picks the config entry by a row value, for example a pie's sector names:
<iv-chart-legend nameKey="browser" />API
Every part also accepts class. Boolean inputs take a bare attribute, like shadcn's JSX: <g ivXAxis hide>.
iv-chart
| Name | Type | Default | Description |
|---|---|---|---|
config |
IvChartConfig |
required | Series by key: label, icon, and a color or a theme of light and dark. |
initialDimension |
IvChartSize |
{ width: 320, height: 200 } |
Size used until the container is measured. |
svg[ivLineChart], svg[ivAreaChart], svg[ivBarChart]
| Name | Type | Default | Description |
|---|---|---|---|
data |
IvChartDatum[] |
required | Rows. A null or missing value leaves a gap. |
margin |
IvChartMargin |
5 each side |
Space around the plot. |
stackOffset |
'none' | 'expand' |
'none' |
Area and bar. expand scales each stack to 0–1. |
layout |
'horizontal' | 'vertical' |
'horizontal' |
Bar only. vertical puts categories on Y and draws horizontal bars. |
barGap |
number | string |
4 |
Bar only. Gap between the bars of one category: px or a percent of the band. |
barCategoryGap |
number | string |
'10%' |
Bar only. Gap on each side of a category: px or a percent of the band. |
aria-label |
string |
chart type and series names | Label of the chart (role="img"). Set it as a plain attribute: <svg ivBarChart aria-label="Revenue">. |
g[ivXAxis], g[ivYAxis]
| Name | Type | Default | Description |
|---|---|---|---|
dataKey |
string |
'' |
Row key for category ticks. |
type |
'category' | 'number' |
X 'category', Y 'number' |
Ticks from rows or from the value scale. |
hide |
boolean |
false |
Hide the axis and free its space. |
tickLine |
boolean |
true |
Draw tick marks. |
axisLine |
boolean |
true |
Draw the axis line. |
tickMargin |
number |
8 |
Gap between tick and label. |
tickFormatter |
(value, index) => string |
— | Formats a tick label. |
minTickGap |
number |
5 |
Category axis. Hides a tick whose label would be closer than this to the next shown one. The last tick stays. Label width is estimated (12px text). |
tickCount |
number |
5 |
Number axis. About how many value ticks; the grid follows it. |
height |
number |
30 |
X only. Space for the labels. |
width |
number |
60 |
Y only. Space for the labels. |
g[ivCartesianGrid]
| Name | Type | Default | Description |
|---|---|---|---|
vertical |
boolean |
true |
Lines at each category. |
horizontal |
boolean |
true |
Lines at each value tick. |
g[ivLine], g[ivArea]
| Name | Type | Default | Description |
|---|---|---|---|
dataKey |
string |
required | Row key of the values. Color: var(--color-<dataKey>). |
curve |
'linear' | 'natural' | 'step' | 'monotone' | 'bump' |
'linear' |
Curve type. |
stroke |
string |
series color | Line color. |
strokeWidth |
number |
line 2, area 1 |
Line width. |
dot |
boolean | IvDotProps | TemplateRef<IvDotContext> |
line true, area false |
Dots; circle props (r, fill, stroke, strokeWidth) over the default (r 3, background fill, series stroke); or a template given IvDot. |
activeDot |
boolean | IvDotProps |
true |
Dot at the active row; circle props over the default (r 4, series fill, background stroke). |
fill |
string |
series color | Area only. |
fillOpacity |
number |
0.6 |
Area only, as in Recharts. |
stackId |
string |
— | Area only. Areas with the same id stack, in markup order. |
g[ivBar]
| Name | Type | Default | Description |
|---|---|---|---|
dataKey |
string |
required | Row key of the values. Color: var(--color-<dataKey>). A row's own fill colors its bar. |
stackId |
string |
— | Bars with the same id stack, in markup order. Others sit side by side. |
radius |
number | [number, number, number, number] |
0 |
Corner radius, or [topLeft, topRight, bottomRight, bottomLeft]. The top is the bar's tip. |
fill |
string |
series color | Bar color. |
activeIndex |
number |
— | The highlighted bar (data-active, or the ivActiveShape template). Default: the bars under the cursor. |
g[ivLabelList]
Put it inside g[ivBar], g[ivLine], g[ivArea], g[ivPie], g[ivRadialBar] or g[ivRadar].
| Name | Type | Default | Description |
|---|---|---|---|
dataKey |
string |
series key | Row key of the label text. |
position |
'top' | 'inside' | 'insideLeft' | 'right' | 'outside' | 'insideStart' |
'top' |
Where the label sits. A negative bar's top is its tip. On a sector, outside is beyond the outer radius. On a radial bar, insideStart runs the text along the ring from the bar's start. Any other value on a sector is the centroid. |
offset |
number |
5 (px, or degrees for insideStart) |
Distance from the item. |
formatter |
(value) => string |
— | Formats the label. |
svg[ivPieChart], svg[ivRadarChart], svg[ivRadialChart]
Angles are degrees, as in Recharts: 0 is 3 o'clock, positive is counter-clockwise.
| Name | Type | Default | Description |
|---|---|---|---|
data |
IvChartDatum[] |
[] |
Rows. A pie may bring its own. |
startAngle |
number |
radar 90, others 0 |
Where the sweep starts. |
endAngle |
number |
radar -270, others 360 |
Where the sweep ends. The radar default goes clockwise from the top. |
innerRadius |
number | string |
0 |
px or a percent of half the smaller side. |
outerRadius |
number | string |
'80%' |
px or a percent of half the smaller side. |
margin |
IvChartMargin |
5 each side |
Space around the chart. The center and radii fit the box left. Negative values grow the chart. |
aria-label |
string |
chart type and series names | Label of the chart (role="img"). Set it as a plain attribute: <svg ivPieChart aria-label="Browser share">. |
g[ivPie]
| Name | Type | Default | Description |
|---|---|---|---|
data |
IvChartDatum[] |
chart data |
Rows of this pie. |
dataKey |
string |
required | Row key of the values. A null value skips the row. All 0 draws nothing. |
nameKey |
string |
'name' |
Row key of the sector name. Color: the row's fill, else var(--color-<name>). |
innerRadius |
number | string |
chart's | Over 0 makes a donut. |
outerRadius |
number | string |
chart's | Several pies with different radii make rings. |
paddingAngle |
number |
0 |
Degrees between sectors. |
stroke |
string |
none | Sector outline. |
strokeWidth |
number |
1 |
Outline width. |
activeIndex |
number |
— | The highlighted sector (data-active, or the ivActiveShape template). Default: the sector under the cursor, in this ring. |
label |
boolean | TemplateRef<IvPieLabelContext> |
false |
Values outside the sectors, or a template given IvPieLabel. |
labelLine |
boolean |
true |
A line from each sector to its label. |
ng-template[ivChartLabel]
Center content, rendered in the SVG. Put it inside g[ivPie], g[ivRadialBar] or g[ivPolarRadiusAxis]. The context is { cx, cy, innerRadius, outerRadius }: let-box for all, let-cx="cx" for one.
g[ivPolarGrid]
| Name | Type | Default | Description |
|---|---|---|---|
gridType |
'polygon' | 'circle' |
'polygon' |
Ring shape. |
radialLines |
boolean |
true |
A spoke per angle tick. |
polarRadius |
number[] |
radius ticks | Ring radii in px. |
stroke |
string |
theme border | Line color. |
class goes on each ring and spoke, as in Recharts, so first:fill-muted works on the rings. Spokes draw over the rings.
g[ivPolarAngleAxis]
| Name | Type | Default | Description |
|---|---|---|---|
dataKey |
string |
'' |
Row key of the labels around the outside. |
tick |
boolean | TemplateRef<IvPolarAngleTickContext> |
true |
Labels, or a template given IvPolarAngleTick. |
tickFormatter |
(value, index) => string |
— | Formats a label. |
g[ivPolarRadiusAxis]
| Name | Type | Default | Description |
|---|---|---|---|
dataKey |
string |
'' |
Radial charts: row key of the ring labels. |
tick |
boolean |
false |
Value labels along the spoke. |
axisLine |
boolean |
false |
The spoke line. |
angle |
number |
0 |
The spoke's angle. |
orientation |
'left' | 'right' | 'middle' |
'right' |
Label side. |
stroke |
string |
muted | Axis line and tick text color, as in Recharts. |
domain |
[number, number] |
0 to the largest value | Radar: a fixed value range. |
tickFormatter |
(value, index) => string |
— | Formats a label. |
g[ivRadar]
| Name | Type | Default | Description |
|---|---|---|---|
dataKey |
string |
required | Row key of the values. A null value leaves the vertex out. |
fill |
string |
series color | Fill color. |
fillOpacity |
number |
1 |
Fill opacity, as in Recharts. |
stroke |
string |
none | Outline color. |
strokeWidth |
number |
— | Outline width. |
dot |
boolean | TemplateRef<IvDotContext> |
false |
Dots on the vertices, or a template given IvDot. |
activeDot |
boolean |
true |
Dot at the active row's vertex. |
g[ivRadialBar]
| Name | Type | Default | Description |
|---|---|---|---|
dataKey |
string |
required | Row key of the values. A ring per row, from the inside out. The largest value fills the sweep. |
background |
boolean |
false |
A muted track over the whole sweep. |
cornerRadius |
number |
0 |
Rounds the bar ends. |
stackId |
string |
— | Bars with the same id share a ring and stack. |
fill |
string |
series color | Bar color. A row's own fill wins. |
iv-chart-tooltip
Put it inside iv-chart. It opens on the active row: the pointer (hover, or a tap on touch), the keyboard, or defaultIndex. Labels, icons and colors come from the config.
| Name | Type | Default | Description |
|---|---|---|---|
indicator |
'dot' | 'line' | 'dashed' |
'dot' |
Indicator shape. With one row, line and dashed move the label into the row. |
hideLabel |
boolean |
false |
Hide the label (the category, or the config label of the series). |
hideIndicator |
boolean |
false |
Hide the indicators. |
nameKey |
string |
— | Row key whose string value names each row's config entry (a pie's sector names). |
labelKey |
string |
— | Config key of the label. |
labelFormatter |
(label, payload) => string |
— | Formats the label. |
formatter |
(value, name, item, index) => string |
— | Replaces each row with text. For markup, use ivChartTooltipItem. |
cursor |
boolean |
true |
A muted band (bar), line (line, area) or spoke (radar) under the active row. |
defaultIndex |
number |
— | Opens on this row at start. Rendered on the server too. |
class goes on the cn-chart-tooltip card. The tooltip sits 10px past the pointer, on the side with more room, inside the chart box.
ng-template[ivChartTooltipContent]
A custom tooltip body inside the card. The context is the rows ($implicit: IvChartPayload[]) and label, the category value: let-payload let-label="label".
ng-template[ivChartTooltipItem]
A custom row, inside the row's flex box. It replaces the indicator, name and value. Rows with no value or name keep the default. The context (IvChartTooltipItemContext):
| Name | Type | Description |
|---|---|---|
$implicit |
IvChartPayload |
The row: key, name, value, color, row (the data row). |
value |
unknown |
The row's value. |
name |
string |
The series key (a pie: the sector name). |
label |
string |
The config label, or name. |
color |
string |
The indicator color. |
index |
number |
The row's position. |
payload |
IvChartPayload[] |
All rows, e.g. for a total after the last one. |
iv-chart-legend
Put it inside iv-chart. A swatch, or the config icon, and the config label per series (per sector on a pie). The chart leaves room for it.
| Name | Type | Default | Description |
|---|---|---|---|
verticalAlign |
'top' | 'bottom' |
'bottom' |
Above or under the chart. |
hideIcon |
boolean |
false |
Show the swatch even when the config has an icon. |
nameKey |
string |
— | Row key whose string value names each item's config entry (a pie's sector names). |
ng-template[ivActiveShape]
Draws the active item instead of its default shape, inside g[ivBar] or g[ivPie]. The active item is activeIndex, or the one under the cursor. let-shape gives IvActiveShapeProps: the item, d (its default path) and, on a pie, the sector (cx, cy, radii, angles) for ivArc.
<g ivPie dataKey="visitors" nameKey="browser" [innerRadius]="60" [activeIndex]="0">
<ng-template ivActiveShape let-shape>
<svg:path [attr.d]="grow(shape)" [attr.fill]="shape.fill" />
</ng-template>
</g>grow = (shape: IvSectorShape) => ivArc({ ...shape, outerRadius: shape.outerRadius + 10 });Accessibility
The container has no role. Chart roots are role="img" with an aria-label (default: the chart type and series names). Set your own with the plain aria-label attribute on the root.
Each chart root is one tab stop (tabindex="0"), like Recharts' accessibilityLayer. Keyboard focus shows a ring (focus-visible:outline-ring/50).
| Key | Action |
|---|---|
| ArrowRight / ArrowLeft | Next / previous row. Wraps. Vertical bar charts and polar charts use ArrowDown / ArrowUp. |
| Home / End | First / last row. |
| Escape | Hide the tooltip. Works while the chart has focus. |
While the chart has focus, the tooltip is an aria-live="polite" region, so the row is read out.