feat:危险房子圆环更新接口以及请求

This commit is contained in:
Free-sss 2025-08-27 21:52:06 +08:00
parent 5a15829710
commit 98c219c17b
2 changed files with 166 additions and 68 deletions

View File

@ -45,7 +45,7 @@ const option = {
left: '60%', // 默认更靠左一点,避免截断 left: '60%', // 默认更靠左一点,避免截断
top: 'center', top: 'center',
icon: 'rect', icon: 'rect',
showEmpty:false, showEmpty: false,
// itemWidth: 10, // itemWidth: 10,
itemHeight: 8, itemHeight: 8,
itemGap: 5, itemGap: 5,
@ -69,8 +69,9 @@ const option = {
center: ['30%', '48%'], center: ['30%', '48%'],
silent: true, silent: true,
z: 1, z: 1,
data: [{ value: 1, name: '', itemStyle: { data: [{
color: { value: 1, name: '', itemStyle: {
color: {
type: 'linear', type: 'linear',
x: 0, x: 0,
y: 0, y: 0,
@ -82,7 +83,8 @@ const option = {
{ offset: 1, color: 'rgba(200, 200, 200, 0.01)' }, { offset: 1, color: 'rgba(200, 200, 200, 0.01)' },
] ]
} }
} }], }
}],
label: { show: false }, label: { show: false },
labelLine: { show: false } labelLine: { show: false }
}, },
@ -160,8 +162,7 @@ const option = {
show: false, show: false,
}, },
itemStyle: { shadowBlur: 12, shadowColor: 'rgba(0, 0, 0, 0.35)' } itemStyle: { shadowBlur: 12, shadowColor: 'rgba(0, 0, 0, 0.35)' }
}, }
data: dataJson.source
}, },
// 内部渐变装饰环(在空洞边缘,提升质感) // 内部渐变装饰环(在空洞边缘,提升质感)
{ {

View File

@ -1,16 +1,13 @@
<template> <template>
<div class="go-border-box"> <div class="go-border-box">
<img src="./assets/title.svg" class="svg" /> <img src="./assets/title.svg" class="svg" />
<div class="header-title">报警统计</div> <div class="header-title">报警统计</div>
<v-chart ref="vChartRef" autoresize :init-options="initOptions" :theme="themeColor" :option="option"></v-chart> <v-chart ref="vChartRef" autoresize :init-options="initOptions" :theme="themeColor" :option="option"></v-chart>
<!-- 使用新的下拉选择器组件 --> <!-- 使用新的下拉选择器组件 -->
<CustomSelect <CustomSelect :options="option.dateTime.dataset" :selectedValue="option.dateTime.selectValue"
:options="option.dateTime.dataset" @change="handleSelectChange" />
:selectedValue="option.dateTime.selectValue"
@change="handleSelectChange"
/>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -27,6 +24,7 @@ import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent, GraphicComponent } from 'echarts/components' import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent, GraphicComponent } from 'echarts/components'
import CustomSelect from './select.vue' import CustomSelect from './select.vue'
import dataJson from './data.json' import dataJson from './data.json'
import axiosInstance from '@/api/axios';
const props = defineProps({ const props = defineProps({
themeSetting: { themeSetting: {
@ -54,7 +52,7 @@ const option = computed(() => {
function calculateTotal(data: any) { function calculateTotal(data: any) {
if (!data || !data.source) return 0 if (!data || !data.source) return 0
return data.source.reduce((total: number, item: any) => { return data.source.reduce((total: number, item: any) => {
return total + (item[data.dimensions[1]] || 0) return total + (item.value || 0)
}, 0) }, 0)
} }
@ -65,18 +63,20 @@ function calculatePercentage(value: number, total: number) {
const updateChartData = (newData: any) => { const updateChartData = (newData: any) => {
if (!newData) return if (!newData) return
//
props.chartConfig.option.dataset = newData
const total = calculateTotal(newData) const total = calculateTotal(newData)
if (props.chartConfig.option.graphic?.[0]) { if (props.chartConfig.option.graphic?.[0]) {
props.chartConfig.option.graphic[0].style.text = total.toString() props.chartConfig.option.graphic[0].style.text = total.toString()
} }
// // " "
props.chartConfig.option.legend.formatter = (name: string) => { props.chartConfig.option.legend.formatter = (name: string) => {
const item = newData.source.find((it: any) => it[newData.dimensions[0]] === name) const item = newData.source.find((it: any) => it.name === name)
if (!item) return null if (!item) return name
const val = item[newData.dimensions[1]] ?? 0 const val = item.value ?? 0
let p = calculatePercentage(val, total) let p = calculatePercentage(val, total)
// return `{row|${name} ${p}%}`
if(Number(p)<10){ if(Number(p)<10){
p=' '+p p=' '+p
} }
@ -143,79 +143,176 @@ const updateChartData = (newData: any) => {
} }
} }
const totalValue=newData.source.reduce((total: number, item: any) => { const totalValue = newData.source.reduce((total: number, item: any) => {
return total + (item.value || 0) return total + (item.value || 0)
}, 0) }, 0)
props.chartConfig.option.series[props.chartConfig.option.series.length-1].label.formatter=`{a|${totalValue}}\n\n{b|总数}` props.chartConfig.option.series[props.chartConfig.option.series.length-1].label.formatter = `{a|${totalValue}}\n\n{b|总数}`
} }
watch( watch(
() => props.chartConfig.option.dataset, () => props.chartConfig.option.dataset,
newData => { newData => {
if (newData) { if (newData) {
props.chartConfig.option.dataset = newData
updateChartData(newData) updateChartData(newData)
} }
}, },
{ deep: false, immediate: true } { deep: true, immediate: true }
) )
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => { const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
props.chartConfig.option.dataset = newData
updateChartData(newData) updateChartData(newData)
}) })
onMounted(() => { onMounted(async () => {
updateChartData(props.chartConfig.option.dataset) //
}) const timeRange = generateTimeRange(props.chartConfig.option.dateTime.selectValue);
const fetchedData = await fetchAlarmData(timeRange);
if (fetchedData) {
updateChartData(fetchedData);
} else {
// 使
updateChartData(props.chartConfig.option.dataset);
}
});
// //
const handleSelectChange = (value: any) => { function formatDateTime(date: Date): string {
props.chartConfig.option.dateTime.selectValue = value const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const day = date.getDate().toString().padStart(2, '0');
const hours = date.getHours().toString().padStart(2, '0');
const minutes = date.getMinutes().toString().padStart(2, '0');
const seconds = date.getSeconds().toString().padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
} }
function generateTimeRange(period: string): { startTime: string; endTime: string } {
const now = new Date();
let startTime: Date;
let endTime: Date;
endTime = new Date(now);
endTime.setDate(endTime.getDate() + 1);
endTime.setHours(0, 0, 0, 0);
switch (period) {
case 'day':
startTime = new Date(now);
startTime.setHours(0, 0, 0, 0);
break;
case 'week':
startTime = new Date(now);
startTime.setDate(startTime.getDate() - 7);
startTime.setHours(0, 0, 0, 0);
break;
case 'month':
startTime = new Date(now.getFullYear(), now.getMonth(), 1);
startTime.setHours(0, 0, 0, 0);
break;
case 'quarter':
const currentMonth = now.getMonth();
const quarterStartMonth = Math.floor(currentMonth / 3) * 3;
startTime = new Date(now.getFullYear(), quarterStartMonth, 1);
startTime.setHours(0, 0, 0, 0);
break;
case 'year':
startTime = new Date(now.getFullYear(), 0, 1);
startTime.setHours(0, 0, 0, 0);
break;
default:
startTime = new Date(now);
startTime.setHours(0, 0, 0, 0);
break;
}
return {
startTime: formatDateTime(startTime),
endTime: formatDateTime(endTime),
};
}
async function fetchAlarmData({ startTime, endTime }: { startTime: string; endTime: string }) {
try {
const res = await axiosInstance({
method: 'GET',
url: '/getAlarmdataRecord',
params: { startTime, endTime },
responseType: 'json',
});
if (Array.isArray(res)) {
//
return {
dimensions: ['name', 'value'],
source: res.map((item: any) => ({
name: item.alarmLevel,
value: item.alarmNun
}))
};
} else {
console.warn('API returned unexpected data structure:', res);
return undefined;
}
} catch (error) {
console.error('Error fetching alarm data:', error);
return undefined;
}
}
async function dataHandle(newData: any) {
if (!newData) {
props.chartConfig.option.dataset = { dimensions: ['name', 'value'], source: [] };
updateChartData(props.chartConfig.option.dataset);
return;
}
updateChartData(newData);
}
const handleSelectChange = async (value: string) => {
props.chartConfig.option.dateTime.selectValue = value;
const { startTime, endTime } = generateTimeRange(value);
const fetchedData = await fetchAlarmData({ startTime, endTime });
await dataHandle(fetchedData);
};
onMounted(async () => {
const timeRange = generateTimeRange(props.chartConfig.option.dateTime.selectValue);
const fetchedData = await fetchAlarmData(timeRange);
await dataHandle(fetchedData);
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@include go(border-box) { @include go(border-box) {
position: relative; position: relative;
border-radius: 5px;
overflow: hidden;
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
height: 100%;
padding: 0;
//
// background-color: #0E121B;
//
background: linear-gradient(to top,
rgba(14, 18, 27, 1) 0%,
rgba(14, 18, 27, 0.6) 100%);
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: 5px; border-radius: 5px;
padding: 2px; overflow: hidden;
/* 边框宽度 */ display: flex;
flex-direction: column;
align-items: center;
width: 100%;
height: 100%;
padding: 0;
//
// background-color: #0E121B;
//
background: linear-gradient(to top, background: linear-gradient(to top,
rgba(128, 128, 128, 0.3), rgba(14, 18, 27, 1) 0%,
rgba(128, 128, 128, 0)); rgba(14, 18, 27, 0.6) 100%);
-webkit-mask:
linear-gradient(#fff, #fff) content-box, &::before {
linear-gradient(#fff, #fff); content: '';
-webkit-mask-composite: xor; position: absolute;
mask-composite: exclude; top: 0;
pointer-events: none; left: 0;
} right: 0;
bottom: 0;
border-radius: 5px;
padding: 2px;
/* 边框宽度 */
background: linear-gradient(to top,
rgba(128, 128, 128, 0.3),
rgba(128, 128, 128, 0));
-webkit-mask:
linear-gradient(#fff, #fff) content-box,
linear-gradient(#fff, #fff);
-webkit-mask-composite: xor;
mask-composite: exclude;
pointer-events: none;
}
} }
.header-title{ .header-title {
position: absolute; position: absolute;
top: 0; top: 0;
height: 45px; height: 45px;
@ -231,7 +328,7 @@ const handleSelectChange = (value: any) => {
.svg { .svg {
width: 100%; width: 100%;
height: 45px; height: 45px;
} }
</style> </style>