ECharts 混合图表(柱状图+折线图)完全指南
文档类型: 实战指南
难度等级: ⭐⭐
源码版本: ECharts 5.x
本文行数: 约480行
📋 目录
🎯 基础组合方式
柱状图 + 折线图
最常见的组合,用于展示不同量级的数据:
typescript
const option = {
title: { text: '销售数据分析' },
tooltip: { trigger: 'axis' },
legend: { data: ['销售额', '增长率'] },
xAxis: {
type: 'category',
data: ['1月', '2月', '3月', '4月', '5月', '6月']
},
yAxis: {
type: 'value',
name: '销售额(万元)'
},
series: [
{
name: '销售额',
type: 'bar', // 柱状图
data: [120, 200, 150, 80, 70, 110]
},
{
name: '增长率',
type: 'line', // 折线图
data: [15, 25, 18, 12, 8, 20],
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
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
应用场景:
- ✅ 销售额与增长率
- ✅ 产量与合格率
- ✅ 访问量与转化率
📊 双Y轴配置
左右双Y轴
当两个系列量级差异大时使用:
typescript
const option = {
tooltip: { trigger: 'axis' },
legend: { data: ['销售额', '增长率'] },
xAxis: {
type: 'category',
data: ['1月', '2月', '3月', '4月', '5月']
},
yAxis: [
{
type: 'value',
name: '销售额',
position: 'left', // 左侧Y轴
axisLine: {
show: true,
lineStyle: { color: '#5470C6' }
}
},
{
type: 'value',
name: '增长率',
position: 'right', // 右侧Y轴
axisLine: {
show: true,
lineStyle: { color: '#91CC75' }
},
axisLabel: {
formatter: '{value}%'
}
}
],
series: [
{
name: '销售额',
type: 'bar',
yAxisIndex: 0, // 使用左侧Y轴
data: [120, 200, 150, 80, 70]
},
{
name: '增长率',
type: 'line',
yAxisIndex: 1, // 使用右侧Y轴
data: [15, 25, 18, 12, 8],
itemStyle: { color: '#91CC75' }
}
]
};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
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
三个Y轴 (极端场景)
typescript
const option = {
yAxis: [
{
type: 'value',
name: '轴1',
position: 'left'
},
{
type: 'value',
name: '轴2',
position: 'right'
},
{
type: 'value',
name: '轴3',
position: 'right',
offset: 80 // 偏移避免重叠
}
],
series: [
{
name: '数据1',
type: 'bar',
yAxisIndex: 0,
data: [100, 200, 150]
},
{
name: '数据2',
type: 'line',
yAxisIndex: 1,
data: [10, 20, 15]
},
{
name: '数据3',
type: 'line',
yAxisIndex: 2,
data: [5, 8, 7]
}
]
};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
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
🎨 多系列组合
双柱状图 + 双折线图
typescript
const option = {
legend: { data: ['今年销售', '去年销售', '今年增长', '去年增长'] },
xAxis: {
type: 'category',
data: ['Q1', 'Q2', 'Q3', 'Q4']
},
yAxis: [
{ type: 'value', name: '销售额' },
{ type: 'value', name: '增长率' }
],
series: [
{
name: '今年销售',
type: 'bar',
yAxisIndex: 0,
data: [480, 520, 610, 590],
itemStyle: { color: '#5470C6' }
},
{
name: '去年销售',
type: 'bar',
yAxisIndex: 0,
data: [420, 480, 550, 530],
itemStyle: { color: '#91CC75' }
},
{
name: '今年增长',
type: 'line',
yAxisIndex: 1,
data: [12, 15, 18, 14],
itemStyle: { color: '#EE6666' }
},
{
name: '去年增长',
type: 'line',
yAxisIndex: 1,
data: [10, 12, 15, 11],
itemStyle: { color: '#FAC858' }
}
]
};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
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
堆叠柱状图 + 折线图
typescript
const option = {
legend: {},
xAxis: { type: 'category' },
yAxis: [
{ type: 'value', name: '销售额' },
{ type: 'value', name: '占比' }
],
series: [
{
name: '线上销售',
type: 'bar',
stack: 'total', // 堆叠
yAxisIndex: 0,
data: [320, 332, 301, 334]
},
{
name: '线下销售',
type: 'bar',
stack: 'total', // 堆叠
yAxisIndex: 0,
data: [120, 132, 101, 134]
},
{
name: '线上占比',
type: 'line',
yAxisIndex: 1,
data: [72, 71, 75, 71],
itemStyle: { color: '#EE6666' }
}
]
};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
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
🔧 复杂组合图表
柱状图 + 折线图 + 面积图
typescript
const option = {
xAxis: { type: 'category' },
yAxis: [
{ type: 'value', name: '数值' },
{ type: 'value', name: '百分比' }
],
series: [
{
name: '实际值',
type: 'bar',
yAxisIndex: 0,
data: [120, 200, 150, 80]
},
{
name: '目标值',
type: 'line',
yAxisIndex: 0,
data: [150, 180, 170, 160],
lineStyle: { type: 'dashed' } // 虚线
},
{
name: '完成率',
type: 'line',
yAxisIndex: 1,
data: [80, 111, 88, 50],
areaStyle: { opacity: 0.3 }, // 面积填充
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
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
正负柱状图 + 基准线
typescript
const option = {
xAxis: { type: 'category' },
yAxis: { type: 'value' },
series: [
{
name: '盈亏',
type: 'bar',
data: [120, -80, 150, -30, 70],
// 正负不同色
itemStyle: {
color: (params: any) => {
return params.value >= 0 ? '#91cc75' : '#ee6666';
}
}
},
{
name: '基准线',
type: 'line',
data: [0, 0, 0, 0, 0], // 零线
lineStyle: {
color: '#333',
width: 2
},
symbol: 'none' // 不显示数据点
}
]
};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
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
💻 实战案例
案例1: 电商数据看板
typescript
import * as echarts from 'echarts';
export class EcommerceDashboard {
private chart: echarts.ECharts;
constructor(container: HTMLElement) {
this.chart = echarts.init(container);
this.render();
}
private render() {
const option = {
title: {
text: '电商月度经营分析',
left: 'center'
},
tooltip: {
trigger: 'axis',
axisPointer: { type: 'cross' }
},
legend: {
data: ['GMV', '订单量', '客单价', '转化率'],
bottom: 10
},
grid: {
left: '3%',
right: '4%',
bottom: '15%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['1月', '2月', '3月', '4月', '5月', '6月']
},
yAxis: [
{
type: 'value',
name: '金额(万元)',
position: 'left'
},
{
type: 'value',
name: '转化率(%)',
position: 'right',
max: 10
}
],
series: [
{
name: 'GMV',
type: 'bar',
yAxisIndex: 0,
data: [1200, 1500, 1800, 2100, 2400, 2800],
itemStyle: { color: '#5470C6' }
},
{
name: '订单量',
type: 'bar',
yAxisIndex: 0,
data: [800, 1000, 1200, 1400, 1600, 1900],
itemStyle: { color: '#91CC75' }
},
{
name: '客单价',
type: 'line',
yAxisIndex: 0,
data: [150, 150, 150, 150, 150, 147],
smooth: true,
itemStyle: { color: '#EE6666' }
},
{
name: '转化率',
type: 'line',
yAxisIndex: 1,
data: [3.2, 3.5, 3.8, 4.1, 4.3, 4.5],
smooth: true,
itemStyle: { color: '#FAC858' },
areaStyle: { opacity: 0.2 }
}
]
};
this.chart.setOption(option);
}
// 响应式
resize() {
this.chart.resize();
}
}
// 使用
const dashboard = new EcommerceDashboard(document.getElementById('chart')!);
window.addEventListener('resize', () => dashboard.resize());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
86
87
88
89
90
91
92
93
94
95
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
86
87
88
89
90
91
92
93
94
95
案例2: 生产质量监控
typescript
const option = {
title: { text: '生产质量日报' },
tooltip: { trigger: 'axis' },
legend: { data: ['产量', '合格数', '合格率'] },
xAxis: { type: 'category' },
yAxis: [
{ type: 'value', name: '数量', min: 0 },
{ type: 'value', name: '合格率', min: 90, max: 100 }
],
visualMap: [
{
dimension: 0,
pieces: [
{ lte: 95, color: 'red' }, // 合格率<95% 红色警告
{ gt: 95, lte: 98, color: 'orange' },
{ gt: 98, color: 'green' } // 合格率>98% 绿色正常
]
}
],
series: [
{
name: '产量',
type: 'bar',
yAxisIndex: 0,
data: [1000, 1200, 1100, 1300, 1250]
},
{
name: '合格数',
type: 'bar',
yAxisIndex: 0,
data: [960, 1150, 1070, 1280, 1230]
},
{
name: '合格率',
type: 'line',
yAxisIndex: 1,
data: [96, 95.8, 97.3, 98.5, 98.4],
markLine: {
data: [
{ yAxis: 95, name: '最低标准' },
{ yAxis: 98, name: '目标标准' }
]
}
}
]
};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
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
案例3: 财务报表可视化
typescript
const option = {
title: { text: '年度财务指标' },
tooltip: { trigger: 'axis' },
legend: {
data: ['收入', '成本', '利润', '利润率'],
selectedMode: 'single' // 单选模式
},
xAxis: { type: 'category' },
yAxis: [
{ type: 'value', name: '金额(百万)' },
{ type: 'value', name: '利润率', axisLabel: { formatter: '{value}%' } }
],
dataZoom: [{ type: 'slider' }], // 支持缩放
series: [
{
name: '收入',
type: 'bar',
yAxisIndex: 0,
data: [450, 520, 580, 630, 710, 780, 850, 920, 1000, 1080, 1150, 1230]
},
{
name: '成本',
type: 'bar',
yAxisIndex: 0,
data: [320, 370, 410, 450, 500, 550, 600, 650, 710, 760, 810, 870]
},
{
name: '利润',
type: 'line',
yAxisIndex: 0,
data: [130, 150, 170, 180, 210, 230, 250, 270, 290, 320, 340, 360],
smooth: true,
areaStyle: { opacity: 0.2 }
},
{
name: '利润率',
type: 'line',
yAxisIndex: 1,
data: [28.9, 28.8, 29.3, 28.6, 29.6, 29.5, 29.4, 29.3, 29.0, 29.6, 29.6, 29.3],
itemStyle: { color: '#EE6666' },
markArea: {
data: [[
{ yAxis: 28, name: '优秀区间' },
{ yAxis: 30 }
]]
}
}
]
};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
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
🎯 最佳实践总结
✅ DO - 推荐做法
合理选择Y轴数量
typescript// ✅ 最多2-3个Y轴 yAxis: [ { type: 'value', name: '主指标' }, { type: 'value', name: '辅助指标' } ]1
2
3
4
5使用不同颜色区分
typescript// ✅ 每个系列用不同颜色 itemStyle: { color: '#5470C6' } // 蓝色 itemStyle: { color: '#91CC75' } // 绿色 itemStyle: { color: '#EE6666' } // 红色1
2
3
4添加图例和提示
typescript// ✅ 清晰的图例 legend: { data: ['销售额', '增长率'] } // ✅ 详细的tooltip tooltip: { trigger: 'axis' }1
2
3
4
5
❌ DON'T - 避免做法
避免过多系列
typescript// ❌ 不好 - 超过5个系列 series: [/* 8个系列 */] // ✅ 好 - 控制在3-4个系列 series: [/* 3-4个系列 */]1
2
3
4
5避免量级差异过大不使用双轴
typescript// ❌ 不好 - 100和0.5在同一个轴 series: [ { data: [100, 200, 150] }, // 百级别 { data: [0.5, 0.8, 0.6] } // 小数级别 ] // ✅ 好 - 使用双Y轴 yAxis: [ { type: 'value' }, // 左轴 { type: 'value' } // 右轴 ]1
2
3
4
5
6
7
8
9
10
11
🔗 相关资源
✅ 数据与系列模块完成!
