1. Echarts 简介

Echarts 是一个由百度开源的,使用 JavaScript 实现的开源可视化库,可以流畅地运行在 PC 和移动设备上。它提供了丰富的图表类型,包括折线图、柱状图、饼图、散点图、地图等,并且支持高度的定制化。Echarts 基于 Canvas 和 SVG 渲染,性能优秀,且拥有活跃的社区和丰富的文档。

1.1 为什么选择 Echarts?

  • 开源免费:Apache 2.0 许可证,可以免费用于商业项目。
  • 功能强大:支持多种图表类型和交互组件。
  • 易于上手:文档详细,示例丰富,适合初学者。
  • 高性能:支持大数据量渲染,流畅的动画效果。
  • 跨平台:兼容主流浏览器,支持移动端。

2. 环境准备与安装

在开始使用 Echarts 之前,我们需要准备好开发环境。Echarts 可以在多种环境中使用,包括原生 HTML/JS、Vue、React 等。这里我们以最基础的原生 HTML/JS 环境为例。

2.1 安装 Echarts

方法一:通过 CDN 引入(推荐初学者)

这是最简单的方式,无需下载任何文件,只需在 HTML 文件中引入 Echarts 的 CDN 链接即可。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Echarts 入门示例</title>
    <!-- 引入 Echarts -->
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
</head>
<body>
    <!-- 准备一个具备大小(宽高)的 DOM -->
    <div id="main" style="width: 600px;height:400px;"></div>
    <script type="text/javascript">
        // 基于准备好的dom,初始化echarts实例
        var myChart = echarts.init(document.getElementById('main'));
        
        // 指定图表的配置项和数据
        var option = {
            title: {
                text: 'ECharts 入门示例'
            },
            tooltip: {},
            legend: {
                data:['销量']
            },
            xAxis: {
                data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
            },
            yAxis: {},
            series: [{
                name: '销量',
                type: 'bar',
                data: [5, 20, 36, 10, 10, 20]
            }]
        };
        
        // 使用刚指定的配置项和数据显示图表。
        myChart.setOption(option);
    </script>
</body>
</html>

说明

  • 首先,我们引入了 Echarts 的 CDN 链接。
  • 然后,创建一个 div 元素作为图表的容器,并设置了宽度和高度。
  • 接着,使用 echarts.init() 初始化 Echarts 实例。
  • 最后,定义一个 option 对象,包含图表的配置和数据,并调用 setOption() 方法渲染图表。

方法二:通过 npm 安装(推荐项目开发)

如果你正在使用 Node.js 环境或构建工具(如 Webpack、Vite),可以通过 npm 安装 Echarts。

npm install echarts

然后在你的 JavaScript 文件中引入:

// 引入 ECharts 模块
import * as echarts from 'echarts';

// 初始化
const chartDom = document.getElementById('main');
const myChart = echarts.init(chartDom);

// 配置项
const option = {
    // ... 你的配置
};

// 渲染
myChart.setOption(option);

3. Echarts 核心概念

要熟练使用 Echarts,必须理解其核心概念:配置项(Option)。Echarts 的所有图表都是通过配置 option 对象来生成的。option 对象包含多个部分,每个部分对应图表的不同组件。

3.1 配置项结构

一个完整的 option 对象通常包含以下部分:

