大屏可视化项目解决方案

63 阅读3分钟

大屏可视化方案

方案 1 scale

1.优点:无需考虑 rem 单位,无需考虑定位,一次适配,无需单独处理图标

2.缺点:两边留白,比例过大时热区偏移,字体模糊.

具体实现

根据屏幕的变化适配的比例

<template>
  <div class="screen-wrapper">
    <div class="screen" id="screen">
      <div class="box">123</div>
    </div>
  </div>
</template><script setup>
import { onMounted } from "vue";
​
const initData = () => {
  const designDraftWidth = 1920; //设计稿的宽度
  const designDraftHeight = 1080; //设计稿的高度
  //根据屏幕的变化适配的比例
  const scale =
    document.documentElement.clientWidth /
      document.documentElement.clientHeight <
    designDraftWidth / designDraftHeight
      ? document.documentElement.clientWidth / designDraftWidth
      : document.documentElement.clientHeight / designDraftHeight;
  //缩放比例
  document.querySelector(
    "#screen"
  ).style.transform = `scale(${scale}) translate(-50%)`;
};
​
onMounted(() => {
  // 初始化时禁止滚动
  document.documentElement.style.overflow = "hidden";
  initData();
  window.onresize = () => initData();
});
</script><style scoped lang="less">
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body {
  overflow: hidden;
}
.screen-wrapper {
  height: 100%;
  width: 100%;
  .screen {
    display: inline-block;
    width: 1920px; //设计稿的宽度
    height: 1080px; //设计稿的高度
    transform-origin: 0 0;
    position: absolute;
    left: 50%;
    .box {
      width: 100%;
      height: 100px;
      background-color: skyblue;
    }
  }
}
</style>

方案 2 vw vh

1.优点:动态处理图标宽高、字体,屏幕两边不留白,比例正常,

2.缺点:每个图标需要做单独处理,费事麻烦

具体实现

1.使用 PostCSS 插件 postcss-px-to-viewport

npm install postcss-px-to-viewport --save-dev

2.vue.config.js

module.exports = defineConfig({
  transpileDependencies: true,
  css: {
    loaderOptions: {
      postcss: {
        postcssOptions: {
          plugins: [
            require("postcss-px-to-viewport")({
              unitToConvert: "px", // 要转换的单位
              viewportWidth: 1920, // 设计稿宽度
              viewportHeight: 1080, // 设计稿高度
              unitPrecision: 5, // 转换后保留的小数位数
              viewportUnit: "vw", // 转换成的单位
              fontViewportUnit: "vw", // 字体转换成的单位
              selectorBlackList: [], // 不转换的选择器(如 .ignore-*)
              minPixelValue: 1, // 最小转换值(1px 以下不转换)
              mediaQuery: false, // 是否转换媒体查询里的 px
            }),
          ],
        },
      },
    },
  },
});

3.直接写 px,自动转 vw

<style lang="less" scoped>
.box {
  width: 300px; /* 自动转成 vw */
  height: 100px; /* 自动转成 vh */
  font-size: 16px; /* 自动转成 vw */
  margin-left: 300px; /* 自动转成 vw */
  margin-top: 100px; /* 自动转成 vh */
}
</style>
图表自适应方案
  1. 安装 element-resize-detector

npm install element-resize-detector --save

  1. 引入工具包在组件中使用或者在单独的 js 中使用

import resizeDetector from 'element-resize-detector'

  1. 封装 directive
js 体验AI代码助手 代码解读复制代码// directive.js
import * as ECharts from "echarts";
import elementResizeDetectorMaker from "element-resize-detector";
import Vue from "vue";
const HANDLER = "_vue_resize_handler";
function bind(el, binding) {
  el[HANDLER] = binding.value
    ? binding.value
    : () => {
        let chart = ECharts.getInstanceByDom(el);
        if (!chart) {
          return;
        }
        chart.resize();
      };
  // 监听绑定的div大小变化,更新 echarts 大小
  elementResizeDetectorMaker().listenTo(el, el[HANDLER]);
}
function unbind(el) {
  // window.removeEventListener("resize", el[HANDLER]);
  elementResizeDetectorMaker().removeListener(el, el[HANDLER]);
  delete el[HANDLER];
}
// 自定义指令:v-chart-resize 示例:v-chart-resize="fn"
Vue.directive("chart-resize", { bind, unbind });
  1. main.js 中引入
import '@/directive/directive';
  1. html 代码
<template>
  <div class="linechart">
    <div ref="chart" v-chart-resize class="chart"></div>
  </div>
</template>
特殊尺寸处理工具

有些特殊情况,echarts只支持具体的px,导致文字过大过小或者重叠,就需要手动适配

  1. 编写 dataUtil.js 工具函数
// Echarts图表字体、间距自适应
export const fitChartSize = (size,defalteWidth = 1920) => {
  let clientWidth = window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth;
  if (!clientWidth) return size;
  let scale = (clientWidth / defalteWidth);
  return Number((size*scale).toFixed(3));
}

2.图表使用

 grid: {
          left: this.fitChartSize(10),
          right: this.fitChartSize(20),
          top: this.fitChartSize(20),
          bottom: this.fitChartSize(10),
        },

方案3 第三方库v-scale-screen

v-scale-screen

vue2请使用v-scale-screen@1.0.0版本,vue3请使用v-scale-screen@2.0.0版本