我来为您介绍大屏适配的几种方案,特别针对数据可视化大屏场景

openclaw AI小龙虾攻略 2

CSS 单位方案

1 使用 vw/vh 单位

/* 基于设计稿1920*1080 */
.container {
  width: calc(100vw - 40px);
  height: calc(100vh - 60px);
}
.card {
  width: 25vw;  /* 占视口宽度25% */
  height: 30vh; /* 占视口高度30% */
  font-size: calc(12px + 0.5vw); /* 字体响应式 */
}

2 rem 方案(推荐)

// 设置基准 rem
function setRem() {
  const baseSize = 16; // 基础字体大小
  const designWidth = 1920; // 设计稿宽度
  const scale = document.documentElement.clientWidth / designWidth;
  document.documentElement.style.fontSize = 
    baseSize * Math.min(scale, 2) + 'px'; // 限制最大缩放
}
window.addEventListener('resize', setRem);
setRem();

缩放方案

1 transform: scale 缩放

class ScreenAdapter {
  constructor(options = {}) {
    this.options = {
      designWidth: 1920,
      designHeight: 1080,
      ...options
    };
    this.init();
  }
  init() {
    this.updateScale();
    window.addEventListener('resize', () => this.updateScale());
  }
  updateScale() {
    const { clientWidth, clientHeight } = document.documentElement;
    const { designWidth, designHeight } = this.options;
    // 计算缩放比例
    const scaleX = clientWidth / designWidth;
    const scaleY = clientHeight / designHeight;
    const scale = Math.min(scaleX, scaleY); // 取最小比例保持比例
    // 应用缩放
    const app = document.getElementById('app');
    if (app) {
      app.style.transform = `scale(${scale})`;
      app.style.transformOrigin = 'top left';
      app.style.width = `${designWidth}px`;
      app.style.height = `${designHeight}px`;
    }
  }
}

媒体查询方案

/* 超宽屏(>2560px) */
@media screen and (min-width: 2560px) {
  .chart-container {
    padding: 2rem;
  }
  .card {
    margin: 1.5rem;
  }
}
/* 标准屏(1920px) */
@media screen and (min-width: 1920px) and (max-width: 2559px) {
  .chart-container {
    padding: 1rem;
  }
}
/* 笔记本屏(1366px) */
@media screen and (max-width: 1919px) {
  .grid-container {
    grid-template-columns: repeat(2, 1fr);
  }
  .font-size {
    font-size: 0.9rem;
  }
}
/* 高度适配 */
@media screen and (max-height: 800px) {
  .header {
    height: 50px;
  }
  .content {
    height: calc(100vh - 50px);
  }
}

Flexible + 网格布局

/* 使用 CSS Grid 创建响应式布局 */
.dashboard {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  grid-gap: 20px;
  padding: 20px;
}
/* 使用 Flexbox */
.chart-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}
.chart-item {
  flex: 1 1 calc(33.333% - 20px);
  min-width: 300px;
  margin: 10px;
}

图表库适配

1 ECharts 适配

const initChart = () => {
  const chart = echarts.init(dom);
  const resizeChart = () => {
    chart.resize();
  };
  // 使用防抖
  const debounceResize = _.debounce(resizeChart, 300);
  window.addEventListener('resize', debounceResize);
  // 响应式配置
  chart.setOption({
    grid: {
      left: '3%',
      right: '4%',
      bottom: '10%',
      top: '10%',
      containLabel: true
    },
    textStyle: {
      fontSize: window.innerWidth < 1920 ? 12 : 14
    }
  });
};

2 AntV G2/G6 适配

class GraphAdapter {
  constructor(graph) {
    this.graph = graph;
    this.initResizeListener();
  }
  initResizeListener() {
    const observer = new ResizeObserver(entries => {
      for (let entry of entries) {
        const { width, height } = entry.contentRect;
        this.graph.changeSize(width, height);
      }
    });
    observer.observe(this.graph.container);
  }
}

完整适配方案示例

// 大屏适配管理器
class ScreenAdapter {
  constructor() {
    this.designWidth = 1920;
    this.designHeight = 1080;
    this.currentMode = 'scale';
    this.init();
  }
  init() {
    this.setRem();
    this.bindEvents();
    this.adaptCharts();
  }
  // 方案1: REM适配
  setRem() {
    const width = document.documentElement.clientWidth;
    const height = document.documentElement.clientHeight;
    // 计算比例
    const scaleX = width / this.designWidth;
    const scaleY = height / this.designHeight;
    const scale = Math.min(scaleX, scaleY);
    // 设置根字体大小
    document.documentElement.style.fontSize = 
      `${16 * scale}px`;
  }
  // 方案2: Scale适配
  scaleAdapt() {
    const app = document.getElementById('app');
    if (!app) return;
    const { clientWidth, clientHeight } = document.documentElement;
    const scaleX = clientWidth / this.designWidth;
    const scaleY = clientHeight / this.designHeight;
    const scale = Math.min(scaleX, scaleY);
    app.style.transform = `scale(${scale})`;
    app.style.transformOrigin = '0 0';
    app.style.width = `${this.designWidth}px`;
    app.style.height = `${this.designHeight}px`;
  }
  // 绑定事件
  bindEvents() {
    const debounceAdapt = _.debounce(() => {
      this.setRem();
      this.adaptCharts();
    }, 300);
    window.addEventListener('resize', debounceAdapt);
    window.addEventListener('orientationchange', debounceAdapt);
  }
  // 适配图表
  adaptCharts() {
    // 获取所有图表实例并重新渲染
    document.querySelectorAll('[data-chart]').forEach(chartDom => {
      const chart = echarts.getInstanceByDom(chartDom);
      if (chart) {
        chart.resize();
      }
    });
  }
  // 切换适配模式
  switchMode(mode) {
    this.currentMode = mode;
    if (mode === 'scale') {
      this.scaleAdapt();
    } else {
      this.setRem();
    }
  }
}
// 使用
const adapter = new ScreenAdapter();

注意事项

  1. 性能优化

    我来为您介绍大屏适配的几种方案,特别针对数据可视化大屏场景-第1张图片-官方获取 | OpenClaw下载 - openclaw官网

    • 使用防抖/节流避免频繁重绘
    • 使用 CSS will-change 属性优化
    • 合理使用硬件加速
  2. 字体适配

    /* 使用 clamp() 函数 */{
      font-size: clamp(16px, 1.5vw, 24px);
    }
  3. 图片适配

    <!-- 使用 picture 标签 -->
    <picture>
      <source media="(min-width: 1920px)" srcset="large.jpg">
      <source media="(min-width: 1366px)" srcset="medium.jpg">
      <img src="small.jpg" alt="...">
    </picture>
  4. 浏览器兼容性

    • 添加必要的 polyfill
    • 测试不同浏览器表现

推荐方案组合

对于 openclaw 这类数据可视化大屏,建议:

主方案:rem + vw/vh 单位
备用方案:transform: scale 缩放
配合:CSS Grid/Flexbox 布局
图表:ECharts/AntV 内置适配

这样既能保证适配效果,又能提供良好的用户体验。

标签: 大屏适配 数据可视化

抱歉,评论功能暂时关闭!