const option = {
    // 1. 标题组件
    title: {
        text: '主标题',
        subtext: '副标题',
        left: 'center' // 标题位置
    },
    
    // 2. 提示框组件
    tooltip: {
        trigger: 'axis', // 触发类型:'item'(数据项图形触发)或 'axis'(坐标轴触发)
        axisPointer: { // 坐标轴指示器配置
            type: 'cross' // 指示器类型:'line'(直线指示器)、'shadow'(阴影指示器)、'cross'(十字准星指示器)
        }
    },
    
    // 3. 图例组件
    legend: {
        data: ['系列1', '系列2'], // 图例数据,与 series 中的 name 对应
        top: 10 // 图例位置
    },
    
    // 4. 坐标轴组件
    xAxis: {
        type: 'category', // 类型:'category'(类目轴)、'value'(数值轴)、'time'(时间轴)
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] // 类目轴数据
    },
    yAxis: {
        type: 'value' // 数值轴
    },
    
    // 5. 系列列表(图表数据)
    series: [
        {
            name: '系列1', // 系列名称,与 legend 的 data 对应
            type: 'line', // 图表类型:'line'(折线图)、'bar'(柱状图)、'pie'(饼图)等
            data: [820, 932, 901, 934, 1290, 1330, 1320], // 数据
            smooth: true, // 平滑曲线
            areaStyle: { // 区域填充样式
                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                    { offset: 0, color: 'rgba(58, 132, 255, 0.5)' },
                    { offset: 1, color: 'rgba(58, 132, 255, 0.0)' }
                ])
            }
        },
        {
            name: '系列2',
            type: 'bar',
            data: [620, 732, 701, 734, 1090, 1130, 1120]
        }
    ],
    
    // 6. 其他组件(如工具栏、数据缩放等)
    toolbox: {
        feature: {
            dataZoom: {
                yAxisIndex: 'none'
            },
            restore: {},
            saveAsImage: {}
        }
    },
    dataZoom: [
        {
            type: 'inside',
            start: 0,
            end: 100
        },
        {
            start: 0,
            end: 100,
            handleIcon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
            handleSize: '80%',
            handleStyle: {
                color: '#fff',
                shadowBlur: 3,
                shadowColor: 'rgba(0, 0, 0, 0.6)',
                shadowOffsetX: 2,
                shadowOffsetY: 2
            }
        }
    ]
};

3.2 关键概念详解

3.2.1 系列(Series)

系列是图表的数据集合,每个系列对应一种图表类型(如折线、柱状、饼图等)。一个图表可以包含多个系列,例如同时显示折线图和柱状图。

series: [
    {
        name: '销售额',
        type: 'bar',
        data: [100, 200, 150, 300, 250],
        // 柱状图特定配置
        barWidth: '60%', // 柱状图宽度
        itemStyle: {
            color: '#5470c6'
        }
    },
    {
        name: '增长率',
        type: 'line',
        data: [10, 20, 15, 30, 25],
        yAxisIndex: 1, // 使用第二个Y轴
        lineStyle: {
            width: 3,
            color: '#91cc75'
        }
    }
]

3.2.2 坐标轴(Axis)

坐标轴用于定义数据的维度。Echarts 支持多种坐标轴类型,最常用的是类目轴(category)和数值轴(value)。

xAxis: {
    type: 'category',
    data: ['一月', '二月', '三月', '四月', '五月'],
    axisLabel: {
        rotate: 45 // X轴标签旋转45度,防止重叠
    }
},
yAxis: [
    {
        type: 'value',
        name: '销售额(万元)',
        position: 'left'
    },
    {
        type: 'value',
        name: '增长率(%)',
        position: 'right'
    }
]

3.2.3 提示框(Tooltip)

提示框用于在鼠标悬停时显示详细信息。可以通过 formatter 函数自定义内容。

tooltip: {
    trigger: 'axis',
    axisPointer: {
        type: 'cross'
    },
    formatter: function(params) {
        // params 是一个数组,包含当前悬停点的所有系列数据
        let html = `<div style="font-weight:bold; margin-bottom:5px;">${params[0].axisValue}</div>`;
        params.forEach(item => {
            html += `<div style="color:${item.color}">${item.seriesName}: ${item.value}</div>`;
        });
        return html;
    }
}

4. 常用图表类型实战

4.1 柱状图(Bar Chart)

