引言:为什么选择ECharts?

ECharts(Enterprise Charts)是由百度开源的一个使用JavaScript实现的开源可视化库,可以流畅地运行在PC和移动设备上。它提供了丰富的图表类型,包括折线图、柱状图、饼图、散点图、地图、雷达图等,并且支持高度的自定义和交互。对于零基础的学习者来说,ECharts的学习曲线相对平缓,且文档和社区资源丰富,是数据可视化入门的绝佳选择。

第一部分:基础准备

1.1 环境搭建

在开始学习ECharts之前,你需要确保你的开发环境已经准备就绪。以下是基本的环境要求:

  • 浏览器:现代浏览器(如Chrome、Firefox、Safari、Edge)都支持ECharts。
  • 代码编辑器:推荐使用Visual Studio Code(VS Code),它轻量且功能强大,支持丰富的插件。
  • Node.js和npm(可选):如果你打算使用构建工具(如Webpack、Vite)或包管理器(如npm、yarn)来管理项目,建议安装Node.js。你可以从Node.js官网下载并安装。

1.2 获取ECharts

你可以通过以下几种方式获取ECharts:

  1. CDN引入:这是最简单的方式,适合快速原型开发和学习。在HTML文件中直接引入ECharts的CDN链接。
  2. npm安装:如果你使用构建工具,可以通过npm安装ECharts。
  3. 下载源码:从ECharts官网或GitHub仓库下载源码。

示例:使用CDN引入ECharts

创建一个HTML文件,命名为index.html,并添加以下代码:

<!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>

将这个HTML文件在浏览器中打开,你将看到一个简单的柱状图。这就是ECharts的起点。

1.3 理解ECharts的基本概念

在深入学习之前,你需要了解ECharts的几个核心概念:

  • 实例(Instance):通过echarts.init()方法创建的ECharts实例,每个实例对应一个DOM容器。
  • 配置项(Option):一个JavaScript对象,用于描述图表的类型、数据、样式和交互行为。setOption()方法用于将配置项应用到实例上。
  • 系列(Series):图表中的数据系列,例如柱状图中的柱子、折线图中的线条。一个图表可以包含多个系列。
  • 坐标轴(Axis):用于定位数据点的参考系,如X轴和Y轴。

第二部分:核心图表类型详解

2.1 柱状图(Bar Chart)

柱状图用于比较不同类别的数据。ECharts提供了丰富的柱状图配置,包括堆叠柱状图、横向柱状图等。

示例:堆叠柱状图

// 堆叠柱状图配置
var option = {
    title: {
        text: '堆叠柱状图'
    },
    tooltip: {
        trigger: 'axis',
        axisPointer: {
            type: 'shadow'
        }
    },
    legend: {
        data: ['直接访问', '邮件营销', '联盟广告', '视频广告', '搜索引擎']
    },
    grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
    },
    xAxis: {
        type: 'category',
        data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
    },
    yAxis: {
        type: 'value'
    },
    series: [
        {
            name: '直接访问',
            type: 'bar',
            stack: '总量',
            data: [320, 302, 301, 334, 390, 330, 320]
        },
        {
            name: '邮件营销',
            type: 'bar',
            stack: '总量',
            data: [120, 132, 101, 134, 90, 230, 210]
        },
        {
            name: '联盟广告',
            type: 'bar',
            stack: '总量',
            data: [220, 182, 191, 234, 290, 330, 310]
        },
        {
            name: '视频广告',
            type: 'bar',
            stack: '总量',
            data: [150, 212, 201, 154, 190, 330, 410]
        },
        {
            name: '搜索引擎',
            type: 'bar',
            data: [862, 1018, 964, 1026, 1679, 1600, 1570],
            markLine: {
                lineStyle: {
                    type: 'dashed'
                },
                data: [
                    [{type: 'min'}, {type: 'max'}]
                ]
            }
        }
    ]
};

2.2 折线图(Line Chart)

折线图用于展示数据随时间或其他连续变量的变化趋势。

示例:平滑折线图

var option = {
    title: {
        text: '平滑折线图'
    },
    tooltip: {
        trigger: 'axis'
    },
    legend: {
        data: ['邮件营销', '联盟广告', '搜索引擎']
    },
    xAxis: {
        type: 'category',
        boundaryGap: false,
        data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
    },
    yAxis: {
        type: 'value'
    },
    series: [
        {
            name: '邮件营销',
            type: 'line',
            stack: '总量',
            smooth: true,
            data: [120, 132, 101, 134, 90, 230, 210]
        },
        {
            name: '联盟广告',
            type: 'line',
            stack: '总量',
            smooth: true,
            data: [220, 182, 191, 234, 290, 330, 310]
        },
        {
            name: '搜索引擎',
            type: 'line',
            stack: '总量',
            smooth: true,
            data: [820, 932, 901, 934, 1290, 1330, 1320]
        }
    ]
};

