在大数据时代,数据可视化已成为信息传递和决策支持的重要手段。ECharts 作为一款功能强大、易于上手的开源可视化库,凭借其丰富的图表类型、灵活的配置项和良好的跨平台兼容性,广泛应用于企业级数据大屏、BI 报表、实时监控等场景。
本教程以“智慧医疗大屏”为例,完整演示了从页面搭建、图表配置到动态交互与响应式适配的全过程。通过循序渐进的讲解,读者将掌握如何使用 ECharts 构建专业、美观、可交互的数据可视化大屏,并具备将其应用于实际项目的能力。
下面的大屏是根据实际需要制作的:
本大屏制作完全使用ECharts和Bootstrap5制作完成。此大屏的数据具有如下特点:
- 动态数据标签:
- 所有图表都显示实时数值
- 添加单位后缀(万/人/%)
- 使用白色字体增强可读性
- 添加文本阴影提升对比度
- 视觉增强:
- 标题栏添加发光动画效果
- 卡片添加悬浮上升动画
- 仪表盘使用渐变颜色
- 饼图添加边框和阴影
- 响应式设计:
- 在小屏幕下自动调整布局
- 图表说明框在移动端自动下移
- 保持所有元素的可读性和可用性
- 交互优化:
- 卡片添加点击动画
- 图表自动适应容器大小
- 添加加载状态提示
1. 项目概述
1.1 项目背景与目标
随着大数据时代的到来,数据可视化成为信息传达的重要手段。ECharts 作为一款由百度开源的 JavaScript 可视化库,凭借其强大的图表类型、灵活的配置项和良好的性能,广泛应用于各类数据展示场景,尤其在“大屏展示”项目中表现出色。
本项目旨在通过 ECharts 实现一个典型的大屏可视化实例,涵盖多种图表类型(如柱状图、折线图、饼图、地图等),并结合响应式布局与动态数据更新,打造一个适用于企业数据监控、运营分析等场景的可视化大屏。
项目目标包括:
-
实现一个完整的大屏展示页面,支持多种图表联动与动态刷新;
-
使用 ECharts 5.x 版本,结合 Vue 3 或原生 JavaScript 实现组件化开发;
-
支持响应式布局,适配不同分辨率的大屏设备;
-
提供数据模拟接口,支持图表数据的定时更新;
-
代码结构清晰,便于后续扩展与维护。
1.2 技术选型与依赖
本项目的技术栈选型如下:
技术 | 版本 | 说明 |
---|---|---|
ECharts | 5.4.3 | 核心图表库,提供丰富的图表类型与交互能力 |
Vue.js | 3.3.4 | 用于组件化开发与数据绑定(可选) |
Axios | 1.4.0 | 用于请求模拟数据接口 |
Sass/SCSS | 1.62.1 | 用于样式编写,支持变量与嵌套 |
WebSocket | - | 用于实时数据推送(可选) |
Node.js | 18.x | 用于本地开发与构建 |
主要依赖包(package.json
摘要):
{
"dependencies": {
"echarts": "^5.4.3",
"vue": "^3.3.4",
"axios": "^1.4.0"
},
"devDependencies": {
"sass": "^1.62.1",
"vite": "^4.3.9"
}
}
此外,项目使用 Vite 作为构建工具,具备快速热更新与按需加载的优势,适合大屏项目的高效开发。
1.3 页面结构总览
本项目的大屏页面结构采用模块化设计,主要分为以下几个区域:
┌───────────────────────────┐
│ 顶部标题栏 │
├─────────┬──────┬──────────┤
│ │ │ │
│ 左侧栏 │ 中栏 │ 右侧栏 │
│ │ │ │
├─────────┼──────┼──────────┤
│ 底部状态栏 │
└───────────────────────────┘
-
顶部标题栏:展示项目名称、当前时间、数据更新时间等信息;
-
左侧栏:包含多个图表模块,如实时数据趋势、分类占比等;
-
主视图:核心展示区域,通常包含地图、关键指标仪表盘等;
-
底部状态栏:展示数据来源、版权信息、告警提示等。
页面布局采用 Flex + Grid 混合布局,确保在不同分辨率下保持良好的展示效果。图表组件通过 ECharts 实例化,并统一封装为可复用的 Vue 组件或 JavaScript 模块,便于管理与复用。
示例目录结构如下:
src/
├── components/
│ ├── BarChart.vue
│ ├── LineChart.vue
│ ├── PieChart.vue
│ └── MapChart.vue
├── views/
│ └── Dashboard.vue
├── utils/
│ └── chartInit.js
├── styles/
│ └── main.scss
└── App.vue
通过上述结构,项目实现了视图与逻辑的分离,便于后期维护与功能扩展。
2. 页面布局与样式设计
2.1 响应式网格布局实现
在大屏展示项目中,响应式布局是确保页面在不同分辨率设备上都能良好展示的关键。本项目采用 Flexbox + CSS Grid 混合布局方式,结合媒体查询实现响应式适配。
-
布局结构:页面整体采用
grid-template-areas
定义区域,便于模块化管理。
-
.dashboard { display: grid; grid-template-areas: "header header" "sidebar main" "footer footer"; grid-template-columns: 300px 1fr; grid-template-rows: auto 1fr auto; height: 100vh; }
-
响应式适配:通过媒体查询动态调整布局结构。
-
@media (max-width: 1200px) { .dashboard { grid-template-columns: 1fr; grid-template-areas: "header" "main" "sidebar" "footer"; } }
-
实际效果:在 1920x1080 分辨率下,左侧栏宽度为 300px,主视图区域自适应;在 1024x768 分辨率下,自动切换为上下布局,确保内容不挤压。
2.2 卡片组件样式与交互动效
图表模块采用卡片式封装,每个图表组件独立为一个 .card
容器,便于样式统一与复用。
-
卡片样式:
-
.card { background: rgba(255, 255, 255, 0.05); border-radius: 8px; padding: 16px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); transition: transform 0.3s ease; } .card:hover { transform: scale(1.02); }
-
动效设计:图表加载时使用 ECharts 自带的动画效果,结合 CSS 动画增强视觉体验。
-
@keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .card { animation: fadeIn 0.5s ease-out forwards; }
-
图表容器尺寸控制:
-
.chart-container { width: 100%; height: 300px; }
2.3 标题栏与主题色设计
标题栏作为页面的视觉焦点,采用深色背景配合高亮主题色,增强科技感与统一性。
-
标题栏样式:
-
.header { grid-area: header; background: linear-gradient(to right, #0f2027, #203a43, #2c5364); color: #fff; padding: 0 24px; display: flex; justify-content: space-between; align-items: center; font-size: 20px; font-weight: bold; }
-
主题色配置:
-
$primary-color: #00c6ff; $secondary-color: #0072ff;
-
图表主题统一:ECharts 配置中统一使用主题色,确保视觉一致性。
-
color: ['#00c6ff', '#0072ff', '#4facfe', '#00f2fe']
-
动态时间显示:标题栏右侧集成实时时间模块,增强数据实时感。
-
setInterval(() => { const now = new Date(); document.getElementById('current-time').innerText = now.toLocaleString(); }, 1000);
通过上述布局与样式设计,项目实现了高可用性、可维护性与视觉统一性,为后续图表模块开发与数据接入提供了坚实基础。
3. ECharts 图表配置详解
3.1 折线图:医疗收入统计
折线图适用于展示时间序列数据的趋势变化,本项目中用于展示医院近12个月的医疗收入变化趋势。
数据结构
const incomeData = {
months: ['2024-07', '2024-08', '2024-09', '2024-10', '2024-11', '2024-12',
'2025-01', '2025-02', '2025-03', '2025-04', '2025-05', '2025-06'],
values: [1200, 1350, 1500, 1420, 1600, 1750, 1680, 1820, 1950, 2100, 2050, 2200]
};
ECharts 配置
option = {
title: {
text: '医疗收入月度趋势',
left: 'center',
textStyle: { color: '#fff' }
},
tooltip: {
trigger: 'axis',
formatter: '{b}<br/>收入:{c} 万元'
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
data: incomeData.months,
axisLine: { lineStyle: { color: '#ccc' } },
axisLabel: { color: '#ccc' }
},
yAxis: {
type: 'value',
name: '收入(万元)',
nameTextStyle: { color: '#ccc' },
axisLine: { lineStyle: { color: '#ccc' } },
splitLine: { lineStyle: { color: 'rgba(255,255,255,0.1)' } }
},
series: [{
name: '医疗收入',
type: 'line',
data: incomeData.values,
smooth: true,
symbol: 'circle',
symbolSize: 6,
itemStyle: { color: '#00c6ff' },
lineStyle: { width: 3, color: '#00c6ff' },
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(0,198,255,0.5)' },
{ offset: 1, color: 'rgba(0,198,255,0.1)' }
])
}
}]
};
可视化效果
-
使用平滑曲线(
smooth: true
)增强视觉流畅性; -
添加渐变区域填充(
areaStyle
)突出趋势变化; -
每月收入数据点使用圆点标记,增强可读性;
-
坐标轴与文字使用浅色,适配深色背景大屏风格。
3.2 柱状图:入院人数堆叠分析
柱状图用于展示不同科室的入院人数分布,并支持按月份堆叠,便于对比分析。
数据结构
const admissionData = {
months: ['2025-01', '2025-02', '2025-03', '2025-04', '2025-05', '2025-06'],
departments: ['内科', '外科', '儿科', '妇产科', '急诊科'],
data: [
[320, 302, 341, 374, 390, 450], // 内科
[220, 232, 201, 234, 290, 330], // 外科
[150, 132, 161, 154, 190, 230], // 儿科
[120, 142, 131, 124, 150, 180], // 妇产科
[80, 92, 101, 94, 110, 130] // 急诊科
]
};
ECharts 配置
option = {
title: {
text: '各科室入院人数统计',
left: 'center',
textStyle: { color: '#fff' }
},
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' }
},
legend: {
data: admissionData.departments,
textStyle: { color: '#ccc' },
top: 'bottom'
},
grid: {
left: '3%',
right: '4%',
bottom: '15%',
containLabel: true
},
xAxis: {
type: 'category',
data: admissionData.months,
axisLine: { lineStyle: { color: '#ccc' } },
axisLabel: { color: '#ccc' }
},
yAxis: {
type: 'value',
name: '入院人数',
nameTextStyle: { color: '#ccc' },
axisLine: { lineStyle: { color: '#ccc' } },
splitLine: { lineStyle: { color: 'rgba(255,255,255,0.1)' } }
},
series: admissionData.departments.map((dept, index) => ({
name: dept,
type: 'bar',
stack: 'total',
emphasis: { focus: 'series' },
data: admissionData.data[index],
itemStyle: {
color: ['#00c6ff', '#0072ff', '#4facfe', '#00f2fe', '#a18cd1'][index]
}
}))
};
可视化效果
-
使用堆叠柱状图(
stack: 'total'
)展示各科室人数总和; -
每月数据清晰对比,支持鼠标悬浮查看具体数值;
-
图例位于底部,便于识别各科室颜色;
-
使用统一主题色,保持视觉一致性。
3.3 仪表盘:床位使用率展示
仪表盘用于展示关键指标的实时状态,本项目中用于展示床位使用率,直观反映医院资源负荷。
数据结构
const bedUsageRate = 78; // 百分比
ECharts 配置
复制
option = {
title: {
text: '床位使用率',
left: 'center',
textStyle: { color: '#fff' }
},
series: [{
type: 'gauge',
startAngle: 180,
endAngle: 0,
min: 0,
max: 100,
splitNumber: 10,
axisLine: {
lineStyle: {
width: 6,
color: [
[0.6, '#4facfe'],
[0.8, '#00c6ff'],
[1, '#FF6E76']
]
}
},
pointer: {
icon: 'path://M12.8,0.7l12,40.1H0.7L12.8,0.7z',
length: '12%',
width: 20,
offsetCenter: [0, '-60%'],
itemStyle: { color: 'auto' }
},
axisTick: { distance: -20, length: 8, lineStyle: { color: '#fff', width: 2 } },
splitLine: { distance: -24, length: 20, lineStyle: { color: '#fff', width: 3 } },
axisLabel: { color: '#ccc', fontSize: 12, distance: -40 },
detail: {
valueAnimation: true,
formatter: '{value}%',
color: '#fff',
fontSize: 24,
offsetCenter: [0, '0%']
},
data: [{ value: bedUsageRate }]
}]
};
可视化效果
-
使用半圆仪表盘,符合大屏视觉习惯;
-
颜色分段显示不同负荷状态(<60%、60%-80%、>80%);
-
指针与数值同步动画,增强实时感;
-
中心显示百分比,直观清晰。
3.4 饼图:科室收入与患者类型占比
饼图用于展示构成比例,本项目中分别展示科室收入占比和患者类型分布。
数据结构
const deptRevenueData = [
{ name: '内科', value: 35 },
{ name: '外科', value: 25 },
{ name: '儿科', value: 15 },
{ name: '妇产科', value: 15 },
{ name: '其他', value: 10 }
];
const patientTypeData = [
{ name: '普通患者', value: 60 },
{ name: '医保患者', value: 25 },
{ name: '急诊患者', value: 10 },
{ name: 'VIP患者', value: 5 }
];
ECharts 配置(以科室收入为例)
option = {
title: {
text: '科室收入占比',
left: 'center',
textStyle: { color: '#fff' }
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
legend: {
orient: 'vertical',
left: 'left',
textStyle: { color: '#ccc' }
},
series: [{
name: '科室收入',
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 6,
borderColor: '#0f2027',
borderWidth: 2
},
label: { show: false },
emphasis: {
label: { show: true, fontSize: 16, fontWeight: 'bold' }
},
labelLine: { show: false },
data: deptRevenueData,
color: ['#00c6ff', '#0072ff', '#4facfe', '#00f2fe', '#a18cd1']
}]
};
可视化效果
-
使用环形饼图(
radius: ['40%', '70%']
)增强视觉层次; -
图例垂直排列,便于阅读;
-
鼠标悬浮显示详细百分比;
-
使用统一配色方案,适配整体大屏风格。
以上图表配置均基于 ECharts 5.4.3 实现,结合统一主题色与响应式布局,适用于企业级数据可视化大屏项目。
4. 动态数据与交互实现
4.1 实时数据生成与更新逻辑
为了实现大屏展示的实时性,项目中采用了模拟数据生成与定时更新机制,确保图表数据动态变化,增强视觉表现力与数据时效性。
数据模拟策略
-
使用
setInterval
定时器每 5 秒更新一次图表数据; -
数据生成基于随机波动算法,模拟真实业务场景中的数据波动;
-
所有图表共享一个全局时间戳,确保数据同步更新。
function generateMockData(baseValue, fluctuation = 0.1) {
const delta = (Math.random() - 0.5) * baseValue * fluctuation;
return Math.max(0, Math.round(baseValue + delta));
}
更新逻辑实现
setInterval(() => {
// 更新折线图数据
incomeData.values.shift();
incomeData.values.push(generateMockData(2000, 0.1));
// 更新柱状图数据
admissionData.data.forEach((dept, index) => {
dept.shift();
dept.push(generateMockData(200, 0.15));
});
// 更新仪表盘数据
bedUsageRate = generateMockData(75, 0.05);
// 更新图表实例
lineChart.setOption({ series: [{ data: incomeData.values }] });
barChart.setOption({ series: admissionData.departments.map((_, i) => ({ data: admissionData.data[i] })) });
gaugeChart.setOption({ series: [{ data: [{ value: bedUsageRate }] }] });
}, 5000);
数据接口模拟(可选)
如需接入后端接口,可使用 Axios 获取数据:
async function fetchData() {
const res = await axios.get('/api/dashboard');
return res.data;
}
4.2 图表联动与提示框配置
图表联动是大屏展示中提升交互体验的重要手段。通过 ECharts 的 dispatchAction
和事件监听机制,实现多个图表之间的联动高亮与提示框同步。
联动逻辑实现
lineChart.on('mouseover', function (params) {
const index = params.dataIndex;
barChart.dispatchAction({
type: 'highlight',
seriesIndex: 0,
dataIndex: index
});
barChart.dispatchAction({
type: 'showTip',
seriesIndex: 0,
dataIndex: index
});
});
提示框统一配置
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(0,0,0,0.7)',
borderColor: '#00c6ff',
textStyle: { color: '#fff' },
formatter: function (params) {
let result = params[0].axisValue + '<br/>';
params.forEach(item => {
result += `${item.marker} ${item.seriesName}: ${item.value}<br/>`;
});
return result;
}
}
多图表联动示例
function syncCharts(charts, eventType = 'mouseover') {
charts.forEach(chart => {
chart.on(eventType, function (params) {
charts.forEach(otherChart => {
if (otherChart !== chart) {
otherChart.dispatchAction({
type: 'highlight',
dataIndex: params.dataIndex
});
}
});
});
});
}
4.3 窗口缩放自适应处理
大屏展示需适配多种分辨率,ECharts 提供了 resize()
方法用于响应窗口大小变化,结合 CSS 媒体查询实现布局与图表的双重适配。
图表自适应处理
window.addEventListener('resize', () => {
lineChart.resize();
barChart.resize();
pieChart.resize();
gaugeChart.resize();
});
响应式布局补充
@media (max-width: 1200px) {
.dashboard {
grid-template-columns: 1fr;
grid-template-areas:
"header"
"main"
"sidebar"
"footer";
}
.chart-container {
height: 250px;
}
}
动态字体与图表尺寸调整
function adjustFontSize() {
const width = window.innerWidth;
const baseSize = width > 1920 ? 16 : 14;
document.documentElement.style.fontSize = `${baseSize}px`;
}
window.addEventListener('resize', adjustFontSize);
adjustFontSize();
通过上述机制,项目实现了图表数据的动态更新、图表间的联动交互以及窗口缩放下的自适应展示,确保大屏系统在不同场景下均具备良好的可视化效果与用户体验。
5. 图例与标签优化
5.1 自定义图例样式与位置
图例作为图表的重要组成部分,直接影响用户对数据含义的理解。在大屏展示中,图例不仅要清晰传达信息,还需与整体视觉风格保持一致。ECharts 提供了丰富的图例配置项,支持自定义样式、位置、布局方式等。
图例样式自定义
通过 legend.textStyle
和 legend.itemStyle
可自定义图例文字与图标样式:
legend: {
data: ['内科', '外科', '儿科', '妇产科', '急诊科'],
textStyle: {
color: '#ccc',
fontSize: 14,
fontFamily: 'Arial'
},
itemStyle: {
borderWidth: 1,
borderColor: '#00c6ff'
},
itemWidth: 20,
itemHeight: 10,
icon: 'rect'
}
图例位置控制
图例位置可通过 top
、left
、right
、bottom
等属性灵活控制:
legend: {
orient: 'horizontal',
top: 'bottom',
left: 'center'
}
在柱状图或折线图中,图例通常放置在底部或顶部,避免遮挡图表主体。在饼图中,图例可放置在右侧或左侧,便于与环形图形成对称布局。
多图例分组
在复杂图表中,可通过 legend.selector
实现图例分组与筛选:
legend: {
selector: [
{ type: 'all', title: '全选' },
{ type: 'inverse', title: '反选' }
]
}
5.2 数据标签格式化与显示策略
数据标签(label
)用于在图表中直接显示数值信息,提升数据可读性。合理配置标签的显示策略与格式化方式,有助于避免信息过载与视觉混乱。
标签格式化
通过 formatter
函数可自定义标签内容,支持字符串模板与回调函数:
label: {
show: true,
formatter: '{c} 人',
fontSize: 12,
color: '#fff'
}
对于数值较大的数据,可使用千分位或单位缩写:
JavaScript
复制
formatter: function (params) {
return (params.value / 1000).toFixed(1) + 'k';
}
标签显示策略
为避免标签重叠,可启用 labelLayout
进行自动避让:
labelLayout: {
hideOverlap: true
}
在柱状图中,标签可放置在柱顶或柱内:
label: {
position: 'top',
distance: 5
}
在折线图中,标签可设置为仅在 hover 时显示:
emphasis: {
label: {
show: true
}
}
5.3 饼图百分比与外部标签布局
饼图中标签常用于展示占比信息,合理布局可提升可读性与美观度。ECharts 支持将标签放置在饼图内部或外部,并支持引导线连接。
百分比显示
通过 formatter
显示百分比:
label: {
show: true,
formatter: '{b}: {d}%',
fontSize: 14,
color: '#fff'
}
外部标签与引导线
将标签放置在饼图外部,并使用引导线连接:
label: {
show: true,
position: 'outside',
formatter: '{b}: {d}%'
},
labelLine: {
show: true,
length: 15,
length2: 20,
smooth: true,
lineStyle: {
color: '#ccc',
width: 1
}
}
标签布局优化
为避免标签重叠,可启用 avoidLabelOverlap
:
series: [{
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: true,
label: {
show: true,
position: 'outside'
}
}]
在数据项较多时,可结合 minShowLabelAngle
控制最小显示角度,避免标签过于密集:
minShowLabelAngle: 5
通过上述优化策略,图例与标签不仅提升了图表的可读性与专业性,也增强了大屏展示的整体视觉效果与用户体验。
6. 总结
本教程围绕 ECharts 大屏实例 的完整实现过程,系统讲解了从项目搭建、页面布局、图表配置到动态交互与优化的关键技术点,帮助开发者掌握构建企业级数据可视化大屏的核心能力。
6.1 项目核心亮点回顾
-
完整技术栈:项目基于 ECharts 5.4.3 + Vue 3 + Vite + Axios,结合 Sass 实现响应式布局与组件化开发,具备良好的可维护性与扩展性。
-
多样化图表支持:涵盖折线图、柱状图、饼图、仪表盘、地图等多种图表类型,满足企业数据监控、运营分析等多场景需求。
-
动态数据模拟:通过定时器与随机波动算法实现图表数据的实时更新,增强大屏的时效性与视觉表现力。
-
图表联动与交互:实现多图表之间的联动高亮与提示框同步,提升用户交互体验。
-
响应式适配:结合 CSS Grid、Flexbox 与 ECharts 的
resize()
方法,确保页面与图表在不同分辨率下均能良好展示。 -
图例与标签优化:通过自定义图例样式、标签格式化与布局策略,提升图表可读性与整体视觉效果。
6.2 技术实现要点总结
模块 | 技术点 | 实现方式 |
---|---|---|
页面布局 | 响应式网格 | Flex + Grid + 媒体查询 |
图表配置 | 多图表类型 | ECharts option 配置 |
动态数据 | 模拟与更新 | setInterval + 随机波动 |
图表联动 | 高亮与提示 | dispatchAction + 事件监听 |
自适应 | 缩放适配 | resize() + 字体动态调整 |
样式优化 | 图例与标签 | legend 、label 、formatter |
6.3 可扩展方向建议
-
接入真实数据接口:替换模拟数据为后端 API,支持 WebSocket 实时推送;
-
引入地图组件:结合 ECharts Map 或百度地图实现地理数据可视化;
-
增加主题切换功能:支持浅色/深色主题切换,适配不同展示环境;
-
图表组件库封装:将常用图表封装为通用组件,提升复用效率;
-
性能优化:对大数据量图表使用懒加载、数据分页等策略,提升渲染性能。
通过本教程的学习与实践,开发者可以快速掌握 ECharts 大屏项目的开发流程与关键技术,具备独立完成企业级可视化系统的能力。