feat(LineDropdownHaz): 添加风险级别筛选功能并更新图表数据

新增风险级别下拉选择器组件,支持按不同风险级别筛选报警数据
添加mock数据文件并实现数据处理逻辑
更新图表样式和交互逻辑
This commit is contained in:
gaohaifeng 2025-08-27 17:03:51 +08:00
parent 5a62df9233
commit 920865c6f8
3 changed files with 246 additions and 24 deletions

View File

@ -5,7 +5,7 @@ export const LineDropdownConfig: ConfigType = {
key: 'LineDropdownHaz', key: 'LineDropdownHaz',
chartKey: 'VLineDropdownHaz', chartKey: 'VLineDropdownHaz',
conKey: 'VCLineDropdownHaz', conKey: 'VCLineDropdownHaz',
title: '下拉折线图', title: '报警趋势',
category: 'HazardousChemicalsSpace', category: 'HazardousChemicalsSpace',
categoryName: '危化品场景', categoryName: '危化品场景',
package: PackagesCategoryEnum.CHARTS, package: PackagesCategoryEnum.CHARTS,

View File

@ -7,17 +7,16 @@
:selectedValue="option.dateTime.selectValue" :selectedValue="option.dateTime.selectValue"
@change="handleSelectChange" @change="handleSelectChange"
/> />
<div class="line-dropdown-container"> <div class="line-dropdown-container">
<!-- 下拉框 --> <!-- 新增的风险级别下拉框 -->
<!-- <div class="dropdown-container"> <div class="risk-level-select">
<select v-model="selectedOption" @change="handleDropdownChange" class="custom-dropdown1"> <CustomSelect
<option value="总数">总数</option> :options="riskLevelOptions"
<option value="类型1">类型1</option> :selectedValue="selectedRiskLevel"
<option value="类型2">类型2</option> @change="handleRiskLevelChange"
<option value="类型3">类型3</option> />
</select> </div>
<div class="dropdown-arrow"></div>
</div> -->
<!-- 折线图 --> <!-- 折线图 -->
<div class="chart-container"> <div class="chart-container">
@ -28,7 +27,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, PropType, ref, watch } from 'vue' import { computed, PropType, ref, watch, onMounted } from 'vue'
import VChart from 'vue-echarts' import VChart from 'vue-echarts'
import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook' import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook'
import { use } from 'echarts/core' import { use } from 'echarts/core'
@ -38,6 +37,7 @@ import { mergeTheme } from '@/packages/public/chart'
import config, { includes } from './config' import config, { includes } from './config'
import { DatasetComponent, GridComponent, TooltipComponent } from 'echarts/components' import { DatasetComponent, GridComponent, TooltipComponent } from 'echarts/components'
import CustomSelect from './select.vue' import CustomSelect from './select.vue'
import mockData from './mock.json'
const props = defineProps({ const props = defineProps({
themeSetting: { themeSetting: {
@ -56,10 +56,86 @@ const props = defineProps({
const selectedOption = ref('总数') const selectedOption = ref('总数')
//
const selectedRiskLevel = ref('全部')
const riskLevelOptions = ref([
{ label: '全部', value: '全部' },
{ label: '重大风险', value: '重大风险' },
{ label: '较大风险', value: '较大风险' },
{ label: '一般风险', value: '一般风险' },
{ label: '低风险', value: '低风险' }
])
const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting) const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting)
use([DatasetComponent, CanvasRenderer, LineChart, GridComponent, TooltipComponent]) use([DatasetComponent, CanvasRenderer, LineChart, GridComponent, TooltipComponent])
//
const processChartData = (timeType: string, riskLevel: string) => {
const rawData = mockData[timeType as keyof typeof mockData] || []
//
let processedData: Array<{time: string, value: number}> = []
switch (timeType) {
case 'day':
processedData = rawData.map((item: any) => ({
time: `${item.hour}:00`,
value: item.alarm_count
}))
break
case 'week':
const weekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
processedData = rawData.map((item: any) => ({
time: weekDays[item.dayOfWeek],
value: item.alarm_count
}))
break
case 'month':
processedData = rawData.map((item: any) => ({
time: `${item.day}`,
value: item.alarm_count
}))
break
case 'quarter':
case 'year':
processedData = rawData.map((item: any) => ({
time: `${item.month}`,
value: item.alarm_count
}))
break
default:
processedData = []
}
//
if (riskLevel !== '全部') {
//
const riskMultiplier = {
'重大风险': 0.4,
'较大风险': 0.3,
'一般风险': 0.2,
'低风险': 0.1
}[riskLevel] || 1
processedData = processedData.map(item => ({
...item,
value: Math.round(item.value * riskMultiplier)
}))
}
return {
dimensions: ['time', 'value'],
source: processedData
}
}
//
const updateChartData = () => {
const newData = processChartData(props.chartConfig.option.dateTime.selectValue, selectedRiskLevel.value)
props.chartConfig.option.dataset = newData
}
const option = computed(() => { const option = computed(() => {
return mergeTheme(props.chartConfig.option, props.themeSetting, includes) return mergeTheme(props.chartConfig.option, props.themeSetting, includes)
}) })
@ -69,10 +145,23 @@ const handleDropdownChange = () => {
console.log('Selected option:', selectedOption.value) console.log('Selected option:', selectedOption.value)
} }
// //
const handleSelectChange = (value: any) => { const handleSelectChange = (value: any) => {
props.chartConfig.option.dateTime.selectValue = value props.chartConfig.option.dateTime.selectValue = value
updateChartData()
} }
//
const handleRiskLevelChange = (value: any) => {
selectedRiskLevel.value = value
updateChartData()
console.log('Selected risk level:', value)
}
//
onMounted(() => {
updateChartData()
})
</script> </script>
<style scoped> <style scoped>
@ -293,18 +382,47 @@ const handleSelectChange = (value: any) => {
white-space: nowrap; white-space: nowrap;
} }
.header-title{ //
position: absolute; .risk-level-select {
position: relative;
width: 90%;
margin: 10px auto 0;
:deep(.custom-select) {
z-index: 999;
position: relative;
top: 0; top: 0;
height: 45px; right: 0;
line-height: 45px; }
left: 80px;
font-size: 16px; :deep(.select-display) {
font-weight: bold; background-color: rgb(19, 22, 33);
color: #eee; border: 1px solid rgb(75, 83, 99);
font-style: italic; color: #fff;
text-shadow: 0 0 10px #00E5FF; border-radius: 6px;
white-space: nowrap; padding: 0 12px;
height: 28px;
font-size: 12px;
min-width: 90px;
}
:deep(.select-dropdown) {
background-color: rgb(19, 22, 33);
border: 1px solid rgb(75, 83, 99);
border-radius: 6px;
}
:deep(.select-option) {
color: #fff;
&:hover {
background-color: rgba(75, 83, 99, 0.3);
}
&.selected {
background-color: rgba(75, 83, 99, 0.5);
}
}
} }
.svg { .svg {

View File

@ -0,0 +1,104 @@
{
"day": [
{
"alarm_count": 1,
"hour": 6
},
{
"alarm_count": 1,
"hour": 7
},
{
"alarm_count": 59,
"hour": 12
},
{
"alarm_count": 71,
"hour": 13
}
],
"week": [
{
"dayOfWeek": 1,
"alarm_count": 14
},
{
"dayOfWeek": 2,
"alarm_count": 15
},
{
"dayOfWeek": 3,
"alarm_count": 132
}
],
"month": [
{
"alarm_count": 13,
"day": 17
},
{
"alarm_count": 75,
"day": 18
},
{
"alarm_count": 94,
"day": 19
},
{
"alarm_count": 34,
"day": 20
},
{
"alarm_count": 23,
"day": 21
},
{
"alarm_count": 6,
"day": 22
},
{
"alarm_count": 14,
"day": 25
},
{
"alarm_count": 15,
"day": 26
},
{
"alarm_count": 132,
"day": 27
}
],
"quarter": [
{
"alarm_count": 18,
"month": 7
},
{
"alarm_count": 406,
"month": 8
}
],
"year": [
{
"alarm_count": 10,
"month": 4
},
{
"alarm_count": 10,
"month": 5
},
{
"alarm_count": 10,
"month": 6
},
{
"alarm_count": 18,
"month": 7
},
{
"alarm_count": 406,
"month": 8
}
]
}