柱状图用于比较不同类别的数值大小。下面是一个完整的柱状图示例,包含数据缩放和工具箱。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>柱状图示例</title>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
</head>
<body>
    <div id="barChart" style="width: 800px;height:500px;"></div>
    <script>
        const chartDom = document.getElementById('barChart');
        const myChart = echarts.init(chartDom);
        
        // 模拟数据:2023年各季度销售额
        const data = {
            quarters: ['Q1', 'Q2', 'Q3', 'Q4'],
            sales: [120, 200, 150, 80],
            target: [100, 180, 160, 90]
        };
        
        const option = {
            title: {
                text: '2023年各季度销售额',
                subtext: '单位:万元',
                left: 'center'
            },
            tooltip: {
                trigger: 'axis',
                axisPointer: {
                    type: 'shadow'
                }
            },
            legend: {
                data: ['实际销售额', '目标销售额'],
                top: 30
            },
            grid: {
                left: '3%',
                right: '4%',
                bottom: '3%',
                containLabel: true
            },
            xAxis: {
                type: 'category',
                data: data.quarters,
                axisTick: {
                    alignWithLabel: true
                }
            },
            yAxis: {
                type: 'value',
                name: '销售额(万元)'
            },
            dataZoom: [
                {
                    type: 'inside',
                    start: 0,
                    end: 100
                },
                {
                    start: 0,
                    end: 100,
                    handleIcon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
                    handleSize: '80%',
                    handleStyle: {
                        color: '#fff',
                        shadowBlur: 3,
                        shadowColor: 'rgba(0, 0, 0, 0.6)',
                        shadowOffsetX: 2,
                        shadowOffsetY: 2
                    }
                }
            ],
            series: [
                {
                    name: '实际销售额',
                    type: 'bar',
                    barWidth: '60%',
                    data: data.sales,
                    itemStyle: {
                        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                            { offset: 0, color: '#83bff6' },
                            { offset: 0.5, color: '#188df0' },
                            { offset: 1, color: '#188df0' }
                        ])
                    },
                    // 柱状图顶部标签
                    label: {
                        show: true,
                        position: 'top',
                        formatter: '{c}'
                    }
                },
                {
                    name: '目标销售额',
                    type: 'bar',
                    barWidth: '60%',
                    data: data.target,
                    itemStyle: {
                        color: '#91cc75'
                    },
                    label: {
                        show: true,
                        position: 'top',
                        formatter: '{c}'
                    }
                }
            ],
            toolbox: {
                feature: {
                    dataZoom: {
                        yAxisIndex: 'none'
                    },
                    restore: {},
                    saveAsImage: {}
                }
            }
        };
        
        myChart.setOption(option);
        
        // 响应窗口大小变化
        window.addEventListener('resize', function() {
            myChart.resize();
        });
    </script>
</body>
</html>

代码说明

  1. 数据准备:使用对象存储季度和销售额数据,便于维护。
  2. 渐变色:使用 echarts.graphic.LinearGradient 为柱状图添加渐变效果,提升视觉吸引力。
  3. 标签显示:在柱状图顶部显示具体数值。
  4. 数据缩放:添加了 dataZoom 组件,当数据量大时可以缩放查看。
  5. 工具箱:提供了数据缩放、恢复和保存为图片的功能。
  6. 响应式:监听窗口大小变化,自动调整图表尺寸。

4.2 折线图(Line Chart)

