xAxis-yAxis坐标轴详解完全指南
📋 概述
**xAxis和yAxis(直角坐标系的横纵轴)**是ECharts中最常用的坐标轴组件,负责数据的刻度、标签、网格线等展示。深入理解坐标轴配置是制作专业图表的基础。
核心价值
- 数据映射:将数据值映射到像素位置
- 刻度控制:精确控制刻度数量和格式
- 视觉引导:通过网格线和轴线辅助阅读
- 多轴支持:双Y轴、多X轴复杂布局
🎯 核心概念
1. 坐标轴类型
javascript
option = {
xAxis: {
type: 'category', // 类目轴
data: ['A', 'B', 'C']
},
yAxis: {
type: 'value' // 数值轴
}
};
// 支持的类型:
// - 'category': 类目轴(离散数据)
// - 'value': 数值轴(连续数据)
// - 'time': 时间轴(日期时间)
// - 'log': 对数轴1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2. 基础配置
javascript
option = {
xAxis: {
type: 'category',
data: ['一月', '二月', '三月'],
// 轴线
axisLine: {
show: true,
lineStyle: {
color: '#333',
width: 1
}
},
// 刻度
axisTick: {
show: true,
alignWithLabel: true
},
// 标签
axisLabel: {
show: true,
color: '#666',
fontSize: 12
},
// 分割线
splitLine: {
show: false // x轴默认不显示
}
},
yAxis: {
type: 'value',
// 分割线
splitLine: {
show: true, // y轴默认显示
lineStyle: {
color: '#eee',
type: 'solid'
}
}
}
};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
🔧 详细配置项
完整xAxis/yAxis配置
javascript
option = {
xAxis: {
// === 基础类型 ===
type: 'category',
data: ['周一', '周二', '周三', '周四', '周五'],
// === 位置 ===
position: 'bottom', // 'top' | 'bottom'
offset: 0, // 偏移距离
// === 名称 ===
name: '星期',
nameLocation: 'end', // 'start' | 'middle' | 'end'
nameGap: 15, // 名称与轴线距离
nameRotate: 0, // 名称旋转角度
nameTextStyle: {
color: '#333',
fontSize: 12,
fontWeight: 'bold'
},
// === 反向 ===
inverse: false, // 是否反向坐标轴
// === 边界 ===
boundaryGap: true, // 类目轴留白
// === 最小最大值 ===
min: undefined, // 自动计算
max: undefined,
minInterval: 0, // 最小间隔(数值轴)
maxInterval: undefined,
// === 刻度数量 ===
interval: undefined, // 强制设置间隔
splitNumber: 5, // 分割段数
// === 轴线样式 ===
axisLine: {
show: true,
onZero: true, // 是否在0刻度
lineStyle: {
color: '#888',
width: 1,
type: 'solid'
}
},
// === 刻度样式 ===
axisTick: {
show: true,
alignWithLabel: true, // 对齐标签
inside: false, // 朝内还是朝外
length: 5,
lineStyle: {
color: '#888',
width: 1
}
},
// === 标签样式 ===
axisLabel: {
show: true,
inside: false,
rotate: 0, // 旋转角度
margin: 8, // 与轴线距离
formatter: '{value}', // 格式化
// formatter: function(value) {
// return value + '元';
// },
color: '#666',
fontSize: 12,
fontWeight: 'normal',
// 溢出处理
overflow: 'none', // 'none' | 'truncate' | 'break' | 'breakAll'
ellipsis: '...',
width: 100,
// 富文本
rich: {
a: { color: '#f00' }
}
},
// === 分割线 ===
splitLine: {
show: false,
interval: 'auto',
lineStyle: {
color: '#eee',
width: 1,
type: 'solid'
// type: [5, 5] // 虚线
}
},
// === 分隔区域 ===
splitArea: {
show: false,
interval: 'auto',
areaStyle: {
color: ['rgba(250,250,250,0.3)', 'rgba(200,200,200,0.3)']
}
},
// === 指针 ===
axisPointer: {
show: false,
type: 'line', // 'line' | 'shadow'
snap: true // 自动吸附
}
},
yAxis: {
type: 'value',
position: 'left', // 'left' | 'right'
// 数值范围
min: 0,
max: 100,
// 刻度
splitNumber: 5,
minInterval: 10,
// 标签格式化
axisLabel: {
formatter: '{value}%'
// formatter: function(value) {
// return '¥' + value.toLocaleString();
// }
},
// 分割线
splitLine: {
show: true,
lineStyle: {
color: '#eee'
}
}
}
};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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
💡 实战案例
案例1:双Y轴对比
javascript
option = {
title: {
text: '销售额与利润率对比'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
legend: {
data: ['销售额', '利润率'],
top: 30
},
xAxis: {
type: 'category',
data: ['Q1', 'Q2', 'Q3', 'Q4']
},
yAxis: [
{
type: 'value',
name: '销售额(万元)',
position: 'left',
axisLabel: {
formatter: '¥{value}'
}
},
{
type: 'value',
name: '利润率',
position: 'right',
min: 0,
max: 100,
axisLabel: {
formatter: '{value}%'
}
}
],
series: [
{
name: '销售额',
type: 'bar',
data: [320, 332, 301, 334],
yAxisIndex: 0 // 使用左侧Y轴
},
{
name: '利润率',
type: 'line',
data: [15, 18, 16, 20],
yAxisIndex: 1, // 使用右侧Y轴
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
53
54
55
56
57
58
59
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
案例2:时间轴
javascript
option = {
xAxis: {
type: 'time',
name: '时间',
// 时间格式化
axisLabel: {
formatter: function(value) {
const date = new Date(value);
return `${date.getMonth() + 1}/${date.getDate()}`;
}
},
// 最小时间单位
minInterval: 3600 * 1000 * 24 // 1天
},
yAxis: {
type: 'value'
},
series: [{
type: 'line',
data: [
[new Date('2023-01-01'), 100],
[new Date('2023-01-02'), 120],
[new Date('2023-01-03'), 150]
]
}]
};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
案例3:对数轴
javascript
option = {
xAxis: {
type: 'category',
data: ['A', 'B', 'C', 'D', 'E']
},
yAxis: {
type: 'log', // 对数轴
name: '数值(对数)',
base: 10, // 对数底数
min: 1,
max: 10000
},
series: [{
type: 'bar',
data: [10, 100, 1000, 10000, 100000]
}]
};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
⚠️ 常见问题
问题1:标签重叠
解决:
javascript
axisLabel: {
rotate: 45, // 旋转45度
interval: 0, // 显示所有标签
formatter: function(value) {
return value.length > 5 ? value.substring(0, 5) + '...' : value;
}
}1
2
3
4
5
6
7
2
3
4
5
6
7
问题2:刻度不均匀
解决:
javascript
yAxis: {
type: 'value',
minInterval: 1, // 最小间隔为1
splitNumber: 5 // 强制分成5段
}1
2
3
4
5
2
3
4
5
🎯 最佳实践
1. 标签格式化
javascript
// 货币格式
axisLabel: {
formatter: '¥{value}'
}
// 百分比格式
axisLabel: {
formatter: '{value}%'
}
// 千分位
axisLabel: {
formatter: function(value) {
return value.toLocaleString();
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2. 响应式调整
javascript
const isMobile = window.innerWidth < 768;
xAxis: {
axisLabel: {
rotate: isMobile ? 45 : 0,
fontSize: isMobile ? 10 : 12
}
}1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
📊 性能指标
| 配置 | 渲染时间 | 建议 |
|---|---|---|
| 简单坐标轴 | 2ms | 无限制 |
| 带格式化 | 5ms | 正常 |
| 双Y轴 | 8ms | 适中 |
| 富文本标签 | 15ms | 谨慎使用 |
🔗 相关链接
- grid直角坐标系
- 富文本样式.md)
💎 总结
坐标轴核心价值:
- ✅ 数据到像素的映射
- ✅ 精确控制刻度和标签
- ✅ 多轴对比分析
- ✅ 时间/对数等特殊类型
关键配置原则:
- 选择合适的type:category/value/time/log
- 标签防重叠:rotate旋转或formatter截断
- 双轴对齐:确保两个y轴的scale一致
- 响应式适配:移动端旋转标签
掌握坐标轴,让数据展示更精准!📏
双Y轴配置
{
"title": {
"text": "双Y轴示例",
"left": "center"
},
"tooltip": {
"trigger": "axis"
},
"legend": {
"data": [
"销量",
"增长率"
],
"top": "10%"
},
"xAxis": {
"type": "category",
"data": [
"1月",
"2月",
"3月",
"4月",
"5月",
"6月"
]
},
"yAxis": [
{
"type": "value",
"name": "销量",
"position": "left"
},
{
"type": "value",
"name": "增长率",
"position": "right"
}
],
"series": [
{
"name": "销量",
"type": "bar",
"data": [
120,
200,
150,
80,
70,
110
]
},
{
"name": "增长率",
"type": "line",
"yAxisIndex": 1,
"data": [
15,
25,
20,
-10,
-5,
12
]
}
]
}