大屏数据可视化解决方案

一、 分辨率

分辨率 典型设备 字体大小 布局策略 单位选择
1920×1080 普通台式显示器、高端笔记本、会议平板 14px-18px 响应式栅格 rem、%、px
2560×1440 普通台式显示器、高端笔记本、会议平板 14px-18px 响应式栅格 rem、%、px
3840×2160 专业显示器、指挥中心、展厅LED/液晶拼接屏、数字标牌、电视墙 >=24px,甚至40px+ 固定比例布局+视口单位 vw/vh、vmin
5120×2880 专业显示器、指挥中心、展厅LED/液晶拼接屏、数字标牌、电视墙 >=24px,甚至40px+ 固定比例布局+视口单位 vw/vh、vmin
7680×4320 专业显示器、指挥中心、展厅LED/液晶拼接屏、数字标牌、电视墙 >=24px,甚至40px+ 固定比例布局+视口单位 vw/vh、vmin
拼接屏(如 3840×1080 多屏) 专业显示器、指挥中心、展厅LED/液晶拼接屏、数字标牌、电视墙 >=24px,甚至40px+ 固定比例布局+视口单位 vw/vh、vmin

超大屏

常见分辨率

  • 3840×2160(4K UHD)

  • 5120×2880(5K)

  • 7680×4320(8K)

  • 或拼接屏(如 3840×1080 多屏)

典型设备

  • 专业显示器、指挥中心、展厅LED/液晶拼接屏、数字标牌、电视墙

字体大小

  • =24px,甚至40px+

布局策略

  • 固定比例布局+视口单位

单位选择

  • vw/vh、vmin

开发注意点

  • 禁用滚动条:超大屏通常是全屏展示,因此需要禁用滚动条

  • 使用vw/vh + clamp() 控制元素大小,确保在4k/8k下比例协调

  • 测试正式设备: 浏览器模拟器无法还原观看距离和像素密度。

  • 1px边框在8k屏上可能看不到,建议使用2px+

二 、开发方案

1. 等比例大屏/超大屏

  • transform: scale() + 容器包裹(最稳定)

2. 超大长屏幕

  • 场景 1:超宽拼接屏(如 3840×1080、5760×1080)------ 常见于数据看板、监控墙

垂直方向:严格按 1080px 高度布局(保证字体、组件高度可读)

水平方向:使用 响应式栅格 / 弹性布局 / 动态列数,填满整个宽度

实现:

【1】禁用全局 scale,改用 vw + rem

复制代码
/* 根字体基于高度固定,避免文字随宽度无限变大 */

html {
  <!-- 16px × (当前屏幕高度 / 设计稿高度) 如果屏幕分辨率高度不是1080,可以直接替换这个公式 -->
  font-size: calc(1080px / 1080 * 16px); /* 固定为 16px,或根据需求微调 */
}

/* 主容器高度固定为 1080px,宽度 100% */
.dashboard {
  width: 100vw;
  height: 1080px; /* 关键:高度锁定 */
  overflow: hidden;
}

【2】水平区域使用弹性布局或 CSS Grid

复制代码
<template>
  <div class="dashboard">
    <Header class="header" />
    <div class="content">
      <!-- 使用 Grid 自动分配列宽 -->
      <ChartCard v-for="item in charts" :key="item.id" />
    </div>
  </div>

</template>
<style scoped>
.content {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); /* 自适应列数 */
  height: calc(100% - 80px);
  gap: 20px;
  padding: 20px;
}

</style>

【3】关键元素使用 vh 控制高度(可选)

复制代码
.card {
  height: 30vh; /* 约 324px @1080p,比例合理 */
}

三 、缩放方案-代码封装

screenAdaptive.ts

复制代码
interface AdaptiveOptions {
  designWidth?: number;     // 设计稿宽度,默认 1920
  designHeight?: number;    // 设计稿高度,默认 1080
  mode?: 'width' | 'height' | 'auto' | 'widthAndHeight'; // 缩放模式
  containerSelector?: string; // 容器选择器,默认 .screen
  transformOrigin?: string; // transform-origin,默认 top left
};
//定义默认配置项
const DefaultContainerSelector = '.screen';
const DEFAULT_OPTIONS: Required<AdaptiveOptions> = {
  designWidth: 1920,
  designHeight: 1080,
  mode: 'auto', // auto = 等比缩放(取 min(scaleX, scaleY))
  containerSelector: DefaultContainerSelector,
  transformOrigin: 'top left'
};

let resizeTimer: number | null = null;