折线图常用于展示数据随时间的变化趋势。下面是一个包含多个系列和标记点的折线图示例。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>折线图示例</title>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
</head>
<body>
    <div id="lineChart" style="width: 800px;height:500px;"></div>
    <script>
        const chartDom = document.getElementById('lineChart');
        const myChart = echarts.init(chartDom);
        
        // 模拟数据:2023年每月用户增长情况
        const months = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'];
        const newUsers = [120, 132, 101, 134, 90, 230, 210, 200, 150, 180, 160, 170];
        const activeUsers = [220, 182, 191, 234, 290, 330, 310, 320, 300, 350, 380, 400];
        
        const option = {
            title: {
                text: '2023年用户增长趋势',
                left: 'center'
            },
            tooltip: {
                trigger: 'axis',
                axisPointer: {
                    type: 'cross',
                    label: {
                        backgroundColor: '#6a7985'
                    }
                }
            },
            legend: {
                data: ['新增用户', '活跃用户'],
                top: 30
            },
            grid: {
                left: '3%',
                right: '4%',
                bottom: '3%',
                containLabel: true
            },
            xAxis: {
                type: 'category',
                boundaryGap: false,
                data: months
            },
            yAxis: {
                type: 'value',
                name: '用户数'
            },
            series: [
                {
                    name: '新增用户',
                    type: 'line',
                    smooth: true, // 平滑曲线
                    data: newUsers,
                    // 标记点
                    markPoint: {
                        data: [
                            { type: 'max', name: '最大值' },
                            { type: 'min', name: '最小值' }
                        ]
                    },
                    // 标记线
                    markLine: {
                        data: [
                            { type: 'average', name: '平均值' }
                        ]
                    },
                    // 区域填充
                    areaStyle: {
                        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                            { offset: 0, color: 'rgba(255, 0, 0, 0.3)' },
                            { offset: 1, color: 'rgba(255, 0, 0, 0.0)' }
                        ])
                    },
                    lineStyle: {
                        width: 3,
                        color: '#ff0000'
                    }
                },
                {
                    name: '活跃用户',
                    type: 'line',
                    smooth: true,
                    data: activeUsers,
                    markPoint: {
                        data: [
                            { type: 'max', name: '最大值' },
                            { type: 'min', name: '最小值' }
                        ]
                    },
                    markLine: {
                        data: [
                            { type: 'average', name: '平均值' }
                        ]
                    },
                    areaStyle: {
                        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                            { offset: 0, color: 'rgba(0, 255, 0, 0.3)' },
                            { offset: 1, color: 'rgba(0, 255, 0, 0.0)' }
                        ])
                    },
                    lineStyle: {
                        width: 3,
                        color: '#00ff00'
                    }
                }
            ],
            toolbox: {
                feature: {
                    dataZoom: {
                        yAxisIndex: 'none'
                    },
                    restore: {},
                    saveAsImage: {}
                }
            },
            dataZoom: [
                {
                    type: 'inside',
                    start: 0,
                    end: 100
                },
                {
                    start: 0,
                    end: 100,
                    handleIcon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
                    handleSize: '80%',
                    handleStyle: {
                        color: '#fff',
                        shadowBlur: 3,
                        shadowColor: 'rgba(0, 0, 0, 0.6)',
                        shadowOffsetX: 2,
                        shadowOffsetY: 2
                    }
                }
            ]
        };
        
        myChart.setOption(option);
        
        window.addEventListener('resize', function() {
            myChart.resize();
        });
    </script>
</body>
</html>

代码说明

  1. 平滑曲线smooth: true 使折线图变为平滑曲线,视觉效果更好。
  2. 标记点与标记线markPointmarkLine 用于突出显示最大值、最小值和平均值。
  3. 区域填充areaStyle 为折线下方添加渐变填充,增强视觉效果。
  4. 多系列对比:同时展示新增用户和活跃用户,便于对比分析。

4.3 饼图(Pie Chart)

