4 changed files with 475 additions and 0 deletions
@ -0,0 +1,91 @@ |
|||||
|
<template> |
||||
|
<div class="tabBox"> |
||||
|
<Card title="氨氮曲线图" :loading="loading"> |
||||
|
<div ref="chartRef1" :style="{ width, height }"></div> |
||||
|
</Card> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup lang="ts"> |
||||
|
import { watch, ref, Ref, watchEffect } from 'vue'; |
||||
|
import { useECharts } from '@/hooks/web/useECharts'; |
||||
|
import { Card } from 'ant-design-vue'; |
||||
|
|
||||
|
const subTab = ref<String>('a'); |
||||
|
const props = defineProps({ |
||||
|
loading: Boolean, |
||||
|
width: { |
||||
|
type: String as PropType<string>, |
||||
|
default: '100%', |
||||
|
}, |
||||
|
height: { |
||||
|
type: String as PropType<string>, |
||||
|
default: '300px', |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
const chartRef1 = ref<HTMLDivElement | null>(null); |
||||
|
const setOptions1 = useECharts(chartRef1 as Ref<HTMLDivElement>).setOptions; |
||||
|
watch( |
||||
|
() => subTab.value, |
||||
|
() => { |
||||
|
setOptions1({ |
||||
|
tooltip: { |
||||
|
trigger: 'axis', |
||||
|
}, |
||||
|
grid: { |
||||
|
left: '3%', |
||||
|
right: '4%', |
||||
|
bottom: '3%', |
||||
|
containLabel: true, |
||||
|
}, |
||||
|
legend: { |
||||
|
data: ['cod', 'tn×10', 'tp×100'], |
||||
|
}, |
||||
|
xAxis: { |
||||
|
type: 'category', |
||||
|
boundaryGap: true, |
||||
|
data: [ |
||||
|
'2025-5-12', |
||||
|
'2025-5-13', |
||||
|
'2025-5-14', |
||||
|
'2025-5-15', |
||||
|
'2025-5-16', |
||||
|
'2025-5-17', |
||||
|
'2025-5-18', |
||||
|
'2025-5-19', |
||||
|
'2025-5-20', |
||||
|
'2025-5-12', |
||||
|
'2025-5-21', |
||||
|
'2025-5-22', |
||||
|
], |
||||
|
}, |
||||
|
yAxis: { |
||||
|
type: 'value', |
||||
|
name: '氨氮曲线图', // 单位说明文本 |
||||
|
nameLocation: 'end', // 文本位置(start/center/end) |
||||
|
nameTextStyle: { |
||||
|
color: '#666', |
||||
|
fontSize: 12, |
||||
|
align: 'left', // 文本对齐方向 |
||||
|
padding: [0, 0, 0, -30], // 调整位置 [上,右,下,左] |
||||
|
}, |
||||
|
}, |
||||
|
series: [ |
||||
|
{ |
||||
|
name: '氨氮', |
||||
|
data: [90, 200, 150, 80, 70, 78, 123, 29, 45, 99], |
||||
|
type: 'line', |
||||
|
itemStyle: {}, |
||||
|
}, |
||||
|
], |
||||
|
}); |
||||
|
}, |
||||
|
{ immediate: true }, |
||||
|
); |
||||
|
</script> |
||||
|
<style lang="less"> |
||||
|
.tabBox { |
||||
|
margin: 20px; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,127 @@ |
|||||
|
<template> |
||||
|
<PageWrapper dense> |
||||
|
<div style="margin: 20px; border-radius: 10px; background: #fff"> |
||||
|
<div class="tabBox"> |
||||
|
<a-tabs v-model:activeKey="activeKey" size="large"> |
||||
|
<a-tab-pane key="总览" tab="总览"> |
||||
|
<div style="margin: 1%; padding: 1%; border-radius: 10px; background: #fff"> |
||||
|
<span>监测因子:</span> |
||||
|
<a-select |
||||
|
v-model:value="searchInfo.monitorType" |
||||
|
style="width: 180px" |
||||
|
:options="monitorTypeOptions" |
||||
|
placeholder="请选择" |
||||
|
allowClear |
||||
|
/> |
||||
|
<span style="margin-left: 20px">时间:</span> |
||||
|
<a-select |
||||
|
v-model:value="searchInfo.timeType" |
||||
|
style="width: 180px" |
||||
|
:options="timeTypeOptions" |
||||
|
placeholder="请选择" |
||||
|
allowClear |
||||
|
/> |
||||
|
<a-button type="primary" @click="search" style="margin-left: 20px">查询</a-button> |
||||
|
<div id="amapContainer" style="height: 80vh; margin-top: 10px"> </div> |
||||
|
</div> |
||||
|
</a-tab-pane> |
||||
|
<a-tab-pane key="实时数据" tab="实时数据"> |
||||
|
<info></info> |
||||
|
</a-tab-pane> |
||||
|
<a-tab-pane key="曲线分析" tab="曲线分析"> |
||||
|
<analysis></analysis> |
||||
|
</a-tab-pane> |
||||
|
</a-tabs> |
||||
|
</div> |
||||
|
</div> |
||||
|
</PageWrapper> |
||||
|
</template> |
||||
|
|
||||
|
<script setup lang="ts"> |
||||
|
import { ref, reactive, onMounted } from 'vue'; |
||||
|
import { PageWrapper } from '@/components/Page'; |
||||
|
import AMapLoader from '@amap/amap-jsapi-loader'; |
||||
|
import info from './info.vue' |
||||
|
import analysis from './analysis.vue'; |
||||
|
const activeKey = ref('总览'); |
||||
|
const searchInfo = reactive({ |
||||
|
monitorType: null, |
||||
|
timeType: null, |
||||
|
}); |
||||
|
const monitorTypeOptions = [ |
||||
|
{ |
||||
|
value: 'PH', |
||||
|
}, |
||||
|
{ |
||||
|
value: 'DO', |
||||
|
}, |
||||
|
{ |
||||
|
value: 'COD', |
||||
|
}, |
||||
|
{ |
||||
|
value: 'TP', |
||||
|
}, |
||||
|
{ |
||||
|
value: 'NH3-N', |
||||
|
}, |
||||
|
]; |
||||
|
const timeTypeOptions = [ |
||||
|
{ |
||||
|
value: '实时数据', |
||||
|
}, |
||||
|
{ |
||||
|
value: '日均值', |
||||
|
}, |
||||
|
{ |
||||
|
value: '月均值', |
||||
|
}, |
||||
|
]; |
||||
|
const search = async () => {}; |
||||
|
const points = ref<any>([ |
||||
|
{ |
||||
|
longitude: 119.21, |
||||
|
latitude: 29.7, |
||||
|
}, |
||||
|
]); |
||||
|
onMounted(() => { |
||||
|
AMapLoader.load({ |
||||
|
key: '786a2e7cc6d4be5ba1d6174a0aa10f2b', |
||||
|
version: '2.0', |
||||
|
plugins: [], // 如果需要插件,请在这里添加 |
||||
|
}) |
||||
|
.then((AMap) => { |
||||
|
const map = new AMap.Map('amapContainer', { |
||||
|
zoom: 10, // 初始化地图层级 |
||||
|
center: [119.0426, 29.6], // 初始化地图中心点坐标 |
||||
|
}); |
||||
|
|
||||
|
// 添加标记点 |
||||
|
points.value.forEach((point) => { |
||||
|
const marker = new AMap.Marker({ |
||||
|
position: new AMap.LngLat(point.longitude, point.latitude), |
||||
|
title: point.station, |
||||
|
}); |
||||
|
|
||||
|
marker.on('click', () => { |
||||
|
console.log('1'); |
||||
|
}); |
||||
|
|
||||
|
map.add(marker); |
||||
|
}); |
||||
|
}) |
||||
|
.catch((e) => { |
||||
|
console.error(e); // 错误处理 |
||||
|
}); |
||||
|
}); |
||||
|
</script> |
||||
|
<style lang="less"> |
||||
|
.tabBox { |
||||
|
margin: 10px; |
||||
|
} |
||||
|
|
||||
|
.title { |
||||
|
margin: 10px 0; |
||||
|
font-size: 20px; |
||||
|
font-weight: 550; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,256 @@ |
|||||
|
<template> |
||||
|
<div class="tabBox"> |
||||
|
<div class="md:flex enter-y"> |
||||
|
<div class="md:w-1/3 w-full"> |
||||
|
<Card title="污染源统计" :loading="loading"> |
||||
|
<div ref="chartRef1" :style="{ width, height }"></div> |
||||
|
</Card> |
||||
|
</div> |
||||
|
<div class="md:w-1/3 w-full"> |
||||
|
<Card title="水源统计" :loading="loading"> |
||||
|
<div class="md:flex enter-y"> |
||||
|
<div class="md:w-1/2 w-full" ref="chartRef2" :style="{ width, height }"> </div> |
||||
|
<div class="md:w-1/2 w-full"> |
||||
|
<div> |
||||
|
<span style="font-weight: 600">全区水质前三:</span> |
||||
|
<div v-for="(item, index) in topThree" :key="index"> |
||||
|
{{ index }}- {{ item.name }}:{{ item.percent }} |
||||
|
</div> |
||||
|
</div> |
||||
|
<div style="top: 50%; position: absolute"> |
||||
|
<span style="font-weight: 600">全区水质后三:</span> |
||||
|
<div v-for="(item, index) in lastThree" :key="index"> |
||||
|
{{ index }}- {{ item.name }}:{{ item.percent }} |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</Card> |
||||
|
</div> |
||||
|
<div class="md:w-1/3 w-full"> |
||||
|
<Card title="河道统计" :loading="loading"> |
||||
|
<div ref="chartRef3" :style="{ width, height }"></div> |
||||
|
</Card> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div> |
||||
|
<Card :loading="loading"> |
||||
|
<div> |
||||
|
<a-table :dataSource="dataSource" :columns="columns" :pagination="false" bordered /> |
||||
|
</div> |
||||
|
</Card> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup lang="ts"> |
||||
|
import { watch, ref, Ref, watchEffect } from 'vue'; |
||||
|
import { useECharts } from '@/hooks/web/useECharts'; |
||||
|
import { Card } from 'ant-design-vue'; |
||||
|
|
||||
|
const subTab = ref<String>('a'); |
||||
|
const props = defineProps({ |
||||
|
loading: Boolean, |
||||
|
width: { |
||||
|
type: String as PropType<string>, |
||||
|
default: '100%', |
||||
|
}, |
||||
|
height: { |
||||
|
type: String as PropType<string>, |
||||
|
default: '300px', |
||||
|
}, |
||||
|
}); |
||||
|
const topThree = [ |
||||
|
{ |
||||
|
name: 'xx', |
||||
|
percent: '100%', |
||||
|
}, |
||||
|
{ |
||||
|
name: 'xx', |
||||
|
percent: '98%', |
||||
|
}, |
||||
|
{ |
||||
|
name: 'xx', |
||||
|
percent: '95%', |
||||
|
}, |
||||
|
]; |
||||
|
const lastThree = [ |
||||
|
{ |
||||
|
name: 'xx', |
||||
|
percent: '60%', |
||||
|
}, |
||||
|
{ |
||||
|
name: 'xx', |
||||
|
percent: '55%', |
||||
|
}, |
||||
|
{ |
||||
|
name: 'xx', |
||||
|
percent: '39%', |
||||
|
}, |
||||
|
]; |
||||
|
const chartRef1 = ref<HTMLDivElement | null>(null); |
||||
|
const setOptions1 = useECharts(chartRef1 as Ref<HTMLDivElement>).setOptions; |
||||
|
const chartRef2 = ref<HTMLDivElement | null>(null); |
||||
|
const setOptions2 = useECharts(chartRef2 as Ref<HTMLDivElement>).setOptions; |
||||
|
const chartRef3 = ref<HTMLDivElement | null>(null); |
||||
|
const setOptions3 = useECharts(chartRef3 as Ref<HTMLDivElement>).setOptions; |
||||
|
const dataSource = ref([]) |
||||
|
const columns = [ |
||||
|
{ |
||||
|
dataIndex: 'index', |
||||
|
key: 'index', |
||||
|
title: '序号', |
||||
|
customCell: (_, index:any) => { |
||||
|
return index |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
dataIndex: 'monitorTime', |
||||
|
key: 'monitorTime', |
||||
|
title: '监测时间', |
||||
|
}, |
||||
|
{ |
||||
|
dataIndex: 'ph', |
||||
|
key: 'ph', |
||||
|
title: 'PH值(6-9)', |
||||
|
}, |
||||
|
{ |
||||
|
dataIndex: 'oxygenDemand', |
||||
|
key: 'oxygenDemand', |
||||
|
title: '化学需氧量(250mg/L)', |
||||
|
}, |
||||
|
{ |
||||
|
dataIndex: 'ammoniaOxygen', |
||||
|
key: 'ammoniaOxygen', |
||||
|
title: '氨氧(mg/L)', |
||||
|
}, |
||||
|
{ |
||||
|
dataIndex: 'flowRate', |
||||
|
key: 'flowRate', |
||||
|
title: '废水瞬时流量(升/秒)', |
||||
|
}, |
||||
|
{ |
||||
|
dataIndex: 'restChlorine', |
||||
|
key: 'restChlorine', |
||||
|
title: '总余氯(8mg/L)', |
||||
|
}, |
||||
|
]; |
||||
|
watch( |
||||
|
() => subTab.value, |
||||
|
() => { |
||||
|
setOptions1({ |
||||
|
tooltip: { |
||||
|
trigger: 'item', |
||||
|
formatter: '{a} <br/>{b}: {c} ({d}%)', // {d}% 表示百分比 |
||||
|
}, |
||||
|
legend: { |
||||
|
top: '5%', |
||||
|
left: 'center', |
||||
|
}, |
||||
|
series: [ |
||||
|
{ |
||||
|
name: '污染源统计', |
||||
|
type: 'pie', |
||||
|
radius: ['40%', '70%'], |
||||
|
avoidLabelOverlap: false, |
||||
|
label: { |
||||
|
show: false, |
||||
|
position: 'center', |
||||
|
}, |
||||
|
labelLine: { |
||||
|
show: false, |
||||
|
}, |
||||
|
data: [ |
||||
|
{ value: 1048, name: '污水处理厂' }, |
||||
|
{ value: 735, name: '工业污染源' }, |
||||
|
{ value: 580, name: '畜禽养殖场' }, |
||||
|
], |
||||
|
}, |
||||
|
], |
||||
|
}); |
||||
|
setOptions2({ |
||||
|
tooltip: { |
||||
|
trigger: 'item', |
||||
|
formatter: '{a} <br/>{b}:({d}%)', // {d}% 表示百分比 |
||||
|
}, |
||||
|
legend: { |
||||
|
top: '5%', |
||||
|
left: 'center', |
||||
|
}, |
||||
|
series: [ |
||||
|
{ |
||||
|
name: '全区水质达标率', |
||||
|
type: 'pie', |
||||
|
radius: ['40%', '70%'], |
||||
|
avoidLabelOverlap: false, |
||||
|
label: { |
||||
|
show: false, |
||||
|
position: 'center', |
||||
|
}, |
||||
|
labelLine: { |
||||
|
show: false, |
||||
|
}, |
||||
|
data: [ |
||||
|
{ value: 800, name: '达标数' }, |
||||
|
{ value: 200, name: '未达标' }, |
||||
|
], |
||||
|
}, |
||||
|
], |
||||
|
graphic: { |
||||
|
elements: [ |
||||
|
{ |
||||
|
type: 'text', |
||||
|
left: 'center', // 水平居中 |
||||
|
bottom: '5%', // 调整位置,在饼图和图例之间 |
||||
|
style: { |
||||
|
text: '良好', |
||||
|
fontSize: 20, |
||||
|
fontWeight: 'bold', |
||||
|
fill: '#00a854', |
||||
|
align: 'center', |
||||
|
}, |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
}); |
||||
|
setOptions3({ |
||||
|
tooltip: { |
||||
|
trigger: 'item', |
||||
|
formatter: '{a} <br/>{b}: {c} ({d}%)', // {d}% 表示百分比 |
||||
|
}, |
||||
|
legend: { |
||||
|
top: '5%', |
||||
|
left: 'center', |
||||
|
}, |
||||
|
series: [ |
||||
|
{ |
||||
|
name: '河道统计', |
||||
|
type: 'pie', |
||||
|
radius: ['40%', '70%'], |
||||
|
avoidLabelOverlap: false, |
||||
|
label: { |
||||
|
show: false, |
||||
|
position: 'center', |
||||
|
}, |
||||
|
labelLine: { |
||||
|
show: false, |
||||
|
}, |
||||
|
data: [ |
||||
|
{ value: 42, name: '河长' }, |
||||
|
{ value: 20, name: '工作人员' }, |
||||
|
{ value: 10, name: '公示牌' }, |
||||
|
{ value: 3, name: '排污口数量' }, |
||||
|
], |
||||
|
}, |
||||
|
], |
||||
|
}); |
||||
|
}, |
||||
|
{ immediate: true }, |
||||
|
); |
||||
|
</script> |
||||
|
<style lang="less"> |
||||
|
.tabBox { |
||||
|
margin: 20px; |
||||
|
} |
||||
|
</style> |
Loading…
Reference in new issue