跳到主要内容

数据大屏设计

概述

数据大屏(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; }
}

性能注意事项

大屏性能
  1. 避免过多 DOM 动画:优先用 Canvas / GPU 动画
  2. 控制更新频率:非关键指标 5-10 秒更新一次即可
  3. 内存泄漏:长时间运行需注意清理定时器和事件监听
  4. 图表销毁:页面切换时 dispose 所有 ECharts 实例
  5. 浏览器全屏:用 document.documentElement.requestFullscreen() 进入全屏

常见面试问题

Q1: 数据大屏如何做屏幕适配?

答案

最常用的是 scale 等比缩放方案:按设计稿尺寸(如 1920x1080)开发,运行时计算屏幕与设计稿的缩放比,对整个容器应用 CSS transform: scale()。优点是实现简单、保持比例不变形;缺点是可能有留白。其他方案包括 vw/vh + rem、CSS Grid 响应式布局。

Q2: 大屏的实时数据如何处理?

答案

用 WebSocket 推送实时数据,配合数据过渡动画平滑更新。非实时指标可用定时轮询。注意控制更新频率、做断线重连、长时间运行的内存管理。

Q3: 大屏长时间运行需要注意什么?

答案

  1. 内存泄漏:清理定时器、事件监听、ECharts 实例
  2. WebSocket 断线重连
  3. 页面自动刷新机制(防止内存持续增长)
  4. 错误容灾:某个图表报错不影响其他模块
  5. 浏览器全屏 + 禁止屏保

相关链接