开发大屏数据统计

250 阅读2分钟

大屏数据统计一般以 1920*1080 比例进行展示。但是需要注意的是,通常这种界面会用大电视进行展示,用于监测数据变化,因此需要通过等比例缩放来兼容各种尺寸的大屏。

一般需要用浏览器全屏展示,但浏览器全屏需要通过用户交互来实现,这是浏览器的机制,我们无法避免。但是有一种办法可以实现,通过写vbs脚本打开全屏打开浏览器访问页面。

Apache Echarts 是最常用的图表工具,为了高效工作会书写通用基础图表组件,在本文中,本人分别用 React 18、Vue 3 写了通用 Echarts 组件。

伪3D柱状图,这种没办法直接实现,需要通过自定义绘制。

1. 1920*1080 等比例缩放

需要将当前页面固定宽高为 1920px/1080px

import { onMounted, onUnmounted, ref } from 'vue';


const dataStatisticsContainerRef = ref(null);

const scaleContent = () => {
    const content = dataStatisticsContainerRef.value.$el;

    const width = 1920;
    const height = 1080;

    const scaleX = window.innerWidth / width;
    const scaleY = window.innerHeight / height;
    const scale = Math.min(scaleX, scaleY);

    content.style.transform = `scale(${scale})`;
    content.style.position = 'absolute';
    content.style.left = '50%';
    content.style.top = '50%';
    content.style.transformOrigin = 'center center';
    content.style.transform = `translate(-50%, -50%) scale(${scale})`;
};

onMounted(() => {
    window.addEventListener('resize', scaleContent);
    window.addEventListener('load', scaleContent);
    scaleContent();
});

onUnmounted(() => {
    window.removeEventListener('resize', scaleContent);
    window.removeEventListener('load', scaleContent);
});

2. 自动进入全屏

浏览器需要用户操作才能进入全屏

// 进入全屏
const enterFullScreen = () => {
    if (document.fullscreenElement) {
        return
    }

    const elem = document.documentElement;
    if (elem.requestFullscreen) {
        elem.requestFullscreen();
    } else if (elem.mozRequestFullScreen) {
        // Firefox
        elem.mozRequestFullScreen();
    } else if (elem.webkitRequestFullscreen) {
        // Chrome, Safari and Opera
        elem.webkitRequestFullscreen();
    } else if (elem.msRequestFullscreen) {
        // IE/Edge
        elem.msRequestFullscreen();
    }
};


// 退出全屏
const exitFullScreen = () => {
    if (!document.fullscreenElement) {
        return
    }

    if (document.exitFullscreen) {
        document.exitFullscreen();
    } else if (document.msExitFullscreen) {
        document.msExitFullscreen();
    } else if (document.mozCancelFullScreen) {
        document.mozCancelFullScreen();
    } else if (document.webkitCancelFullScreen) {
        document.webkitCancelFullScreen();
    }
};

但是可以通过vbs打开浏览器进入全屏

Set s = CreateObject("WScript.Shell")
s.Run"""C:\Users\用户\AppData\Local\Google\Chrome\Application\chrome.exe""" & "url"
WScript.Sleep 1000
s.SendKeys "{F11}" 

3. 通用Echarts组件

React 18

import { useEffect, useRef } from 'react';
import { init } from 'echarts';

export default (props) => {
    const chartInstance = useRef(null);

    const chartRef = useRef(null);

    // 监听到宽高变化更新实例大小
    const resizeObserver = new ResizeObserver(() => {
        chartInstance.current && chartInstance.current.resize();
    });

    // 监听、取消监听
    useEffect(() => {
        chartRef.current && resizeObserver.observe(chartRef.current);
        return () => {
            resizeObserver.disconnect();
        }
    }, [chartRef.current]);

    // 根据 props.option 进行更新视图
    useEffect(() => {
        const container = chartRef.current;

        // 如果已经有实例,先销毁
        chartInstance.current && chartInstance.current.dispose();

        // 初始化创建实例,挂载
        chartInstance.current = init(container);

        // 设置 option
        chartInstance.current.setOption(props.option || {});

        return () => {
            chartInstance.current && chartInstance.current.dispose();
        }
    }, [props.option]);

    return <div ref={chartRef} style={{ height: '100%', width: '100%' }} />
}

Vue 3(都差不多,注释就不重复写了)

<template>
    <div ref="chartRef" style="height: 100%; width: 100%;" />
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch } from 'vue';
import { init } from 'echarts';

const props = defineProps(['option']);

const chartInstance = ref(null);

const chartRef = ref(null);

// 监听到宽高变化更新实例大小
const resizeObserver = new ResizeObserver(() => {
    chartInstance.value && chartInstance.value.resize();
});

const renderChart = () => {
    // 如果已经有实例,先销毁
    chartInstance.value && chartInstance.value.dispose();

    // 初始化创建实例,挂载
    chartInstance.value = init(chartRef.value);

    // 设置 option
    chartInstance.value.setOption(props.option || {});
};

watch(() => props.option, renderChart, { deep: true, immediate: true });

onMounted(() => {
    chartRef.value && resizeObserver.value.observe(chartRef.value);
});

onUnmounted(() => {
    resizeObserver.value.disconnect();

    // 销毁
    chartInstance.value && chartInstance.value.dispose();
});
</script>

4. 伪3D柱状图

案例参考 PPChart 配置

单列

双列

如果需要多列,直接复制好了,对 location[0] 和 xAxisPoint[0] 进行调整即可。例如向左移动:

const option = {
  series: [
    {
      type: "custom",
      renderItem: (params, api) => {
        const location = api.coord([api.value(0), api.value(1)]);
        location[0] -= 10;

        const xAxisPoint = api.coord([api.value(0), 0]);
        xAxisPoint[0] -= 10;

        return {
          // ...
        };
      },
    },
  ],
};

5. 渐变折线图

案例参考 PPChart 配置

6. 带阴影的饼图

案例参考 PPChart 配置