跳转到内容

数据大屏

刀刀

1/2/2025

0 字

0 分钟

适配方案

数据大屏需要适配用户的屏幕大小,否则会出现用户屏幕大小不同时出现样式错乱问题。适配解决方案一般分为 vwvhscalc 缩放功能。

vw与vh

IE8后推出一个新单位:vwvh。当为盒子设置 100vw100vh 时,会直接占满整个屏幕。因此可以通过计算把 px 换算为 vwvh,实现响应式自适应。

案例

现有一个盒子,需要其占满整个屏幕,里面有一个盒子,需要其宽高为 100px

占满整个屏幕只需要让其 100vw100vh 即可。里面的小盒子需要计算,计算公式为屏幕宽度除以100得出 1vw 对应多少像素,如我的屏幕为 1920px,则 1920 / 100 = 19.2 。即 1vw 对应 19.2px,则 100px 则是 100 / 19.2 = 5vw 左右。高度计算同理。

优缺点

  • 优点

    简单快捷,使用方便

  • 缺点

    需要大量计算,无法控制字体本身的大小,如果盒子过窄会使得字体覆盖旁边的盒子

scalc

通过 CSS 中 transform 中的 scalc() 缩放属性实现功能。

首先为最外层的盒子设置宽高、固定定位属性,定位到页面的正中央。

css
.box {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: (-50%, -50%);
    width: 1920px;
    height: 1080px;
    transform-origin: left top;
}

⚠ 注意

scalc() 属性默认以盒子正中心为单位做缩放处理,这样会导致放大时把内容顶出左侧,需要修改缩放定位点。transform-origin 可以修改定位点。

然后通过 JavaScript 获取最外层盒子元素,设置一个函数获取该元素的宽高,计算出需要缩放的倍数,并比较宽高倍数,返回更小的那个。

js
let box = document.querySelector('.box')
box.style.transform = `scalc(${getScalc()})`

function getScalc(w = 1920, h = 1080) {
    let ww = window.innerWidth / w
    let wh = window.innerHeight / h
    
    return ww < wh ? ww : wh
}

⚠ 注意

函数接收需要缩放的主屏幕宽高,默认值为 1920 与 1080,真实场景下需要动态获取并传参。

最后为 window 绑定一个页面缩放事件,页面缩放后动态缩放。

js
// ....

window.onresize = () => {
    box.style.transform = `scalc(${getScalc()})`
}

ECharts

使用

echarts官网指路:echarts

根据文档的指示,想要使用 echarts ,需要做到以下步骤:

  1. 下载 echarts

    shell
    pnpm i echarts
  2. 引入第三方包

    js
    import * as echarts from 'echarts'
  3. 设置一个渲染的节点

    vue
    <div class="map" ref="chartsRef"></div>
  4. 在组件挂载完毕的生命周期挂载 echarts 图表(以饼图为例)

    js
    const echartsRef = ref()
    
    onMounted(() => {
      let myCharts = echarts.init(echartsRef.value)
    
      let option = {
      tooltip: {
        trigger: 'item'
      },
      legend: {
        top: 30,
        right: 20,
        orient: 'vertical', // 图例默认方向(垂直)
        textStyle: {
          color: '#fff',
          fontSize: 14
        }
      },
      series: [
        {
          name: 'Access From',
          type: 'pie',
          radius: ['40%', '70%'],
          avoidLabelOverlap: false,
          itemStyle: {
            borderRadius: 10,
            borderColor: '#fff',
            borderWidth: 2
          },
          label: {
            show: true,
            position: 'inside',
            color: '#fff'
          },
          emphasis: {
            label: {
              show: true,
              fontSize: 40,
              fontWeight: 'bold'
            }
          },
          labelLine: {
            show: false
          },
          data: [
            { value: 1048, name: '50以上' },
            { value: 735, name: '40-50' },
            { value: 580, name: '30-40' },
            { value: 484, name: '20-30' },
            { value: 300, name: '20以下' }
          ]
        }
      ]
    };
    
      // 设置实例
      myCharts.setOption(option)
    })

水球图

水球图的设计可以访问 ECharts Demo 集的官网 ECharts Demo ,里面是民间对 echarts 图表的修改,以至于实现更多的需求。其中也包括水球图与地图。