2.3 饼图(Pie Chart)

饼图用于显示部分与整体之间的关系。

示例:环形饼图

var option = {
    title: {
        text: '环形饼图',
        left: 'center'
    },
    tooltip: {
        trigger: 'item',
        formatter: '{a} <br/>{b}: {c} ({d}%)'
    },
    legend: {
        orient: 'vertical',
        left: 'left',
        data: ['直接访问', '邮件营销', '联盟广告', '视频广告', '搜索引擎']
    },
    series: [
        {
            name: '访问来源',
            type: 'pie',
            radius: ['40%', '70%'],
            avoidLabelOverlap: false,
            itemStyle: {
                borderRadius: 10,
                borderColor: '#fff',
                borderWidth: 2
            },
            label: {
                show: false,
                position: 'center'
            },
            emphasis: {
                label: {
                    show: true,
                    fontSize: 40,
                    fontWeight: 'bold'
                }
            },
            labelLine: {
                show: false
            },
            data: [
                {value: 1048, name: '搜索引擎'},
                {value: 735, name: '直接访问'},
                {value: 580, name: '邮件营销'},
                {value: 484, name: '联盟广告'},
                {value: 300, name: '视频广告'}
            ]
        }
    ]
};

2.4 散点图(Scatter Plot)

散点图用于展示两个变量之间的关系。

示例:气泡图

var option = {
    title: {
        text: '气泡图',
        left: 'center'
    },
    tooltip: {
        formatter: function (params) {
            return params.value[2] + ' ' + params.value[1] + ' ' + params.value[0];
        }
    },
    xAxis: {
        splitLine: {
            show: false
        }
    },
    yAxis: {
        splitLine: {
            show: false
        }
    },
    series: [{
        symbolSize: function (data) {
            return Math.sqrt(data[2]) * 5;
        },
        data: [
            [10.0, 8.04, 10],
            [8.0, 6.95, 20],
            [13.0, 7.58, 30],
            [9.0, 8.81, 40],
            [11.0, 8.33, 50],
            [14.0, 9.96, 60],
            [6.0, 7.24, 70],
            [4.0, 4.26, 80],
            [12.0, 10.84, 90],
            [7.0, 4.81, 100],
            [5.0, 5.68, 110]
        ],
        type: 'scatter'
    }]
};

2.5 地图(Map)

ECharts支持多种地图类型,包括世界地图、中国地图以及自定义地图。

示例:中国地图

// 注意:需要先注册中国地图数据
// 你可以从ECharts官网下载中国地图的JSON数据,然后注册
// 这里假设你已经注册了中国地图,名为'china'

var option = {
    title: {
        text: '中国地图',
        left: 'center'
    },
    tooltip: {
        trigger: 'item',
        formatter: '{b}<br/>{c} (亿元)'
    },
    visualMap: {
        min: 800,
        max: 50000,
        text: ['高', '低'],
        realtime: false,
        calculable: true,
        inRange: {
            color: ['#50a3ba', '#eac736', '#d94e5d']
        }
    },
    series: [
        {
            name: '中国',
            type: 'map',
            mapType: 'china',
            roam: true,
            label: {
                show: true
            },
            data: [
                {name: '北京', value: 20000},
                {name: '天津', value: 15000},
                {name: '上海', value: 25000},
                {name: '重庆', value: 18000},
                {name: '河北', value: 12000},
                {name: '河南', value: 11000},
                {name: '云南', value: 9000},
                {name: '辽宁', value: 10000},
                {name: '黑龙江', value: 8000},
                {name: '湖南', value: 13000},
                {name: '安徽', value: 14000},
                {name: '山东', value: 16000},
                {name: '新疆', value: 7000},
                {name: '江苏', value: 17000},
                {name: '浙江', value: 18000},
                {name: '江西', value: 12000},
                {name: '湖北', value: 15000},
                {name: '广西', value: 10000},
                {name: '甘肃', value: 6000},
                {name: '山西', value: 11000},
                {name: '内蒙古', value: 9000},
                {name: '陕西', value: 13000},
                {name: '吉林', value: 8000},
                {name: '福建', value: 14000},
                {name: '贵州', value: 7000},
                {name: '广东', value: 22000},
                {name: '青海', value: 5000},
                {name: '西藏', value: 4000},
                {name: '四川', value: 16000},
                {name: '宁夏', value: 6000},
                {name: '海南', value: 8000},
                {name: '台湾', value: 15000},
                {name: '香港', value: 20000},
                {name: '澳门', value: 18000}
            ]
        }
    ]
};

