• echarts优秀使用案例


    echarts优秀使用案例

    在这里插入图片描述
    在这里插入图片描述

    App.vue

    <template>
        <div class="box">
            <a-card size="small" title="各类型监测设备利用率" class="center">
                
                
                <SmallChartVue :data="store.EquUseRatio" type="利用率" :color="['#66a6ff', '#89f7fe']" />
            a-card>
        div>
        <div class="box">
            <a-card size="small" title="各类型监测站在线率" class="center">
                <SmallChartVue :data="store.StationOnlineRatio" type="在线率" :color="['#84fab0', '#8fd3f4']" />
            a-card>
        div>
    template>
    <script setup>
    import SmallChartVue from './SmallChart.vue';
    import { onUnmounted } from 'vue';
    import { UseRateStore } from './store.js'
    const store = UseRateStore();
    
    // 初始化数据加载及获取
    store.initData();
    
    
    // 实时循环刷新数据
    var Timer = setInterval(() => {
        store.initData();
    }, 2000);
    
    // 注销时,清除循环
    onUnmounted(() => {
        clearInterval(Timer);
    });
    script>
    <style scoped>
    .box {
        width: 310px;
        height: 175px;
        margin-bottom: 15px;
    }
    
    :deep(.ant-card) {
        background: #191a23;
    }
    
    :deep(.ant-card-head-title) {
        color: #fff;
        /* 标题内边距 */
        padding: 12px 0 !important;
        /* 字间距 */
        letter-spacing: 2px;
    }
    
    :deep(.ant-card) {
        border: 1px solid rgba(255, 255, 255, 0.1)
    }
    
    :deep(.ant-card-body) {
        height: 130px;
        padding: 5px;
    }
    
    :deep(.params-name) {
        text-align: left;
        color: rgba(255, 255, 255, 0.5);
    }
    
    :deep(.params-value) {
        text-align: right;
        color: #18be6b;
    }
    
    :deep(.w-100) {
        width: 100px;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76

    SmallChart.vue

    <template>
        <div ref="SmallDar" class="wh-100">div>
    template>
    <script setup>
    import { ref, onMounted, onUnmounted, watch } from 'vue';
    import chart from './SmallChart.js'
    
    var _chart = null;
    
    const props = defineProps({
        data: Object,
        type: String,
        color: Array,
    })
    const SmallDar = ref();
    
    // 格式化数据方法
    const buildChart = (res) => {
        // 哪怕 res.length 值为 0 ,只会不渲染数据,并不会阻止程序运行
        // 深拷贝位置更改
        let data = JSON.parse(JSON.stringify(res));
        var xAxisData = [];
        var SeriesData = [];
        for (var i = 0; i < data.length; i++) {
            xAxisData.push(data[i].name)
            SeriesData.push(data[i].value)
        }
        _chart.setData(xAxisData, SeriesData);
    }
    
    // 监听数据变化
    watch(() => props.data, (res) => {
        buildChart(res);
    })
    
    // 初始化图表
    onMounted(() => {
        _chart = new chart(SmallDar.value, {
            Grid: {
                top: 15,
                left: 30,
                right: 8,
                bottom: 25
            },
            type: props.type,
            Color: props.color,
        });
        buildChart(props.data);
    })
    
    // 组件注销时,删除图表
    onUnmounted(() => {
        _chart.destroy()
    })
    
    script>
    <style scoped>
    .wh-100 {
        width: 100%;
        height: 100%;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    SmallChart.js

    import * as echarts from 'echarts'
    
    class BarEchart {
        constructor(view, option) {
            this.chart = echarts.init(view, 'dark');
            this.color = option.Color;
            this.grid = option.Grid;
            // type 值由外部传递
            this.type = option.type || '';
            // 给最大值最小值一个默认值
            this.MAX = option.MAX || 100;
            this.MIN = option.MIN || 0;
        }
        setData(xAxisData, SeriesData) {
            // 删除了 UI 中用不到的 Echart 配置项
            var option = {
                backgroundColor: '#191a23',
                tooltip: {
                    trigger: 'axis',
                    backgroundColor: "#191a23",
                    borderColor: "rgba(255, 255, 255, 0.1)",
                    axisPointer: {
                        type: 'shadow'
                    },
                    formatter: (params) => {
                        // 使用模板语法,看起来更好看一些
                        // 使他对其到左侧,为了实际输出代码时,减少左侧的字符串(其实没啥用)
                        return `
    ${params[0].name}
    ${this.type}
    ${params[0].value}%
    `
    ; } }, grid: this.grid, xAxis: { type: 'category', axisLine: { show: true, lineStyle: { // 此处颜色改为实色,挡住最后一个分割中的虚线 color: 'rgba(80, 80, 80)', }, }, axisTick: { show: false }, axisLabel: { padding: [3, 0, 0, 0], color: 'rgba(255, 255, 255, 0.5)', // 修改文字大小 fontSize: 12, // 强制显示X轴所有标签 interval: 0 }, data: xAxisData, }, yAxis: { type: 'value', min: this.MIN, max: this.MAX, // 设置分割间隔 interval: 25, axisLabel: { show: true, // 修改文字大小 fontSize: 11, color: 'rgba(255, 255, 255, 0.5)' }, splitLine: { show: true, // 虚线 lineStyle: { type: [2, 1], } }, }, series: [{ name: '排名', type: 'bar', // 修改柱状条宽度 barWidth: '35%', data: SeriesData, itemStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: this.color[0] }, { offset: 1, color: this.color[1] }, ]) }, }] }; this.chart.setOption(option); } destroy() { // 修改了 注销方法 this.chart.dispose(); } } export default BarEchart
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100

    TestData.js

    // 测试数据生成方法
    // 用于接口伪装
    const random = (min, max) => min + Math.floor(Math.random() * (max - min + 1))
    let renderFunction = (label) => {
        var total = random(0, 100);
        var online = random(0, total);
        var working = random(0, online);
        return {
            label: label,
            total: total,
            online: online,
            working: working
        }
    }
    let LabelArray = ["一类", "二类", "三类", "四类", "监测", "船载", "便携", "传感器"];
    
    const install = () => {
        // 数据由同步获取改为异步获取
        return new Promise((resolve, reject) => {
            let res = [];
            LabelArray.forEach(item => {
                res.push(renderFunction(item))
            });
            // 给数组一个随机函数,用来打乱数组顺序(给自己增加难度)
            res.sort((a, b) => Math.random() > 0.5 ? 1 : -1)
            resolve(res);
        });
    }
    
    export default install;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    store.js

    import { defineStore } from 'pinia'
    import TestData from './TestData.js';
    
    // 格式化数据方法
    const Formatter = (_arr, callback) => {
        // 使用Array.prototype.map()方法生成新数组,可以省略创建数组的一步。
        // 如果严格要求效率的情况下,仍然建议使用For循环
        return _arr.map(item => {
            return {
                name: item.label,
                // 因为是计算属性,在不计较 ∞ 时,直接判断是否为真
                value: callback(item) || 0,
            }
        });
    }
    
    // 此处 store ID 是为了区分示例项目模块。请勿效仿
    export const UseRateStore = defineStore('901_inspect', {
        state: () => {
            return {
                // 将两份数据分开进行存放,更贴合业务实际情况
                EquData: [],
                StationData: [],
            }
        },
        getters: {
            // 通过Getter 实时刷新数据
            EquUseRatio() {
                return Formatter(this.EquData, (stat) => {
                    // 取两位小数并四舍五入(注,不用 Number.toFix(2) 方法的原因是这种方法会出现 20.00 的情况 )
                    return Math.round(stat.working / stat.total * 10000) / 100;
                });
            },
            StationOnlineRatio() {
                return Formatter(this.StationData, (stat) => {
                    return Math.round(stat.online / stat.total * 10000) / 100;
                });
            },
        },
        actions: {
            // 初始化数据方法,使数据可以实时刷新
            async initData() {
                // 假设数组返回值时乱序的,如何根据已有数据顺序排序返回值
                // Array 写在这个地方是为了方便大家寻找逻辑,实际情况请将 Array 对象放在全局中,防止重复创建 
                const LabelArray = ["一类", "二类", "三类", "四类", "监测", "船载", "便携", "传感器"];
    
                // 根据指定的 Key 值,在已经排序好的数组里面取 当前值的下标,
                // 下方为 indexOf 方法示例
    
                this.EquData = (await TestData()).sort((a, b) => {
                    return LabelArray.indexOf(a.label) - LabelArray.indexOf(b.label)
                });
    
    
                // 如果 indexOf 的效率满足不了需求,还可以用 Mapping 结构提升效率查询值过程的效率
                // 注:Mapping 写在这个地方是为了方便大家寻找逻辑,实际情况请将 Mapping 对象放在全局中,防止重复创建 
                const LabelMapping = {
                    "一类": 0,
                    "二类": 1,
                    "三类": 2,
                    "四类": 3,
                    "监测": 4,
                    "船载": 5,
                    "便携": 6,
                    "传感器": 7
                }
                this.StationData = (await TestData()).sort((a, b) => {
                    return LabelMapping[a.label] - LabelMapping[b.label]
                });;
            },
        }
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
  • 相关阅读:
    常见树种(贵州省):004杨树种类
    解读Redis常见命令
    私有化的即时通讯工具能为企业带来哪些帮助?
    代码随想录 贪心算法-简单题目
    【JavaWeb】JSP系列——EL表达式
    Jenkins 自动打包发布 SpringCloud 微服务项目
    引入嵌入和向量搜索时的三个错误
    ios面试准备 - objective-c篇
    如何用虚拟仿真实训室提质增效?
    简单OpenSL ES学习
  • 原文地址:https://blog.csdn.net/qq_38946996/article/details/127988295