折线图 (趋势/平滑)
ECharts 折线图完全指南:从基础到高级应用
📖 概述
折线图(Line Chart)是最常用的图表类型之一,用于显示数据随时间或类别的变化趋势。ECharts 提供了丰富的配置选项,支持普通折线、平滑曲线、阶梯线、面积图等多种变体。
核心特点:
- 支持直角坐标系和极坐标系
- 内置多种插值算法(平滑曲线)
- 支持面积填充
- 支持断点处理
- 大数据量优化
🔍 核心概念
1. 基础折线图
javascript
option = {
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line'
}]
};1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
2. 平滑曲线
javascript
series: [{
type: 'line',
smooth: true, // 开启平滑
smoothMonotone: 'x', // 平滑方向
data: [150, 230, 224, 218, 135, 147, 260]
}]1
2
3
4
5
6
2
3
4
5
6
smooth 参数说明:
false: 直线(默认)true: 自动平滑number (0-1): 平滑程度,0.5 为中等平滑
3. 阶梯线
javascript
series: [{
type: 'line',
step: 'start', // 'start' | 'middle' | 'end'
data: [150, 230, 224, 218, 135, 147, 260]
}]1
2
3
4
5
2
3
4
5
4. 面积图
javascript
series: [{
type: 'line',
areaStyle: {
opacity: 0.3,
color: '#5470c6'
},
data: [150, 230, 224, 218, 135, 147, 260]
}]1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
💡 使用场景
场景 1: 时间序列趋势
javascript
// 股票价格走势
option = {
title: { text: '股票价格走势' },
tooltip: { trigger: 'axis' },
xAxis: {
type: 'time',
axisLabel: { formatter: '{MM}-{dd}' }
},
yAxis: { type: 'value' },
series: [{
name: '收盘价',
type: 'line',
data: stockData,
smooth: true,
symbol: 'none' // 隐藏数据点
}]
};1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
场景 2: 多系列对比
javascript
option = {
legend: { data: ['2023年', '2024年'] },
xAxis: { type: 'category', data: months },
yAxis: { type: 'value' },
series: [
{
name: '2023年',
type: 'line',
data: data2023,
lineStyle: { color: '#91cc75' }
},
{
name: '2024年',
type: 'line',
data: data2024,
lineStyle: { color: '#5470c6' }
}
]
};1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
场景 3: 阈值告警
javascript
option = {
series: [
{
name: '实际值',
type: 'line',
data: actualData,
markLine: {
data: [
{ yAxis: 80, name: '警告线', lineStyle: { color: '#fac858' } },
{ yAxis: 100, name: '危险线', lineStyle: { color: '#ee6666' } }
]
}
}
]
};1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
🔧 配置详解
线条样式
javascript
series: [{
type: 'line',
// 线条样式
lineStyle: {
width: 2, // 线宽
color: '#5470c6', // 颜色
type: 'solid', // 线型: 'solid' | 'dashed' | 'dotted'
opacity: 1 // 透明度
},
// 数据点样式
symbol: 'circle', // 点的形状
symbolSize: 4, // 点的大小
symbolRotate: 0, // 点的旋转角度
showSymbol: true, // 是否显示点
// 数据点单独样式
itemStyle: {
color: '#fff',
borderColor: '#5470c6',
borderWidth: 2
}
}]1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
标签配置
javascript
series: [{
type: 'line',
label: {
show: true,
position: 'top', // 'top' | 'bottom' | 'left' | 'right'
formatter: '{c}', // 格式化字符串
fontSize: 12,
color: '#333'
}
}]1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
断点处理
javascript
// 使用 null 或 '-' 表示断点
series: [{
type: 'line',
connectNulls: false, // 是否连接空值
data: [120, 132, null, 190, '-', 230, 210]
}]1
2
3
4
5
6
2
3
4
5
6
大数据优化
javascript
series: [{
type: 'line',
data: hugeData, // 10万+数据
showSymbol: false, // 关闭数据点
hoverAnimation: false, // 关闭悬停动画
sampling: 'lttb', // 降采样算法
animation: false // 关闭动画
}]1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
📝 代码示例
示例 1: 完整业务案例 - 销售趋势分析
javascript
const option = {
title: {
text: '月度销售趋势分析',
left: 'center'
},
tooltip: {
trigger: 'axis',
formatter: function(params) {
const data = params[0];
return `
<div style="padding: 8px">
<strong>${data.name}</strong><br/>
销售额: ¥${data.value.toLocaleString()}<br/>
环比增长: +12.5%
</div>
`;
}
},
legend: {
data: ['销售额', '目标', '去年同期'],
top: 30
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['1月', '2月', '3月', '4月', '5月', '6月',
'7月', '8月', '9月', '10月', '11月', '12月']
},
yAxis: {
type: 'value',
axisLabel: {
formatter: '¥{value}'
}
},
series: [
{
name: '销售额',
type: 'line',
smooth: true,
data: [120000, 132000, 101000, 134000, 90000, 230000,
210000, 200000, 220000, 250000, 280000, 300000],
lineStyle: {
width: 3,
color: '#5470c6'
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(84, 112, 198, 0.3)' },
{ offset: 1, color: 'rgba(84, 112, 198, 0.05)' }
])
}
},
{
name: '目标',
type: 'line',
data: [100000, 110000, 120000, 130000, 140000, 150000,
160000, 170000, 180000, 190000, 200000, 210000],
lineStyle: {
type: 'dashed',
color: '#91cc75',
width: 2
},
symbol: 'none'
},
{
name: '去年同期',
type: 'line',
data: [90000, 95000, 88000, 105000, 85000, 180000,
170000, 165000, 175000, 195000, 210000, 225000],
lineStyle: {
color: '#fac858',
width: 2
},
symbol: 'none'
}
]
};
chart.setOption(option);1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
示例 2: 实时数据流
javascript
class RealtimeChart {
constructor(dom) {
this.chart = echarts.init(dom);
this.data = [];
this.maxDataPoints = 100;
this.init();
}
init() {
this.chart.setOption({
title: { text: '实时数据监控' },
tooltip: { trigger: 'axis' },
xAxis: {
type: 'time',
splitLine: { show: false }
},
yAxis: {
type: 'value',
boundaryGap: [0, '100%'],
splitLine: { show: true, lineStyle: { type: 'dashed' } }
},
series: [{
name: '实时值',
type: 'line',
showSymbol: false,
smooth: true,
lineStyle: {
width: 2,
color: '#ee6666'
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(238, 102, 102, 0.3)' },
{ offset: 1, color: 'rgba(238, 102, 102, 0.05)' }
])
},
data: this.data
}]
});
// 模拟实时数据
setInterval(() => this.addData(), 1000);
}
addData() {
const now = new Date();
const value = Math.random() * 100;
this.data.push([now, value]);
// 保持数据长度
if (this.data.length > this.maxDataPoints) {
this.data.shift();
}
// 更新图表
this.chart.setOption({
series: [{ data: this.data }]
});
}
dispose() {
this.chart.dispose();
}
}
// 使用
const realtimeChart = new RealtimeChart(document.getElementById('chart'));1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
示例 3: 多条Y轴
javascript
option = {
tooltip: { trigger: 'axis' },
legend: { data: ['温度', '湿度', '气压'] },
xAxis: {
type: 'category',
data: hours
},
yAxis: [
{
type: 'value',
name: '温度(°C)',
position: 'left',
axisLine: { show: true, lineStyle: { color: '#ee6666' } }
},
{
type: 'value',
name: '湿度(%)',
position: 'right',
axisLine: { show: true, lineStyle: { color: '#5470c6' } }
},
{
type: 'value',
name: '气压(hPa)',
position: 'right',
offset: 80,
axisLine: { show: true, lineStyle: { color: '#91cc75' } }
}
],
series: [
{
name: '温度',
type: 'line',
yAxisIndex: 0,
data: tempData,
smooth: true
},
{
name: '湿度',
type: 'line',
yAxisIndex: 1,
data: humidityData,
smooth: true
},
{
name: '气压',
type: 'line',
yAxisIndex: 2,
data: pressureData,
smooth: true
}
]
};1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
⚠️ 常见问题
Q1: 折线不平滑怎么办?
javascript
// 方法1: 开启平滑
series: [{ type: 'line', smooth: true }]
// 方法2: 调整平滑程度
series: [{ type: 'line', smooth: 0.3 }] // 0-1之间
// 方法3: 增加数据点密度
// 通过插值增加中间点1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
Q2: 数据点太多导致卡顿?
javascript
series: [{
type: 'line',
data: largeData,
showSymbol: false, // 关闭数据点
hoverAnimation: false, // 关闭悬停动画
sampling: 'lttb', // 降采样
progressive: 1000 // 渐进式渲染
}]1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
Q3: 如何自定义提示框内容?
javascript
tooltip: {
trigger: 'axis',
formatter: function(params) {
let html = `<strong>${params[0].name}</strong><br/>`;
params.forEach(param => {
html += `${param.marker} ${param.seriesName}: ${param.value}<br/>`;
});
return html;
}
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
Q4: 如何处理缺失数据?
javascript
// 方法1: 使用 null
data: [120, null, 150, '-', 200]
// 方法2: 连接空值
series: [{
connectNulls: true, // 自动连接null值
data: [120, null, 150, 200]
}]1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
🎯 最佳实践
1. 选择合适的平滑度
javascript
// 数据波动大 - 使用较小平滑度
smooth: 0.2
// 数据较平稳 - 使用较大平滑度
smooth: 0.5
// 需要精确展示 - 不使用平滑
smooth: false1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
2. 颜色搭配原则
javascript
// 主线条: 高饱和度
color: '#5470c6'
// 辅助线: 低饱和度或虚线
lineStyle: { type: 'dashed', opacity: 0.6 }
// 背景区域: 渐变透明
areaStyle: {
color: new echarts.graphic.LinearGradient(...)
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
3. 响应式设计
javascript
window.addEventListener('resize', () => {
chart.resize();
});
// 或使用 ResizeObserver
const resizeObserver = new ResizeObserver(() => {
chart.resize();
});
resizeObserver.observe(container);1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
4. 性能优化清单
- ✅ 数据量 > 1000 时关闭
showSymbol - ✅ 实时更新时使用
setOption增量更新 - ✅ 大数据开启
sampling - ✅ 不需要动画时设置
animation: false - ✅ 定期清理不再使用的图表实例
📊 性能指标
| 数据量 | 推荐配置 | 渲染时间 | 内存占用 |
|---|---|---|---|
| < 100 | 默认配置 | < 10ms | ~2MB |
| 100-1000 | 关闭部分特效 | 10-50ms | ~5MB |
| 1000-10000 | 开启 sampling | 50-200ms | ~15MB |
| > 10000 | large 模式 | 200-500ms | ~30MB |
🔗 相关链接
- 柱状图.md)
- 散点图.md)
- 数据格式规范
- 性能优化 - 大数据模式
- 官方示例
最后更新: 2026-04-22
难度等级: ⭐⭐
预计阅读时间: 20 分钟
基础折线图 vs 平滑曲线对比
{
"title": {
"text": "销售趋势分析",
"left": "center"
},
"tooltip": {
"trigger": "axis"
},
"legend": {
"data": [
"产品A",
"产品B"
],
"top": "10%"
},
"xAxis": {
"type": "category",
"data": [
"周一",
"周二",
"周三",
"周四",
"周五",
"周六",
"周日"
]
},
"yAxis": {
"type": "value"
},
"series": [
{
"name": "产品A",
"type": "line",
"smooth": true,
"data": [
150,
230,
224,
218,
135,
147,
260
],
"itemStyle": {
"color": "#5470c6"
}
},
{
"name": "产品B",
"type": "line",
"smooth": false,
"data": [
120,
180,
200,
190,
110,
130,
220
],
"itemStyle": {
"color": "#91cc75"
}
}
]
}面积图效果
{
"title": {
"text": "温度变化面积图",
"left": "center"
},
"tooltip": {
"trigger": "axis"
},
"xAxis": {
"type": "category",
"boundaryGap": false,
"data": [
"00:00",
"04:00",
"08:00",
"12:00",
"16:00",
"20:00",
"24:00"
]
},
"yAxis": {
"type": "value",
"axisLabel": {
"formatter": "{value} °C"
}
},
"series": [
{
"name": "温度",
"type": "line",
"smooth": true,
"data": [
15,
12,
18,
25,
23,
19,
16
],
"areaStyle": {
"opacity": 0.3,
"color": {
"type": "linear",
"x": 0,
"y": 0,
"x2": 0,
"y2": 1,
"colorStops": [
{
"offset": 0,
"color": "rgba(84,112,198,0.5)"
},
{
"offset": 1,
"color": "rgba(84,112,198,0.05)"
}
]
}
},
"lineStyle": {
"width": 3
}
}
]
}