饼图用于展示各部分占总体的比例。下面是一个环形饼图示例,包含标签和提示框自定义。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>饼图示例</title>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
</head>
<body>
    <div id="pieChart" style="width: 800px;height:500px;"></div>
    <script>
        const chartDom = document.getElementById('pieChart');
        const myChart = echarts.init(chartDom);
        
        // 模拟数据:2023年产品销售占比
        const data = [
            { value: 1048, name: '产品A' },
            { value: 735, name: '产品B' },
            { value: 580, name: '产品C' },
            { value: 484, name: '产品D' },
            { value: 300, name: '其他' }
        ];
        
        const option = {
            title: {
                text: '2023年产品销售占比',
                subtext: '单位:万元',
                left: 'center'
            },
            tooltip: {
                trigger: 'item',
                formatter: '{b}: {c} ({d}%)' // 自定义提示框格式
            },
            legend: {
                orient: 'vertical',
                left: 'left',
                data: data.map(item => item.name)
            },
            series: [
                {
                    name: '销售占比',
                    type: 'pie',
                    radius: ['40%', '70%'], // 环形饼图
                    avoidLabelOverlap: false,
                    itemStyle: {
                        borderRadius: 10, // 圆角
                        borderColor: '#fff',
                        borderWidth: 2
                    },
                    label: {
                        show: true,
                        formatter: '{b}: {d}%' // 标签显示名称和百分比
                    },
                    emphasis: {
                        label: {
                            show: true,
                            fontSize: 16,
                            fontWeight: 'bold'
                        },
                        itemStyle: {
                            shadowBlur: 10,
                            shadowOffsetX: 0,
                            shadowColor: 'rgba(0, 0, 0, 0.5)'
                        }
                    },
                    labelLine: {
                        show: true,
                        length: 15,
                        length2: 10
                    },
                    data: data,
                    // 颜色数组
                    color: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de']
                }
            ],
            toolbox: {
                feature: {
                    saveAsImage: {}
                }
            }
        };
        
        myChart.setOption(option);
        
        window.addEventListener('resize', function() {
            myChart.resize();
        });
    </script>
</body>
</html>

代码说明

  1. 环形饼图:通过 radius: ['40%', '70%'] 实现环形效果。
  2. 圆角与边框borderRadiusborderWidth 增强视觉效果。
  3. 标签格式formatter 自定义标签显示内容。
  4. 强调效果emphasis 配置鼠标悬停时的放大和阴影效果。
  5. 自定义颜色:通过 color 数组指定每个扇区的颜色。

4.4 散点图(Scatter Chart)

散点图用于展示两个变量之间的关系。下面是一个散点图示例,包含回归线和数据缩放。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>散点图示例</title>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
</head>
<body>
    <div id="scatterChart" style="width: 800px;height:500px;"></div>
    <script>
        const chartDom = document.getElementById('scatterChart');
        const myChart = echarts.init(chartDom);
        
        // 模拟数据:广告投入与销售额的关系
        const data = [
            [10, 85], [20, 95], [30, 110], [40, 130], [50, 150],
            [60, 170], [70, 190], [80, 210], [90, 230], [100, 250],
            [15, 90], [25, 100], [35, 120], [45, 140], [55, 160],
            [65, 180], [75, 200], [85, 220], [95, 240], [105, 260]
        ];
        
        const option = {
            title: {
                text: '广告投入与销售额关系',
                left: 'center'
            },
            tooltip: {
                trigger: 'item',
                formatter: function(params) {
                    return `广告投入: ${params.value[0]}万元<br/>销售额: ${params.value[1]}万元`;
                }
            },
            grid: {
                left: '3%',
                right: '4%',
                bottom: '3%',
                containLabel: true
            },
            xAxis: {
                type: 'value',
                name: '广告投入(万元)',
                splitLine: {
                    show: false
                }
            },
            yAxis: {
                type: 'value',
                name: '销售额(万元)',
                splitLine: {
                    lineStyle: {
                        type: 'dashed'
                    }
                }
            },
            series: [
                {
                    name: '数据点',
                    type: 'scatter',
                    symbolSize: function(data) {
                        // 根据销售额调整点的大小
                        return data[1] / 10;
                    },
                    data: data,
                    itemStyle: {
                        color: '#5470c6',
                        shadowBlur: 10,
                        shadowColor: 'rgba(84, 112, 198, 0.5)',
                        shadowOffsetX: 0,
                        shadowOffsetY: 0
                    },
                    // 回归线(线性回归)
                    markLine: {
                        lineStyle: {
                            type: 'solid',
                            color: '#ff0000',
                            width: 2
                        },
                        data: [
                            [
                                { coord: [10, 85], symbol: 'none' },
                                { coord: [105, 260], symbol: 'none' }
                            ]
                        ]
                    }
                }
            ],
            toolbox: {
                feature: {
                    dataZoom: {
                        yAxisIndex: 'none'
                    },
                    restore: {},
                    saveAsImage: {}
                }
            },
            dataZoom: [
                {
                    type: 'inside',
                    start: 0,
                    end: 100
                },
                {
                    start: 0,
                    end: 100,
                    handleIcon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
                    handleSize: '80%',
                    handleStyle: {
                        color: '#fff',
                        shadowBlur: 3,
                        shadowColor: 'rgba(0, 0, 0, 0.6)',
                        shadowOffsetX: 2,
                        shadowOffsetY: 2
                    }
                }
            ]
        };
        
        myChart.setOption(option);
        
        window.addEventListener('resize', function() {
            myChart.resize();
        });
    </script>
