Browse Source

feat:在线整编-水位的逐日显示

master
waibao2 4 weeks ago
parent
commit
bb32b2e1ba
  1. 367
      src/components/ChartsTimeLine/index.vue
  2. 32
      src/components/ZhengBian/index.vue

367
src/components/ChartsTimeLine/index.vue

@ -0,0 +1,367 @@
<template>
<div ref="ChartsBarLineRef" style="height:100%;width: 100%;" class="chart-container"></div>
</template>
<script setup>
import * as echarts from "echarts";
import dayjs from 'dayjs';
import { onMounted, nextTick, ref, onUnmounted, watch } from "vue";
const props = defineProps({
legendData: {
type: Array,
default: () => []
},
xAxisData: {
type: Array,
default: () => []
},
seriesData: {
type: Array,
default: () => []
},
baseOptionData: {
type: Array,
default: () => []
},
textTitle: {
type: String,
default: ''
},
fixed: {
type: Number,
default: 2
},
unit: {
type: String,
default: 'mm'
},
echartType: {
type: String,
default: 'line'
},
grid: {
type: Object,
default: () => {
return {
left: "5%",
right: "5%",
bottom: "20%",
top: "16%",
containLabel: true,
}
}
}
});
let ChartsBarLineRef = ref(null);
let echartsBar = null;
let resizeObserver = null;
// props
watch([() => props.legendData, () => props.xAxisData, () => props.seriesData], () => {
if (echartsBar) {
updateChart();
}
}, { deep: true });
onMounted(() => {
initEcharts();
window.addEventListener('resize', handleResize);
//
if (ChartsBarLineRef.value) {
resizeObserver = new ResizeObserver(handleResize);
resizeObserver.observe(ChartsBarLineRef.value);
}
});
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
if (resizeObserver && ChartsBarLineRef.value) {
resizeObserver.unobserve(ChartsBarLineRef.value);
}
if (echartsBar) {
echartsBar.dispose();
}
});
const echartsLoading = ref(true);
const initEcharts = () => {
nextTick(() => {
if (ChartsBarLineRef.value) {
echartsBar = echarts.init(ChartsBarLineRef.value, "macarons");
let option = getChartOption();
echartsBar.setOption(option);
//
const resizeChart = () => {
if (echartsBar && ChartsBarLineRef.value) {
echartsBar.resize({
width: ChartsBarLineRef.value.clientWidth,
height: ChartsBarLineRef.value.clientHeight
});
}
};
//
resizeChart();
}
});
};
const updateChart = () => {
nextTick(() => {
if (echartsBar) {
let option = getChartOption();
echartsBar.setOption(option, true); // 使notMerge:true
resizeChart();
}
});
};
const resizeChart = () => {
if (echartsBar && ChartsBarLineRef.value) {
echartsBar.resize({
width: ChartsBarLineRef.value.clientWidth,
height: ChartsBarLineRef.value.clientHeight
});
}
};
const handleResize = () => {
if (echartsBar && ChartsBarLineRef.value) {
//
clearTimeout(window.resizeTimer);
window.resizeTimer = setTimeout(() => {
echartsBar.resize({
width: ChartsBarLineRef.value.clientWidth,
height: ChartsBarLineRef.value.clientHeight,
animation: {
duration: 300
}
});
}, 100);
}
};
// 使 dayjs
const formatTimelineLabel = (s) => {
return dayjs(s).format('MM-DD');
};
// 使 dayjs X
const formatXAxisLabel = (value) => {
return dayjs(value).format('HH:mm');
};
// 使 dayjs tooltip
const formatTooltipDate = (dateValue) => {
return dayjs(dateValue).format('YYYY-MM-DD HH:mm');
};
// 使 dayjs tooltip
const formatTooltipDataDate = (dateValue) => {
const date = dayjs(dateValue);
return `${date.format('YYYY-MM-DD')} ${date.format('HH:mm')}`;
};
const getChartOption = () => {
let xAxisType = 'time';
let yAxisBoundaryGap = ['5%', '5%'];
if (props.echartType == 'bar') {
xAxisType = 'category';
yAxisBoundaryGap = [0, '5%'];
}
//
const CHART_COLORS = [
["#FA8072", "#B22222"],
["#0fec7d", "#04793e"],
["#ab36fc", "#7705a4"],
["#ffbd89", "#8a5c08"],
["#CD9B1D", "#8B6914"],
["#ff7f50", "#a93f07"],
["#EE1289", "#8B0A50"],
["#ee9c9c", "#755252"],
["#06e8d6", "#078075"],
["#de79c2", "#cd5c5c"],
["#00F5FF", "#6b8e23"],
["#f50000", "#590404"],
["#00CD66", "#3cb371"],
["#c400fa", "#48005d"],
["#eca86c", "#5e4310"],
["#bebe0f", "#8B8B00"]
];
let optionsData = props.baseOptionData.map((base, idx) => ({
series: props.seriesData.map((item, index) => {
const color = CHART_COLORS[index % CHART_COLORS.length];
return {
name: props.legendData[index],
type: 'line',
symbolSize: 0,
smooth: false,
lineStyle: {
width: 2,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: color[0] },
{ offset: 1, color: color[1] }
])
},
itemStyle: {
opacity: 0
},
markPoint: {
data: [
{ type: 'max', name: '最高值', label: { formatter: '{c}' } },
{ type: 'min', name: '最低值', label: { formatter: '{c}' } }
],
itemStyle: {
color: color[0]
},
label: {
color: '#fff',
}
},
data: item[idx]
};
})
}));
console.log(optionsData, 'optionsData')
let option = {
baseOption: {
color: CHART_COLORS,
timeline: {
axisType: 'category',
autoPlay: false,
playInterval: 2000,
data: props.baseOptionData,
label: {
formatter: formatTimelineLabel
},
lineStyle: {
color: "#464b50"
},
controlStyle: {
color: "#464b50",
borderColor: "#464b50"
},
bottom:'10%'
},
title: {
text: props.textTitle,
x: 'center',
textStyle: {
color: '#464b50',
fontSize: 16
}
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
shadowStyle: {
color: "rgba(133,131,131,0.3)"
}
},
backgroundColor: 'rgba(255,255,255,1)',
padding: [5, 10],
textStyle: {
color: '#7588E4',
align: 'left'
},
extraCssText: 'box-shadow: 0 0 5px rgba(0,0,0,0.3)',
formatter: function (params) {
const dateValue = params[0].data[0];
const formattedDate = formatTooltipDataDate(dateValue);
let text = formattedDate + '<br/>';
for (let i = 0; i < params.length; i++) {
text += `<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${params[i].color}"></span>`
text += params[i].seriesName + " : " + params[i].data[1] + '<br/>';
}
return text;
}
},
legend: {
data: props.legendData,
right: 10,
top: 20,
textStyle: {
color: "#333"
},
itemWidth: 15,
itemHeight: 8,
},
grid: props.grid,
toolbox: {
show: true,
feature: {
mark: { show: true },
restore: { iconStyle: { borderColor: '#000' } },
saveAsImage: { iconStyle: { borderColor: '#000' } }
},
y: 'center',
orient: 'vertical'
},
xAxis: [
{
type: 'time',
boundaryGap: true,
axisLabel: {
formatter: formatXAxisLabel,
textStyle: {
color: '#606e7a'
}
},
axisLine: {
lineStyle: {
color: '#b3b6b9'
}
}
}
],
yAxis: [
{
type: 'value',
axisLabel: {
textStyle: {
color: "#606e7a",
},
formatter: function (value, index) {
return value.toFixed(props.fixed);
}
},
name: props.unit,
nameLocation: 'middle',
nameGap: 50,
nameTextStyle: {
color: '#464b50'
},
scale: true,
boundaryGap: ['5%', '5%'],
axisLine: {
show: true,
lineStyle: {
color: '#b3b6b9'
}
}
}
],
series: []
},
options: optionsData
};
return option;
};
</script>
<style scoped>
.chart-container {
width: 100%;
height: 100%;
min-height: 300px;
position: relative;
}
</style>

