longyvfengyun
2023-09-28 b6fd39998f67f7fea48ac8b3be169dc6de3985b5
内容提交
1个文件已删除
2个文件已修改
5个文件已添加
773 ■■■■ 已修改文件
src/components/chartBox.vue 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/echarts/basic.js 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/echarts/hdwChart.vue 84 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/echarts/options/gauge.js 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/echarts/options/horizontalTechnologyBar.js 260 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/echarts/options/radiusBar.js 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/images/chart-icon.png 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home.vue 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/chartBox.vue
New file
@@ -0,0 +1,50 @@
<script setup>
import chartIcon from "./images/chart-icon.png";
const props = defineProps({
    title: {
        type: String,
        default: ""
    }
});
</script>
<template>
    <div class="chart-box-wrapper">
        <div class="chart-box-header">
            <div class="chart-box-icon">
                <img :src="chartIcon" alt="" />
            </div>
            <div class="chart-box-title">{{title}}</div>
        </div>
        <div class="chart-box-body">
            <slot></slot>
        </div>
    </div>
</template>
<style scoped lang="less">
.chart-box-wrapper {
    display: flex;
    height: 100%;
    flex-direction: column;
    .chart-box-body {
        flex: 1;
    }
}
.chart-box-header {
    .chart-box-icon {
        display: inline-block;
        height: 12px;
        img {
            width: auto;
            height: 100%;
        }
    }
    .chart-box-title {
        display: inline-block;
        font-size: 14px;
        color: #FFFFFF;
        margin-left: 4px;
    }
}
</style>
src/components/echarts/basic.js
File was deleted
src/components/echarts/hdwChart.vue
@@ -1,23 +1,81 @@
<script setup>
import {onMounted, ref} from "vue";
import basicEcharts from "@/components/echarts/basic";
import {computed, onMounted, onUnmounted, ref, watch} from "vue";
import "./transparent";
import usePageMenuStore from "@/stores/pageMenu";
import * as echarts from "echarts";
const pageMenu = usePageMenuStore()
const hdwChart = ref({});
const {
    init,
    resize,
    setOption
} = basicEcharts();
const setChartOption = (option)=>{
    setOption(option);
let chart = "";
const init = (container)=>{
    chart = echarts.init(container);
}
onMounted(async ()=>{
    await init(hdwChart.value, 'transparent');
    setChartOption();
/**
 * 设置图表内容
 * @param option 生成图表的配置项
 */
const setOption = (option)=> {
    if (chart) {
        chart.setOption(option);
    }
}
/**
 * 重置图表的大小
 */
const resize = ()=>{
    if (chart) {
        chart.resize();
        setTimeout(()=>{
            chart.resize();
        });
    }
}
/**
 * 销毁echarts实例释放内存
 * @return  {[type]}  [return description]
 */
const dispose = ()=>{
    // 销毁chart
    if(chart) {
        chart.dispose();
    }
}
/**
 * 获取图表对象
 * @return {string}
 */
const getChart=()=>{
    return chart;
}
const isCollapse = computed(()=>{
    return pageMenu.isCollapse;
})
watch(isCollapse, ()=>{
    setTimeout(()=>{
        resize();
    }, 300);
});
onMounted(()=>{
    init(hdwChart.value);
    // 监听windows窗口的缩放,绑定resize事件
    window.addEventListener("resize", resize);
});
onUnmounted(()=>{
    // 销毁resize事件
    window.removeEventListener("resize", resize);
    dispose();
});
defineExpose({
    setChartOption,
    setOption,
    resize
});
</script>
src/components/echarts/options/gauge.js
New file
@@ -0,0 +1,115 @@
const getGaugeOption = (val, total, name)=>{
  return {
    series: [
      {
        name: '刻度1',
        type: 'gauge',
        radius: '100%',
        min: 0,//最小刻度
        max: total,//最大刻度
        splitNumber: 10, //刻度数量
        startAngle: 225,
        endAngle: -45,
        axisLine: {
          show: true,
          lineStyle: {
            width: 1,
            color: [[1,'rgba(0,0,0,0)']]
          }
        },//仪表盘轴线
        axisLabel: {
          show: true,
          color:'#fff',
          distance:15,
          formatter:function(v){
            let num50 = (total*50/100).toFixed(0);
            switch (v+'') {
              case '0' : return 0;
              case num50: return num50;
              case total+'': return total;
            }
          }
        },//刻度标签。
        axisTick: {
          show: true,
          lineStyle: {
            color: '#5c53de',  //用颜色渐变函数不起作用
            width: 1,
          },
        },//刻度样式
        splitLine: {
          show: true,
          length: -10,
          lineStyle: {
            color: '#5c53de',  //用颜色渐变函数不起作用
          }
        },//分隔线样式
        detail: {
          show: false
        },
        pointer: {
          show: false
        }
      },
      {
        name: "仪表盘1",
        type: "gauge",
        radius: '65%',
        splitNumber: 10,
        axisLine: {
          lineStyle: {
            color: [
              [val / total, "#BF18FE"],
              [1, "#111F42"]
            ],
            width: 8
          }
        },
        axisLabel: {
          show: false,
        },
        axisTick: {
          show: false,
        },
        splitLine: {
          show: false,
        },
        itemStyle: {
          show: true,
        },
        detail: {
          formatter: function(value) {
            if (value !== 0) {
              return Number(val).toFixed(0);
            } else {
              return 0;
            }
          },
          offsetCenter: [0, 0],
          textStyle: {
            padding: [0, 0, 80, 0],
            fontSize: 24,
            fontWeight: '700',
            color: '#00ffd9'
          }
        },
        title: {
          color: '#fff',
          fontSize: 10,
          offsetCenter: [0, "120%"]
        },
        data: [{
          name: name,
          value: val,
        }],
        pointer: {
          show: false,
          length: '75%',
          width: 20, //指针粗细
        },
      },
    ]
  };
}
export default getGaugeOption;
src/components/echarts/options/horizontalTechnologyBar.js
New file
@@ -0,0 +1,260 @@
const getHorizontalTechnologyOption = ()=> {
  let category= [
    {
      name: "告警1",
      value: 2500
    },
    {
      name: "告警2",
      value: 8000
    },
    {
      name: "告警3",
      value: 3000
    },
    {
      name: "告警4",
      value: 3000
    },
    {
      name: "告警5",
      value: 3000
    }
  ]; // 类别
  let total = 10000; // 数据总数
  let datas = [];
  category.forEach(value => {
    datas.push(value.value);
  });
  return {
    xAxis: {
      max: total,
      splitLine: {
        show: false
      },
      axisLine: {
        show: false
      },
      axisLabel: {
        show: false
      },
      axisTick: {
        show: false
      }
    },
    grid: {
      top: 5,
      right: '3%',
      left: '3%',
      bottom: 5
    },
    yAxis: [{
      type: "category",
      inverse: false,
      data: category,
      axisLine: {
        show: false
      },
      axisTick: {
        show: false
      },
      axisLabel: {
        show: false
      }
    }],
    series: [{
      // 内
      type: "bar",
      barWidth: 18,
      legendHoverLink: false,
      silent: true,
      itemStyle: {
        normal: {
          color: function(params) {
            var color;
            if(params.dataIndex==19){
              color = {
                type: "linear",
                x: 0,
                y: 0,
                x2: 1,
                y2: 0,
                colorStops: [{
                  offset: 0,
                  color: "#EB5118" // 0% 处的颜色
                },
                  {
                    offset: 1,
                    color: "#F21F02" // 100% 处的颜色
                  }
                ]
              }
            }else if(params.dataIndex==18){
              color = {
                type: "linear",
                x: 0,
                y: 0,
                x2: 1,
                y2: 0,
                colorStops: [{
                  offset: 0,
                  color: "#FFA048" // 0% 处的颜色
                },
                  {
                    offset: 1,
                    color: "#B25E14" // 100% 处的颜色
                  }
                ]
              }
            }else if(params.dataIndex==17){
              color = {
                type: "linear",
                x: 0,
                y: 0,
                x2: 1,
                y2: 0,
                colorStops: [{
                  offset: 0,
                  color: "#F8E972" // 0% 处的颜色
                },
                  {
                    offset: 1,
                    color: "#E5C206" // 100% 处的颜色
                  }
                ]
              }
            }else{
              color = {
                type: "linear",
                x: 0,
                y: 0,
                x2: 1,
                y2: 0,
                colorStops: [{
                  offset: 0,
                  color: "#1588D1" // 0% 处的颜色
                },
                  {
                    offset: 1,
                    color: "#0F4071" // 100% 处的颜色
                  }
                ]
              }
            }
            return color;
          },
        }
      },
      label: {
        normal: {
          show: true,
          position: [0, -16],
          formatter: "{b}",
          textStyle: {
            color: "#fff",
            fontSize: 14
          }
        }
      },
      data: category,
      z: 1,
      animationEasing: "elasticOut"
    },
      {
        // 分隔
        type: "pictorialBar",
        itemStyle: {
          normal:{
            color:"#061348"
          }
        },
        symbolRepeat: "fixed",
        symbolMargin: 6,
        symbol: "rect",
        symbolClip: true,
        symbolSize: [1, 21],
        symbolPosition: "start",
        symbolOffset: [1, -1],
        symbolBoundingData: total,
        data: category,
        z: 2,
        animationEasing: "elasticOut"
      },
      {
        // 外边框
        type: "pictorialBar",
        symbol: "rect",
        symbolBoundingData: total,
        itemStyle: {
          normal: {
            color: "none"
          }
        },
        label: {
          normal: {
            formatter: (params) => {
              var text;
              if(params.dataIndex==1){
                text = '{f|  '+params.data+'}';
              }else if(params.dataIndex==2){
                text = '{f|  '+params.data+'}';
              }else if(params.dataIndex==3){
                text = '{f|  '+params.data+'}';
              }else{
                text = '{f|  '+params.data+'}';
              }
              return text;
            },
            rich:{
              a: {
                color: 'red'
              },
              b: {
                color: 'blue'
              },
              c:{
                color: 'yellow'
              },
              d:{
                color:"green"
              },
              f:{
                color:"#ffffff"
              }
            },
            position: "insideTopRight",
            distance: 0, // 向右偏移位置
            show: true
          }
        },
        data: datas,
        z: 0,
        animationEasing: "elasticOut"
      },
      {
        name: "外框",
        type: "bar",
        barGap: "-120%", // 设置外框粗细
        data: [total, total, total,total,total,total,total,total,total,total,total,total,total,total,total,total,total,total,total,total],
        barWidth: 25,
        itemStyle: {
          normal: {
            color: "transparent", // 填充色
            barBorderColor: "#1C4B8E", // 边框色
            barBorderWidth: 1, // 边框宽度
            // barBorderRadius: 0, //圆角半径
            label: {
              // 标签显示位置
              show: false,
              position: "top" // insideTop 或者横向的 insideLeft
            }
          }
        },
        z: 0
      }
    ]
  };
}
export default getHorizontalTechnologyOption;
src/components/echarts/options/radiusBar.js
New file
@@ -0,0 +1,76 @@
import * as echarts from "echarts";
const getRadiusBarOption = ()=>{
  return {
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      }
    },
    grid: {
      top: '15%',
      right: '3%',
      left: '10%',
      bottom: '12%'
    },
    xAxis: [{
      type: 'category',
      data: ['9.21', '9.22', '9.23', '9.24', '9.25', '9.26', '9.27'],
      axisLine: {
        lineStyle: {
          color: 'rgba(255,255,255,0.12)'
        }
      },
      axisLabel: {
        margin: 10,
        color: '#e2e9ff',
        textStyle: {
          fontSize: 14
        },
      },
    }],
    yAxis: [{
      axisLabel: {
        formatter: '{value}',
        color: '#e2e9ff',
      },
      axisLine: {
        show: false
      },
      splitLine: {
        lineStyle: {
          color: 'rgba(255,255,255,0.12)'
        }
      }
    }],
    series: [{
      type: 'bar',
      data: [300, 450, 770, 203, 255, 188, 156],
      barWidth: '20px',
      itemStyle: {
        normal: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
            offset: 0,
            color: 'rgba(0,244,255,1)' // 0% 处的颜色
          }, {
            offset: 1,
            color: 'rgba(0,77,167,1)' // 100% 处的颜色
          }], false),
          barBorderRadius: [30, 30, 0, 0],
          shadowColor: 'rgba(0,160,221,1)',
          shadowBlur: 4,
        }
      },
      label: {
        normal: {
          show: true,
          position: "top",
          color: "#FFFFFF"
        }
      }
    }]
  }
}
export default getRadiusBarOption;
src/components/images/chart-icon.png
src/views/home.vue
@@ -4,13 +4,49 @@
import mapJson from "@/assets/mapJson/map_config";
import {FullScreen} from "@element-plus/icons-vue";
import BoxComponent from "@/components/boxComponent.vue";
import HdwChart from "@/components/echarts/hdwChart.vue";
import getGaugeOption from "@/components/echarts/options/gauge";
import getRadiusBarOption from "@/components/echarts/options/radiusBar";
import getHorizontalTechnologyOption from "@/components/echarts/options/horizontalTechnologyBar";
import ChartBox from "@/components/chartBox.vue";
const isFullScreen = ref(false);
const mapStyle = ref({styleJson: mapJson});
const boxGauge = ref(null);
const boxBar = ref(null);
const videoGauge = ref(null);
const videoBar = ref(null);
const battGauge = ref(null);
const battBar = ref(null);
const alarmBar = ref(null);
const changeScreenState = ()=>{
    isFullScreen.value = !isFullScreen.value;
}
onMounted(()=>{});
onMounted(()=>{
    const boxGaugeOption = getGaugeOption(10, 90, "今日在线盒子数");
    boxGauge.value.setOption(boxGaugeOption);
    const boxBarOption = getRadiusBarOption();
    boxBar.value.setOption(boxBarOption);
    const videoGaugeOption = getGaugeOption(1, 500, "今日在线摄像头数");
    videoGauge.value.setOption(videoGaugeOption);
    const videoBarOption = getRadiusBarOption();
    videoBar.value.setOption(videoBarOption);
    const battGaugeOption = getGaugeOption(1, 500, "今日在线电池数");
    battGauge.value.setOption(videoGaugeOption);
    const battBarOption = getRadiusBarOption();
    battBar.value.setOption(videoBarOption);
    const alarmBarOption = getHorizontalTechnologyOption();
    alarmBar.value.setOption(alarmBarOption);
});
</script>
<template>
@@ -48,17 +84,49 @@
                                                    <div class="text-value">0</div>
                                                </div>
                                            </el-col>
                                            <el-col :span="12">
                                                <div class="hdw-chart-box">
                                                    <hdw-chart ref="boxGauge"></hdw-chart>
                                                </div>
                                            </el-col>
                                        </el-row>
                                    </div>
                                    <div class="content-inner-body">
                                        <chart-box title="最近7天在线盒子数">
                                            <hdw-chart ref="boxBar"></hdw-chart>
                                        </chart-box>
                                    </div>
                                </div>
                            </box-component>
                        </div>
                        <div class="box-container-top">
                            <box-component>
                                <div class="box-content-inner-wrapper">
                                    <div class="content-inner-header">
                                        <el-row>
                                            <el-col :span="12">
                                                <div class="box-value-wrapper">
                                                    <div class="text-content">今日在线摄像头数:</div>
                                                    <div class="text-value">0</div>
                                                </div>
                                                <div class="box-value-wrapper">
                                                    <div class="text-content">摄像头总数:</div>
                                                    <div class="text-value">0</div>
                                                </div>
                                            </el-col>
                                            <el-col :span="12">
                                                <div class="hdw-chart-box">
                                                    <hdw-chart ref="videoGauge"></hdw-chart>
                                                </div>
                                            </el-col>
                                        </el-row>
                                    </div>
                                    <div class="content-inner-body">
                                        <chart-box title="最近7天在线摄像头数">
                                            <hdw-chart ref="videoBar"></hdw-chart>
                                        </chart-box>
                                    </div>
                                </div>
                            </box-component>
                        </div>
                    </div>