第三部分:高级功能与交互

3.1 动态数据更新

ECharts支持动态更新数据,这对于实时数据可视化非常重要。

示例:动态更新柱状图

// 初始化图表
var myChart = echarts.init(document.getElementById('main'));
var option = {
    title: {
        text: '动态数据'
    },
    xAxis: {
        type: 'category',
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    },
    yAxis: {
        type: 'value'
    },
    series: [{
        data: [820, 932, 901, 934, 1290, 1330, 1320],
        type: 'line'
    }]
};
myChart.setOption(option);

// 每隔2秒更新数据
setInterval(function () {
    // 生成随机数据
    var data = [];
    for (var i = 0; i < 7; i++) {
        data.push(Math.round(Math.random() * 1000));
    }
    // 更新数据
    myChart.setOption({
        series: [{
            data: data
        }]
    });
}, 2000);

3.2 事件监听与交互

ECharts提供了丰富的事件监听机制,允许开发者响应用户的交互行为。

示例:点击事件

// 初始化图表
var myChart = echarts.init(document.getElementById('main'));
var option = {
    title: {
        text: '点击事件示例'
    },
    tooltip: {},
    legend: {
        data:['销量']
    },
    xAxis: {
        data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
    },
    yAxis: {},
    series: [{
        name: '销量',
        type: 'bar',
        data: [5, 20, 36, 10, 10, 20]
    }]
};
myChart.setOption(option);

// 监听点击事件
myChart.on('click', function (params) {
    // params 包含点击的系列、数据点等信息
    console.log('点击了:' + params.name + ',销量:' + params.value);
    alert('你点击了:' + params.name + ',销量:' + params.value);
});

3.3 自定义样式

ECharts允许高度自定义图表的样式,包括颜色、字体、边框等。

示例:自定义柱状图样式

var option = {
    title: {
        text: '自定义样式柱状图',
        textStyle: {
            color: '#333',
            fontSize: 18,
            fontWeight: 'bold'
        }
    },
    tooltip: {
        trigger: 'axis',
        axisPointer: {
            type: 'shadow'
        }
    },
    xAxis: {
        type: 'category',
        data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
        axisLabel: {
            rotate: 45, // 旋转标签
            color: '#666'
        }
    },
    yAxis: {
        type: 'value',
        axisLabel: {
            color: '#666'
        }
    },
    series: [{
        name: '销量',
        type: 'bar',
        data: [120, 200, 150, 80, 70, 110, 130],
        itemStyle: {
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                {offset: 0, color: '#83bff6'},
                {offset: 0.5, color: '#188df0'},
                {offset: 1, color: '#188df0'}
            ]),
            borderRadius: [5, 5, 0, 0] // 圆角
        },
        label: {
            show: true,
            position: 'top',
            color: '#333'
        }
    }]
};

第四部分:实战项目

4.1 项目一:销售数据仪表盘

项目描述

创建一个销售数据仪表盘,展示不同产品的销售情况、趋势和占比。

步骤

  1. 数据准备:准备销售数据,包括产品名称、销售额、销售量、时间等。
  2. 布局设计:使用HTML和CSS布局,将多个图表放置在同一个页面中。
  3. 图表实现:使用ECharts创建柱状图、折线图、饼图等。
  4. 交互与联动:添加交互功能,如点击图表元素显示详细信息。

示例代码

<!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>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 20px;
            background-color: #f5f5f5;
        }
        .container {
            display: grid;
            grid-template-columns: 1fr 1fr;
            grid-template-rows: 300px 300px;
            gap: 20px;
        }
        .chart-box {
            background: white;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            padding: 10px;
        }
        .chart-box h3 {
            margin: 0 0 10px 0;
            color: #333;
            font-size: 16px;
        }
        .chart {
            width: 100%;
            height: 250px;
        }
    </style>