水球图需要下载 liquidFill 插件用于设置类型:

shell
pnpm i echarts-liquidfill

设置水球图参数:和其他 ECharts 图表一样,水球图提供将系列的 type 指定为 liquidFill(注意大小写)来表明这是一个水球图类型。

简单的配置项代码
js
onMounted(() => {
  let myCharts = echarts.init(echartsRef.value)

  // 设置实例
  myCharts.setOption({
    // 标题
    // title: {
    //   text: '水球图'
    // },
    // x | y轴
    xAxis: {},
    yAxis: {},
    // 系列:决定展示什么图形
    series: {
      type: 'liquidFill', // 系列
      data: [0.6, 0.4, 0.2], // 展示数据
      waveAnimation: true, // 是否展示动画
      animationDuration: 3,
      animationDurationUpdate: 0,
      radius: '100%', // 半径
      // 外边框
      outline: {
        show: true,
        borderDistance: 8,
        itemStyle: {
          color: 'none',
          borderWidth: 8,
          shadowBlur: 20,
          shadowColor: 'rgba(0,0,0,.25)'
        }
      }
    },
    // 布局组合:
    grid: {
      left: 0,
      right: 0,
      top: 0,
      bottom: 0,
    }
  })
})

更多具体配置可以查看 GitHub 上详细的文档

地图

地图则是通过网上下载地图 JSON 数据,通过 echarts 提供的方法实现。

下载地图数据网站指路:地图

pCIbQl6.png

点击链接复制打开新的标签页,复制 JSON 代码粘贴到本地项目内,在需要使用的 .vue 文件中引入使用即可。

地图数据引入后,echarts 使用生成地图,步骤如下:

  1. 通过 echartsregisterMap() 方法注册地图,官方文档:registerMap 。其中

    • 参数一:注册地图的名称
    • 参数二:注册地图的数据
  2. 设置实例

    setOption() 方法中通过 geo 创建地图,其中属性 map 为刚刚注册地图的地图名称。

  3. 设置参数

    其他参数的设置可前往官网查看,例如:

    • geo:地理坐标系组件。

      地理坐标系组件用于地图的绘制,支持在地理坐标系上绘制散点图线集

      • roam :是否开启鼠标缩放和平移漫游。默认不开启。如果只想要开启缩放或者平移,可以设置成 'scale' 或者 'move'。设置成 true 为都开启
      • emphasis :地图高亮设置
    • series-lines:路径图。

      用于带有起点和终点信息的线数据的绘制,主要用于地图上的航线,路线的可视化。

      • data:线数据集。
      • emphasis:高亮的线条和标签样式。
      • effect:航线特效

更多详细 API 请前往官网阅读。

代码示例
js
import { ref, onMounted } from 'vue'
import * as echarts from 'echarts'
import chinaJSON from './china.json'

// 注册地图
echarts.registerMap('china', chinaJSON as any)
const map = ref()

onMounted(() => {
  let myCharts = echarts.init(map.value)

  // 设置实例
  myCharts.setOption({
    geo: {
      map: 'china', // 中国地图
      roam: true, // 开启鼠标缩放
      // 地图位置
      left: 50,
      top: 100,
      bottom: 0,
      right: 50,
      // 地图上的文字设置
      label: {
        show: true, // 文字渲染
        color: '#fff',
        fontSize: 14,
        // rotate: 20
      },
      // 每一个多边形样式
      itemStyle: {
        areaColor: 'skyblue',
        color: 'red',
        opacity: 0.8,
      },
      // 地图高亮
      emphasis: {
        itemStyle: {
          color: 'red',
        },
        label: {
          color: '#fff',
          fontSize: 20,
        },
      },
    },
    // 布局
    grid: {
      left: 0,
      right: 0,
      top: 0,
      bottom: 0,
    },
    series: [
      {
        type: 'lines', // 航线
        data: [
          {
            coords: [
              [116.405285, 39.904989], // 起点
              [119.306239, 26.075302], // 终点
            ],
            // 统一样式设置
            lineStyle: {
              color: 'orange',
              width: 5,
            },
          },
        ],
        // 特效
        effect: {
          show: true,
          symbol: 'pin',
          symbolSize: 30,
          color:'#fff'
        },
      },
    ],
  })
})