Chart.js 教程

Chart.js 教程

Chart.js 是一款轻量、开源的 JavaScript 图表库,基于 HTML5 Canvas 绘制,支持 8 种核心图表类型,API 简洁,是数据可视化的入门首选。

核心特性

  • 轻量:压缩后仅约 60KB,无外部依赖
  • 响应式:自动适配容器大小与移动端
  • 动画:内置平滑动画与过渡效果
  • 8 种图表:折线、柱状、饼图、环形、雷达、极地、散点、气泡、混合
  • 可扩展:插件系统(缩放、标签、自定义)

引入方式

<!-- CDN -->
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>

# npm
npm install chart.js

第一个图表

<canvas id="myChart"></canvas>

<script>
const ctx = document.getElementById("myChart");
new Chart(ctx, {
    type: "bar",           // 图表类型
    data: {
        labels: ["周一", "周二", "周三"],
        datasets: [{
            label: "访问量",
            data: [120, 150, 180],
            backgroundColor: "#3498db"
        }]
    },
    options: {
        responsive: true,
        scales: {
            y: { beginAtZero: true }
        }
    }
});
</script>

学习路线

  1. 安装与基本使用
  2. 各图表类型(柱形/气泡/环形/饼图/折线/混合/极地/雷达/散点)
  3. 配置与自定义

Chart.js 安装

Chart.js 安装

1. CDN 引入

<!-- 最新版本 -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

<!-- 指定版本 -->
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>

<!-- 中国镜像(可选) -->
<script src="https://cdn.bootcdn.net/ajax/libs/Chart.js/4.4.0/chart.umd.min.js"></script>

2. npm 安装

# 安装
npm install chart.js

# 导入(ES Module)
import Chart from "chart.js/auto";

# 或按需导入
import { Chart, BarController, BarElement,
         CategoryScale, LinearScale } from "chart.js";

Chart.register(BarController, BarElement,
    CategoryScale, LinearScale);

3. 浏览器模块

// 直接使用全局对象
const ctx = document.getElementById("chart");
new Chart(ctx, { type: "bar", data: {...} });

// Vue 集成
npm install vue-chartjs chart.js

// React 集成
npm install react-chartjs-2 chart.js

4. 验证安装

<!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0"></script>
</head>
<body>
  <canvas id="demo" width="400" height="200"></canvas>
  <script>
    new Chart(document.getElementById("demo"), {
      type: "line",
      data: {
        labels: ["A", "B", "C"],
        datasets: [{ data: [1, 2, 3] }]
      }
    });
  </script>
</body>
</html>

5. 版本说明

Chart.js 2.x   旧版(option 结构不同)
Chart.js 3.x   重构,scale 配置变化
Chart.js 4.x   当前稳定版
# 3/4 版本注意: scales.y.ticks 等配置层级变化

Chart.js 使用

Chart.js 使用

1. 核心结构

new Chart(ctx, {
    type: "bar",          // 图表类型
    data: {               // 数据
        labels: [...],    // 标签(X 轴)
        datasets: [{      // 数据集数组
            label: "...", // 系列名
            data: [...],  // 数据值
            backgroundColor: "...",
            borderColor: "..."
        }]
    },
    options: {            // 配置
        responsive: true,
        plugins: {...},
        scales: {...}
    }
});

2. 数据配置

data: {
    labels: ["北京", "上海", "广州"],
    datasets: [
        {
            label: "2025年",
            data: [100, 120, 90],
            backgroundColor: "rgba(52,152,219,0.5)",
            borderColor: "#2980b9",
            borderWidth: 2
        },
        {
            label: "2026年",
            data: [130, 140, 110],
            backgroundColor: "rgba(46,204,113,0.5)",
            borderColor: "#27ae60",
            borderWidth: 2
        }
    ]
}

3. 常用配置

options: {
    responsive: true,        // 响应式
    maintainAspectRatio: false,  // 不保持比例
    animation: {
        duration: 1000,      // 动画时长
        easing: "easeOutBounce"
    },
    plugins: {
        title: {
            display: true,
            text: "图表标题",
            font: { size: 18 }
        },
        legend: {
            display: true,
            position: "top"
        },
        tooltip: {
            enabled: true,
            callbacks: {
                label: (ctx) => ctx.dataset.label + ": " + ctx.parsed.y
            }
        }
    },
    scales: {
        x: { title: { display: true, text: "X 轴" } },
        y: {
            title: { display: true, text: "Y 轴" },
            beginAtZero: true
        }
    }
}

