数据分析

This commit is contained in:
冯少康 2026-08-03 18:09:36 +08:00
parent af3ac25fef
commit 10a7cca13e
4 changed files with 270 additions and 52 deletions

View File

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<metadata>
<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""
xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:creator>
<rdf:Seq><rdf:li>Freeicon</rdf:li></rdf:Seq>
</dc:creator>
<dc:rights>
<rdf:Alt><rdf:li xml:lang="x-default">Free for personal and commercial use - freeicon.com</rdf:li></rdf:Alt>
</dc:rights>
</rdf:Description>
<rdf:Description rdf:about=""
xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/">
<Iptc4xmpCore:CreditLine>freeicon.com</Iptc4xmpCore:CreditLine>
</rdf:Description>
<rdf:Description rdf:about=""
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">
<photoshop:Credit>freeicon.com</photoshop:Credit>
<photoshop:Source>freeicon.com</photoshop:Source>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?>
</metadata>
<g id="_x31_3_x2C__Correct_x2C__Calendar_x2C__Time_And_Date_x2C__Check_x2C__Sign">
<g>
<g id="XMLID_2598_">
<path id="XMLID_2648_" style="fill:#89CCFF;" d="M501,141v330c0,16.57-13.43,30-30,30H41c-16.57,0-30-13.43-30-30V141
C42.754,141,479.697,141,501,141z"/>
<path id="XMLID_2646_" style="fill:#89CCFF;" d="M471,51c16.57,0,30,13.43,30,30v60l-227.606,43L11,141V81
c0-16.57,13.43-30,30-30"/>
<rect id="XMLID_2645_" x="51" y="141" style="fill:#FFFFFF;" width="410" height="320"/>
<path id="XMLID_2644_" style="fill:#FFFFFF;" d="M461,66c0,13.81-11.19,25-25,25s-25-11.19-25-25c0-10.492,0-19.508,0-30
c0-13.81,11.19-25,25-25c13.824,0,25,11.199,25,25C461,36,461,55.508,461,66z"/>
<path id="XMLID_2643_" style="fill:#FFFFFF;" d="M371,66c0,13.81-11.19,25-25,25s-25-11.19-25-25c0-10.492,0-19.508,0-30
c0-13.81,11.19-25,25-25c13.824,0,25,11.199,25,25C371,36,371,55.508,371,66z"/>
<path id="XMLID_2642_" style="fill:#FFFFFF;" d="M281,66c0,13.81-11.19,25-25,25s-25-11.19-25-25c0-10.492,0-19.508,0-30
c0-13.81,11.19-25,25-25c13.824,0,25,11.199,25,25C281,46.492,281,55.508,281,66z"/>
<path id="XMLID_2641_" style="fill:#FFFFFF;" d="M191,66c0,13.81-11.19,25-25,25s-25-11.19-25-25c0-10.492,0-19.508,0-30
c0-13.81,11.19-25,25-25c13.824,0,25,11.199,25,25C191,36,191,55.508,191,66z"/>
<path id="XMLID_2640_" style="fill:#FFFFFF;" d="M101,66c0,13.81-11.19,25-25,25S51,79.81,51,66c0-10.492,0-19.508,0-30
c0-13.81,11.19-25,25-25c13.824,0,25,11.199,25,25C101,46.492,101,55.508,101,66z"/>
<path id="XMLID_2639_" style="fill:#2169AC;" d="M141,61h-40c-5.523,0-10-4.477-10-10s4.477-10,10-10h40c5.523,0,10,4.477,10,10
S146.523,61,141,61z"/>
<path id="XMLID_2638_" style="fill:#2169AC;" d="M321,61h-40c-5.523,0-10-4.477-10-10s4.477-10,10-10h40c5.523,0,10,4.477,10,10
S326.523,61,321,61z"/>
<path id="XMLID_2637_" style="fill:#2169AC;" d="M471,511H41c-22.056,0-40-17.944-40-40V81c0-22.056,17.944-40,40-40h10
c5.523,0,10,4.477,10,10s-4.477,10-10,10H41c-11.028,0-20,8.972-20,20v390c0,11.028,8.972,20,20,20h430c11.028,0,20-8.972,20-20
V81c0-11.028-8.972-20-20-20h-10c-5.523,0-10-4.477-10-10s4.477-10,10-10h10c22.056,0,40,17.944,40,40v390
C511,493.056,493.056,511,471,511z"/>
<path id="XMLID_2636_" style="fill:#2169AC;" d="M411,61h-40c-5.523,0-10-4.477-10-10s4.477-10,10-10h40c5.523,0,10,4.477,10,10
S416.523,61,411,61z"/>
<path id="XMLID_2635_" style="fill:#2169AC;" d="M231,61h-40c-5.523,0-10-4.477-10-10s4.477-10,10-10h40c5.523,0,10,4.477,10,10
S236.523,61,231,61z"/>
<path id="XMLID_2618_" style="fill:#2169AC;" d="M76,101c-19.299,0-35-15.701-35-35V36C41,16.701,56.701,1,76,1
c19.351,0,35,15.647,35,35v30C111,85.299,95.299,101,76,101z M76,21c-8.271,0-15,6.729-15,15v30c0,8.271,6.729,15,15,15
s15-6.729,15-15V36C91,27.704,84.298,21,76,21z"/>
<path id="XMLID_2615_" style="fill:#2169AC;" d="M166,101c-19.299,0-35-15.701-35-35V36c0-19.299,15.701-35,35-35
c19.35,0,35,15.647,35,35v30C201,85.299,185.299,101,166,101z M166,21c-8.271,0-15,6.729-15,15v30c0,8.271,6.729,15,15,15
s15-6.729,15-15V36C181,27.704,174.298,21,166,21z"/>
<path id="XMLID_2612_" style="fill:#2169AC;" d="M256,101c-19.299,0-35-15.701-35-35V36c0-19.299,15.701-35,35-35
c19.35,0,35,15.647,35,35v30C291,85.299,275.299,101,256,101z M256,21c-8.271,0-15,6.729-15,15v30c0,8.271,6.729,15,15,15
s15-6.729,15-15V36C271,27.704,264.298,21,256,21z"/>
<path id="XMLID_2609_" style="fill:#2169AC;" d="M346,101c-19.299,0-35-15.701-35-35V36c0-19.299,15.701-35,35-35
c19.35,0,35,15.647,35,35v30C381,85.299,365.299,101,346,101z M346,21c-8.271,0-15,6.729-15,15v30c0,8.271,6.729,15,15,15
s15-6.729,15-15V36C361,27.704,354.298,21,346,21z"/>
<path id="XMLID_2606_" style="fill:#2169AC;" d="M436,101c-19.299,0-35-15.701-35-35V36c0-19.299,15.701-35,35-35
c19.35,0,35,15.647,35,35v30C471,85.299,455.299,101,436,101z M436,21c-8.271,0-15,6.729-15,15v30c0,8.271,6.729,15,15,15
s15-6.729,15-15V36c0-4.01-1.56-7.778-4.391-10.609C443.778,22.56,440.01,21,436,21z"/>
<path id="XMLID_2605_" style="fill:#2169AC;" d="M461,471c-5.523,0-10-4.477-10-10V141c0-5.523,4.477-10,10-10s10,4.477,10,10
v320C471,466.523,466.523,471,461,471z"/>
<path id="XMLID_2604_" style="fill:#2169AC;" d="M461,471H51c-5.523,0-10-4.477-10-10V141c0-5.523,4.477-10,10-10s10,4.477,10,10
v310h400c5.523,0,10,4.477,10,10S466.523,471,461,471z"/>
<path id="XMLID_2603_" style="fill:#2169AC;" d="M501,151H11c-5.523,0-10-4.477-10-10s4.477-10,10-10h490c5.523,0,10,4.477,10,10
S506.523,151,501,151z"/>
<polygon id="XMLID_2601_" style="fill:#89CCFF;" points="378.31,240.86 258.05,361.13 258.06,361.14 222.71,396.5 133.69,307.48
169.05,272.13 222.69,325.77 342.95,205.5 "/>
<path id="XMLID_2600_" style="fill:#2169AC;" d="M250.979,368.201c-3.905-3.905-3.906-10.237-0.001-14.142L364.168,240.86
l-21.218-21.217L229.761,332.841c-3.905,3.905-10.237,3.906-14.142,0.001c-3.905-3.905-3.906-10.237,0-14.142l120.26-120.27
c3.902-3.903,10.237-3.905,14.143,0l35.359,35.36c3.905,3.905,3.905,10.236,0,14.142l-120.26,120.27
C261.217,372.106,254.884,372.107,250.979,368.201z"/>
<path id="XMLID_2599_" style="fill:#2169AC;" d="M215.639,403.571l-89.02-89.02c-3.903-3.904-3.905-10.238,0.001-14.144
l35.36-35.35c3.906-3.904,10.236-3.903,14.142,0.001l53.64,53.64c3.905,3.905,3.905,10.237,0,14.143
c-3.905,3.905-10.237,3.905-14.143,0l-46.57-46.57l-21.216,21.21l74.876,74.876l28.007-28.015
c3.926-4.236,10.599-4.284,14.575-0.108l0.01,0.01c3.743,3.93,3.668,10.128-0.169,13.966l-35.35,35.36
C225.879,407.474,219.545,407.476,215.639,403.571z"/>
</g>
</g>
</g>
<g id="Layer_1">
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@ -156,6 +156,17 @@ const symnTool = ref<MapControlItem[]>([
},
]);
//
const sjfxTool = ref<MapControlItem[]>([
{
name: "calendar",
isMargin: false,
tooltip: "日历",
isActive: false,
activeName: "calendar",
},
]);
const gifFormData = reactive({
minLon: "",
maxLon: "",
@ -248,6 +259,13 @@ function handleIconClick(item: MapControlItem) {
isShowGif.value = true;
}
);
}else if(item.name=='calendar'){
let falg: any = !item.isActive;
switchIconActive(item.name, falg);
EventBusTool.getEventBus().publish("sjfxCalendarEvent", {
key: item.name,
falg,
});
}
//
else {
@ -387,6 +405,8 @@ onMounted(() => {
svgList.value = [...baseList.value, ...yxcjTool.value];
} else if (res.key === "gifIcon") {
svgList.value = [...baseList.value, ...symnTool.value];
}else if(res.key=="sjfxList"){
svgList.value = [...baseList.value, ...sjfxTool.value];
}
//
if (res.key === "dataExport") {
@ -397,6 +417,10 @@ onMounted(() => {
//
switchIconActive(res.key, res.falg);
}
if(res.key == "calendar"){
switchIconActive(res.key, res.falg);
}
});
EventBusTool.getEventBus().subscribe("speciesChange", (res: any) => {

View File

@ -1,44 +1,56 @@
<script setup lang="ts">
import type { RouteRecordRaw } from 'vue-router';
import { ElMessage, ElMessageBox } from 'element-plus';
import { useI18n } from 'vue-i18n';
import { setActiveMenu } from '@/gis/ol/index';
import { ExcludeRouting } from '@/interface/index';
import { usePermissionStore } from '@/store/modules/permission';
import { useUserStore } from '@/store/modules/useUser';
import type { RouteRecordRaw } from "vue-router";
import { ElMessage, ElMessageBox } from "element-plus";
import { useI18n } from "vue-i18n";
import { setActiveMenu } from "@/gis/ol/index";
import { ExcludeRouting } from "@/interface/index";
import { usePermissionStore } from "@/store/modules/permission";
import { useUserStore } from "@/store/modules/useUser";
const { t, locale } = useI18n();
const router = useRouter();
const routerList = ref<RouteRecordRaw[]>([]);
const activeMenu = ref('输运模拟');
const activeMenu = ref("输运模拟");
//
const language = computed(() => locale.value === 'zh' ? 'CH' : 'EN');
const language = computed(() => (locale.value === "zh" ? "CH" : "EN"));
function menuItemClick(name: string, nick: string) {
async function menuItemClick(name: string, nick: string) {
activeMenu.value = nick;
// gis
// eslint-disable-next-line prefer-const
let eventbus: any = EventBusTool.getEventBus();
eventbus.publish('playData', {
key: 'clear',
eventbus.publish("playData", {
key: "clear",
activeMenu: nick,
});
eventbus.publish('mapRightMenuUIEvent', {
key: activeMenu.value === '源项重建' ? 'allList' : 'baseList',
});
//
router.push({ name });
//
setTimeout(() => {
if (activeMenu.value === "数据分析") {
eventbus.publish("mapRightMenuUIEvent", {
key: "sjfxList",
});
} else {
eventbus.publish("mapRightMenuUIEvent", {
key: activeMenu.value === "源项重建" ? "allList" : "baseList",
});
}
}, 500);
// router.push({ name });
}
function tabLanguage() {
//
const newLocale = locale.value === 'zh' ? 'en' : 'zh';
const newLocale = locale.value === "zh" ? "en" : "zh";
locale.value = newLocale;
//
localStorage.setItem('locale', newLocale);
localStorage.setItem("locale", newLocale);
}
//
@ -55,7 +67,9 @@ onMounted(async () => {
// 2.
const filteredRoutes = allAccessibleRoutes.filter((item) => {
const isNotExcluded = !Object.values(ExcludeRouting).includes(item.name as ExcludeRouting);
const isNotExcluded = !Object.values(ExcludeRouting).includes(
item.name as ExcludeRouting
);
const isNotHidden = !item.hidden;
return isNotExcluded && isNotHidden;
});
@ -74,14 +88,17 @@ onMounted(async () => {
// const matchedMenu = sortedRoutes.find(item => item.redirect === currentPath);
// activeMenu.value = matchedMenu.meta.nick;
const matchedMenu = ref();
console.log(currentPath, 'currentPath');
const path = currentPath.split('/')[1];
const pathArr = ['sjfx', 'system'];
console.log(currentPath, "currentPath");
const path = currentPath.split("/")[1];
const pathArr = ["sjfx", "system"];
if (!pathArr.includes(path)) {
matchedMenu.value = sortedRoutes.find(item => item.redirect === currentPath);
}
else {
matchedMenu.value = sortedRoutes.find(item => item.redirect.split('/')[1] === currentPath.split('/')[1]);
matchedMenu.value = sortedRoutes.find(
(item) => item.redirect === currentPath
);
} else {
matchedMenu.value = sortedRoutes.find(
(item) => item.redirect.split("/")[1] === currentPath.split("/")[1]
);
}
activeMenu.value = matchedMenu.value?.meta?.nick;
setActiveMenu(activeMenu.value);
@ -89,23 +106,22 @@ onMounted(async () => {
const { logOut } = useUserStore();
function logout() {
ElMessageBox.confirm('确定退出?', '退出', {
confirmButtonText: '退出',
cancelButtonText: '取消',
type: 'warning',
ElMessageBox.confirm("确定退出?", "退出", {
confirmButtonText: "退出",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
try {
logOut();
}
catch (error) {
console.error('退出失败:', error);
} catch (error) {
console.error("退出失败:", error);
}
})
.catch(() => {
ElMessage({
type: 'info',
message: '取消',
type: "info",
message: "取消",
duration: 500,
});
});
@ -116,22 +132,32 @@ function logout() {
<div class="header">
<div class="logo">
<SvgIcon name="logo" width="60" height="60" />
{{ t('title') }}
{{ t("title") }}
</div>
<div class="base-menu">
<div
v-for="item in routerList" :key="item.name"
:class="item.meta?.nick === activeMenu ? 'base-menu-item menu-active' : 'base-menu-item'"
v-for="item in routerList"
:key="item.name"
:class="
item.meta?.nick === activeMenu
? 'base-menu-item menu-active'
: 'base-menu-item'
"
@click="menuItemClick(item.name as string, item.meta?.nick as string)"
>
<SvgIcon
:name="item.meta?.icon as string + (item.meta?.nick === activeMenu ? '_active' : '')" width="30"
:name="item.meta?.icon as string + (item.meta?.nick === activeMenu ? '_active' : '')"
width="30"
height="30"
/>
<div v-if="locale === 'zh'" class="base-menu-item-txt">
{{ item.meta?.nick }}
</div>
<div v-if="locale === 'en'" class="base-menu-item-txt" style="font-size: 12px">
<div
v-if="locale === 'en'"
class="base-menu-item-txt"
style="font-size: 12px"
>
{{ item.meta?.en }}
</div>
</div>
@ -140,9 +166,9 @@ function logout() {
<div class="user-info">
<div class="translate" @click="tabLanguage">
<div class="translate-right-top">
{{ language === 'CH' ? 'En' : 'Ch' }}
{{ language === "CH" ? "En" : "Ch" }}
</div>
<div>{{ language === 'CH' ? '中' : '英' }}</div>
<div>{{ language === "CH" ? "中" : "英" }}</div>
</div>
</div>
<!-- <div class="user-info"> -->

View File

@ -48,13 +48,14 @@ interface TimeListData {
[key: string]: any; // key "2025-01-17"value
}
const searchResultTimeListData = ref<TimeListData>({});
const initStationLevelCount = ref([]);
interface StationBaseData {
stationCode: string; // stationCode
lon: string;
lat: string;
}
const searchResultBaseData = ref<StationBaseData[]>([]);
const searchResultBaseData = ref<StationBaseData[]>([]);
//
const sliderValue = ref(0);
@ -102,6 +103,8 @@ const currentPickervalue = ref<Date | null>(null); // 明确类型为Date或null
const showCalendar = ref(false); //
const showSilder = ref(false); //
const playFalg = ref<boolean>(false);
const flagMaxRunHandle = ref<boolean>(false);//
const checkBoxList = ref([{
isCheck: true,
label: '级别1',
@ -174,10 +177,12 @@ function getData() {
sliderStart.value = dayjs(startDateStr);
sliderEnd.value = dayjs(endDateStr);
//
currentPickervalue.value = new Date(startDateStr);
// currentPickervalue.value = new Date(startDateStr);
//
searchResultBaseData.value = res.result.stationInfo;
searchResultTimeListData.value = res.result.sampleMonitorResultList;
initStationLevelCount.value = res.result.stationLevelCount
initPointSt()
}
else {
ElMessage({
@ -190,6 +195,39 @@ function getData() {
});
}
//
function initPointSt(){
const currentList = initStationLevelCount.value||[];
const data: any = [];
currentList.forEach((item: any) => {
const find = searchResultBaseData.value.find((v) => {
return item.stationCode === v.stationCode;
});
if (find) {
data.push({
id: find.stationCode,
longitude: find.lon,
latitude: find.lat,
label: find.stationCode,
level: item.categoryCount ? JSON.parse(JSON.stringify(item.categoryCount)) : {},
});
}
});
const noCheckData = checkBoxList.value.filter((item: any) => !item.isCheck).map((item: any) => item.key);
data.forEach((item: any) => {
Object.keys(item.level).forEach((levelKey) => {
//
if (noCheckData.includes(levelKey)) {
delete item.level[levelKey as keyof typeof item.level];
}
});
});
console.log(data);
sjfxPointHandle.value?.addPoints(data);
}
//
function runHandle() {
showSilder.value = true;
@ -212,11 +250,14 @@ function playAnimation() {
//
function resetHandle() {
const [startDateStr] = form.value.createTime; //
currentPickervalue.value = new Date(startDateStr);
checkBoxList.value.forEach((item) => {
item.isCheck = true;
});
// const [startDateStr] = form.value.createTime; //
// currentPickervalue.value = new Date(startDateStr);
// checkBoxList.value.forEach((item) => {
// item.isCheck = true;
// });
currentPickervalue.value = null;
initPointSt();
playFalg.value = false;
showSilder.value = false;
setShouldAnimate(false);
@ -224,6 +265,7 @@ function resetHandle() {
//
function getTimeDataFromDate(date: string) {
console.log(date,"222222")
const currentList = searchResultTimeListData.value[date];
const data: any = [];
currentList.forEach((item: any) => {
@ -258,7 +300,11 @@ function getTimeDataFromDate(date: string) {
//
function closeCalendar() {
showCalendar.value = false;
sjfxPointHandle.value?.clearPoints();
EventBusTool.getEventBus().publish('mapRightMenuUIEvent', {
key: 'calendar',
falg: false,
});
// sjfxPointHandle.value?.clearPoints();
}
//
@ -272,8 +318,19 @@ watch(currentPickervalue, (newDate) => {
const sliderVal = Math.max(date.diff(sliderStart.value, 'day'), 0);
// max
sliderValue.value = Math.min(sliderVal, sliderMax.value);
//
getTimeDataFromDate(ymd);
console.log(sliderVal,sliderValue.value,sliderMax.value,"12121")
if((sliderVal==sliderMax.value&&!flagMaxRunHandle)){
flagMaxRunHandle.value = true;
getTimeDataFromDate(ymd);
}else if(sliderVal!=sliderMax.value){
getTimeDataFromDate(ymd);
}else{
playFalg.value = false;
// showSilder.value = false;
setShouldAnimate(false);
}
}
else {
console.log('取消了日期选中');
@ -296,6 +353,12 @@ onMounted(() => {
}
},
});
EventBusTool.getEventBus().subscribe('sjfxCalendarEvent', (res: any) => {
showCalendar.value = res.falg;
});
});
});
@ -391,9 +454,15 @@ onUnmounted(() => {
/>
</div>
<div class="btnGruop">
<div class="runBtn" @click="runHandle">
<div class="runBtn" @click="runHandle" v-if="!showSilder">
运行
</div>
<div class="runBtn" @click="playAnimation()" v-else-if="!playFalg">
播放
</div>
<div class="runBtn" @click="playAnimation()" v-else-if="playFalg">
暂停
</div>
<div class="resetBtn" @click="resetHandle">
重置
</div>