Chart.js 基础使用 #
创建第一个图表 #
最简单的图表 #
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>我的第一个图表</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<div style="width: 600px; height: 400px;">
<canvas id="myChart"></canvas>
</div>
<script>
const ctx = document.getElementById('myChart');
new Chart(ctx, {
type: 'bar',
data: {
labels: ['红色', '蓝色', '黄色', '绿色', '紫色', '橙色'],
datasets: [{
label: '投票数',
data: [12, 19, 3, 5, 2, 3]
}]
}
});
</script>
</body>
</html>
图表配置结构 #
text
┌─────────────────────────────────────────────────────────────┐
│ Chart.js 配置结构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ new Chart(ctx, { │
│ type: '图表类型', ← bar, line, pie 等 │
│ data: { ← 数据配置 │
│ labels: [], │
│ datasets: [] │
│ }, │
│ options: { ← 选项配置 │
│ responsive: true, │
│ plugins: {}, │
│ scales: {} │
│ } │
│ }); │
│ │
└─────────────────────────────────────────────────────────────┘
数据结构 #
基本数据结构 #
javascript
const data = {
// 标签数组:X 轴的刻度标签
labels: ['一月', '二月', '三月', '四月', '五月', '六月'],
// 数据集数组:可以包含多个数据集
datasets: [{
// 数据集标签
label: '2024年销售额',
// 数据数组:与 labels 一一对应
data: [65, 59, 80, 81, 56, 55],
// 样式配置
backgroundColor: 'rgba(75, 192, 192, 0.5)',
borderColor: 'rgba(75, 192, 192, 1)',
borderWidth: 1
}]
};
多数据集 #
javascript
const data = {
labels: ['一月', '二月', '三月', '四月', '五月', '六月'],
datasets: [
{
label: '2023年',
data: [65, 59, 80, 81, 56, 55],
backgroundColor: 'rgba(255, 99, 132, 0.5)',
borderColor: 'rgba(255, 99, 132, 1)'
},
{
label: '2024年',
data: [28, 48, 40, 19, 86, 27],
backgroundColor: 'rgba(54, 162, 235, 0.5)',
borderColor: 'rgba(54, 162, 235, 1)'
}
]
};
对象数组数据 #
javascript
const data = {
datasets: [{
label: '散点数据',
data: [
{ x: 10, y: 20 },
{ x: 15, y: 25 },
{ x: 20, y: 30 },
{ x: 25, y: 28 }
],
backgroundColor: 'rgba(75, 192, 192, 0.5)'
}]
};
气泡图数据 #
javascript
const data = {
datasets: [{
label: '气泡图',
data: [
{ x: 10, y: 20, r: 10 },
{ x: 15, y: 25, r: 15 },
{ x: 20, y: 30, r: 5 }
]
}]
};
图表类型 #
8 种基本图表 #
javascript
// 1. 柱状图
new Chart(ctx, { type: 'bar', data, options });
// 2. 折线图
new Chart(ctx, { type: 'line', data, options });
// 3. 饼图
new Chart(ctx, { type: 'pie', data, options });
// 4. 环形图
new Chart(ctx, { type: 'doughnut', data, options });
// 5. 雷达图
new Chart(ctx, { type: 'radar', data, options });
// 6. 极坐标图
new Chart(ctx, { type: 'polarArea', data, options });
// 7. 气泡图
new Chart(ctx, { type: 'bubble', data, options });
// 8. 散点图
new Chart(ctx, { type: 'scatter', data, options });
图表类型变体 #
javascript
// 水平柱状图
new Chart(ctx, {
type: 'bar',
data: data,
options: {
indexAxis: 'y'
}
});
// 堆叠柱状图
new Chart(ctx, {
type: 'bar',
data: data,
options: {
scales: {
x: { stacked: true },
y: { stacked: true }
}
}
});
基本配置选项 #
响应式配置 #
javascript
const options = {
// 响应式:自动调整大小
responsive: true,
// 保持宽高比
maintainAspectRatio: true,
// 宽高比(当 maintainAspectRatio 为 true 时生效)
aspectRatio: 2,
// 调整大小延迟
resizeDelay: 0,
// 容器
resizeObserver: true
};
标题配置 #
javascript
const options = {
plugins: {
title: {
// 是否显示标题
display: true,
// 标题文本
text: '月度销售报告',
// 位置:'top', 'bottom', 'left', 'right'
position: 'top',
// 对齐方式:'start', 'center', 'end'
align: 'center',
// 字体配置
font: {
family: 'Arial',
size: 16,
weight: 'bold',
style: 'normal'
},
// 颜色
color: '#333',
// 内边距
padding: {
top: 10,
bottom: 10
}
}
}
};
图例配置 #
javascript
const options = {
plugins: {
legend: {
// 是否显示图例
display: true,
// 位置:'top', 'bottom', 'left', 'right'
position: 'top',
// 对齐方式
align: 'center',
// 最大宽度/高度
maxWidth: 200,
maxHeight: 100,
// 是否可点击切换显示
onClick: (e, legendItem, legend) => {
const index = legendItem.datasetIndex;
const ci = legend.chart;
const meta = ci.getDatasetMeta(index);
meta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null;
ci.update();
},
// 标签配置
labels: {
// 字体
font: {
size: 12
},
// 颜色
color: '#666',
// 使用数据集样式
usePointStyle: true,
// 盒子尺寸
boxWidth: 40,
boxHeight: 12,
// 内边距
padding: 20
}
}
}
};
提示框配置 #
javascript
const options = {
plugins: {
tooltip: {
// 是否启用
enabled: true,
// 模式:'point', 'nearest', 'index', 'dataset', 'x', 'y'
mode: 'index',
// 是否相交
intersect: false,
// 背景色
backgroundColor: 'rgba(0, 0, 0, 0.8)',
// 标题字体
titleFont: {
size: 14,
weight: 'bold'
},
// 正文字体
bodyFont: {
size: 12
},
// 内边距
padding: 10,
// 圆角
cornerRadius: 4,
// 自定义回调
callbacks: {
title: function(context) {
return '标题: ' + context[0].label;
},
label: function(context) {
return context.dataset.label + ': ' + context.parsed.y;
}
}
}
}
};
坐标轴配置 #
基本坐标轴 #
javascript
const options = {
scales: {
// X 轴
x: {
// 是否显示
display: true,
// 标题
title: {
display: true,
text: '月份'
},
// 刻度配置
ticks: {
color: '#666',
font: { size: 12 }
},
// 网格线
grid: {
display: true,
color: '#eee'
}
},
// Y 轴
y: {
display: true,
title: {
display: true,
text: '销售额'
},
ticks: {
color: '#666'
},
grid: {
color: '#eee'
}
}
}
};
Y 轴范围 #
javascript
const options = {
scales: {
y: {
// 最小值
min: 0,
// 最大值
max: 100,
// 从零开始
beginAtZero: true
}
}
};
多 Y 轴 #
javascript
const options = {
scales: {
y: {
type: 'linear',
display: true,
position: 'left',
title: {
display: true,
text: '销售额'
}
},
y1: {
type: 'linear',
display: true,
position: 'right',
title: {
display: true,
text: '增长率'
},
grid: {
drawOnChartArea: false
}
}
}
};
// 数据集指定使用的轴
const data = {
datasets: [
{
label: '销售额',
data: [65, 59, 80],
yAxisID: 'y'
},
{
label: '增长率',
data: [10, 15, 20],
yAxisID: 'y1'
}
]
};
图表实例操作 #
获取图表实例 #
javascript
// 创建图表并保存实例
const myChart = new Chart(ctx, config);
// 获取图表实例
const chartInstance = Chart.getChart('myChart');
更新数据 #
javascript
const myChart = new Chart(ctx, config);
// 方式一:直接修改数据
myChart.data.datasets[0].data = [1, 2, 3, 4, 5];
myChart.update();
// 方式二:添加数据
myChart.data.labels.push('七月');
myChart.data.datasets[0].data.push(70);
myChart.update();
// 方式三:移除数据
myChart.data.labels.pop();
myChart.data.datasets[0].data.pop();
myChart.update();
更新配置 #
javascript
// 更新选项
myChart.options.plugins.title.text = '新标题';
myChart.update();
// 更新数据集
myChart.data.datasets[0].backgroundColor = 'red';
myChart.update();
更新模式 #
javascript
// 默认模式:带动画
myChart.update();
// 指定模式
myChart.update('active'); // 动画
myChart.update('resize'); // 调整大小
myChart.update('none'); // 无动画
myChart.update('default'); // 默认动画
销毁图表 #
javascript
// 销毁图表实例
myChart.destroy();
// 清空画布
myChart.clear();
// 重置图表
myChart.reset();
获取数据 #
javascript
// 获取数据集
const datasets = myChart.data.datasets;
// 获取特定数据点的值
const dataPoint = myChart.getDatasetMeta(0).data[0];
// 获取图表区域
const chartArea = myChart.chartArea;
样式定制 #
颜色配置 #
javascript
const data = {
datasets: [{
// 单色
backgroundColor: 'rgba(75, 192, 192, 0.5)',
borderColor: 'rgba(75, 192, 192, 1)',
// 多色(数组)
backgroundColor: [
'rgba(255, 99, 132, 0.5)',
'rgba(54, 162, 235, 0.5)',
'rgba(255, 206, 86, 0.5)'
],
// 渐变色
backgroundColor: function(context) {
const chart = context.chart;
const { ctx, chartArea } = chart;
if (!chartArea) return;
const gradient = ctx.createLinearGradient(0, chartArea.bottom, 0, chartArea.top);
gradient.addColorStop(0, 'rgba(75, 192, 192, 0.5)');
gradient.addColorStop(1, 'rgba(255, 99, 132, 0.5)');
return gradient;
}
}]
};
边框样式 #
javascript
const data = {
datasets: [{
borderColor: 'blue',
borderWidth: 2,
borderDash: [5, 5], // 虚线
borderDashOffset: 0,
borderRadius: 5, // 圆角
borderSkipped: false // 不跳过任何边
}]
};
点样式 #
javascript
const data = {
datasets: [{
// 点样式:'circle', 'cross', 'crossRot', 'dash', 'line', 'rect', 'rectRounded', 'rectRot', 'star', 'triangle'
pointStyle: 'circle',
// 点半径
pointRadius: 5,
// 悬停点半径
pointHoverRadius: 8,
// 点颜色
pointBackgroundColor: 'rgba(75, 192, 192, 1)',
pointBorderColor: '#fff',
pointBorderWidth: 2,
// 悬停颜色
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(75, 192, 192, 1)'
}]
};
事件处理 #
基本事件 #
javascript
const options = {
// 点击事件
onClick: (event, elements, chart) => {
if (elements.length > 0) {
const element = elements[0];
console.log('点击了第', element.index, '个数据点');
}
},
// 悬停事件
onHover: (event, elements, chart) => {
event.native.target.style.cursor = elements.length ? 'pointer' : 'default';
},
// 离开事件
onLeave: (event, elements, chart) => {
event.native.target.style.cursor = 'default';
}
};
插件事件 #
javascript
const options = {
plugins: {
legend: {
onClick: (e, legendItem, legend) => {
console.log('点击了图例:', legendItem.text);
}
},
tooltip: {
onShow: (tooltip) => {
console.log('显示提示框');
},
onHide: (tooltip) => {
console.log('隐藏提示框');
}
}
}
};
实用示例 #
动态更新图表 #
javascript
const ctx = document.getElementById('myChart');
const myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [],
datasets: [{
label: '实时数据',
data: [],
borderColor: 'rgb(75, 192, 192)',
tension: 0.4
}]
},
options: {
animation: {
duration: 300
}
}
});
// 模拟实时数据
setInterval(() => {
const now = new Date();
const timeLabel = now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds();
const value = Math.random() * 100;
// 添加新数据
myChart.data.labels.push(timeLabel);
myChart.data.datasets[0].data.push(value);
// 保持最多 10 个数据点
if (myChart.data.labels.length > 10) {
myChart.data.labels.shift();
myChart.data.datasets[0].data.shift();
}
myChart.update('none');
}, 1000);
导出图表为图片 #
javascript
function exportChart(chart) {
const link = document.createElement('a');
link.download = 'chart.png';
link.href = chart.toBase64Image();
link.click();
}
// 使用
document.getElementById('exportBtn').addEventListener('click', () => {
exportChart(myChart);
});
响应式图表 #
javascript
const options = {
responsive: true,
maintainAspectRatio: false,
plugins: {
title: {
display: true,
text: '响应式图表'
}
},
scales: {
x: {
ticks: {
// 小屏幕时隐藏标签
display: window.innerWidth > 400
}
}
}
};
// 监听窗口大小变化
window.addEventListener('resize', () => {
myChart.options.scales.x.ticks.display = window.innerWidth > 400;
myChart.resize();
});
最佳实践 #
1. 使用变量存储配置 #
javascript
// 好的做法
const chartData = {
labels: ['A', 'B', 'C'],
datasets: [{ data: [1, 2, 3] }]
};
const chartOptions = {
responsive: true
};
const myChart = new Chart(ctx, {
type: 'bar',
data: chartData,
options: chartOptions
});
2. 销毁旧图表 #
javascript
// 在创建新图表前销毁旧图表
let myChart = null;
function createChart(data) {
if (myChart) {
myChart.destroy();
}
myChart = new Chart(ctx, {
type: 'bar',
data: data
});
}
3. 使用 TypeScript 类型 #
typescript
import { ChartConfiguration } from 'chart.js';
const config: ChartConfiguration = {
type: 'bar',
data: {
labels: ['A', 'B', 'C'],
datasets: [{ data: [1, 2, 3] }]
}
};
下一步 #
现在你已经掌握了 Chart.js 的基础使用,接下来学习 配置选项,深入了解各种配置参数!
最后更新:2026-03-28