4. 更新与销毁

const chart = new Chart(ctx, {...});

// 更新数据
chart.data.datasets[0].data = [10, 20, 30];
chart.update();

// 添加数据
chart.data.labels.push("D");
chart.data.datasets[0].data.push(40);
chart.update();

// 删除数据
chart.data.labels.pop();
chart.data.datasets[0].data.pop();
chart.update();

// 销毁
chart.destroy();

5. 事件处理

options: {
    onClick: (event, elements, chart) => {
        if (elements.length > 0) {
            const index = elements[0].index;
            console.log("点击了:", chart.data.labels[index]);
        }
    },
    onHover: (event, elements) => {
        // 悬停时 canvas 光标
        event.native.target.style.cursor =
            elements.length > 0 ? "pointer" : "default";
    }
}

Chart.js 柱形图

Chart.js 柱形图

1. 基本柱形图

<canvas id="barChart"></canvas>

<script>
new Chart(document.getElementById("barChart"), {
    type: "bar",
    data: {
        labels: ["一月", "二月", "三月", "四月", "五月"],
        datasets: [{
            label: "销售额",
            data: [120, 150, 130, 180, 200],
            backgroundColor: "rgba(52,152,219,0.7)",
            borderColor: "#2980b9",
            borderWidth: 2
        }]
    },
    options: {
        responsive: true,
        scales: {
            y: { beginAtZero: true }
        }
    }
});
</script>

2. 多系列柱形

datasets: [
    {
        label: "线上",
        data: [60, 80, 70, 90, 100],
        backgroundColor: "#3498db"
    },
    {
        label: "线下",
        data: [60, 70, 60, 90, 100],
        backgroundColor: "#2ecc71"
    }
]

3. 堆叠柱形

options: {
    scales: {
        x: { stacked: true },
        y: { stacked: true, beginAtZero: true }
    }
},
datasets: [
    { label: "A产品", data: [30, 40, 50], backgroundColor: "#3498db" },
    { label: "B产品", data: [20, 30, 40], backgroundColor: "#2ecc71" },
    { label: "C产品", data: [15, 20, 25], backgroundColor: "#f39c12" }
]

4. 横向柱形图

// indexAxis: "y" 横向
new Chart(ctx, {
    type: "bar",
    data: {...},
    options: {
        indexAxis: "y",    // 横向
        scales: {
            x: { beginAtZero: true }
        }
    }
});

5. 圆角与渐变

datasets: [{
    data: [30, 50, 40],
    borderRadius: 8,          // 圆角
    backgroundColor: (context) => {
        // 渐变填充
        const { ctx, chartArea } = context.chart;
        if (!chartArea) return "#3498db";
        const gradient = ctx.createLinearGradient(
            0, chartArea.bottom, 0, chartArea.top);
        gradient.addColorStop(0, "rgba(52,152,219,0.2)");
        gradient.addColorStop(1, "rgba(52,152,219,1)");
        return gradient;
    }
}]

Chart.js 气泡图

Chart.js 气泡图

1. 基本气泡图

<canvas id="bubbleChart"></canvas>

<script>
new Chart(document.getElementById("bubbleChart"), {
    type: "bubble",
    data: {
        datasets: [{
            label: "产品",
            data: [
                { x: 10, y: 20, r: 15 },   // r: 气泡半径
                { x: 20, y: 35, r: 25 },
                { x: 30, y: 25, r: 20 },
                { x: 40, y: 50, r: 30 }
            ],
            backgroundColor: "rgba(52,152,219,0.6)"
        }]
    },
    options: {
        scales: {
            x: { title: { display: true, text: "销量" } },
            y: { title: { display: true, text: "利润" } }
        }
    }
});
</script>

2. 多系列气泡

datasets: [
    {
        label: "A组",
        data: [{x:10,y:20,r:15},{x:20,y:30,r:20}],
        backgroundColor: "rgba(52,152,219,0.6)"
    },
    {
        label: "B组",
        data: [{x:15,y:40,r:18},{x:30,y:20,r:25}],
        backgroundColor: "rgba(231,76,60,0.6)"
    }
]

