数据大屏设计
概述
数据大屏(Dashboard)通常用于展示厅、会议室等场景,将业务数据可视化在大尺寸屏幕上。技术挑战集中在屏幕适配、实时数据和动效设计。
屏幕自适应方案
方案一:等比缩放(scale)
最常用方案,设计稿固定分辨率(如 1920x1080),整体缩放:
function initScaleScreen(
designWidth: number = 1920,
designHeight: number = 1080
): void {
const container = document.getElementById('bindary-screen')!;
function resize(): void {
const scaleX = window.innerWidth / designWidth;
const scaleY = window.innerHeight / designHeight;
const scale = Math.min(scaleX, scaleY); // 等比缩放,保证不溢出
container.style.transform = `scale(${scale})`;
container.style.transformOrigin = 'left top';
container.style.width = `${designWidth}px`;
container.style.height = `${designHeight}px`;
// 居中(如果有留白)
container.style.left = `${(window.innerWidth - designWidth * scale) / 2}px`;
container.style.top = `${(window.innerHeight - designHeight * scale) / 2}px`;
}
resize();
window.addEventListener('resize', resize);
}
方案二:vw/vh + rem
/* 以 1920 设计稿为基准 */
html {
font-size: calc(100vw / 192); /* 1rem = 10px@1920 */
}
.chart-container {
width: 40rem;
height: 30rem;
margin: 1rem;
}
方案三:CSS Grid + 百分比
.screen-grid {
display: grid;
grid-template-columns: 25% 50% 25%;
grid-template-rows: 15% 55% 30%;
width: 100vw;
height: 100vh;
gap: 8px;
padding: 8px;
}
方案对比
| 方案 | 优势 | 劣势 | 适用场景 |
|---|---|---|---|
| scale 等比缩放 | 实现简单、不变形 | 可能留白 | 固定比例大屏 |
| vw/vh + rem | 充满屏幕 | 可能拉伸变形 | 比例接近的屏幕 |
| CSS Grid | 响应式布局 | 组件需适配 | 多分辨率兼容 |
实时数据更新
WebSocket + 定时轮询
class DataService {
private ws: WebSocket | null = null;
private listeners = new Map<string, Set<(data: unknown) => void>>();
connect(url: string): void {
this.ws = new WebSocket(url);
this.ws.onmessage = (event) => {
const { type, data } = JSON.parse(event.data);
this.listeners.get(type)?.forEach((cb) => cb(data));
};
this.ws.onclose = () => {
// 自动重连
setTimeout(() => this.connect(url), 3000);
};
}
subscribe(type: string, callback: (data: unknown) => void): () => void {
if (!this.listeners.has(type)) this.listeners.set(type, new Set());
this.listeners.get(type)!.add(callback);
return () => this.listeners.get(type)?.delete(callback);
}
}
数据过渡动画
数据更新时不应跳变,而应平滑过渡:
// 数字翻牌器
function animateNumber(
el: HTMLElement,
from: number,
to: number,
duration: number = 1000
): void {
const start = performance.now();
const diff = to - from;
function tick(now: number): void {
const progress = Math.min((now - start) / duration, 1);
const eased = progress * (2 - progress); // easeOutQuad
const current = from + diff * eased;
el.textContent = Math.round(current).toLocaleString();
if (progress < 1) requestAnimationFrame(tick);
}
requestAnimationFrame(tick);
}
动效设计
常见大屏动效
| 动效类型 | 实现方式 | 场景 |
|---|---|---|
| 数字翻牌 | CSS transform / JS | 关键指标 |
| 流光线条 | SVG stroke-dashoffset 动画 | 连接线 |
| 粒子效果 | Canvas / WebGL | 装饰背景 |
| 水波球 | SVG / Canvas | 占比指标 |
| 地图飞线 | Canvas bezier + 渐变 | 地理关系 |
| 3D 旋转 | Three.js / CSS 3D | 地球、模型 |
流光线条
/* SVG 路径流光效果 */
.flow-line {
stroke: url(#gradient);
stroke-width: 2;
stroke-dasharray: 20, 200;
fill: none;
animation: flow 3s linear infinite;
}
@keyframes flow {
to { stroke-dashoffset: -220; }
}
性能注意事项
大屏性能
- 避免过多 DOM 动画:优先用 Canvas / GPU 动画
- 控制更新频率:非关键指标 5-10 秒更新一次即可
- 内存泄漏:长时间运行需注意清理定时器和事件监听
- 图表销毁:页面切换时 dispose 所有 ECharts 实例
- 浏览器全屏:用
document.documentElement.requestFullscreen()进入全屏
常见面试问题
Q1: 数据大屏如何做屏幕适配?
答案:
最常用的是 scale 等比缩放方案:按设计稿尺寸(如 1920x1080)开发,运行时计算屏幕与设计稿的缩放比,对整个容器应用 CSS transform: scale()。优点是实现简单、保持比例不变形;缺点是可能有留白。其他方案包括 vw/vh + rem、CSS Grid 响应式布局。
Q2: 大屏的实时数据如何处理?
答案:
用 WebSocket 推送实时数据,配合数据过渡动画平滑更新。非实时指标可用定时轮询。注意控制更新频率、做断线重连、长时间运行的内存管理。
Q3: 大屏长时间运行需要注意什么?
答案:
- 内存泄漏:清理定时器、事件监听、ECharts 实例
- WebSocket 断线重连
- 页面自动刷新机制(防止内存持续增长)
- 错误容灾:某个图表报错不影响其他模块
- 浏览器全屏 + 禁止屏保