</head>
<body>
    <h1>销售数据仪表盘</h1>
    <div class="container">
        <div class="chart-box">
            <h3>产品销售额(柱状图)</h3>
            <div id="barChart" class="chart"></div>
        </div>
        <div class="chart-box">
            <h3>销售趋势(折线图)</h3>
            <div id="lineChart" class="chart"></div>
        </div>
        <div class="chart-box">
            <h3>产品占比(饼图)</h3>
            <div id="pieChart" class="chart"></div>
        </div>
        <div class="chart-box">
            <h3>销售区域(地图)</h3>
            <div id="mapChart" class="chart"></div>
        </div>
    </div>

    <script>
        // 模拟数据
        const salesData = {
            products: ['产品A', '产品B', '产品C', '产品D', '产品E'],
            sales: [120, 200, 150, 80, 110],
            months: ['1月', '2月', '3月', '4月', '5月', '6月'],
            trend: [120, 132, 101, 134, 90, 230],
            regions: [
                {name: '华北', value: 300},
                {name: '华东', value: 450},
                {name: '华南', value: 280},
                {name: '华中', value: 200},
                {name: '西南', value: 150},
                {name: '西北', value: 100},
                {name: '东北', value: 120}
            ]
        };

        // 柱状图
        const barChart = echarts.init(document.getElementById('barChart'));
        barChart.setOption({
            tooltip: {},
            xAxis: {
                type: 'category',
                data: salesData.products
            },
            yAxis: {
                type: 'value'
            },
            series: [{
                data: salesData.sales,
                type: 'bar',
                itemStyle: {
                    color: '#5470c6'
                }
            }]
        });

        // 折线图
        const lineChart = echarts.init(document.getElementById('lineChart'));
        lineChart.setOption({
            tooltip: {
                trigger: 'axis'
            },
            xAxis: {
                type: 'category',
                data: salesData.months
            },
            yAxis: {
                type: 'value'
            },
            series: [{
                data: salesData.trend,
                type: 'line',
                smooth: true,
                areaStyle: {
                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                        {offset: 0, color: 'rgba(84, 112, 198, 0.5)'},
                        {offset: 1, color: 'rgba(84, 112, 198, 0.1)'}
                    ])
                }
            }]
        });

        // 饼图
        const pieChart = echarts.init(document.getElementById('pieChart'));
        pieChart.setOption({
            tooltip: {
                trigger: 'item',
                formatter: '{b}: {c} ({d}%)'
            },
            series: [{
                type: 'pie',
                radius: ['40%', '70%'],
                data: salesData.products.map((product, index) => ({
                    name: product,
                    value: salesData.sales[index]
                })),
                itemStyle: {
                    borderRadius: 5,
                    borderColor: '#fff',
                    borderWidth: 2
                }
            }]
        });

        // 地图(这里使用中国地图,需要先注册)
        // 注意:实际使用时需要引入中国地图数据
        const mapChart = echarts.init(document.getElementById('mapChart'));
        mapChart.setOption({
            tooltip: {
                trigger: 'item',
                formatter: '{b}: {c}'
            },
            visualMap: {
                min: 0,
                max: 500,
                text: ['高', '低'],
                realtime: false,
                calculable: true,
                inRange: {
                    color: ['#50a3ba', '#eac736', '#d94e5d']
                }
            },
            series: [{
                name: '销售区域',
                type: 'map',
                mapType: 'china',
                roam: true,
                label: {
                    show: true
                },
                data: salesData.regions
            }]
        });

        // 响应窗口大小变化
        window.addEventListener('resize', function() {
            barChart.resize();
            lineChart.resize();
            pieChart.resize();
            mapChart.resize();
        });
    </script>
</body>
</html>

4.2 项目二:实时数据监控面板

项目描述

创建一个实时数据监控面板,展示服务器状态、网络流量等实时数据。

步骤

  1. 数据源:模拟实时数据,或连接WebSocket获取真实数据。
  2. 布局设计:设计一个适合监控的布局,通常使用深色背景。
  3. 图表实现:使用折线图展示趋势,使用仪表盘展示状态。
  4. 实时更新:使用定时器或WebSocket实时更新数据。

示例代码(模拟实时数据)

<!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>
    <style>
        body {
            margin: 0;
            padding: 20px;
            background-color: #1a1a1a;
            color: #fff;
            font-family: Arial, sans-serif;
        }
        .dashboard {
            display: grid;
            grid-template-columns: repeat(2, 1fr);
            grid-template-rows: repeat(2, 300px);
            gap: 20px;
        }
        .panel {
            background: #2a2a2a;
            border-radius: 8px;
            padding: 15px;
            box-shadow: 0 4px 8px rgba(0,0,0,0.3);
        }
        .panel h3 {
            margin: 0 0 10px 0;
            color: #4fc3f7;
            font-size: 16px;
        }
        .chart {
            width: 100%;
            height: 250px;
        }
    </style>