3. 气泡大小调整

// r 值对应像素半径
// 可用函数控制
data: [
    { x: 10, y: 20, r: Math.sqrt(100) * 2 },
    { x: 20, y: 35, r: Math.sqrt(400) * 2 }
]

4. 边界与动画

options: {
    animation: {
        duration: 800,
        easing: "easeInOutQuad"
    },
    scales: {
        x: { min: 0, max: 50 },
        y: { min: 0, max: 60 }
    },
    plugins: {
        tooltip: {
            callbacks: {
                label: (ctx) => {
                    const d = ctx.raw;
                    return ctx.dataset.label +
                        ": 销量" + d.x +
                        " 利润" + d.y +
                        " 规模" + d.r;
                }
            }
        }
    }
}

Chart.js 环形图

Chart.js 环形图

1. 基本环形图

<canvas id="doughnutChart"></canvas>

<script>
new Chart(document.getElementById("doughnutChart"), {
    type: "doughnut",
    data: {
        labels: ["直接访问", "搜索引擎", "社交媒体", "邮件"],
        datasets: [{
            data: [40, 30, 20, 10],
            backgroundColor: [
                "#3498db", "#2ecc71", "#f39c12", "#e74c3c"
            ],
            borderWidth: 2,
            borderColor: "#fff"
        }]
    },
    options: {
        plugins: {
            legend: {
                position: "bottom"
            }
        }
    }
});
</script>

2. 环形宽度控制

options: {
    cutout: "60%"    // 内部挖空比例(0=饼图, 60%=环形)
}
// 环形图: cutout 设置内部半径百分比
// 饼图:   cutout: 0 或使用 type: "pie"

3. 环形图文字中心

// 使用插件在中心显示文字
const centerText = {
    id: "centerText",
    afterDraw(chart) {
        const { ctx } = chart;
        const meta = chart.getDatasetMeta(0);
        const x = meta.data[0].x;
        const y = meta.data[0].y;
        ctx.save();
        ctx.textAlign = "center";
        ctx.fillStyle = "#333";
        ctx.font = "bold 24px sans-serif";
        ctx.fillText("总计", x, y - 10);
        ctx.font = "16px sans-serif";
        ctx.fillText("100%", x, y + 20);
        ctx.restore();
    }
};

new Chart(ctx, {
    type: "doughnut",
    data: {...},
    options: {...},
    plugins: [centerText]
});

4. 交互与动画

options: {
    cutout: "55%",
    animation: {
        animateRotate: true,   // 旋转动画
        animateScale: true     // 缩放动画
    },
    plugins: {
        legend: {
            position: "right",
            labels: { padding: 20, usePointStyle: true }
        },
        tooltip: {
            callbacks: {
                label: (ctx) => {
                    const total = ctx.dataset.data.reduce(
                        (a, b) => a + b, 0);
                    const pct = Math.round(
                        ctx.parsed / total * 100);
                    return ctx.label + ": " + ctx.parsed +
                        " (" + pct + "%)";
                }
            }
        }
    }
}

Chart.js 饼图

Chart.js 饼图

1. 基本饼图

<canvas id="pieChart"></canvas>

<script>
new Chart(document.getElementById("pieChart"), {
    type: "pie",
    data: {
        labels: ["Chrome", "Edge", "Firefox", "Safari", "其他"],
        datasets: [{
            data: [65, 12, 8, 10, 5],
            backgroundColor: [
                "#3498db", "#2ecc71", "#f39c12",
                "#9b59b6", "#95a5a6"
            ],
            borderWidth: 2,
            borderColor: "#fff"
        }]
    },
    options: {
        plugins: {
            legend: {
                position: "bottom",
                labels: { usePointStyle: true }
            },
            title: {
                display: true,
                text: "浏览器市场份额",
                font: { size: 16 }
            }
        }
    }
});
</script>

2. 显示百分比

options: {
    plugins: {
        tooltip: {
            callbacks: {
                label: (ctx) => {
                    const total = ctx.dataset.data.reduce(
                        (a, b) => a + b, 0);
                    const pct = ((ctx.parsed / total) * 100).toFixed(1);
                    return ctx.label + ": " + pct + "%";
                }
            }
        },
        legend: {
            labels: {
                generateLabels: (chart) => {
                    const data = chart.data;
                    return data.labels.map((label, i) => {
                        const total = data.datasets[0].data
                            .reduce((a, b) => a + b, 0);
                        const pct = Math.round(
                            data.datasets[0].data[i] / total * 100);
                        return {
                            text: label + " (" + pct + "%)",
                            fillStyle: data.datasets[0].backgroundColor[i],
                            index: i
                        };
                    });
                }
            }
        }
    }
}

