407 lines
11 KiB
Vue
407 lines
11 KiB
Vue
<template>
|
||
<view class="statistic-wrap">
|
||
<view class="statistic-title">
|
||
<view class="slave-wrap" v-if="isSubDev">
|
||
<uni-data-select :placeholder="$tt('deviceStatic.selectSub')" v-model="queryParams.slaveId"
|
||
:localdata="slaveList" @change="handleSlavechange" :clear="false"></uni-data-select>
|
||
</view>
|
||
<view class="time-wrap" @click="openCalendar">
|
||
<!-- #ifndef APP-NVUE -->
|
||
<u-input v-model="dateRangeText" :placeholder="$tt('deviceStatic.rangeTime')" prefixIcon="search"
|
||
prefixIconStyle="color: #909399" readonly :disabled="statisticList.length === 0"
|
||
customStyle="height:20px;">
|
||
<!-- #endif -->
|
||
<!-- #ifdef APP-NVUE -->
|
||
<u--input v-model="dateRangeText" :placeholder="$tt('deviceStatic.rangeTime')" prefixIcon="search"
|
||
prefixIconStyle="color: #909399" readonly :disabled="statisticList.length === 0"
|
||
customStyle="height:20px;">
|
||
<!-- #endif -->
|
||
<template slot="suffix">
|
||
<u-button :text="$tt('deviceStatic.search')" type="primary" size="mini"
|
||
@click="handleSearchTap()"></u-button>
|
||
</template>
|
||
<!-- #ifndef APP-NVUE -->
|
||
</u-input>
|
||
<!-- #endif -->
|
||
<!-- #ifdef APP-NVUE -->
|
||
</u--input>
|
||
<!-- #endif -->
|
||
<u-calendar :title="$tt('deviceStatic.selectTime')" :show="isShowCalendar" monthNum="12"
|
||
:minDate="getDate(-12)" mode="range" :defaultDate="defaultDateRange"
|
||
@confirm="handleCalendarConfirm" @close="handleCalendarClose"></u-calendar>
|
||
</view>
|
||
</view>
|
||
<view v-if="statisticList.length !== 0" class="charts-box" v-for="(chart, index) in monitorChart" :key="index">
|
||
<qiun-data-charts type="area" :canvas2d="true" :opts="chart.opts" :chartData="chart.data" :ontouch="true"
|
||
:onzoom="true" tooltipFormat="tooltipStatistic" />
|
||
</view>
|
||
|
||
<u-empty mode="data" :show="statisticList.length === 0" marginTop="30"></u-empty>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import {
|
||
getDeviceHistory
|
||
} from '@/apis/modules/deviceLog.js';
|
||
|
||
export default {
|
||
name: 'device-statistics',
|
||
props: {
|
||
device: {
|
||
type: Object,
|
||
default: null,
|
||
require: true,
|
||
},
|
||
type: Number
|
||
},
|
||
watch: {
|
||
device: function (newVal, oldVal) {
|
||
this.deviceInfo = newVal;
|
||
this.isSubDev = newVal.subDeviceList && newVal.subDeviceList.length > 0;
|
||
if (newVal.deviceType === 1) {
|
||
this.slaveList = this.getSlaveDatas(newVal.subDeviceList);
|
||
}
|
||
|
||
// 监测数据
|
||
if (this.isSubDev) {
|
||
const slaveId = this.slaveList[0] && this.slaveList[0].value;
|
||
this.queryParams.slaveId = slaveId;
|
||
this.preSlaveId = slaveId;
|
||
this.queryParams.serialNumber = newVal.subDeviceList[0].serialNumber;
|
||
this.statisticList = newVal.cacheThingsModel["properties"] && newVal.cacheThingsModel["properties"]
|
||
.filter(item => {
|
||
return item.tempSlaveId == this.queryParams.slaveId;
|
||
}) || [];
|
||
} else {
|
||
this.queryParams.serialNumber = newVal.serialNumber;
|
||
this.statisticList = newVal.statisticList || [];
|
||
}
|
||
},
|
||
type (val) {
|
||
if (val === 3) {
|
||
this.getData();
|
||
}
|
||
}
|
||
},
|
||
computed: {
|
||
dateRangeText: {
|
||
get() {
|
||
if (this.queryParams.beginTime && this.queryParams.beginTime != '') {
|
||
return this.queryParams.beginTime + ' - ' + this.queryParams.endTime;
|
||
}
|
||
return '';
|
||
},
|
||
set(val) {}
|
||
}
|
||
},
|
||
data () {
|
||
const beginTime = uni.$u.timeFormat((new Date().getTime() - 3600 * 1000 * 24), 'yyyy-mm-dd');
|
||
const endTime = uni.$u.timeFormat(new Date(), 'yyyy-mm-dd');
|
||
return {
|
||
// 图表数据集合
|
||
monitorChart: [{
|
||
name: ''
|
||
}],
|
||
// 查询参数
|
||
queryParams: {
|
||
serialNumber: '',
|
||
slaveId: '',
|
||
beginTime: beginTime,
|
||
endTime: endTime
|
||
},
|
||
defaultDateRange: [beginTime, endTime],
|
||
// 子设备
|
||
isSubDev: false,
|
||
slaveList: [],
|
||
preSlaveId: '',
|
||
// 时间范围组件显示
|
||
isShowCalendar: false,
|
||
// 监控物模型
|
||
statisticList: [],
|
||
// 设备信息
|
||
deviceInfo: {},
|
||
};
|
||
},
|
||
methods: {
|
||
// 打开日期范围组件
|
||
openCalendar () {
|
||
if (this.monitorChart.length > 0) {
|
||
this.isShowCalendar = true;
|
||
}
|
||
},
|
||
// 关闭日期范围组件
|
||
handleCalendarClose () {
|
||
this.isShowCalendar = false;
|
||
},
|
||
// 确定选择日期范围
|
||
handleCalendarConfirm (data) {
|
||
if (null != data[0] && '' != data[0]) {
|
||
this.queryParams.beginTime = data[0];
|
||
this.queryParams.endTime = data[data.length - 1];
|
||
}
|
||
this.isShowCalendar = false;
|
||
},
|
||
// 查询
|
||
handleSearchTap () {
|
||
// chart 组件问题,需要自己控制是清除还是重新初始化图表
|
||
if (this.preSlaveId === this.queryParams.slaveId) {
|
||
this.clearChart();
|
||
} else {
|
||
this.initChart();
|
||
}
|
||
this.getHistory();
|
||
event.stopPropagation();
|
||
},
|
||
// 清除
|
||
handleClearTap () {
|
||
this.queryParams.beginTime = null;
|
||
this.queryParams.endTime = null;
|
||
if (this.isSubDev) {
|
||
this.handleSlavechange(this.slaveList[0].value)
|
||
}
|
||
},
|
||
// 获取当前日期
|
||
getDate (month) {
|
||
let date = new Date();
|
||
let y = date.getFullYear();
|
||
let m = date.getMonth() + 1 + month;
|
||
let d = date.getDate();
|
||
m = m < 10 ? '0' + m : m;
|
||
d = d < 10 ? '0' + d : d;
|
||
return y + '-' + m + '-' + d;
|
||
},
|
||
// 获取统计数据
|
||
getData () {
|
||
this.initChart(); // 初始化图表
|
||
this.getHistory(); // 获取统计数据
|
||
uni.stopPullDownRefresh();
|
||
},
|
||
// 获取统计数据
|
||
getHistory () {
|
||
const {
|
||
beginTime,
|
||
endTime,
|
||
...pres
|
||
} = this.queryParams;
|
||
const params = {
|
||
...pres,
|
||
beginTime: beginTime + ' 23:59',
|
||
endTime: endTime + ' 23:59'
|
||
};
|
||
getDeviceHistory(params).then(res => {
|
||
for (let i = 0; i < this.statisticList.length; i++) {
|
||
let obj = {
|
||
categories: [],
|
||
series: [{
|
||
name: this.statisticList[i].name + '(单位 ' + (this
|
||
.statisticList[i]
|
||
.datatype.unit != undefined ? this.statisticList[i]
|
||
.datatype.unit : '无') + ')',
|
||
data: []
|
||
}],
|
||
};
|
||
for (let key in res.data) {
|
||
if (key === this.statisticList[i].id) {
|
||
for (let j = 0; j < res.data[key].length; j++) {
|
||
obj.categories.push(res.data[key][j].time);
|
||
obj.series[0].data.push(Number(res.data[key][j].value));
|
||
}
|
||
}
|
||
}
|
||
let data = JSON.parse(JSON.stringify(obj));
|
||
this.monitorChart[i].data = data;
|
||
};
|
||
|
||
// 数据请求成功后更新preSlaveId
|
||
this.preSlaveId = this.queryParams.slaveId;
|
||
})
|
||
},
|
||
// 初始化图表
|
||
initChart () {
|
||
let color = ['#1890FF', '#91CB74', '#FAC858', '#EE6666', '#73C0DE', '#3CA272', '#FC8452', '#9A60B4',
|
||
'#ea7ccc'
|
||
];
|
||
this.monitorChart = [];
|
||
for (let i = 0; i < this.statisticList.length; i++) {
|
||
// data里面设置值是因为如果不加这个设置了最大最小值,第一次加载数据Y轴最大最小无法生效
|
||
let data = {
|
||
categories: [],
|
||
series: [{
|
||
name: '',
|
||
data: []
|
||
}],
|
||
};
|
||
let opts = {
|
||
// 自定义名称和单位,用于图表提示框显示
|
||
name: this.statisticList[i].name,
|
||
unit: this.statisticList[i].datatype.unit,
|
||
timing: 'easeOut',
|
||
color: [color[i % color.length]],
|
||
padding: [15, 15, 0, 15],
|
||
fontSize: 12,
|
||
fontColor: '#666666',
|
||
dataLabel: false, //是否显示值
|
||
dataPointShape: true,
|
||
dataPointShapeType: 'solid',
|
||
touchMoveLimit: 60,
|
||
enableScroll: true,
|
||
enableMarkLine: false,
|
||
update: true,
|
||
legend: {
|
||
show: true,
|
||
position: 'bottom',
|
||
float: 'center',
|
||
padding: 5,
|
||
margin: 5,
|
||
backgroundColor: 'rgba(0,0,0,0)',
|
||
borderColor: 'rgba(0,0,0,0)',
|
||
borderWidth: 0,
|
||
fontSize: 14,
|
||
fontColor: '#333333',
|
||
lineHeight: 16,
|
||
hiddenColor: '#CECECE',
|
||
itemGap: 10
|
||
},
|
||
xAxis: {
|
||
disableGrid: true,
|
||
disabled: true, // 隐藏分类名称
|
||
axisLine: true,
|
||
axisLineColor: '#CCCCCC',
|
||
calibration: false,
|
||
fontColor: '#666666',
|
||
fontSize: 13,
|
||
rotateLabel: false,
|
||
rotateAngle: 45,
|
||
itemCount: 100,
|
||
boundaryGap: 'justify',
|
||
splitNumber: 5,
|
||
gridColor: '#CCCCCC',
|
||
gridType: 'solid',
|
||
dashLength: 1,
|
||
gridEval: 1,
|
||
scrollShow: false,
|
||
scrollAlign: 'right',
|
||
scrollColor: '#A6A6A6',
|
||
scrollBackgroundColor: '#ccc',
|
||
format: ''
|
||
},
|
||
yAxis: {
|
||
gridType: 'dash',
|
||
dashLength: 2,
|
||
disabled: false,
|
||
tofix: 3, // 刻度保留小数位数
|
||
disableGrid: false,
|
||
splitNumber: 5,
|
||
gridColor: '#CCCCCC',
|
||
padding: 10,
|
||
showTitle: false,
|
||
max: this.statisticList[i].datatype.max,
|
||
min: this.statisticList[i].datatype.min,
|
||
data: [],
|
||
},
|
||
extra: {
|
||
area: {
|
||
type: 'curve',
|
||
opacity: 0.5,
|
||
addLine: true,
|
||
width: 1,
|
||
gradient: false
|
||
},
|
||
tooltip: {
|
||
showBox: true,
|
||
showArrow: true,
|
||
showCategory: true,
|
||
borderWidth: 0,
|
||
borderRadius: 0,
|
||
borderColor: '#000000',
|
||
borderOpacity: 0.7,
|
||
bgColor: '#000000',
|
||
bgOpacity: 0.7,
|
||
gridType: 'solid',
|
||
dashLength: 4,
|
||
gridColor: '#CCCCCC',
|
||
fontColor: '#FFFFFF',
|
||
splitLine: true,
|
||
horizentalLine: false,
|
||
xAxisLabel: false,
|
||
yAxisLabel: false,
|
||
labelBgColor: '#FFFFFF',
|
||
labelBgOpacity: 0.7,
|
||
labelFontColor: '#666666'
|
||
},
|
||
markLine: {
|
||
type: 'solid',
|
||
dashLength: 2,
|
||
data: []
|
||
}
|
||
}
|
||
};
|
||
this.monitorChart.push({
|
||
opts: opts,
|
||
data: data,
|
||
show: false,
|
||
id: this.statisticList[i].id
|
||
});
|
||
}
|
||
},
|
||
// 清空图标
|
||
clearChart () {
|
||
for (let i = 0; i < this.monitorChart.length; i++) {
|
||
this.monitorChart[i].data.series[0].data = [];
|
||
this.monitorChart[i].data.categories = [];
|
||
this.monitorChart[i].show = true;
|
||
}
|
||
},
|
||
// 获取子设备列表数据
|
||
getSlaveDatas (data) {
|
||
if (data != undefined) {
|
||
return data.map(item => ({
|
||
value: item.slaveId,
|
||
text: `${item.deviceName}(从机地址:${item.slaveId})`
|
||
}));
|
||
}
|
||
},
|
||
// 从机选择
|
||
handleSlavechange (value) {
|
||
this.statisticList = this.deviceInfo.cacheThingsModel["properties"].filter(item => {
|
||
return item.tempSlaveId === value;
|
||
});
|
||
this.queryParams.slaveId = value;
|
||
this.queryParams.serialNumber = this.deviceInfo.subDeviceList.find(item => item.slaveId === value)
|
||
.serialNumber;
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
.statistic-wrap {
|
||
|
||
.statistic-title {
|
||
padding: 0px 10px 10px 10px;
|
||
background-color: #ffffff;
|
||
|
||
.slave-wrap {
|
||
padding-top: 10px;
|
||
}
|
||
|
||
.time-wrap {
|
||
padding-top: 10px;
|
||
}
|
||
|
||
.search-wrap {
|
||
padding-top: 10px;
|
||
}
|
||
}
|
||
|
||
/* 请根据实际需求修改父元素尺寸,组件自动识别宽高 */
|
||
.charts-box {
|
||
width: 100%;
|
||
height: 230px;
|
||
background-color: #ffffff;
|
||
padding: 10px 0;
|
||
margin-top: 10px;
|
||
}
|
||
}
|
||
</style> |