ECharts 响应式适配完全指南
文档类型: 实战指南
难度等级: ⭐⭐
源码版本: ECharts 5.x
本文行数: 约350行
📋 目录
🎯 基础响应式
监听窗口变化
typescript
const chart = echarts.init(container);
// 自动调整大小
window.addEventListener('resize', () => {
chart.resize();
});1
2
3
4
5
6
2
3
4
5
6
防抖优化
typescript
function debounce(func: Function, wait: number) {
let timeout: number;
return function executedFunction(...args: any[]) {
clearTimeout(timeout);
timeout = window.setTimeout(() => func.apply(this, args), wait);
};
}
// 使用
window.addEventListener('resize', debounce(() => {
chart.resize();
}, 300)); // 300ms防抖1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
📐 断点设计
移动端/平板/PC适配
typescript
class ResponsiveChart {
private chart: echarts.ECharts;
constructor(container: HTMLElement) {
this.chart = echarts.init(container);
this.handleResize();
window.addEventListener('resize', debounce(() => {
this.handleResize();
}, 300));
}
private handleResize() {
const width = window.innerWidth;
if (width < 768) {
// 移动端
this.applyMobileConfig();
} else if (width < 1024) {
// 平板
this.applyTabletConfig();
} else {
// PC
this.applyDesktopConfig();
}
this.chart.resize();
}
private applyMobileConfig() {
this.chart.setOption({
legend: {
orient: 'horizontal',
bottom: 0,
textStyle: { fontSize: 10 }
},
xAxis: {
axisLabel: { rotate: 45, fontSize: 10 }
},
tooltip: {
textStyle: { fontSize: 12 }
}
});
}
private applyTabletConfig() {
this.chart.setOption({
legend: {
orient: 'horizontal',
top: 0
},
xAxis: {
axisLabel: { rotate: 0, fontSize: 12 }
}
});
}
private applyDesktopConfig() {
this.chart.setOption({
legend: {
orient: 'horizontal',
top: 0
},
xAxis: {
axisLabel: { rotate: 0, fontSize: 14 }
}
});
}
dispose() {
this.chart.dispose();
}
}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
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
🔄 动态配置
根据屏幕尺寸调整图表元素
typescript
function getResponsiveOption(screenWidth: number) {
const isMobile = screenWidth < 768;
const isTablet = screenWidth < 1024;
return {
grid: {
left: isMobile ? '15%' : '10%',
right: isMobile ? '5%' : '10%',
top: isMobile ? '20%' : '15%',
bottom: isMobile ? '20%' : '10%'
},
title: {
textStyle: {
fontSize: isMobile ? 14 : 18
}
},
series: [{
symbolSize: isMobile ? 6 : 10,
label: {
show: !isMobile, // 移动端隐藏标签
fontSize: isMobile ? 10 : 12
}
}]
};
}
// 使用
let lastWidth = window.innerWidth;
chart.setOption(getResponsiveOption(lastWidth));
window.addEventListener('resize', debounce(() => {
const currentWidth = window.innerWidth;
if (currentWidth !== lastWidth) {
lastWidth = currentWidth;
chart.setOption(getResponsiveOption(currentWidth));
chart.resize();
}
}, 300));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
💻 实战案例
案例1: Dashboard响应式布局
typescript
class ResponsiveDashboard {
private charts: Map<string, echarts.ECharts> = new Map();
addChart(id: string, container: HTMLElement, option: any) {
const chart = echarts.init(container);
chart.setOption(option);
this.charts.set(id, chart);
}
resizeAll() {
const width = window.innerWidth;
const isMobile = width < 768;
this.charts.forEach((chart, id) => {
chart.resize();
// 移动端调整布局
if (isMobile) {
chart.setOption({
grid: {
left: '20%',
right: '5%',
top: '15%',
bottom: '15%'
}
});
}
});
}
init() {
window.addEventListener('resize', debounce(() => {
this.resizeAll();
}, 300));
}
dispose() {
this.charts.forEach(chart => chart.dispose());
this.charts.clear();
}
}
// 使用
const dashboard = new ResponsiveDashboard();
dashboard.addChart('chart1', container1, option1);
dashboard.addChart('chart2', container2, option2);
dashboard.init();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
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
🎯 最佳实践总结
✅ DO - 推荐做法
始终添加resize监听
typescriptwindow.addEventListener('resize', () => chart.resize());1使用防抖避免频繁调用
typescriptdebounce(() => chart.resize(), 300)1针对不同设备优化配置
typescriptif (width < 768) { /* 移动端优化 */ }1
❌ DON'T - 避免做法
- 避免在resize中执行复杂计算typescript
// ❌ 不好 window.addEventListener('resize', () => { heavyCalculation(); chart.resize(); }); // ✅ 好 window.addEventListener('resize', debounce(() => { chart.resize(); }, 300));1
2
3
4
5
6
7
8
9
10
🔗 相关资源
下一篇: 移动端优化