3. 分离扇区

// 点击分离效果
options: {
    onClick: (event, elements, chart) => {
        if (elements.length > 0) {
            const idx = elements[0].index;
            const ds = chart.data.datasets[0];
            // 增加 offset
            chart.data.datasets[0].offset = [0,0,0,0];
            chart.data.datasets[0].offset[idx] = 20;
            chart.update();
        }
    }
}

4. 圆角与边框

datasets: [{
    data: [30, 40, 30],
    backgroundColor: ["#e74c3c", "#f39c12", "#2ecc71"],
    borderColor: "#fff",
    borderWidth: 3,
    borderRadius: 6,     // 扇区圆角
    hoverOffset: 10      // 悬停分离距离
}]

Chart.js 折线图

Chart.js 折线图

1. 基本折线图

<canvas id="lineChart"></canvas>

<script>
new Chart(document.getElementById("lineChart"), {
    type: "line",
    data: {
        labels: ["1月", "2月", "3月", "4月", "5月", "6月"],
        datasets: [{
            label: "气温",
            data: [5, 8, 12, 18, 24, 28],
            borderColor: "#e74c3c",
            backgroundColor: "rgba(231,76,60,0.1)",
            fill: true,           // 填充面积
            tension: 0.4,         // 曲线平滑度
            pointRadius: 4,
            pointBackgroundColor: "#e74c3c"
        }]
    },
    options: {
        responsive: true,
        scales: {
            y: { beginAtZero: true }
        }
    }
});
</script>

2. 平滑曲线

datasets: [{
    data: [10, 25, 15, 30, 20, 35],
    tension: 0.4        // 0=直线, 0.4=平滑曲线
}]

// 或者用 spline 效果
datasets: [{
    data: [...],
    cubicInterpolationMode: "monotone"  // 自然平滑
}]

3. 面积图

datasets: [{
    label: "访问量",
    data: [100, 150, 120, 180, 160, 220],
    fill: true,                 // 填充面积
    backgroundColor: (context) => {
        // 渐变填充
        const { ctx, chartArea } = context.chart;
        if (!chartArea) return "rgba(52,152,219,0.3)";
        const grad = ctx.createLinearGradient(
            0, chartArea.top, 0, chartArea.bottom);
        grad.addColorStop(0, "rgba(52,152,219,0.6)");
        grad.addColorStop(1, "rgba(52,152,219,0.05)");
        return grad;
    }
}]

4. 多线对比

datasets: [
    {
        label: "2025年",
        data: [100, 120, 110, 140, 130, 160],
        borderColor: "#3498db",
        tension: 0.4
    },
    {
        label: "2026年",
        data: [120, 140, 130, 160, 150, 190],
        borderColor: "#2ecc71",
        borderDash: [5, 5],      // 虚线
        tension: 0.4
    }
]

5. 数据点标签

// 需要 datalabels 插件
npm install chartjs-plugin-datalabels

import ChartDataLabels from "chartjs-plugin-datalabels";
Chart.register(ChartDataLabels);

options: {
    plugins: {
        datalabels: {
            display: true,
            anchor: "end",
            align: "top",
            font: { size: 11 },
            formatter: (value) => value + "°"
        }
    }
}

Chart.js 混合图

Chart.js 混合图

1. 柱状+折线混合

<canvas id="mixedChart"></canvas>

<script>
new Chart(document.getElementById("mixedChart"), {
    data: {
        labels: ["Q1", "Q2", "Q3", "Q4"],
        datasets: [
            {
                type: "bar",          // 柱状
                label: "销售额",
                data: [120, 150, 130, 180],
                backgroundColor: "rgba(52,152,219,0.7)"
            },
            {
                type: "line",         // 折线
                label: "利润率",
                data: [20, 25, 18, 30],
                borderColor: "#e74c3c",
                tension: 0.4,
                yAxisID: "y2"         // 第二 Y 轴
            }
        ]
    },
    options: {
        scales: {
            y: {
                type: "linear",
                position: "left",
                title: { display: true, text: "销售额" }
            },
            y2: {
                type: "linear",
                position: "right",
                title: { display: true, text: "利润率(%)" },
                grid: { drawOnChartArea: false }
            }
        }
    }
});
</script>