export const initScreenAdaptive = (options: AdaptiveOptions = {}) => {
  const opts = { ...DEFAULT_OPTIONS, ...options };
  const { designWidth, designHeight, mode, containerSelector, transformOrigin } = opts;

  const adapt = () => {
    const container = document.querySelector<HTMLElement>(containerSelector);
    if (!container) return;

    const screenWidth = window.innerWidth;
    const screenHeight = window.innerHeight;

    let scale: number = 1;
    let scaleX: number = 1;
    let scaleY: number = 1;
    if (mode === 'width') {
      // 仅按宽度缩放(高度可能溢出)
      scale = screenWidth / designWidth;
    } else if (mode === 'height') {
      // 仅按高度缩放(宽度可能溢出)
      scale = screenHeight / designHeight;
    } else if (mode === 'widthAndHeight') {
      // 宽高都按比例缩放
      scaleX = screenWidth / designWidth;
      scaleY = screenHeight / designHeight;
    } else {
      // auto: 等比缩放,保证完整显示(类似 background-size: contain)
      const scaleX = screenWidth / designWidth;
      const scaleY = screenHeight / designHeight;
      scale = Math.min(scaleX, scaleY);
    }
    
    // 设置容器尺寸和缩放
    container.style.width = `${designWidth}px`;
    container.style.height = `${designHeight}px`;
    container.style.transform = mode === 'widthAndHeight' ? `scale(${scaleX}, ${scaleY})` : `scale(${scale})`;
    container.style.transformOrigin = transformOrigin;
  };

  // 首次执行
  adapt();

  // 监听窗口变化(带防抖)
  const onResize = () => {
    if (resizeTimer) {
      clearTimeout(resizeTimer);
    }
    resizeTimer = window.setTimeout(adapt, 100);
  };

  window.addEventListener('resize', onResize);

  // 返回销毁函数(可选)
  return () => {
    window.removeEventListener('resize', onResize);
    if (resizeTimer) clearTimeout(resizeTimer);
  };
}

// 将 页面坐标(clientX, clientY)转换为 设计稿坐标
export const getDesignCoords = (
  clientX: number,
  clientY: number,
  containerSelector = DefaultContainerSelector
): { x: number; y: number } => {
  const container = document.querySelector<HTMLElement>(containerSelector);
  if (!container) {
    return { x: clientX, y: clientY };
  }

  // 获取容器的边界和 transform 值
  const rect = container.getBoundingClientRect();
  const style = window.getComputedStyle(container);
  const transform = style.transform;

  let scaleX = 1;
  let scaleY = 1;

  if (transform && transform !== 'none') {
    // 解析 matrix( a, b, c, d, tx, ty )
    const matrix = new DOMMatrix(transform);
    scaleX = matrix.a; // scaleX
    scaleY = matrix.d; // scaleY
  }

  // 将页面坐标转换为容器内的原始设计稿坐标
  const x = (clientX - rect.left) / scaleX;
  const y = (clientY - rect.top) / scaleY;

  return { x, y };
}

使用方法:

【1】引入

复制代码
import { initScreenAdaptive } from './screenAdaptive';

【2】使用

复制代码
//定义设计稿的分辨率
const DesignDraftWidth = 1920;
const DesignDraftHeight = 1080;

//dom加载完成后,进行可视窗口大小判断
if (window.innerWidth > DesignDraftWidth) {
    initScreenAdaptive({
    	 designWidth: DesignDraftWidth,
      designHeight: DesignDraftHeight,
      mode: 'height',
      transformOrigin: 'center'
    });
} 

//div容器需要配置默认样式名称.screen(也可以自定义)
<div class='screen'>
	/* 这里存放需要缩放的dom元素 */
</div>

注意

对于大多数组件库的弹框、抽屉等组件默认绑定到是body标签上,故无法进行缩放,只有把这些组件绑定到你的包裹容器(.srceen)才可以实现缩放

相关推荐
极光代码工作室2 小时前
基于Spark的电商用户点击流分析系统
大数据·python·数据分析·spark·数据可视化
FIT2CLOUD飞致云2 小时前
加强安全防护,图表与仪表板功能优化,DataEase开源BI工具v2.10.23 LTS版本发布
数据分析·开源·数据可视化·dataease·bi
SAP_奥维奥科技1 天前
从产品合规到体系出海:中国医疗器械企业经营底座重构白皮书
sap·数据可视化·复杂供应链管理·sap医疗器械·sap生命科学
Elastic 中国社区官方博客1 天前
从平均值到任意百分位:Elasticsearch 在 ES|QL 中提供原生 exponential histogram 支持
大数据·人工智能·elasticsearch·搜索引擎·信息可视化·全文检索·数据可视化
SZLSDH1 天前
行业洞察 | 场景、孪生与智能体:数字孪生平台协同演进的底层逻辑
ai·数字孪生·数据可视化·智能体
AllData公司负责人2 天前
亲测丝滑,体验跃迁|AllData通过集成开源项目Datart,让数据可视化一目了然
java·大数据·数据库·python·数据可视化·数据视图·datart
hdsoft_huge2 天前
全开源数字孪生系统搭建方案:从三维建模到可视化展示全流程落地
数学建模·信息可视化·开源·数据可视化
SZLSDH3 天前
当数字孪生陷入“交付即闲置”困境:从重建设到重运营的路径选择
ai·数字孪生·数据可视化·智能体
SZLSDH4 天前
从“立体沙盘”到“实时决策系统”:数字孪生在基础设施运营中的效能跃迁
数据可视化