2026-04-10 11:11:30 +08:00
|
|
|
|
<!-- SidePanelItem.vue -->
|
|
|
|
|
|
<template>
|
2026-05-18 09:03:20 +08:00
|
|
|
|
<SidePanelItem
|
|
|
|
|
|
title="沿程水温变化"
|
|
|
|
|
|
:prompt="prompts"
|
|
|
|
|
|
:select="select"
|
|
|
|
|
|
:datetimePicker="datetimePicker"
|
|
|
|
|
|
>
|
2026-04-10 11:11:30 +08:00
|
|
|
|
<div ref="chartRef" class="chart-container"></div>
|
|
|
|
|
|
</SidePanelItem>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script lang="ts" setup>
|
2026-05-18 09:03:20 +08:00
|
|
|
|
import { ref, onMounted, onBeforeUnmount } from "vue";
|
|
|
|
|
|
import * as echarts from "echarts";
|
|
|
|
|
|
import type { ECharts } from "echarts";
|
|
|
|
|
|
import SidePanelItem from "@/components/SidePanelItem/index.vue";
|
|
|
|
|
|
import { getKendoListCust } from "@/api/sw";
|
2026-04-10 11:11:30 +08:00
|
|
|
|
|
|
|
|
|
|
// 定义组件名(便于调试和递归)
|
|
|
|
|
|
defineOptions({
|
2026-05-18 09:03:20 +08:00
|
|
|
|
name: "yanchengshuiwenChangeMod",
|
2026-04-10 11:11:30 +08:00
|
|
|
|
});
|
2026-05-15 18:08:29 +08:00
|
|
|
|
// 选择器配置
|
|
|
|
|
|
const select = ref({
|
2026-05-18 09:03:20 +08:00
|
|
|
|
show: true,
|
|
|
|
|
|
value: undefined,
|
|
|
|
|
|
options: [],
|
|
|
|
|
|
picker: undefined,
|
|
|
|
|
|
format: undefined,
|
2026-05-15 18:08:29 +08:00
|
|
|
|
});
|
2026-04-10 11:11:30 +08:00
|
|
|
|
|
2026-05-15 18:08:29 +08:00
|
|
|
|
// 日期选择器配置
|
|
|
|
|
|
const datetimePicker = ref({
|
2026-05-18 09:03:20 +08:00
|
|
|
|
show: true,
|
|
|
|
|
|
value: "2026-05-15 15",
|
|
|
|
|
|
format: "YYYY-MM-DD HH",
|
|
|
|
|
|
picker: "date" as const,
|
|
|
|
|
|
options: [],
|
2026-05-15 18:08:29 +08:00
|
|
|
|
});
|
2026-04-10 11:11:30 +08:00
|
|
|
|
const prompts = ref({
|
|
|
|
|
|
show: true,
|
2026-05-18 09:03:20 +08:00
|
|
|
|
value: "注:最新数据时间为2026-04-08 23",
|
2026-04-10 11:11:30 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const chartRef = ref<HTMLElement | null>(null);
|
|
|
|
|
|
let chartInstance: ECharts | null = null;
|
|
|
|
|
|
|
|
|
|
|
|
// 静态数据 - 站点名称
|
2026-05-18 09:03:20 +08:00
|
|
|
|
const stationNames = ref([]);
|
2026-04-10 11:11:30 +08:00
|
|
|
|
|
|
|
|
|
|
// 静态数据 - 水温值 (°C),班多无数据设为 null
|
2026-05-18 09:03:20 +08:00
|
|
|
|
const waterTemperatures = ref([]);
|
2026-04-10 11:11:30 +08:00
|
|
|
|
|
|
|
|
|
|
// 静态时间数据
|
2026-05-18 09:03:20 +08:00
|
|
|
|
const currentTime = "2026-04-08 23";
|
2026-04-10 11:11:30 +08:00
|
|
|
|
|
|
|
|
|
|
// 初始化图表
|
|
|
|
|
|
const initChart = () => {
|
|
|
|
|
|
if (!chartRef.value) return;
|
|
|
|
|
|
|
|
|
|
|
|
chartInstance = echarts.init(chartRef.value);
|
|
|
|
|
|
|
|
|
|
|
|
const option = {
|
|
|
|
|
|
title: {
|
2026-05-18 09:03:20 +08:00
|
|
|
|
text: "水温(°C)",
|
2026-04-10 11:11:30 +08:00
|
|
|
|
left: 5,
|
|
|
|
|
|
top: 0,
|
|
|
|
|
|
textStyle: {
|
2026-05-18 09:03:20 +08:00
|
|
|
|
color: "#000000",
|
2026-04-10 11:11:30 +08:00
|
|
|
|
fontSize: 12,
|
2026-05-18 09:03:20 +08:00
|
|
|
|
fontWeight: "normal",
|
|
|
|
|
|
},
|
2026-04-10 11:11:30 +08:00
|
|
|
|
},
|
|
|
|
|
|
tooltip: {
|
2026-05-18 09:03:20 +08:00
|
|
|
|
trigger: "axis",
|
2026-04-10 11:11:30 +08:00
|
|
|
|
formatter: (params: any) => {
|
|
|
|
|
|
if (params && params.length > 0) {
|
|
|
|
|
|
const data = params[0];
|
|
|
|
|
|
// 过滤掉 null 值的数据点
|
|
|
|
|
|
if (data.value !== null && data.value !== undefined) {
|
|
|
|
|
|
return `${currentTime}<br/>${data.name}:${data.value}°C`;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-05-18 09:03:20 +08:00
|
|
|
|
return "";
|
|
|
|
|
|
},
|
2026-04-10 11:11:30 +08:00
|
|
|
|
},
|
|
|
|
|
|
grid: {
|
2026-05-18 09:03:20 +08:00
|
|
|
|
left: "3%",
|
|
|
|
|
|
right: "4%",
|
|
|
|
|
|
bottom: "3%",
|
|
|
|
|
|
top: "15%",
|
|
|
|
|
|
containLabel: true,
|
2026-04-10 11:11:30 +08:00
|
|
|
|
},
|
|
|
|
|
|
xAxis: {
|
2026-05-18 09:03:20 +08:00
|
|
|
|
type: "category",
|
2026-04-10 11:11:30 +08:00
|
|
|
|
data: stationNames.value,
|
|
|
|
|
|
boundaryGap: true,
|
|
|
|
|
|
axisLine: {
|
|
|
|
|
|
show: true,
|
|
|
|
|
|
lineStyle: {
|
2026-05-18 09:03:20 +08:00
|
|
|
|
color: "#8f8f8f",
|
|
|
|
|
|
},
|
2026-04-10 11:11:30 +08:00
|
|
|
|
},
|
|
|
|
|
|
axisTick: {
|
2026-05-18 09:03:20 +08:00
|
|
|
|
show: false,
|
2026-04-10 11:11:30 +08:00
|
|
|
|
},
|
|
|
|
|
|
axisLabel: {
|
2026-05-18 09:03:20 +08:00
|
|
|
|
color: "#333",
|
2026-04-10 11:11:30 +08:00
|
|
|
|
fontSize: 12,
|
|
|
|
|
|
margin: 8,
|
|
|
|
|
|
interval: 0,
|
|
|
|
|
|
formatter: (value: string, index: number) => {
|
|
|
|
|
|
// 偶数索引(0, 2, 4, 6)的标签在上方
|
|
|
|
|
|
// 奇数索引(1, 3, 5)的标签在下方
|
|
|
|
|
|
// 通过添加空行实现上下错位
|
|
|
|
|
|
if (index % 2 === 0) {
|
2026-05-18 09:03:20 +08:00
|
|
|
|
return `${value}\n `; // 上方标签:文字 + 换行 + 空格占位
|
2026-04-10 11:11:30 +08:00
|
|
|
|
} else {
|
2026-05-18 09:03:20 +08:00
|
|
|
|
return ` \n${value}`; // 下方标签:空格占位 + 换行 + 文字
|
2026-04-10 11:11:30 +08:00
|
|
|
|
}
|
2026-05-18 09:03:20 +08:00
|
|
|
|
},
|
2026-04-10 11:11:30 +08:00
|
|
|
|
},
|
|
|
|
|
|
splitLine: {
|
|
|
|
|
|
show: true,
|
|
|
|
|
|
lineStyle: {
|
2026-05-18 09:03:20 +08:00
|
|
|
|
color: "#e0e0e0",
|
|
|
|
|
|
type: "solid",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
2026-04-10 11:11:30 +08:00
|
|
|
|
},
|
|
|
|
|
|
yAxis: {
|
2026-05-18 09:03:20 +08:00
|
|
|
|
type: "value",
|
2026-04-10 11:11:30 +08:00
|
|
|
|
min: 0,
|
2026-05-18 09:03:20 +08:00
|
|
|
|
// max: 10,
|
2026-04-10 11:11:30 +08:00
|
|
|
|
interval: 2,
|
|
|
|
|
|
axisLine: {
|
|
|
|
|
|
show: true,
|
|
|
|
|
|
lineStyle: {
|
2026-05-18 09:03:20 +08:00
|
|
|
|
color: "#8f8f8f",
|
|
|
|
|
|
},
|
2026-04-10 11:11:30 +08:00
|
|
|
|
},
|
|
|
|
|
|
axisTick: {
|
|
|
|
|
|
show: true,
|
|
|
|
|
|
length: 3,
|
|
|
|
|
|
lineStyle: {
|
2026-05-18 09:03:20 +08:00
|
|
|
|
color: "#8f8f8f",
|
|
|
|
|
|
},
|
2026-04-10 11:11:30 +08:00
|
|
|
|
},
|
|
|
|
|
|
axisLabel: {
|
2026-05-18 09:03:20 +08:00
|
|
|
|
color: "#333",
|
|
|
|
|
|
fontSize: 12,
|
2026-04-10 11:11:30 +08:00
|
|
|
|
},
|
|
|
|
|
|
splitLine: {
|
|
|
|
|
|
show: true,
|
|
|
|
|
|
lineStyle: {
|
2026-05-18 09:03:20 +08:00
|
|
|
|
color: "#e0e0e0",
|
|
|
|
|
|
type: "solid",
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
2026-04-10 11:11:30 +08:00
|
|
|
|
},
|
|
|
|
|
|
series: [
|
|
|
|
|
|
{
|
2026-05-18 09:03:20 +08:00
|
|
|
|
name: "水温",
|
|
|
|
|
|
type: "line",
|
2026-04-10 11:11:30 +08:00
|
|
|
|
smooth: true,
|
2026-05-18 09:03:20 +08:00
|
|
|
|
symbol: "circle",
|
2026-04-10 11:11:30 +08:00
|
|
|
|
symbolSize: 6,
|
|
|
|
|
|
lineStyle: {
|
2026-05-18 09:03:20 +08:00
|
|
|
|
color: "#6ca4f7",
|
|
|
|
|
|
width: 2,
|
2026-04-10 11:11:30 +08:00
|
|
|
|
},
|
|
|
|
|
|
itemStyle: {
|
2026-05-18 09:03:20 +08:00
|
|
|
|
color: "#6ca4f7",
|
2026-04-10 11:11:30 +08:00
|
|
|
|
},
|
|
|
|
|
|
areaStyle: {
|
|
|
|
|
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
|
|
|
|
{
|
|
|
|
|
|
offset: 0,
|
2026-05-18 09:03:20 +08:00
|
|
|
|
color: "rgba(108, 164, 247, 0.3)",
|
2026-04-10 11:11:30 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
offset: 1,
|
2026-05-18 09:03:20 +08:00
|
|
|
|
color: "rgba(108, 164, 247, 0.05)",
|
|
|
|
|
|
},
|
|
|
|
|
|
]),
|
2026-04-10 11:11:30 +08:00
|
|
|
|
},
|
2026-05-18 09:03:20 +08:00
|
|
|
|
data: waterTemperatures.value,
|
|
|
|
|
|
},
|
|
|
|
|
|
],
|
2026-04-10 11:11:30 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
chartInstance.setOption(option);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 处理窗口大小变化
|
|
|
|
|
|
const handleResize = () => {
|
|
|
|
|
|
chartInstance?.resize();
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2026-05-18 09:03:20 +08:00
|
|
|
|
const init = async () => {
|
|
|
|
|
|
const params = {
|
|
|
|
|
|
filter: {
|
|
|
|
|
|
logic: "and",
|
|
|
|
|
|
filters: [
|
|
|
|
|
|
{ field: "rvcd", operator: "eq", dataType: "string", value: "SJLY1U" },
|
|
|
|
|
|
{ field: "tm", operator: "gte", dataType: "date", value: "2026-04-17 00:00:00" },
|
|
|
|
|
|
{ field: "tm", operator: "lte", dataType: "date", value: "2026-05-17 23:00:00" },
|
|
|
|
|
|
],
|
|
|
|
|
|
},
|
|
|
|
|
|
sort: [{ field: "sort", dir: "asc" }],
|
|
|
|
|
|
};
|
|
|
|
|
|
let res = await getKendoListCust(params);
|
|
|
|
|
|
stationNames.value = res.data.data
|
|
|
|
|
|
.filter((item: any) => item.sttp == "1")
|
|
|
|
|
|
.map((item: any) => item.stnm);
|
|
|
|
|
|
console.log(stationNames.value);
|
|
|
|
|
|
|
|
|
|
|
|
waterTemperatures.value = res.data.data
|
|
|
|
|
|
.filter((item: any) => item.sttp == "2")
|
|
|
|
|
|
.map((item: any) => item.temperature);
|
|
|
|
|
|
// waterTemperatures.value = res.data.data.map((item: any) => item.temperature);
|
|
|
|
|
|
console.log(waterTemperatures.value);
|
|
|
|
|
|
|
|
|
|
|
|
// 数据获取完成后,初始化或更新图表
|
2026-04-10 11:11:30 +08:00
|
|
|
|
setTimeout(() => {
|
2026-05-18 09:03:20 +08:00
|
|
|
|
if (!chartInstance) {
|
|
|
|
|
|
initChart();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 如果图表已存在,只更新数据
|
|
|
|
|
|
chartInstance.setOption({
|
|
|
|
|
|
xAxis: {
|
|
|
|
|
|
data: stationNames.value,
|
|
|
|
|
|
},
|
|
|
|
|
|
series: [
|
|
|
|
|
|
{
|
|
|
|
|
|
data: waterTemperatures.value,
|
|
|
|
|
|
},
|
|
|
|
|
|
],
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2026-04-10 11:11:30 +08:00
|
|
|
|
// 强制重绘,确保尺寸正确
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
chartInstance?.resize();
|
|
|
|
|
|
}, 100);
|
|
|
|
|
|
}, 50);
|
2026-05-18 09:03:20 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 页面加载时执行的逻辑
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
|
// 延迟初始化,确保 DOM 渲染完成
|
|
|
|
|
|
init();
|
2026-04-10 11:11:30 +08:00
|
|
|
|
|
2026-05-18 09:03:20 +08:00
|
|
|
|
window.addEventListener("resize", handleResize);
|
2026-04-10 11:11:30 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 组件卸载前清理
|
|
|
|
|
|
onBeforeUnmount(() => {
|
2026-05-18 09:03:20 +08:00
|
|
|
|
window.removeEventListener("resize", handleResize);
|
2026-04-10 11:11:30 +08:00
|
|
|
|
chartInstance?.dispose();
|
|
|
|
|
|
});
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
|
.chart-container {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 252px;
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|