</head>
<body>
    <h1>实时数据监控面板</h1>
    <div class="dashboard">
        <div class="panel">
            <h3>CPU使用率</h3>
            <div id="cpuChart" class="chart"></div>
        </div>
        <div class="panel">
            <h3>内存使用率</h3>
            <div id="memoryChart" class="chart"></div>
        </div>
        <div class="panel">
            <h3>网络流量</h3>
            <div id="networkChart" class="chart"></div>
        </div>
        <div class="panel">
            <h3>服务器状态</h3>
            <div id="statusChart" class="chart"></div>
        </div>
    </div>

    <script>
        // 初始化图表
        const cpuChart = echarts.init(document.getElementById('cpuChart'));
        const memoryChart = echarts.init(document.getElementById('memoryChart'));
        const networkChart = echarts.init(document.getElementById('networkChart'));
        const statusChart = echarts.init(document.getElementById('statusChart'));

        // 初始数据
        let cpuData = [];
        let memoryData = [];
        let networkData = [];
        const maxDataPoints = 20;

        // CPU使用率仪表盘
        cpuChart.setOption({
            series: [{
                type: 'gauge',
                startAngle: 180,
                endAngle: 0,
                min: 0,
                max: 100,
                splitNumber: 10,
                axisLine: {
                    lineStyle: {
                        width: 20,
                        color: [
                            [0.3, '#67e0e3'],
                            [0.7, '#37a2da'],
                            [1, '#ff6e76']
                        ]
                    }
                },
                pointer: {
                    itemStyle: {
                        color: 'auto'
                    }
                },
                axisTick: {
                    distance: -20,
                    length: 8,
                    lineStyle: {
                        color: '#fff',
                        width: 2
                    }
                },
                splitLine: {
                    distance: -20,
                    length: 20,
                    lineStyle: {
                        color: '#fff',
                        width: 4
                    }
                },
                axisLabel: {
                    color: 'auto',
                    distance: 30,
                    fontSize: 12
                },
                detail: {
                    valueAnimation: true,
                    formatter: '{value}%',
                    color: 'auto',
                    fontSize: 20
                },
                data: [{
                    value: 0,
                    name: 'CPU'
                }]
            }]
        });

        // 内存使用率仪表盘
        memoryChart.setOption({
            series: [{
                type: 'gauge',
                startAngle: 180,
                endAngle: 0,
                min: 0,
                max: 100,
                splitNumber: 10,
                axisLine: {
                    lineStyle: {
                        width: 20,
                        color: [
                            [0.3, '#67e0e3'],
                            [0.7, '#37a2da'],
                            [1, '#ff6e76']
                        ]
                    }
                },
                pointer: {
                    itemStyle: {
                        color: 'auto'
                    }
                },
                axisTick: {
                    distance: -20,
                    length: 8,
                    lineStyle: {
                        color: '#fff',
                        width: 2
                    }
                },
                splitLine: {
                    distance: -20,
                    length: 20,
                    lineStyle: {
                        color: '#fff',
                        width: 4
                    }
                },
                axisLabel: {
                    color: 'auto',
                    distance: 30,
                    fontSize: 12
                },
                detail: {
                    valueAnimation: true,
                    formatter: '{value}%',
                    color: 'auto',
                    fontSize: 20
                },
                data: [{
                    value: 0,
                    name: '内存'
                }]
            }]
        });

        // 网络流量折线图
        networkChart.setOption({
            tooltip: {
                trigger: 'axis'
            },
            xAxis: {
                type: 'category',
                boundaryGap: false,
                data: []
            },
            yAxis: {
                type: 'value',
                name: '流量 (KB/s)',
                splitLine: {
                    lineStyle: {
                        color: '#333'
                    }
                }
            },
            series: [{
                data: [],
                type: 'line',
                smooth: true,
                areaStyle: {
                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                        {offset: 0, color: 'rgba(55, 162, 218, 0.5)'},
                        {offset: 1, color: 'rgba(55, 162, 218, 0.1)'}
                    ])
                },
                itemStyle: {
                    color: '#37a2da'
                }
            }]
        });

        // 服务器状态饼图
        statusChart.setOption({
            tooltip: {
                trigger: 'item',
                formatter: '{b}: {c} ({d}%)'
            },
            series: [{
                type: 'pie',
                radius: ['40%', '70%'],
                avoidLabelOverlap: false,
                itemStyle: {
                    borderRadius: 5,
                    borderColor: '#1a1a1a',
                    borderWidth: 2
                },
                label: {
                    show: false,
                    position: 'center'
                },
                emphasis: {
                    label: {
                        show: true,
                        fontSize: 20,
                        fontWeight: 'bold',
                        color: '#fff'
                    }
                },
                data: [
                    {value: 0, name: '正常', itemStyle: {color: '#67e0e3'}},
                    {value: 0, name: '警告', itemStyle: {color: '#37a2da'}},
                    {value: 0, name: '异常', itemStyle: {color: '#ff6e76'}}
                ]
            }]
        });

        // 模拟实时数据更新
        function updateData() {
            // 生成随机数据
            const cpuValue = Math.round(Math.random() * 100);
            const memoryValue = Math.round(Math.random() * 100);
            const networkValue = Math.round(Math.random() * 1000);
            const now = new Date();
            const timeStr = now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds();

            // 更新CPU仪表盘
            cpuChart.setOption({
                series: [{
                    data: [{
                        value: cpuValue,
                        name: 'CPU'
                    }]
                }]
            });

            // 更新内存仪表盘
            memoryChart.setOption({
                series: [{
                    data: [{
                        value: memoryValue,
                        name: '内存'
                    }]
                }]
            });

            // 更新网络流量
            if (networkData.length >= maxDataPoints) {
                networkData.shift();
            }
            networkData.push(networkValue);

            if (networkChart.getOption().xAxis[0].data.length >= maxDataPoints) {
                networkChart.getOption().xAxis[0].data.shift();
            }
            networkChart.getOption().xAxis[0].data.push(timeStr);

            networkChart.setOption({
                xAxis: {
                    data: networkChart.getOption().xAxis[0].data
                },
                series: [{
                    data: networkData
                }]
            });

            // 更新服务器状态
            const statusData = [
                {value: Math.round(Math.random() * 50), name: '正常'},
                {value: Math.round(Math.random() * 30), name: '警告'},
                {value: Math.round(Math.random() * 20), name: '异常'}
            ];
            statusChart.setOption({
                series: [{
                    data: statusData
                }]
            });
        }

        // 每秒更新一次数据
        setInterval(updateData, 1000);

        // 响应窗口大小变化
        window.addEventListener('resize', function() {
            cpuChart.resize();
            memoryChart.resize();
            networkChart.resize();
            statusChart.resize();
        });
    </script>