@@ -67,12 +135,37 @@
                    <div class="box-container">
                        <div class="box-container-top">
                            <box-component>
                                <div class=""></div>
                                <div class="box-content-inner-wrapper">
                                    <div class="content-inner-header">
                                        <el-row>
                                            <el-col :span="12">
                                                <div class="box-value-wrapper">
                                                    <div class="text-content">今日在电池数:</div>
                                                    <div class="text-value">0</div>
                                                </div>
                                                <div class="box-value-wrapper">
                                                    <div class="text-content">电池总数:</div>
                                                    <div class="text-value">0</div>
                                                </div>
                                            </el-col>
                                            <el-col :span="12">
                                                <div class="hdw-chart-box">
                                                    <hdw-chart ref="battGauge"></hdw-chart>
                                                </div>
                                            </el-col>
                                        </el-row>
                                    </div>
                                    <div class="content-inner-body">
                                        <chart-box title="最近7天在线电池数">
                                            <hdw-chart ref="battBar"></hdw-chart>
                                        </chart-box>
                                    </div>
                                </div>
                            </box-component>
                        </div>
                        <div class="box-container-top">
                            <box-component>
                                <hdw-chart ref="alarmBar"></hdw-chart>
                            </box-component>
                        </div>
                    </div>
@@ -174,7 +267,7 @@
}
.box-value-wrapper {
    margin-bottom: 16px;
    margin-bottom: 24px;
    background: linear-gradient(to bottom, #0363f1, #033f8f, #0363f1);
    white-space: nowrap;
    color: #FFFFFF;
@@ -195,4 +288,7 @@
        vertical-align: middle;
    }
}
.hdw-chart-box {
    height: 150px;
}
</style>