ECharts 时间轴(timeline)完全指南
文档类型: 深度技术文档
难度等级: ⭐⭐⭐
源码版本: ECharts 5.x
本文行数: 约500行
📋 目录
🎯 timeline基础
什么是timeline?
timeline是ECharts中的时间轴组件,用于展示数据随时间的变化,支持:
- 多帧数据切换
- 自动播放
- 手动拖拽
- 历史回溯
typescript
const option = {
// 时间轴配置
timeline: {
data: ['2010', '2011', '2012', '2013', '2014', '2015'],
axisType: 'category',
autoPlay: false,
playInterval: 2000 // 自动播放间隔(毫秒)
},
// 每个时间点对应的配置
options: [
{
// 2010年的数据
series: [{ data: [100, 120, 150] }]
},
{
// 2011年的数据
series: [{ data: [110, 130, 160] }]
},
// ... 更多年份
]
};1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
⚙️ 时间轴配置详解
完整配置示例
typescript
const option = {
timeline: {
// === 数据 ===
data: [
{ value: '2010', tooltip: '2010年度' },
{ value: '2011', tooltip: '2011年度' },
{ value: '2012', tooltip: '2012年度' }
],
// === 类型 ===
axisType: 'category', // 'category' | 'value' | 'time'
// === 当前索引 ===
currentIndex: 0,
// === 自动播放 ===
autoPlay: true,
playInterval: 2000, // 2秒切换一次
loop: true, // 循环播放
// === 方向 ===
orient: 'horizontal', // 'horizontal' | 'vertical'
inverse: false, // 是否反向
// === 位置尺寸 ===
left: '10%',
right: '10%',
bottom: '5%',
height: 50,
// === 轴线样式 ===
lineStyle: {
color: '#5470C6',
width: 2
},
// === 控制点 ===
checkpointStyle: {
color: '#5470C6',
borderColor: '#fff',
borderWidth: 2,
symbol: 'circle',
symbolSize: 10
},
// === 控制按钮 ===
controlStyle: {
showPlayBtn: true,
showPrevBtn: true,
showNextBtn: true,
itemSize: 15,
itemGap: 10
},
// === 标签 ===
label: {
show: true,
position: 'bottom',
distance: 5,
formatter: '{value}',
color: '#333'
}
}
};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
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
🔄 动态数据切换
编程式控制
typescript
class TimelineController {
private chart: echarts.ECharts;
constructor(container: HTMLElement) {
this.chart = echarts.init(container);
}
/**
* 跳转到指定时间点
*/
goToIndex(index: number) {
this.chart.setOption({
timeline: {
currentIndex: index
}
});
}
/**
* 播放/暂停
*/
togglePlay() {
const timeline = this.chart.getOption().timeline[0];
this.chart.setOption({
timeline: {
autoPlay: !timeline.autoPlay
}
});
}
/**
* 设置播放速度
*/
setSpeed(interval: number) {
this.chart.setOption({
timeline: {
playInterval: interval
}
});
}
/**
* 动态添加时间点
*/
addTimePoint(year: string, data: any[]) {
const currentData = this.chart.getOption().timeline[0].data;
currentData.push(year);
this.chart.setOption({
timeline: {
data: currentData
},
options: [
...this.chart.getOption().options,
{ series: [{ data }] }
]
});
}
}
// 使用
const controller = new TimelineController(document.getElementById('chart')!);
// 跳转到2015年
controller.goToIndex(5);
// 调整播放速度
controller.setSpeed(1000); // 1秒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
💻 实战案例
历年GDP变化趋势
typescript
import * as echarts from 'echarts';
class GDPTimeline {
private chart: echarts.ECharts;
constructor(container: HTMLElement) {
this.chart = echarts.init(container);
this.render();
}
private render() {
const years = ['2010', '2011', '2012', '2013', '2014', '2015', '2016', '2017', '2018', '2019'];
const gdpData = [
[41211, 48794, 19560], // 2010
[48794, 59524, 21720], // 2011
[54036, 64397, 23560], // 2012
[59524, 70477, 25640], // 2013
[64397, 77328, 27890], // 2014
[68905, 84320, 30150], // 2015
[74639, 91928, 32560], // 2016
[82712, 101351, 35230], // 2017
[91928, 110386, 38100], // 2018
[98651, 119820, 40890] // 2019
];
const option = {
baseOption: {
title: { text: '中国历年GDP变化' },
timeline: {
data: years,
autoPlay: true,
playInterval: 2000,
controlStyle: {
showPlayBtn: true,
showPrevBtn: true,
showNextBtn: true
}
},
tooltip: { trigger: 'axis' },
legend: { data: ['第一产业', '第二产业', '第三产业'] },
xAxis: {
type: 'category',
data: ['一季度', '二季度', '三季度', '四季度']
},
yAxis: {
type: 'value',
name: '亿元'
},
series: [
{ name: '第一产业', type: 'bar' },
{ name: '第二产业', type: 'bar' },
{ name: '第三产业', type: 'bar' }
]
},
options: gdpData.map(data => ({
series: [
{ data: [data[0] / 4, data[0] / 4, data[0] / 4, data[0] / 4] },
{ data: [data[1] / 4, data[1] / 4, data[1] / 4, data[1] / 4] },
{ data: [data[2] / 4, data[2] / 4, data[2] / 4, data[2] / 4] }
]
}))
};
this.chart.setOption(option);
}
resize() {
this.chart.resize();
}
dispose() {
this.chart.dispose();
}
}
// 使用
const gdpChart = new GDPTimeline(document.getElementById('chart')!);
window.addEventListener('resize', () => gdpChart.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
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
疫情数据演变
typescript
const pandemicOption = {
timeline: {
data: Array.from({ length: 30 }, (_, i) => {
const date = new Date('2020-01-20');
date.setDate(date.getDate() + i);
return date.toLocaleDateString();
}),
autoPlay: true,
playInterval: 500, // 快速播放
lineStyle: { color: '#EE6666' },
checkpointStyle: { color: '#EE6666' }
},
baseOption: {
title: { text: '疫情数据演变' },
xAxis: { type: 'category' },
yAxis: { type: 'value' },
series: [
{ name: '确诊', type: 'line', smooth: true },
{ name: '治愈', type: 'line', smooth: true }
]
},
options: generateDailyData()
};
function generateDailyData() {
const options = [];
let confirmed = 100;
let recovered = 0;
for (let i = 0; i < 30; i++) {
confirmed += Math.floor(Math.random() * 500 + 200);
recovered += Math.floor(Math.random() * 300 + 100);
options.push({
series: [
{ data: Array.from({ length: i + 1 }, (_, j) => confirmed - (i - j) * 100) },
{ data: Array.from({ length: i + 1 }, (_, j) => recovered - (i - j) * 50) }
]
});
}
return options;
}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
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
🎯 最佳实践总结
✅ DO - 推荐做法
控制时间点数量
typescript// 保持在10-20个以内 data: years.slice(0, 15)1
2提供播放控制
typescriptcontrolStyle: { showPlayBtn: true, showPrevBtn: true, showNextBtn: true }1
2
3
4
5使用tooltip说明
typescriptdata: [ { value: '2010', tooltip: '2010年度数据' } ]1
2
3
❌ DON'T - 避免做法
- 避免过快播放typescript
// ❌ 不好 - 太快看不清 playInterval: 200 // ✅ 好 - 适中速度 playInterval: 20001
2
3
4
5
🔗 相关资源
下一篇: 实时数据流
时间轴效果
{
"title": {
"text": "历年数据对比",
"left": "center"
},
"tooltip": {
"trigger": "axis"
},
"baseOption": {
"timeline": {
"axisType": "category",
"autoPlay": true,
"playInterval": 3000,
"data": [
"2020",
"2021",
"2022",
"2023",
"2024"
]
},
"xAxis": {
"type": "category",
"data": [
"Q1",
"Q2",
"Q3",
"Q4"
]
},
"yAxis": {
"type": "value"
}
},
"options": [
{
"series": [
{
"type": "bar",
"data": [
100,
120,
145,
160
]
}
]
},
{
"series": [
{
"type": "bar",
"data": [
110,
135,
160,
180
]
}
]
},
{
"series": [
{
"type": "bar",
"data": [
125,
150,
175,
200
]
}
]
},
{
"series": [
{
"type": "bar",
"data": [
140,
165,
190,
220
]
}
]
},
{
"series": [
{
"type": "bar",
"data": [
155,
180,
210,
245
]
}
]
}
]
}下一篇: 实时数据流