</body>
</html>

代码说明

  1. 动态点大小:通过 symbolSize 函数根据销售额动态调整点的大小。
  2. 回归线:使用 markLine 添加一条简单的回归线(示例中为直线,实际中可使用算法计算回归线)。
  3. 阴影效果:为散点添加阴影,增强立体感。
  4. 数据缩放:支持数据缩放,便于查看密集数据点。

5. 进阶技巧与最佳实践

5.1 响应式图表

在实际项目中,图表需要适应不同屏幕尺寸。可以通过监听窗口 resize 事件并调用 myChart.resize() 来实现。

// 初始化图表
const myChart = echarts.init(document.getElementById('main'));

// 监听窗口大小变化
window.addEventListener('resize', function() {
    myChart.resize();
});

5.2 动态更新数据

Echarts 支持动态更新数据,无需重新初始化图表。

// 假设有一个定时器,每5秒更新一次数据
setInterval(() => {
    // 生成新数据
    const newData = generateNewData();
    
    // 更新图表
    myChart.setOption({
        series: [{
            data: newData
        }]
    });
}, 5000);

5.3 使用主题

Echarts 提供了内置主题(如 dark),也可以自定义主题。

// 使用内置暗色主题
const myChart = echarts.init(document.getElementById('main'), 'dark');

// 或者自定义主题
const customTheme = {
    color: ['#ff7875', '#ffc069', '#95de64', '#5cdbd3', '#69c0ff'],
    backgroundColor: '#f0f2f5',
    textStyle: {
        fontFamily: 'Arial'
    }
};
echarts.registerTheme('custom', customTheme);
const myChart = echarts.init(document.getElementById('main'), 'custom');

5.4 性能优化

当数据量非常大时(如超过10万条),可以采取以下优化措施:

  1. 使用 large: true:适用于大数据量的散点图。
  2. 关闭动画animation: false
  3. 使用 progressive 渐进式渲染
series: [{
    type: 'scatter',
    large: true, // 大数据量优化
    progressive: 1000, // 渐进式渲染,每帧渲染1000个点
    data: largeData // 大数据集
}]

5.5 与框架集成

5.5.1 Vue 集成

在 Vue 中,可以使用 vue-echarts 组件库。

npm install echarts vue-echarts
<template>
  <div>
    <v-chart :option="option" style="width: 100%; height: 400px;" />
  </div>
</template>

<script>
import { defineComponent } from 'vue';
import VChart from 'vue-echarts';
import { use } from 'echarts/core';
import { BarChart } from 'echarts/charts';
import { TitleComponent, TooltipComponent, GridComponent } from 'echarts/components';

// 按需引入
use([
  BarChart,
  TitleComponent,
  TooltipComponent,
  GridComponent
]);

export default defineComponent({
  components: {
    VChart
  },
  data() {
    return {
      option: {
        title: {
          text: 'Vue 集成 Echarts 示例'
        },
        tooltip: {},
        xAxis: {
          data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
        },
        yAxis: {},
        series: [{
          name: '销量',
          type: 'bar',
          data: [5, 20, 36, 10, 10, 20]
        }]
      }
    };
  }
});
</script>