2. 柱状+面积混合

datasets: [
    {
        type: "bar",
        label: "预算",
        data: [50, 60, 55, 70],
        backgroundColor: "rgba(243,156,18,0.6)"
    },
    {
        type: "line",
        label: "实际",
        data: [48, 65, 50, 75],
        fill: true,
        backgroundColor: "rgba(46,204,113,0.2)",
        borderColor: "#2ecc71",
        tension: 0.4
    }
]

3. 混合图配置要点

// 1. datasets 中指定 type
// 2. 双轴用 yAxisID / xAxisID 关联
// 3. 每轴独立配置 title、min/max
// 4. grid 可关闭避免重叠线

options: {
    scales: {
        y: {
            type: "linear",
            beginAtZero: true
        },
        y2: {
            type: "linear",
            position: "right",
            grid: { drawOnChartArea: false },
            min: 0,
            max: 100
        }
    }
}

4. 混合图应用场景

  • 销量 + 增长率
  • 预算 vs 实际
  • 温度 + 湿度
  • 访问量 + 转化率

Chart.js 极地图

Chart.js 极地图

1. 基本极地图

<canvas id="polarChart"></canvas>

<script>
new Chart(document.getElementById("polarChart"), {
    type: "polarArea",
    data: {
        labels: ["速度", "可靠性", "舒适度", "性价比", "油耗"],
        datasets: [{
            data: [8, 9, 7, 6, 8],
            backgroundColor: [
                "rgba(52,152,219,0.7)",
                "rgba(46,204,113,0.7)",
                "rgba(243,156,18,0.7)",
                "rgba(155,89,182,0.7)",
                "rgba(231,76,60,0.7)"
            ],
            borderWidth: 2,
            borderColor: "#fff"
        }]
    },
    options: {
        scales: {
            r: {        // 半径轴
                beginAtZero: true,
                max: 10
            }
        }
    }
});
</script>

2. 样式配置

options: {
    scales: {
        r: {
            ticks: {
                display: true,
                stepSize: 2,
                backdropColor: "transparent"
            },
            grid: { color: "#e0e0e0" }
        }
    },
    plugins: {
        legend: {
            position: "bottom"
        },
        tooltip: {
            callbacks: {
                label: (ctx) => ctx.label + ": " +
                    ctx.parsed.r + " 分"
            }
        }
    }
}

3. 动画效果

options: {
    animation: {
        animateRotate: true,
        animateScale: true
    }
}

Chart.js 雷达图

Chart.js 雷达图

1. 基本雷达图

<canvas id="radarChart"></canvas>

<script>
new Chart(document.getElementById("radarChart"), {
    type: "radar",
    data: {
        labels: ["技术", "沟通", "管理", "创新", "执行力", "学习"],
        datasets: [
            {
                label: "张三",
                data: [8, 6, 5, 7, 9, 8],
                borderColor: "#3498db",
                backgroundColor: "rgba(52,152,219,0.2)",
                pointBackgroundColor: "#3498db"
            },
            {
                label: "李四",
                data: [6, 8, 7, 5, 6, 7],
                borderColor: "#e74c3c",
                backgroundColor: "rgba(231,76,60,0.2)",
                pointBackgroundColor: "#e74c3c"
            }
        ]
    },
    options: {
        scales: {
            r: {
                beginAtZero: true,
                max: 10,
                ticks: { stepSize: 2 }
            }
        },
        plugins: {
            legend: { position: "top" }
        }
    }
});
</script>

2. 雷达图特性

# 适合多维对比
# - 能力评估
# - 产品多维对比
# - 用户体验评分

options: {
    scales: {
        r: {
            angleLines: { display: true },
            grid: { circular: true },  // 圆形网格
            pointLabels: {
                font: { size: 12 },
                color: "#333"
            }
        }
    },
    elements: {
        line: { borderWidth: 2, tension: 0.2 },
        point: { radius: 4 }
    }
}

3. 填充透明度

