@pxch/pixi-charts
v0.1.0
Published
GPU-accelerated chart library built on PixiJS
Downloads
10
Maintainers
Readme
@pxch/pixi-charts
GPU-accelerated chart library built on PixiJS v8.
Features
- GPU-accelerated rendering -- WebGL2/WebGPU via PixiJS v8
- Pie and donut charts with configurable slices, labels, and legends
- Smooth animations -- sweep/fade entry animations, data transitions
- Interactive -- hover tooltips, click selection with typed events
- Configurable theming -- colors, typography, spacing (Tableau 10 default palette)
- Framework-agnostic imperative API -- works with any framework or vanilla JS
- Angular 19+ components -- standalone signal-based wrappers
- Full TypeScript support with type declarations for all exports
- Tree-shakeable ESM output -- import only what you need
Installation
npm install @pxch/pixi-charts pixi.jspixi.js is a peer dependency and must be installed alongside the library.
Quick Start (Imperative API)
<div id="chart" style="width: 400px; height: 400px;"></div>import { createPieChart } from '@pxch/pixi-charts';
const chart = await createPieChart(document.getElementById('chart')!, {
data: [
{ value: 30, label: 'Chrome' },
{ value: 25, label: 'Firefox' },
{ value: 20, label: 'Safari' },
{ value: 15, label: 'Edge' },
{ value: 10, label: 'Other' },
],
legend: { position: 'bottom' },
});
// Update data reactively
chart.update({
data: [
{ value: 40, label: 'Chrome' },
{ value: 30, label: 'Firefox' },
{ value: 30, label: 'Safari' },
],
});
// Listen for events
chart.on('select', (e) => console.log('Selected:', e));
// Clean up when done
chart.destroy();The createPieChart function returns a Promise<PieChartHandle> with these methods:
| Method | Description |
| --------------------- | ---------------------------------------- |
| update(options) | Update data and/or options |
| destroy() | Destroy the chart, release GPU resources |
| getTheme() | Get a copy of the current resolved theme |
| setTheme(theme) | Set a new theme (merges with defaults) |
| getCanvas() | Get the underlying canvas element |
| on(event, handler) | Subscribe to a chart event |
| off(event, handler) | Unsubscribe from a chart event |
Donut Chart
import { createDonutChart } from '@pxch/pixi-charts';
const chart = await createDonutChart(document.getElementById('chart')!, {
data: [
{ value: 60, label: 'Used' },
{ value: 40, label: 'Free' },
],
});createDonutChart is a convenience wrapper that sets innerRadius to 0.6 (60% of the outer radius) by default. You can override it:
const chart = await createPieChart(container, {
data: myData,
innerRadius: 0.5, // custom inner radius ratio
});Values between 0 and 1 are treated as a proportion of the outer radius. Values >= 1 are treated as absolute pixels.
Quick Start (Angular)
Requires @angular/core >= 19.0.0. The Angular wrappers are standalone signal-based components.
import { PixiPieChartComponent } from '@pxch/pixi-charts/angular';
import { PixiDonutChartComponent } from '@pxch/pixi-charts/angular';@Component({
selector: 'app-dashboard',
standalone: true,
imports: [PixiPieChartComponent],
template: `
<pixi-pie-chart
[data]="chartData"
[options]="chartOptions"
[width]="'400px'"
[height]="'400px'"
(select)="onSliceSelect($event)"
(hover)="onSliceHover($event)"
/>
`,
})
export class DashboardComponent {
chartData: SliceData[] = [
{ value: 30, label: 'Chrome' },
{ value: 25, label: 'Firefox' },
{ value: 20, label: 'Safari' },
];
chartOptions = {
legend: { position: 'bottom' as const },
theme: { colors: { palette: [0x4e79a7, 0xf28e2b, 0xe15759] } },
};
onSliceSelect(event: SelectEvent) {
console.log('Selected slice:', event);
}
onSliceHover(event: HoverEvent) {
console.log('Hovered slice:', event);
}
}Angular Component Inputs
| Input | Type | Default | Description |
| --------- | -------------------------------- | -------- | ------------------------ |
| data | SliceData[] | required | Chart slice data |
| options | Partial<PieChartCreateOptions> | {} | Chart configuration |
| width | string | '100%' | CSS width of container |
| height | string | '100%' | CSS height of container |
Angular Component Outputs
| Output | Type | Description |
| ----------- | ----------------- | ----------------------------- |
| select | SelectEvent | Slice selected |
| hover | HoverEvent | Slice hovered |
| rendered | RenderedEvent | Chart finished initial render |
| destroyed | DestroyedEvent | Chart destroyed |
| error | ChartErrorEvent | Chart encountered an error |
Theming
Charts use the Tableau 10 palette by default. Customize by passing a theme object:
import { createPieChart } from '@pxch/pixi-charts';
const chart = await createPieChart(container, {
data: myData,
theme: {
colors: {
palette: [0x1f77b4, 0xff7f0e, 0x2ca02c, 0xd62728],
background: 0xf5f5f5,
text: 0x333333,
textMuted: 0x999999,
},
typography: {
fontFamily: 'Inter, sans-serif',
labelFontSize: 12,
titleFontSize: 18,
},
spacing: {
chartPadding: 20,
legendItemGap: 8,
legendGap: 16,
tooltipPadding: 8,
},
},
});Use mergeTheme for partial overrides on top of defaults:
import { mergeTheme, defaultTheme } from '@pxch/pixi-charts/themes';
const myTheme = mergeTheme(defaultTheme, {
colors: { palette: [0x1f77b4, 0xff7f0e, 0x2ca02c] },
typography: { fontFamily: 'Inter, sans-serif' },
});You can also update the theme at runtime:
chart.setTheme({
colors: { palette: [0xe15759, 0x76b7b2, 0x59a14f] },
});Labels
Configure labels with the labels option:
const chart = await createPieChart(container, {
data: myData,
labels: {
position: 'outside', // 'inside' | 'outside' | 'auto'
formatter: (data) => `${data.label}: ${data.percentage}%`,
},
});Labels are enabled by default. Disable them with labels: false.
Position modes:
'inside'-- Labels rendered inside slices at 70% from inner to outer radius'outside'-- Labels rendered outside with leader lines'auto'(default) -- Inside for large slices, outside for small slices (< 15 degrees)
HTML label templates are also supported:
labels: {
position: 'outside',
htmlTemplate: '<b>{{label}}</b>: {{percentage}}%',
}Template variables: {{value}}, {{percentage}}, {{label}}, {{index}}.
Legend
Enable the legend by providing a position:
const chart = await createPieChart(container, {
data: myData,
legend: {
position: 'bottom', // 'top' | 'bottom' | 'left' | 'right'
},
});The legend is interactive -- click an entry to select its slice, hover to highlight.
Events
Subscribe to typed events using on() and off():
// Slice selection
chart.on('select', (e: SelectEvent) => {
// e.index, e.data, e.selected, e.position
console.log(`Slice ${e.index} ${e.selected ? 'selected' : 'deselected'}`);
});
// Slice hover
chart.on('hover', (e: HoverEvent) => {
// e.index, e.data, e.hovering
console.log(`Hovering slice ${e.index}`);
});
// Lifecycle events
chart.on('rendered', () => console.log('Chart rendered'));
chart.on('destroyed', () => console.log('Chart destroyed'));
chart.on('error', (e) => console.error('Chart error:', e.message));
// Unsubscribe
const handler = (e: SelectEvent) => { /* ... */ };
chart.on('select', handler);
chart.off('select', handler);Architecture
+------------------------------------------------------------------+
| @pxch/pixi-charts |
| |
| +-------------------+ +-----------------------------------+ |
| | Angular Layer | | Imperative API | |
| | | | | |
| | PixiPieChartComp |--->| createPieChart(container, opts) | |
| | PixiDonutChartComp|--->| createDonutChart(container, opts) | |
| | (signal I/O) | | => PieChartHandle | |
| +-------------------+ +-----------------------------------+ |
| | |
| v |
| +------------------------------------------------------------+ |
| | Core Engine | |
| | | |
| | ChartRenderer PieChart EventBus | |
| | (PixiJS v8 app) (slice geometry) (typed pub/sub) | |
| +------------------------------------------------------------+ |
| | | |
| +------------+--------------+-------------+ |
| v v v v |
| +-----------+ +------------+ +-----------+ +-----------+ |
| | Theming | | Animation | |Interaction| | Labels | |
| | | | | | | | | |
| | colors | | sweep/fade | | hover mgr | | inside/ | |
| | typo | | transitions| | selection | | outside | |
| | spacing | | easing | | tooltips | | HTML tmpl | |
| +-----------+ +------------+ +-----------+ +-----------+ |
| | |
| v |
| +--------------+ |
| | Legend | |
| | interactive | |
| | hover/click | |
| +--------------+ |
| |
+------------------------------------------------------------------+
|
v
+-------------------+
| PixiJS v8 |
| WebGL2 / WebGPU |
+-------------------+The Angular layer is a thin wrapper around the imperative API. All rendering logic lives in the framework-agnostic core. Angular components use NgZone.runOutsideAngular to prevent PixiJS's requestAnimationFrame loop from triggering change detection.
Subpath Exports
Import from granular subpaths for tree-shaking or direct access:
| Import Path | Contents |
| ---------------------------------- | ----------------------------------------- |
| @pxch/pixi-charts | Core API: createPieChart, createDonutChart, types, utilities |
| @pxch/pixi-charts/angular | Angular components: PixiPieChartComponent, PixiDonutChartComponent |
| @pxch/pixi-charts/themes | Theme types, defaultTheme, mergeTheme |
| @pxch/pixi-charts/animation | Animation engine, easing functions, types |
| @pxch/pixi-charts/interactions | Hover manager, selection manager, types |
| @pxch/pixi-charts/legend | Legend renderer and types |
| @pxch/pixi-charts/tooltips | Tooltip renderer and types |
TypeScript
All types are exported. Configure your tsconfig.json with one of these module resolution strategies:
{
"compilerOptions": {
"moduleResolution": "bundler"
}
}Or use "node16" / "nodenext". Both correctly resolve the exports field in package.json.
Key types available from the root import:
import type {
SliceData,
PieChartHandle,
PieChartCreateOptions,
ChartEventMap,
SelectEvent,
HoverEvent,
Theme,
DeepPartial,
} from '@pxch/pixi-charts';Browser Support
Requires a modern browser with WebGL2 or WebGPU support:
- Chrome 56+
- Firefox 51+
- Safari 15+
- Edge 79+
No SSR support. The library requires a browser context (DOM + WebGL/WebGPU). For server-rendered applications, load the chart component lazily on the client side.
Peer Dependencies
| Package | Version | Required |
| --------------- | ---------- | -------- |
| pixi.js | ^8.15.0 | Yes |
| @angular/core | >=19.0.0 | No (only for Angular components) |
