大屏可视化项目

248 阅读3分钟

项目通过引入 EChart 图表的形式,实现了大屏数据动态显示的功能,由于没有后端数据作为支撑,所以项目使用的是静态数据。下面总结下做项目过程中遇到的难点,主要包括两个:屏幕的适配问题和 EChart 图表引入的配置问题。

一、屏幕的适配

假设设计稿的宽高确定,比例为 16:9,但是,屏幕的比例不确定,这种情况,屏幕该如何适配?

333.png

下面是该项目大屏的适配工式,页面的比例保持和设计稿一致,然后上下居、左右居中、四周留白。然后,设置根元素的 font-size,即 1em = Wp / 100,该单位在后面会用到。

1303f19f4f3d1926d2ec133e3d798ff.png

屏幕适配后,像素等度量单位已经不能用了,因为屏幕大小是动态的,用固定的度量单位肯定会出错。因此,我们需要将设计稿的固定像素转化为网页的动态像素

image.png

详细代码如下所示:

// html
<html lang="zh">
  <head>
    <script>
      const clientWidth = document.documentElement.clientWidth;
      const clientHeight = document.documentElement.clientHeight;
      window.pageWidth =
        clientWidth / clientHeight > 16 / 9
          ? clientHeight * (16 / 9)
          : clientWidth;
      const pageHeight = pageWidth / (16 / 9);
      const string = `<style>html{
      font-size: ${pageWidth / 100}px
    }</style>`;
      document.write(string);
    </script>
  </head>
  <body>
    <div id="root"></div>
    <script>
      root.style.width = pageWidth + "px";
      root.style.height = pageHeight + "px";
      root.style.marginTop = (clientHeight - pageHeight) / 2 + "px";
      root.style.marginLeft = (clientWidth - pageWidth) / 2 + "px";
    </script>
  </body>
</html>

// scss
@function px($n) {
  @return $n/1920 * 100rem;  // 1920 为设计稿宽度,100 rem 为屏幕宽度。根据测量的像素 $n 就可以计算出网页的动态像素。
}

// ts
function px(n) {
  return  (n / 1920) * (window as any).pageWidth
}

二、EChart 图表的配置

项目引进了大量 EChart 图表,包括柱状图、析线图、饼图、地图等,其中配置是其中的难点,下面说说项目中用到的一些配置。

1、配置 grid,直角坐标系内绘图的位置。

// 假设 box 宽高已知
grid: [
  {
    left: px(20),  // 内绘图距离盒子上下左右的距离
    right: px(20),
    top: px(20),
    bottom: px(20),
    containLabel: true,// grid 区域是否包含坐标轴
  },
],

2、配置 xAxis 和 yAxis,直角坐标系 grid 中的 x 轴和 y 轴。

// 以 xAxis 为例
xAxis: {
  // x 轴是否展示
  show: true
  // x 轴类型。包括数值轴、时间轴、对数轴和类目轴。
  type: 'category',
  // x 轴两边是否留空白,类目轴和非类目轴配置参数不一样。
  boundaryGap: truedata: ["兰州新区","兰州新区","兰州新区",],
  // x 轴的刻度相关配置
  axisTick: { show: false },
  // x 轴的轴线相关配置
  axisLine: {lineStyle: { color: "#083B70" }},
  // x 轴刻度标签相关配置
  axisLabel: {
    fontSize: px(12),
    color: "#79839E",
    width: px(15),
    // 坐标轴刻度标签的显示间隔,在类目轴中有效。0 表示全部显示,1 表示间隔一个标签,2 表示间隔两个标签。
    interval: 0// 文字超出宽度是否截断或者换行
    overflow: "breakAll",
    // 对标签内容进行格式化
    formatter(val) {
      if (val.length > 2) {
        const array = val.split("");
        array.splice(2, 0, "\n");
        return array.join("");
      } else {
        return val;
      }
    },
  },
},

3、配置 length,图例组件。

legend:{
  // 是否展示
  show:true,
  // 图例在上下左右的位置
  left:'auto',
  right:'right'
  top:'20%',
  bottom:20,
  // 图例组件的宽高
  width:'auto',
  height:16,
  // 图例标记图形的宽度
  itemWidth:25,
  itemHeight:25,
  // 图例标记图形的样式
  itemStyle:{...},
  // 图例文字的样式
  textStyle:{...}
}

4、配置 series,包含了一系列图表,先确定 type,再进行相关配置。

// 以折线图为例
series: [{
  type: "line",
  // 数据
  data: [932, 901, 934, 1290, 1330, 1320],
  // 折点处标记的图形和标记的大小
  showSymbol: true,
  symbol: "rect",
  symbolSize: 12,
  // 鼠标悬浮在图形上时鼠标的样式
  cursor: "pointer",
  // 图形上文本标签的相关配置
  label: {...},
  // 标签的视觉引导线的相关配置
  labelLine: {...},
  // 拆线拐点标志的样式
  itemStyle: {},
  // 区域填充样式的相关配置
  areaStyle: {},
}]

源码链接:github.com/wgbcode/big…

项目预览:wgbcode.gitee.io/big-screen/