New file |
| | |
| | | <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> |
| | |
| | | <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> |
New file |
| | |
| | | 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; |
New file |
| | |
| | | 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; |
New file |
| | |
| | | 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; |
| | |
| | | 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> |
| | |
| | | <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> |
| | |
| | | <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> |
| | |
| | | } |
| | | |
| | | .box-value-wrapper { |
| | | margin-bottom: 16px; |
| | | margin-bottom: 24px; |
| | | background: linear-gradient(to bottom, #0363f1, #033f8f, #0363f1); |
| | | white-space: nowrap; |
| | | color: #FFFFFF; |
| | |
| | | vertical-align: middle; |
| | | } |
| | | } |
| | | .hdw-chart-box { |
| | | height: 150px; |
| | | } |
| | | </style> |