32
src/components/ZhengBian/index.vue

@ -68,7 +68,8 @@
</pane> </pane>
<pane :size="100 - firstSize"> <pane :size="100 - firstSize">
<div v-table-height='{bottom:0}' style="width:100%;"> <div v-table-height='{bottom:0}' style="width:100%;">
<TimeBarChart v-loading="echartsLoading" :timeType="timeType" :legendData='legendData' :xAxisData="xAxisData" :seriesData="seriesData" :textTitle="textTitle" :unit="unit" :echartType="echartType" /> <TimeBarChart v-if="stationType !== 'A' && staticType == '1'" v-loading="echartsLoading" :timeType="timeType" :legendData='legendData' :xAxisData="xAxisData" :seriesData="seriesData" :textTitle="textTitle" :unit="unit" :baseOptionData='baseOptionData' :key="`${staticType}-${props.stationType}`" :fixed="fixed"/>
<DataZoomChart v-else v-loading="echartsLoading" :timeType="timeType" :legendData='legendData' :xAxisData="xAxisData" :seriesData="seriesData" :textTitle="textTitle" :unit="unit" :echartType="echartType" :key="`${staticType}-${props.stationType}`" />
</div> </div>
</pane> </pane>
</splitpanes> </splitpanes>
@ -121,7 +122,8 @@
Pane Pane
} from 'splitpanes' } from 'splitpanes'
import 'splitpanes/dist/splitpanes.css' import 'splitpanes/dist/splitpanes.css'
import TimeBarChart from '@/components/ChartsDataZoom/index.vue' import DataZoomChart from '@/components/ChartsDataZoom/index.vue'
import TimeBarChart from '@/components/ChartsTimeLine/index.vue'
import ESelectSingle from '@/components/ESelectSingle/index.vue' import ESelectSingle from '@/components/ESelectSingle/index.vue'
import { getToken } from "@/utils/auth"; import { getToken } from "@/utils/auth";
import useAppStore from '@/store/modules/app' import useAppStore from '@/store/modules/app'
@ -180,7 +182,6 @@
return options; return options;
}); });
const textTitle = computed(() => { const textTitle = computed(() => {
switch (props.stationType) { switch (props.stationType) {
case 'A': case 'A':
@ -509,8 +510,13 @@
const legendData = ref([]) const legendData = ref([])
const xAxisData = ref([]) const xAxisData = ref([])
const seriesData = ref([]) const seriesData = ref([])
const baseOptionData = ref([])
const echartsLoading = ref(false) const echartsLoading = ref(false)
const getEchartsData = async () => { const getEchartsData = async () => {
legendData.value = []
seriesData.value = []
baseOptionData.value = []
xAxisData.value = []
echartsLoading.value = true echartsLoading.value = true
let baseUrl = '/chartdata' let baseUrl = '/chartdata'
if (staticType.value == '1' && props.stationType != 'A') { if (staticType.value == '1' && props.stationType != 'A') {
@ -521,6 +527,17 @@
let res = await proxy.axiosPost2(url, queryParams); let res = await proxy.axiosPost2(url, queryParams);
if (res.code === 0) { if (res.code === 0) {
legendData.value = res.data.legend legendData.value = res.data.legend
if (props.stationType !== 'A' && staticType.value == '1') {
seriesData.value = res.data.data
baseOptionData.value = res.data.baseOptionData
xAxisData.value = ['08:00', '09:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00', '21:00', '22:00', '23:00', '00:00', '01:00', '02:00', '03:00', '04:00', '05:00', '06:00', '07:00', '08:00']
console.log(props.stationType, staticType.value,)
console.log('seriesData.value', seriesData.value)
console.log('baseOptionData.value', baseOptionData.value)
console.log('xAxisData.value', xAxisData.value)
} else {
// seriesdata // seriesdata
if (res.data.series && res.data.series.length > 0) { if (res.data.series && res.data.series.length > 0) {
// seriesdata // seriesdata
@ -538,6 +555,7 @@
} }
seriesData.value = res.data.series seriesData.value = res.data.series
} }
}
} catch (error) { } catch (error) {
console.log(error) console.log(error)
} finally { } finally {
@ -545,7 +563,15 @@
} }
}; };
watch(staticType.value, (newVal, oldVal) => {
if (oldVal !== undefined) { //
// dataType
queryParams.dataType = newVal
//
getEchartsData()
}
})
// //
const yclExport = () => { const yclExport = () => {
let url = `${props.requestPrefix}/exportoriginaldata?stnmId=${queryParams.stnmId}&startTime=${queryParams.startTime}&endTime=${queryParams.endTime}` let url = `${props.requestPrefix}/exportoriginaldata?stnmId=${queryParams.stnmId}&startTime=${queryParams.startTime}&endTime=${queryParams.endTime}`

Loading…
Cancel
Save