It can handle line, area, bar, bubble, radar, pie, and donut charts from plain arrays, records, multi-series data, or x/y points.
The distinctive part appears when the data changes. Existing particles move into their new positions, which turns a normal chart update into a morph between datasets and chart shapes.
Features
- Line, area, bar, bubble, radar, pie, and donut rendering.
- Particle morphs between data updates and chart shapes.
- Grouped, stacked, and horizontal bar layouts.
- Multi-series data and continuous numeric axes.
- Bubble sizing from a third data dimension.
- Responsive Canvas2D rendering with HiDPI handling.
- Tooltips, crosshairs, axes, legends, and value labels.
- Dark and light chart themes.
- Screen-reader data tables and keyboard legend controls.
- CDN, ES module, CommonJS, and TypeScript distribution.
See It In Action
How To Use It
Installation
Load the browser build directly in your HTML page:
<script src="https://cdn.jsdelivr.net/npm/particle-charts@1/dist/particle-charts.min.js"></script>
Or install and import it via NPM:
npm install particle-charts
import { ParticleChart } from 'particle-charts';
CommonJS is available through the package entry:
const { ParticleChart } = require('particle-charts');
Basic Usage
Create a chart container.
<div id="salesChart" style="height: 320px"></div>
Create a new ParticleChart instance, specify the chart type and prepare your data. All available chart types:
* `line` for smooth, linear, or stepped lines.
* `area` for a particle-filled line chart.
* `bar` for grouped, stacked, or horizontal bars.
* `bubble` for x/y points with optional size values.
* `radar` for multi-axis polygon charts.
* `pie` for part-to-whole data.
* `donut` for a pie chart with a center opening.
<script>
const chart = new ParticleCharts.ParticleChart('#salesChart', {
type: 'bar',
data: {
labels: ['Q1', 'Q2', 'Q3', 'Q4'],
values: [38, 52, 47, 69]
}
});
</script>
Data Formats
A plain array is enough for a basic single-series chart:
const data = [8, 13, 11, 20, 18, 27];
Labels and values can use several structures:
const labeledPoints = [
{ label: 'Jan', value: 8 },
{ label: 'Feb', value: 13 },
{ label: 'Mar', value: 11 }
];
const labeledValues = {
labels: ['Jan', 'Feb', 'Mar'],
values: [8, 13, 11]
};
const trafficSources = {
Organic: 54,
Referral: 28,
Paid: 18
};
Multi-series charts share labels:
const data = {
labels: ['Q1', 'Q2', 'Q3', 'Q4'],
series: [
{
name: 'Revenue',
data: [44, 57, 61, 76],
color: '#3987e5'
},
{
name: 'Costs',
data: [31, 36, 43, 49]
}
]
};
Line and bubble charts also accept numeric x/y coordinates:
const data = {
series: [
{
name: 'Latency',
data: [
{ x: 0, y: 18 },
{ x: 5, y: 24 },
{ x: 12, y: 21 }
]
}
]
};
Bubble charts read a third value for mark size:
const data = {
series: [
{
name: 'Markets',
data: [
{ x: 12, y: 34, r: 16 },
{ x: 27, y: 49, r: 38 },
{ x: 41, y: 28, r: 25 }
]
}
]
};
Chart Helpers
Module builds expose shorthand functions for each primary chart type:
import { donut } from 'particle-charts';
const chart = donut('#trafficChart', {
Direct: 4820,
Search: 3140,
Referral: 1270
});
Update Data
Call update() when the dataset changes. Existing particles receive new destinations and move into the new chart geometry.
chart.update({
labels: ['Jan', 'Feb', 'Mar', 'Apr'],
values: [22, 31, 29, 44]
});
The second argument changes configuration during the update:
chart.update(
{
labels: ['Jan', 'Feb', 'Mar', 'Apr'],
values: [22, 31, 29, 44]
},
{
type: 'area'
}
);
Light And Dark Themes
Switch the chart chrome with theme:
chart.setOptions({
theme: 'light',
particleBloom: 0.15,
particleOpacity: 0.9
});
A page that follows the operating system preference can update the chart when the color scheme changes:
const media = matchMedia('(prefers-color-scheme: light)');
function syncChartTheme() {
chart.setOptions({
theme: media.matches ? 'light' : 'dark'
});
}
media.addEventListener('change', syncChartTheme);
syncChartTheme();
All Configuration Options
Core Options
type(string): Chart type. Default isline.column,scatter, andspiderare aliases.data(ChartData): Chart data in one of the accepted input structures.theme(dark | light): Chart chrome theme. Default isdark.background(string): Canvas background fill. Default istransparent.padding(number | array | object | null): Plot padding. Default is automatic measurement.responsive(boolean): Recalculates the layout after container size changes. Default istrue.maxDpr(number): Caps the HiDPI backing-store ratio. Default is2.pauseWhenHidden(boolean): Stops the render loop when the tab hides or the chart leaves the viewport. Default istrue.animate(boolean): Controls the entrance animation. Default istrue.duration(number): Entrance duration in milliseconds. Default is1100.stagger(number): Spreads entrance timing across particles from0to1. Default is0.5.showAxis(boolean): Shows the chart axes. Default istrue.showGrid(boolean): Shows grid lines. Default istrue.showLegend(boolean): Shows the legend when applicable. Default istrue.showTooltip(boolean): Shows hover tooltips and crosshairs. Default istrue.showValues(boolean): Prints values beside applicable marks. Default isfalse.
Particle Options
particle.color(string | string[] | function | null): Particle colors. Default uses the built-in palette.particle.size(number): Base particle radius in CSS pixels. Default is0.8.particle.sizeJitter(number): Random size variation from0to1. Default is0.particle.density(number): Multiplier for the calculated particle budget. Default is15.particle.max(number): Hard particle-count ceiling. Default is50000.particle.bloom(number): Additive glow strength from0to1. Default is0.8.particle.bloomRadius(number): Bloom blur radius in CSS pixels. Default is14.particle.opacity(number): Global particle alpha. Default is0.7.particle.jitter(number): Idle drift amplitude in pixels. Default is1.particle.jitterSpeed(number): Idle drift speed. Default is1.particle.speed(number): Spring stiffness toward each particle destination. Default is0.085.particle.damping(number): Motion damping. Default is0.78.particle.shape(soft | dot | square): Particle rendering style. Default issoft.
Axis Options
axis.color(string): Axis line color.axis.gridColor(string): Grid line color.axis.textColor(string): Tick and axis-title color.axis.crosshairColor(string): Hover crosshair color.axis.fontFamily(string): Font used for chart labels.axis.fontSize(number): Axis label size. Default is11.axis.ticks(number): Approximate y-axis tick count. Default is5.axis.grid(boolean): Shows y-axis grid lines. Default istrue.axis.xGrid(boolean): Shows x-axis grid lines. Default isfalse.axis.xLabels(boolean): Shows x-axis labels. Default istrue.axis.yLabels(boolean): Shows y-axis labels. Default istrue.axis.beginAtZero(boolean): Includes zero in the value domain. Default istrue.axis.min(number | null): Fixed minimum value. Default is automatic.axis.max(number | null): Fixed maximum value. Default is automatic.axis.format(function | null): Formats value-axis labels and tooltip values.axis.xTitle(string): X-axis title. Default is empty.axis.yTitle(string): Y-axis title. Default is empty.
Bubble charts change axis.beginAtZero to false and axis.xGrid to true unless those values are set explicitly.
Legend Options
legend.position(top | bottom | left | right): Legend position.legend.align(start | center | end): Legend alignment.legend.interactive(boolean): Lets legend controls mute and restore a series. Default istrue.legend.markerSize(number): Legend marker size. Default is8.legend.fontSize(number): Legend text size. Default is12.legend.color(string): Legend text color.
Line, area, bar, bubble, and radar charts place the legend at the bottom and center it by default. Pie and donut charts retain the top/start defaults.
Tooltip Options
tooltip.format(function | null): Returns custom tooltip HTML.tooltip.background(string): Tooltip background.tooltip.color(string): Tooltip text color.tooltip.borderColor(string): Tooltip border color.
Line And Area Options
line.curve(smooth | linear | step): Line interpolation. Default issmooth.line.width(number): Particle stroke width. Default is3.2.line.area(boolean): Fills the region beneath the line. Default isfalse.line.areaAmount(number): Particle share assigned to the area fill. Default is0.55.line.areaFade(number): Concentrates fill particles near the line. Default is0.9.line.points(boolean): Shows particle clusters at data points. Default istrue.line.pointRadius(number): Point-cluster radius. Default is4.5.
Bar Options
bar.padding(number): Gap between categories. Default is0.3.bar.groupPadding(number): Gap between bars inside a group. Default is0.16.bar.stacked(boolean): Stacks multiple series. Default isfalse.bar.horizontal(boolean): Draws horizontal bars. Default isfalse.bar.fade(number): Thins particle density toward the growing end. Default is0.45.bar.radius(number): Rounded cap radius. Default is4.
Bubble Options
bubble.minRadius(number): Smallest bubble radius. Default is5.bubble.maxRadius(number): Largest bubble radius. Default is30.bubble.edgeFade(number): Feathers the bubble rim. Default is0.35.bubble.minValue(number | null): Fixed lower end of the size domain.bubble.maxValue(number | null): Fixed upper end of the size domain.bubble.outline(boolean): Draws a ring behind every bubble. Default isfalse.
Radar Options
radar.levels(number): Number of web rings. Default is4.radar.shape(polygon | circle): Web-ring shape. Default ispolygon.radar.width(number): Particle outline width. Default is2.6.radar.fill(boolean): Fills the radar polygon. Default istrue.radar.fillAmount(number): Particle share assigned to the fill. Default is0.55.radar.fillFade(number): Thins the fill toward the center. Default is0.55.radar.points(boolean): Shows vertex particle clusters. Default istrue.radar.pointRadius(number): Vertex-cluster radius. Default is4.radar.startAngle(number): First spoke angle in degrees. Default is-90.
Pie And Donut Options
pie.innerRadius(number): Hole size as a fraction of the outer radius. Pie defaults to0.pie.startAngle(number): First slice angle in degrees. Default is-90.pie.padAngle(number): Slice gap in degrees. Default is1.2.pie.radius(number): Chart radius relative to available plot space. Default is0.95.pie.edgeFade(number): Feathers the outer edge. Default is0.25.pie.labels(percent | value | label | none): Label content when values are shown. Default ispercent.pie.center(auto | total | none | string): Controls donut center content.
Flat Option Aliases
particleColor→particle.color.particleSize→particle.size.particleDensity→particle.density.particleCount→particle.max.particleBloom→particle.bloom.particleOpacity→particle.opacity.particleJitter→particle.jitter.particleSpeed→particle.speed.particleShape→particle.shape.colors→particle.color.curve→line.curve.fillArea→line.area.lineWidth→line.width.showPoints→line.points.stacked→bar.stacked.horizontal→bar.horizontal.barPadding→bar.padding.minRadius→bubble.minRadius.maxRadius→bubble.maxRadius.levels→radar.levels.webShape→radar.shape.innerRadius→pie.innerRadius.startAngle→pie.startAngle.padAngle→pie.padAngle.legendPosition→legend.position.legendAlign→legend.align.min→axis.min.max→axis.max.beginAtZero→axis.beginAtZero.valueFormat→axis.format.format→axis.format.ticks→axis.ticks.xTitle→axis.xTitle.yTitle→axis.yTitle.fontFamily→axis.fontFamily.textColor→axis.textColor.axisColor→axis.color.gridColor→axis.gridColor.crosshairColor→axis.crosshairColor.
API Methods
// Replace the data and optionally change configuration.
chart.update(nextData, options);
// Change configuration while keeping the current data.
chart.setOptions({
theme: 'light'
});
// Recalculate the layout.
chart.resize();
// Mute or restore a series or radial slice.
chart.toggleSeries('Revenue');
// Pause the render loop.
chart.stop();
// Resume the render loop.
chart.start();
// Export the current frame.
const png = chart.toDataURL();
// Export another image format or quality.
const jpeg = chart.toDataURL('image/jpeg', 0.9);
// Remove the chart, listeners, and render loop.
chart.destroy();
Alternatives
- Modern Canvas JavaScript Charting Library – MyChart.js
- Lightweight Performant Canvas Charting Library – Chartie
- GPU-Powered WebGL Canvas Chart Library for JavaScript – WebGL Chart
- Responsive & Animated Chart JavaScript Library – RGraph
FAQs
Q: Why is my Particle Charts chart blank?
A: Check the container height first. The chart needs a measurable height before it can calculate its plot area.
Q: How can I reduce the rendering workload?
A: Lower particleDensity, set an appropriate particleCount ceiling, or use particleJitter: 0 for charts that do not need continuous idle movement.
The post Particle Charts: Animated Canvas Charts Made of Particles appeared first on CSS Script.
Discover more from RSS Feeds Cloud
Subscribe to get the latest posts sent to your email.
