<template>
|
<div shadow="hover" class="flex-auto scroll-table-card">
|
<titleBox :title="state.selectSinalInfo?.LogicalName">
|
<template v-slot:right>
|
<div class="titleBoxRightSlot">
|
开始/结束日期:
|
<el-date-picker
|
v-model="state.themetime"
|
range-separator="~"
|
start-placeholder="开始日期"
|
end-placeholder="结束日期"
|
:disabled-date="disablesDate"
|
type="daterange"
|
:default-time="defaultTime"
|
clearable
|
value-format="YYYY-MM-DD HH:mm:ss"
|
@change="getDateTime"
|
/>
|
|
<el-button class="ml10 mb5" type="primary" @click="timeQuery(1)" :disabled="queryDisabled">查询</el-button>
|
</div>
|
</template>
|
</titleBox>
|
<div style="width: 100%; height: 100%" v-loading="state.lineChartLoading">
|
<div id="chartMain" style="width: 100%; height: calc(100% - 30px)"></div>
|
</div>
|
</div>
|
</template>
|
|
<script setup lang="ts">
|
import titleBox from '/@/components/titleBox.vue';
|
import { reactive, onMounted, ref, nextTick, toRefs, shallowRef } from 'vue';
|
import * as echarts from 'echarts';
|
import moment from 'moment';
|
import { ElMessage } from 'element-plus';
|
import { GetLimitBySignalIDOfTimeRange, GetDisplayParasByID } from '/@/api/monitor/rangeHistory';
|
const myChart = shallowRef(null);
|
const defaultTime = ref<[Date, Date]>([new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]);
|
// 定义变量内容
|
const state = reactive({
|
themetime: '' as any,
|
loadingPumpStationTree: false,
|
treeDataLoading: false,
|
queryBtn: false,
|
option: null,
|
lineChartLoading: true,
|
queryDisabled: false,
|
chartData: [], //获取图表的data
|
getFormatJsonInfo: {
|
FormatType: '' as any,
|
DisplayParas: {
|
UnitValue: '',
|
DecimalPlaces: '',
|
BreakSpace: '',
|
AxisCoord: '',
|
AxisLabels: '',
|
},
|
} as any, //获取参数
|
selectSignalName: '',
|
selectSinalInfo: {} as any,
|
});
|
//#region ====================== 参数传参 ======================
|
const props = defineProps({
|
selectDataInfo: {
|
type: Object,
|
},
|
request: {
|
type: Function,
|
},
|
queryDisabled: {
|
type: Boolean,
|
default: false,
|
},
|
});
|
let { selectDataInfo, queryDisabled } = toRefs(props);
|
//#endregion
|
// 页面加载时
|
onMounted(async () => {
|
state.themetime = getdatatime();
|
window.addEventListener('resize', selfAdaption);
|
});
|
//#region ====================== 时间事件 ======================
|
// 时间限制
|
const disablesDate = (time) => {
|
return time.getTime() > new Date().getTime();
|
};
|
//默认时间选择前7天/默认选择当天
|
const getdatatime = () => {
|
let sevenAgo = moment(new Date()).subtract(7, 'days').startOf('day').format('YYYY-MM-DD HH:mm:ss');
|
let today = moment().endOf('day').format('YYYY-MM-DD HH:mm:ss');
|
return [sevenAgo, today];
|
};
|
//获取日期的时间
|
const getDateTime = (val) => {
|
state.themetime[0] = val[0];
|
state.themetime[1] = val[1];
|
if (!queryDisabled.value) {
|
getChartList();
|
}
|
};
|
//查询时间
|
const timeQuery = (type) => {
|
getChartList();
|
};
|
//#endregion
|
//#region ====================== init 图表 ======================
|
//清空图表
|
const clearEChartData = () => {
|
setTimeout(() => {
|
ElMessage.warning('该区间暂无数据');
|
myChart.value &&
|
myChart.value.setOption({
|
xAxis: {
|
min: '',
|
max: '',
|
},
|
yAxis: [],
|
series: [
|
{
|
data: [],
|
},
|
],
|
});
|
}, 300);
|
return;
|
};
|
const getTableData = () => {
|
state.selectSinalInfo = selectDataInfo.value;
|
getFormatJson();
|
};
|
//获取格式显示参数
|
const getFormatJson = async () => {
|
myChart.value && myChart.value.clear();
|
state.lineChartLoading = true;
|
let res = await GetDisplayParasByID(
|
{
|
ID: state.selectSinalInfo.LogicalID,
|
},
|
props.request
|
);
|
|
if (res.Code != 0) {
|
return;
|
}
|
if (res.Data == null || res.Data == '') {
|
return;
|
}
|
state.getFormatJsonInfo = res.Data;
|
state.getFormatJsonInfo.DisplayParas.UnitValue = res.Data.DisplayParas.UnitName;
|
getChartList();
|
};
|
//获取data数据列表
|
const getChartList = async () => {
|
myChart.value && myChart.value.clear();
|
let res = await GetLimitBySignalIDOfTimeRange(
|
{
|
Limit: 10000,
|
SignalID: state.selectSinalInfo.LogicalID,
|
StartTime: state.themetime[0],
|
EndTime: state.themetime[1],
|
},
|
props.request
|
);
|
state.lineChartLoading = false;
|
if (res.Code != 0) {
|
return;
|
}
|
if (res.Data == null || res.Data == '') {
|
clearEChartData();
|
}
|
|
state.chartData = res.Data || [];
|
if (state.getFormatJsonInfo.FormatType == 1) {
|
setTimeout(() => {
|
initChart();
|
}, 100);
|
}
|
if (state.getFormatJsonInfo.FormatType == 2) {
|
setTimeout(() => {
|
formatBar();
|
}, 100);
|
}
|
};
|
// 初始化chart
|
const initChart = () => {
|
myChart.value && myChart.value.clear();
|
//先获取Dom上的实例
|
let chartDom = echarts.getInstanceByDom(document.getElementById('chartMain') as HTMLDivElement);
|
//然后判断实例是否存在,如果不存在,就创建新实例
|
if (chartDom == null) {
|
chartDom = echarts.init(document.getElementById('chartMain') as HTMLDivElement);
|
myChart.value = chartDom;
|
}
|
let x_yData = [];
|
state.chartData.forEach((item) => {
|
x_yData.push([item.DataTime, item.DataValue]);
|
});
|
let series_arr = [];
|
if (state.getFormatJsonInfo.FormatType == 1) {
|
series_arr.push({
|
type: 'line',
|
showSymbol: false,
|
emphasis: { scale: false },
|
data: x_yData,
|
itemStyle: {
|
color: '#4169E1',
|
},
|
});
|
}
|
let option = {
|
tooltip: {
|
trigger: 'axis',
|
},
|
toolbox: {
|
show: true,
|
feature: {
|
dataZoom: {
|
yAxisIndex: 'none',
|
},
|
dataView: { readOnly: false },
|
magicType: { type: ['line', 'bar'] },
|
restore: {},
|
saveAsImage: {},
|
},
|
},
|
xAxis: {
|
type: 'category',
|
axisLabel: {
|
showMaxLabel: true,
|
formatter: function (value) {
|
//在这里写你需要的时间格式
|
var t_date = new Date(value);
|
return [t_date.getFullYear(), t_date.getMonth() + 1, t_date.getDate()].join('-');
|
},
|
},
|
name: '时间',
|
// axisLine: { onZero: true, show: true },
|
minorTick: {
|
show: false,
|
splitNumber: 2,
|
},
|
splitLine: {
|
show: true, //是否显示分隔线
|
interval: 'auto', //坐标轴分隔线的显示间隔
|
},
|
},
|
yAxis: {
|
boundaryGap: ['20%', '20%'],
|
name: state.getFormatJsonInfo.DisplayParas.UnitValue,
|
type: 'value',
|
axisLabel: {
|
formatter: '{value}',
|
},
|
min: 0,
|
// 整条y轴
|
axisLine: {
|
show: true,
|
},
|
// y轴上的小横线
|
axisTick: {
|
show: true,
|
},
|
},
|
dataZoom: [
|
{
|
type: 'inside',
|
start: 0,
|
end: 100,
|
},
|
{
|
id: 'dataZoomY',
|
type: 'slider',
|
xAxisIndex: [0],
|
filterMode: 'empty',
|
},
|
],
|
series: series_arr,
|
};
|
|
myChart.value.setOption(option);
|
setTimeout(() => {
|
state.lineChartLoading = false;
|
}, 3000);
|
selfAdaption();
|
};
|
//#endregion
|
//#region ====================== 文本图表 ======================
|
|
const getFormatData4Enum = (arr) => {
|
var temp = arr[0];
|
var formatData = [];
|
for (var i = 0; i < arr.length - 1; i++) {
|
//var node = arr[i];
|
if (arr[i].DataValue != arr[i + 1].DataValue) {
|
var duration = ((+new Date(arr[i + 1].DataTime) - +new Date(temp.DataTime)) / 1000 / 60 / 60).toFixed(2);
|
formatData.push({ StartTime: temp.DataTime, EndTime: arr[i + 1].DataTime, Status: temp.DataValue, Duration: duration });
|
temp = arr[i + 1];
|
}
|
if (i == arr.length - 2) {
|
var len = arr.length - 1;
|
let duration = null;
|
duration = Math.round(((+new Date(arr[len].DataTime) - +new Date(temp.DataTime)) / 1000 / 60 / 60) * 100) / 100;
|
formatData.push({ StartTime: temp.DataTime, EndTime: arr[len].DataTime, Status: temp.DataValue, Duration: duration });
|
}
|
}
|
return formatData;
|
};
|
//文本图
|
const formatBar = () => {
|
myChart.value && myChart.value.clear();
|
//先获取Dom上的实例
|
let chartDom = echarts.getInstanceByDom(document.getElementById('chartMain') as HTMLDivElement);
|
//然后判断实例是否存在,如果不存在,就创建新实例
|
if (chartDom == null) {
|
chartDom = echarts.init(document.getElementById('chartMain') as HTMLDivElement);
|
myChart.value = chartDom;
|
}
|
var formatData = getFormatData4Enum(state.chartData); //数据转换
|
const series_data_enum = [];
|
const getParamsList = state.getFormatJsonInfo.DisplayParas.Items;
|
formatData.forEach((item) => {
|
getParamsList.forEach((paramsItem) => {
|
if (paramsItem.EnumName == item.Status) {
|
series_data_enum.push({
|
name: state.selectSinalInfo.LogicalName,
|
value: [
|
0,
|
+new Date(item.StartTime) - 0,
|
+new Date(item.EndTime) - 0,
|
item.Status,
|
item.Duration,
|
{ id: state.selectSinalInfo.LogicalID, name: state.selectSinalInfo.LogicalName },
|
],
|
itemStyle: {
|
color: paramsItem.DisplayColor,
|
},
|
});
|
}
|
});
|
});
|
|
let option = {
|
tooltip: {
|
show: true,
|
formatter: function (params) {
|
return (
|
params.marker +
|
params.name +
|
': ' +
|
params.value[4] +
|
'小时' +
|
'<br/> ' +
|
'开始时间: ' +
|
new Date(params.value[1]).getHours() +
|
':' +
|
new Date(params.value[1]).getMinutes() +
|
'<br/> ' +
|
'结束时间: ' +
|
new Date(params.value[2]).getHours() +
|
':' +
|
new Date(params.value[2]).getMinutes()
|
);
|
},
|
},
|
title: {
|
text: '',
|
left: 'center',
|
},
|
legend: {
|
data: [],
|
},
|
grid: {
|
containLabel: true,
|
x: '25',
|
y: '65',
|
x2: '60',
|
y2: '90',
|
},
|
axisPointer: {
|
link: { xAxisIndex: 'all' },
|
},
|
xAxis: [
|
{
|
name: '时间',
|
type: 'time',
|
axisLabel: {
|
show: true,
|
formatter: function (val) {
|
let date = moment(val).format('MM-DD');
|
return date;
|
},
|
},
|
axisLine: { onZero: true, show: true },
|
splitLine: {
|
show: true,
|
},
|
axisTick: {
|
// 轴刻度
|
show: true,
|
},
|
},
|
],
|
yAxis: [
|
{
|
inverse: true,
|
triggerEvent: true,
|
data: [state.selectSinalInfo.LogicalName],
|
},
|
],
|
dataZoom: [
|
{
|
type: 'inside',
|
start: 0,
|
end: 100,
|
},
|
{
|
start: 0,
|
end: 100,
|
},
|
],
|
series: [
|
{
|
type: 'custom',
|
renderItem: renderItemFunc,
|
itemStyle: {
|
opacity: 0.8,
|
},
|
encode: {
|
x: [1, 2],
|
y: 0,
|
},
|
data: series_data_enum,
|
},
|
],
|
};
|
myChart.value.setOption(option);
|
selfAdaption();
|
};
|
//自定义图表方法
|
function renderItemFunc(params, api) {
|
var categoryIndex = api.value(0);
|
var start = api.coord([api.value(1), categoryIndex]);
|
var end = api.coord([api.value(2), categoryIndex]);
|
var height = api.size([0, 1])[1] * 0.6 < 40 ? api.size([0, 1])[1] * 0.6 : 40;
|
var barLength = end[0] - start[0];
|
var runtime = api.value(3) + ':' + api.value(4) + 'h';
|
var flightNumberWidth = echarts.format.getTextRect(runtime).width;
|
var text = runtime;
|
text = barLength > flightNumberWidth ? text : '';
|
|
var rectShape = echarts.graphic.clipRectByRect(
|
{
|
x: start[0],
|
y: start[1] - height / 2,
|
width: end[0] - start[0],
|
height: height,
|
},
|
{
|
x: params.coordSys.x,
|
y: params.coordSys.y,
|
width: params.coordSys.width,
|
height: params.coordSys.height,
|
}
|
);
|
|
return {
|
type: 'rect',
|
shape: rectShape,
|
style: {
|
...api.style(),
|
text: text,
|
textFill: '#fff',
|
},
|
};
|
}
|
// 自适应
|
const selfAdaption = () => {
|
if (!myChart.value) return;
|
myChart.value.resize();
|
};
|
//#endregion
|
// 导出对象
|
defineExpose({ getTableData, clearEChartData });
|
</script>
|
<style scoped lang="scss">
|
.titleBoxRightSlot {
|
width: 100%;
|
}
|
</style>
|