Lightweight, data-driven chart library for the web.
Zero dependencies. Single <script> tag. ~195 KB minified.
- 19 Chart Types β Line, Bar, Area, Spline, Area-Spline, Pie, Donut, Scatter, Radar, Gauge, Candlestick, Funnel, Heatmap, Waterfall, Bubble, Treemap, BoxPlot, Polar, Horizontal Bar
- Mixed/Combo Charts β Combine different chart types (line + bar, area + spline, etc.) in one chart
- Data-Driven β Auto-detect data types from JSON, CSV, or API URL
- Zero Dependencies β Pure vanilla JavaScript, no npm required
- Plug & Play β Single
<script>tag, no build tools needed - Smart Colors β 20 maximally distinct palette colors + golden angle algorithm for unlimited series
- Smart Numbers β Auto-abbreviation (K/M/B/T) with locale support (Indonesian: rb/jt/M/T)
- Interactive β Tooltips with arrow + 4-way auto-positioning, crosshair, legend toggle, zoom/pan, click events
- Responsive β Auto-resize with ResizeObserver + HiDPI/Retina support
- Animated β Smooth entry animations with data points following the line
- Themeable β Built-in light/dark themes + custom theming
- Plugin System β Extensible lifecycle hooks for custom features
- Export β Save chart as PNG/JPEG image
<script src="dist/cz-chart.js"></script><div id="myChart" style="width:600px; height:400px;"></div>
<script>
czChart.create('#myChart', {
type: 'line',
data: [
{ month: 'Jan', revenue: 4200, cost: 2800 },
{ month: 'Feb', revenue: 5100, cost: 3200 },
{ month: 'Mar', revenue: 4800, cost: 2900 },
{ month: 'Apr', revenue: 6300, cost: 3500 }
],
x: 'month',
y: ['revenue', 'cost']
});
</script>That's it! czChart will:
- β
Auto-detect
monthas X-axis (category) - β
Create 2 series from
revenueandcost - β Assign distinct colors automatically
- β Render with smooth animation (points follow the line)
- β Show tooltip with arrow on hover
- β Format numbers smartly (5000 β 5K)
czChart.create('#chart', {
type: 'line',
data: [...],
x: 'date',
y: ['revenue', 'cost'],
series: { smooth: true, pointRadius: 3 }
});// Line with smooth curves (c3.js compatible)
czChart.create('#chart', {
type: 'spline',
data: [...],
x: 'month',
y: ['sales', 'target']
});czChart.create('#chart', {
type: 'area', // Line with gradient fill, supports negative values
data: [...],
series: { smooth: true }
});// Area with smooth curves
czChart.create('#chart', {
type: 'area-spline',
data: [...],
x: 'date',
y: ['pageviews', 'sessions']
});czChart.create('#chart', {
type: 'bar',
data: [...],
x: 'quarter',
y: ['north', 'south'],
bar: { borderRadius: 6, gap: 0.25 }
});czChart.create('#chart', {
type: 'horizontalBar',
data: [...],
x: 'department',
y: 'headcount'
});// Pie
czChart.create('#chart', { type: 'pie', data: [...] });
// Donut (pie with inner radius)
czChart.create('#chart', { type: 'donut', data: [...] });czChart.create('#chart', {
type: 'scatter',
data: [...],
x: 'height',
y: 'weight',
scatter: { pointRadius: 6, pointShape: 'circle' }
});czChart.create('#chart', {
type: 'bubble',
data: [...],
x: 'gdp',
y: 'lifeExpectancy',
size: 'population'
});czChart.create('#chart', {
type: 'radar',
data: [...],
x: 'skill',
y: ['player_a', 'player_b'],
radar: { gridType: 'polygon', fillOpacity: 0.2 }
});// Speedometer-style with needle, ticks, and colored zones
czChart.create('#chart', {
type: 'gauge',
data: [{ value: 72 }],
gauge: { min: 0, max: 100, zones: [
{ min: 0, max: 50, color: '#10b981' },
{ min: 50, max: 80, color: '#f59e0b' },
{ min: 80, max: 100, color: '#ef4444' }
]}
});czChart.create('#chart', {
type: 'candlestick',
data: [...], // { date, open, high, low, close }
x: 'date'
});czChart.create('#chart', {
type: 'funnel',
data: [
{ stage: 'Visitors', count: 10000 },
{ stage: 'Leads', count: 5000 },
{ stage: 'Sales', count: 1200 }
],
x: 'stage',
y: 'count'
});czChart.create('#chart', {
type: 'heatmap',
data: [...], // { row, col, value }
x: 'col',
y: 'row'
});czChart.create('#chart', {
type: 'waterfall',
data: [...],
x: 'item',
y: 'amount'
});czChart.create('#chart', {
type: 'treemap',
data: [
{ name: 'Electronics', value: 5000 },
{ name: 'Clothing', value: 3200 },
{ name: 'Food', value: 2100 }
],
x: 'name',
y: 'value'
});czChart.create('#chart', {
type: 'boxplot',
data: [...],
x: 'group',
y: 'values'
});czChart.create('#chart', {
type: 'polar',
data: [...],
x: 'category',
y: 'value'
});// Combine different chart types in one chart
czChart.create('#chart', {
type: 'bar', // default type
types: {
revenue: 'bar',
trend: 'spline',
target: 'line'
},
data: [...],
x: 'month',
y: ['revenue', 'trend', 'target']
});czChart accepts multiple data formats β pass data as-is, it figures out the rest.
data: [
{ date: '2024-01', sales: 100 },
{ date: '2024-02', sales: 200 }
]data: [10, 45, 30, 70, 60, 85]data: "product,Q1,Q2,Q3\nLaptop,120,150,180\nPhone,200,180,220"data: 'https://api.example.com/sales.json'// Colors change on every page load, but stay maximally distinct
data: [
{ category: 'A', value: 100, color: 'random' },
{ category: 'B', value: 200, color: 'random' }
]Numbers are automatically abbreviated on axes:
| Value | Display |
|---|---|
| 500 | 500 |
| 5000 | 5K |
| 1500 | 1.5K |
| 2000000 | 2M |
| 3500000000 | 3.5B |
| 1000000000000 | 1T |
czChart.create('#chart', {
numberAbbr: {
thousands: 'rb', // 5rb
millions: 'jt', // 2jt
billions: 'M', // 1M (miliar)
trillions: 'T' // 1T (triliun)
},
...
});Numbers below 1000 automatically use toLocaleString() for locale-aware thousand separators (. for Indonesian, , for English).
20 maximally distinct colors, ordered so adjacent colors always have high contrast:
π΅ #3b82f6 π΄ #ef4444 π’ #22c55e π‘ #f59e0b π£ #8b5cf6
π©΅ #06b6d4 π #f97316 π #14b8a6 πΉ #e11d48 π #84cc16
...and 10 more
czChart.create('#chart', {
colors: ['#e74c3c', '#3498db', '#2ecc71'],
...
});When more than 20 series exist, colors are generated using the golden angle algorithm (137.5Β° spacing) to guarantee maximum visual distinction.
// Dark theme
czChart.create('#chart', { theme: 'dark', ... });
// Light theme (default)
czChart.create('#chart', { theme: 'light', ... });czChart.create('#chart', {
tooltip: {
align: 'auto' // auto, right, left, top, bottom
},
...
});| Align | Behavior |
|---|---|
auto |
Smart β picks best direction based on viewport space |
right |
Always right of cursor |
left |
Always left of cursor |
top |
Always above cursor |
bottom |
Always below cursor |
Features:
- Arrow pointer with seamless rotated-square technique
- Auto-hides on scroll
- Semi-transparent with uniform opacity (no double-layer artifacts)
- Shared mode shows all series values at once
const chart = czChart.create('#chart', { ... });
chart.on('click', (point) => {
console.log('Clicked:', point.label, point.value);
});
chart.on('hover', (point) => {
console.log('Hovering:', point.seriesName);
});czChart.create('#chart', {
zoom: { enabled: true, mode: 'x' },
...
});const chart = czChart.create('#chart', { ... });
chart.downloadImage('my-chart', 'png');const myPlugin = {
name: 'highlight',
afterSeriesDraw(chart, ctx) {
// Custom drawing after series
},
onClick(chart, point) {
// React to clicks
}
};
czChart.use(myPlugin); // Global
// or per chart:
czChart.create('#chart', { plugins: [myPlugin], ... });Threshold Line β horizontal target/reference lines:
czChart.create('#chart', {
thresholds: [
{ value: 75, color: '#ef4444', label: 'Target' }
],
...
});Watermark β background text:
czChart.create('#chart', {
watermark: { text: 'DRAFT', opacity: 0.05 },
...
});czChart.create('#chart', {
// ββ Chart Type ββββββββββββββββββββββββββββββββββββββ
type: 'line',
// line, spline, area, area-spline, bar, horizontalBar,
// pie, donut, scatter, bubble, radar, gauge, candlestick,
// funnel, heatmap, waterfall, treemap, boxplot, polar
// ββ Mixed/Combo Chart βββββββββββββββββββββββββββββββ
types: { // Per-dataset type override
revenue: 'bar',
trend: 'spline'
},
// ββ Data ββββββββββββββββββββββββββββββββββββββββββββ
data: [...],
x: 'column_name', // X-axis key (auto-detected if omitted)
y: ['col1', 'col2'], // Y-axis key(s) (auto-detected if omitted)
// ββ Colors ββββββββββββββββββββββββββββββββββββββββββ
colors: ['#3b82f6', ...], // Custom color palette
// ββ Number Formatting βββββββββββββββββββββββββββββββ
numberAbbr: {
thousands: 'K', // 'rb' for Indonesian
millions: 'M', // 'jt' for Indonesian
billions: 'B', // 'M' for Indonesian (miliar)
trillions: 'T' // 'T' for Indonesian
},
// ββ Theme βββββββββββββββββββββββββββββββββββββββββββ
theme: 'light', // 'light', 'dark', or custom object
// ββ Animation βββββββββββββββββββββββββββββββββββββββ
animation: { enabled: true, duration: 500, easing: 'easeOutCubic' },
// ββ Axes ββββββββββββββββββββββββββββββββββββββββββββ
xAxis: {
show: true,
gridLines: false,
maxTicks: 0,
rotation: 0,
title: null // e.g. 'Month'
},
yAxis: {
show: true,
gridLines: true,
beginAtZero: true,
maxTicks: 6,
format: null, // Custom format function: (val) => '...'
title: null // e.g. 'Revenue (USD)'
},
// ββ Tooltip βββββββββββββββββββββββββββββββββββββββββ
tooltip: {
enabled: true,
shared: true, // Show all series values
align: 'auto' // auto, right, left, top, bottom
},
// ββ Legend βββββββββββββββββββββββββββββββββββββββββββ
legend: { show: true, position: 'top' }, // top, bottom
// ββ Crosshair βββββββββββββββββββββββββββββββββββββββ
crosshair: { enabled: true },
// ββ Zoom ββββββββββββββββββββββββββββββββββββββββββββ
zoom: { enabled: false, mode: 'x' }, // x, y, xy
// ββ Series (line/area/spline) βββββββββββββββββββββββ
series: {
lineWidth: 1.5,
pointRadius: 2.5,
pointHoverRadius: 8,
smooth: false,
fill: false,
fillOpacity: 0.15
},
// ββ Bar βββββββββββββββββββββββββββββββββββββββββββββ
bar: { borderRadius: 4, gap: 0.2, groupGap: 0.1 },
// ββ Pie / Donut βββββββββββββββββββββββββββββββββββββ
pie: {
innerRadius: 0, // >0 for donut
padAngle: 0.02,
cornerRadius: 0,
startAngle: -90,
showLabels: true,
labelFormat: 'percent' // percent, value, name
},
// ββ Scatter βββββββββββββββββββββββββββββββββββββββββ
scatter: { pointRadius: 5, pointShape: 'circle' },
// ββ Radar βββββββββββββββββββββββββββββββββββββββββββ
radar: { gridType: 'polygon', fillOpacity: 0.2, pointRadius: 3 },
// ββ Padding βββββββββββββββββββββββββββββββββββββββββ
padding: { top: 20, right: 20, bottom: 20, left: 20 }
});node build.jsOutputs:
dist/cz-chart.jsβ Unminified (~298 KB)dist/cz-chart.min.jsβ Minified (~195 KB)
MIT Β© CyberZilla