</body>
</html>

第五部分:学习资源与进阶建议

5.1 官方文档与教程

5.2 社区与论坛

  • ECharts官方论坛https://github.com/apache/echarts/discussions - 提问和讨论。
  • Stack Overflow:搜索ECharts相关问题,通常能找到解决方案。
  • 中文社区:如SegmentFault、掘金等平台有大量ECharts相关文章。

5.3 进阶学习路径

  1. 深入学习配置项:掌握所有常用配置项,理解其作用和组合方式。
  2. 学习自定义系列:通过custom系列实现更复杂的图表。
  3. 学习ECharts与框架集成:如React、Vue、Angular等框架中使用ECharts。
  4. 学习性能优化:处理大数据量时的性能优化技巧。
  5. 学习ECharts扩展:如ECharts GL(3D图表)、ECharts Flow(流程图)等。

5.4 常见问题与解决方案

问题1:图表不显示或显示不全

  • 原因:DOM容器没有设置宽高,或宽高为0。
  • 解决方案:确保容器有明确的宽高,可以使用CSS设置。

问题2:数据更新后图表没有变化

  • 原因setOption方法调用时,ECharts会合并新旧配置项,如果新旧配置项结构相同,可能不会触发更新。
  • 解决方案:使用setOption的第二个参数notMerge设置为true,强制更新。

问题3:图表在移动端显示异常

  • 原因:没有正确处理响应式布局。
  • 解决方案:监听resize事件,调用chart.resize()方法。

结语

通过以上学习路线,你可以从零基础开始,逐步掌握ECharts的使用。从简单的柱状图、折线图,到复杂的仪表盘和实时监控面板,ECharts都能胜任。记住,实践是最好的老师,多动手写代码,多参考官方示例,你一定能成为ECharts的高手。祝你学习愉快!