5.5.2 React 集成

在 React 中,可以使用 echarts-for-react 组件库。

npm install echarts echarts-for-react
import React from 'react';
import ReactECharts from 'echarts-for-react';

const EchartsComponent = () => {
  const option = {
    title: {
      text: 'React 集成 Echarts 示例'
    },
    tooltip: {},
    xAxis: {
      data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
    },
    yAxis: {},
    series: [{
      name: '销量',
      type: 'bar',
      data: [5, 20, 36, 10, 10, 20]
    }]
  };

  return (
    <div>
      <ReactECharts
        option={option}
        style={{ height: '400px', width: '100%' }}
        onEvents={{
          click: (params) => {
            console.log('点击了', params);
          }
        }}
      />
    </div>
  );
};

export default EchartsComponent;

6. 常见问题与解决方案

6.1 图表不显示

问题:图表容器没有设置宽高,或者 echarts.init() 时容器不存在。 解决方案

  1. 确保容器有明确的宽高(如 style="width: 600px; height: 400px;")。
  2. 确保在 DOM 加载完成后初始化图表(将脚本放在 </body> 前,或使用 DOMContentLoaded 事件)。
// 确保 DOM 加载完成
document.addEventListener('DOMContentLoaded', function() {
    const chartDom = document.getElementById('main');
    if (chartDom) {
        const myChart = echarts.init(chartDom);
        // ... 设置 option
    }
});

6.2 数据更新后图表不刷新

问题:使用 setOption 更新数据时,图表没有变化。 解决方案:确保 setOption 被正确调用,并且数据格式正确。可以使用 notMerge 参数控制是否合并配置。

// 不合并配置,完全替换
myChart.setOption(newOption, true);

// 或者使用 notMerge 参数
myChart.setOption(newOption, { notMerge: true });

6.3 移动端适配问题

问题:在移动端显示不正常,如字体过小、触摸交互不灵敏。 解决方案

  1. 使用 remvw 单位设置容器大小。
  2. 调整 tooltiplabel 的字体大小。
  3. 使用 dataZoom 的移动端适配配置。
// 移动端适配配置
const option = {
    // ... 其他配置
    tooltip: {
        textStyle: {
            fontSize: 12 // 移动端字体调小
        }
    },
    label: {
        fontSize: 10
    },
    dataZoom: [
        {
            type: 'inside',
            start: 0,
            end: 100,
            zoomOnMouseWheel: false, // 关闭滚轮缩放
            moveOnMouseMove: true, // 移动端拖拽
            moveOnMouseWheel: false
        }
    ]
};

7. 学习资源与扩展

7.1 官方文档

7.2 推荐书籍

  • 《Echarts 数据可视化》
  • 《JavaScript 数据可视化》

7.3 社区与论坛

7.4 扩展学习

  1. 学习 D3.js:D3.js 是更底层的可视化库,学习 D3 可以帮助理解 Echarts 的底层原理。
  2. 学习 WebGL:Echarts 支持 WebGL 渲染,学习 WebGL 可以处理更复杂的可视化场景。
  3. 学习数据可视化理论:了解可视化原则、颜色理论、图表选择等。

8. 总结

通过本指南,你已经从零开始学习了 Echarts 的安装、核心概念、常用图表类型以及进阶技巧。从简单的柱状图到复杂的散点图,从原生 HTML/JS 到 Vue/React 集成,你已经掌握了 Echarts 的基本使用方法。

下一步建议

  1. 实践项目:尝试用 Echarts 制作一个个人数据仪表盘,整合多种图表类型。
  2. 深入源码:阅读 Echarts 源码,理解其架构和实现原理。
  3. 参与社区:在 GitHub 上提交 Issue 或 PR,为 Echarts 社区做贡献。

记住,数据可视化不仅仅是技术实现,更重要的是如何通过图表清晰、准确地传达信息。不断练习和探索,你将能够创建出既美观又实用的数据可视化作品。

祝你学习愉快!