datasets: [{
    data: [8, 6, 5, 7, 9, 8],
    backgroundColor: "rgba(52,152,219,0.15)",
    borderColor: "#3498db",
    pointRadius: 5,
    pointHoverRadius: 8,
    fill: true
}]

Chart.js 散点图

Chart.js 散点图

1. 基本散点图

<canvas id="scatterChart"></canvas>

<script>
new Chart(document.getElementById("scatterChart"), {
    type: "scatter",
    data: {
        datasets: [{
            label: "数据点",
            data: [
                { x: 1, y: 3 },
                { x: 2, y: 5 },
                { x: 3, y: 4 },
                { x: 4, y: 8 },
                { x: 5, y: 6 }
            ],
            backgroundColor: "rgba(52,152,219,0.7)",
            pointRadius: 5
        }]
    },
    options: {
        scales: {
            x: {
                type: "linear",      // 数值轴
                position: "bottom",
                title: { display: true, text: "X 值" }
            },
            y: {
                beginAtZero: true,
                title: { display: true, text: "Y 值" }
            }
        }
    }
});
</script>

2. 分组散点

datasets: [
    {
        label: "组A",
        data: [{x:1,y:2},{x:2,y:3},{x:3,y:5}],
        backgroundColor: "#3498db"
    },
    {
        label: "组B",
        data: [{x:2,y:1},{x:3,y:2},{x:4,y:4}],
        backgroundColor: "#e74c3c"
    }
]

3. 拟合趋势线

// 手动计算线性回归并叠加
const points = [{x:1,y:3},{x:2,y:5},{x:3,y:4},{x:4,y:8}];

// 最小二乘
const n = points.length;
let sx=0, sy=0, sxy=0, sxx=0;
points.forEach(p => {
    sx += p.x; sy += p.y;
    sxy += p.x * p.y; sxx += p.x * p.x;
});
const slope = (n*sxy - sx*sy) / (n*sxx - sx*sx);
const intercept = (sy - slope*sx) / n;

const trend = [
    {x: points[0].x, y: slope*points[0].x + intercept},
    {x: points[n-1].x, y: slope*points[n-1].x + intercept}
];

datasets: [
    { label: "数据", data: points, type: "scatter" },
    {
        label: "趋势线",
        data: trend,
        type: "line",
        borderColor: "#e74c3c",
        borderDash: [5,5],
        pointRadius: 0
    }
]

Chart.js 总结与资源

Chart.js 总结与资源

1. 核心知识回顾

  • 核心结构:type + data(labels/datasets) + options
  • 8 种图表:bar、line、pie、doughnut、radar、polarArea、scatter、bubble + 混合
  • 响应式:responsive + maintainAspectRatio 控制
  • 动画:animation 配置时长与缓动
  • 交互:onClick、tooltip callbacks、datalabels 插件

2. 常用配置速查

# 标题/图例/提示
plugins: {
    title: { display: true, text: "..." },
    legend: { position: "top|bottom|left|right" },
    tooltip: { enabled: true, callbacks: {...} }
}

# 坐标轴
scales: {
    x: { title: {...}, stacked: true },
    y: { beginAtZero: true, title: {...} }
}

# 数据集常用属性
label / data / backgroundColor / borderColor
borderWidth / tension / fill / pointRadius / stack

3. 常用插件

chartjs-plugin-datalabels    数据标签
chartjs-plugin-zoom          缩放/平移
chartjs-plugin-annotation    注解线/区域
chartjs-plugin-labels        饼图标签
chartjs-chart-geo            地图图表
chartjs-chart-treemap        树状图
chartjs-chart-boxplot        箱线图

4. 官方资源

官网:       chartjs.org
GitHub:     github.com/chartjs/Chart.js
示例库:     chartjs.org/docs/latest/samples
API 文档:   chartjs.org/docs/latest
Vue 封装:   vue-chartjs
React 封装: react-chartjs-2

5. 最佳实践

  • 用容器包裹 canvas 并设置高度,避免变形
  • 大数据量考虑采样或改用 WebGL 图表
  • 移动端控制点密度与标签显示
  • 颜色使用语义化配色,保持一致性
  • 图表销毁时调用 destroy() 防止内存泄漏

Chart.js 上手快、文档好,是前端数据可视化的理想起点。掌握后可根据需求迁移到 ECharts(功能更强)或 D3(定制化最高)。

第 1 / 13 节