vue实现表计监测界面
已经好几个月没有更新博客了,因为最近太忙,忙得连写博客的时间都没有。上班赶项目开启996模式,下班要去练车考驾照,一边还在赶书稿,一边还接了私活。不由得感叹:年纪大了,再也经不起那么折腾.....
每个人的时间都很宝贵,谁也没有义务去分享知识,但正是由于有那么一群爱分享的程序员,我们工作中遇到许多问题时才能迎刃而解,所以我还是愿意做个乐于分享的人,不管分享的东西对他人是否有帮助,至少敢于亮剑。有些人经常看别人分享东西,去学习别人的东西,自己却从来不分享,这也无可厚非,可如果自己从不分享又对别人的东西一脸不屑和肆意贬低,这就感觉人品就有问题了。对你没用的东西你大可以选择不看嘛!只有经常写文章的人,才知道写一篇出来是多不的不易!不是每一个人都像我脸皮这么厚的。
刚转到前端组就接手一些一眼看上去让我一脸懵逼的工作,诸如画电表电路图界面,自定义报表界面(就是在浏览器端操作excel一样),还有下面的表计监测界面。我又开始怀疑个人IQ了,每一个界面我都想了半天才开始动手,是我不适合做前端还是界面真的很难做,我又开始怀疑自己,怀疑人生了。
我发现很有意思的一件事情,刚出来工作时,要做什么东西,往往是做了再想,后来是边做边想,现在做东西却是先想再做,有时候想问题花的时间比做花的时间更多。
需求和解决思路
需求:一个交换机中心下面有N 采集器,每一个采集器下面有N个电表,电表下面有N个支路。电表和采集器有两种状态:正常和中断,用不同的颜色区分。采集器的数目是根据所选择的项目动态变化的。每一个项目下都只有一个交换机中心。
其它需求:支路列表中,左侧实心椭圆用不同颜色表示支路的在线状态,右侧空心椭圆根据边框的颜色不同表示不同的在线率。界面文字超出部分用省略号表示,鼠标移动上去,显示完整文字。
思路:交换机只有一个,找个交换机图片,将其位置固定。那么实际变化的,是根据项目变换采集器数据,有几个采集器就有几根连线。采集器用一个图片表示,这个图片的宽度,我们可以将其指定。这样一来,我们只要动态计算线的位置就可以了,而线条直接可以用css样式来渲染。难点在交换机和采集器最左边的那条连线,因为它会根据采集器数据的编号,位置会有变化,交换机下面的连线按比例来画,1根,在50%的位置,两根最左边那根线在25%的位置,以此类推。
画线,可以利用dom结构的边框,也可以通过使用伪类content,当然也可以采用H5画图,个人感觉H5画图那种方式太过复杂,对计算要求太高,所以为了项目进度我果断抛弃了。
技术场景:vue组件化+element+HTML5
下面看一下几种界面场景:
第一种
JSON数据:
{
"data": {
"array": [{
"collectorStatus": ,
"collectorOnlineRate": "98.97",
"collectorId": ,
"coms": [{
"comId": ,
"comName": "com1",
"branches": [{
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.0,
"branchName": "电梯",
"onlineRate": "",
"status":
}]
}, {
"comId": ,
"comName": "com2",
"branches": [{
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.0,
"branchName": "1-3层照明插座",
"onlineRate": "",
"status":
}]
}, {
"comId": ,
"comName": "com3",
"branches": [{
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.0,
"branchName": "厨房用电",
"onlineRate": "",
"status":
}]
}, {
"comId": ,
"comName": "com4",
"branches": [{
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.0,
"branchName": "照明干线",
"onlineRate": "",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.0,
"branchName": "1#变压器",
"onlineRate": "",
"status":
}]
}],
"collectorName": "采集器01"
}]
},
"code": ,
"msg": "",
"errors": null
}
第二种
JSON数据:
{
"data": {
"array": [{
"collectorStatus": ,
"collectorOnlineRate": "",
"collectorId": ,
"coms": [{
"comId": ,
"comName": "com1",
"branches": [{
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 1381.63,
"branchName": "空调主机",
"onlineRate": "27.69",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 927.61,
"branchName": "生活水泵",
"onlineRate": "27.69",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.0,
"branchName": "计算机房电源",
"onlineRate": "",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.0,
"branchName": "主楼2-5层热水器",
"onlineRate": "",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.0,
"branchName": "冷却泵",
"onlineRate": "",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.0,
"branchName": "2#冷水机",
"onlineRate": "",
"status":
}]
}, {
"comId": ,
"comName": "com2",
"branches": [{
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 458.71,
"branchName": "客梯2",
"onlineRate": "27.69",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.0,
"branchName": "厨房用电(1)",
"onlineRate": "",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.0,
"branchName": "附楼1-5层热水器",
"onlineRate": "",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.0,
"branchName": "生活水泵",
"onlineRate": "",
"status":
}]
}, {
"comId": ,
"comName": "com3",
"branches": [{
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 1314.01,
"branchName": "冷冻水泵",
"onlineRate": "27.69",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.0,
"branchName": "1#变压器计量柜",
"onlineRate": "",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.0,
"branchName": "附楼2-5层照明插座",
"onlineRate": "",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.0,
"branchName": "冷冻泵",
"onlineRate": "",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.0,
"branchName": "冷却塔",
"onlineRate": "",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.0,
"branchName": "",
"onlineRate": "",
"status":
}]
}, {
"comId": ,
"comName": "com4",
"branches": [{
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 1304.22,
"branchName": "冷却水泵",
"onlineRate": "27.69",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 723.75,
"branchName": "消防电梯",
"onlineRate": "27.69",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.0,
"branchName": "主楼1-5层照明插座",
"onlineRate": "",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.0,
"branchName": "大厦射灯",
"onlineRate": "",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.0,
"branchName": "1#冷水机",
"onlineRate": "",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 24824.63,
"branchName": "1#变压器",
"onlineRate": "27.69",
"status":
}]
}],
"collectorName": "采集器01"
}, {
"collectorStatus": ,
"collectorOnlineRate": "",
"collectorId": ,
"coms": [{
"comId": ,
"comName": "COM1236",
"branches": [{
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.0,
"branchName": "2F信息中心",
"onlineRate": "",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.0,
"branchName": "中央空调",
"onlineRate": "",
"status":
}]
}],
"collectorName": "采集器1000000"
}]
},
"code": ,
"msg": "",
"errors": null
}
第三种
JSON数据:
{
"data": {
"array": [{
"collectorStatus": ,
"collectorOnlineRate": "",
"collectorId": ,
"coms": [{
"comId": ,
"comName": "com1",
"branches": [{
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 148.78,
"branchName": "海鲜池、超市冷柜(主)",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 294.57,
"branchName": "地下室应急照明(副)",
"onlineRate": "95.31",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 49149.49,
"branchName": "1#总柜",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 34714.92,
"branchName": "肯德基",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 18.13,
"branchName": "银行(主)",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 17933.02,
"branchName": "海鲜池、超市冷柜(副)",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 28.4,
"branchName": "消防电梯1",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 2718.35,
"branchName": "风柜、风机盘管",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 1880.3,
"branchName": "2#冷冻泵",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.0,
"branchName": "3号支路",
"onlineRate": "",
"status":
}]
}, {
"comId": ,
"comName": "com2",
"branches": [{
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 12009.76,
"branchName": "西竖井1~2层普通负荷",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 1677.36,
"branchName": "2#冷却塔",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 1979.76,
"branchName": "2#冷却泵",
"onlineRate": "98.44",
"status":
}]
}, {
"comId": ,
"comName": "com3",
"branches": [{
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 7520.13,
"branchName": "电脑机房、办公室",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 5048.18,
"branchName": "易天手机",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 12135.82,
"branchName": "西竖井3~6层普通负荷",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 24504.42,
"branchName": "真功夫(主)",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 2289.83,
"branchName": "生活水泵",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 2182.22,
"branchName": "观光电梯",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 6005.46,
"branchName": "3#冷冻泵",
"onlineRate": "98.44",
"status":
}]
}, {
"comId": ,
"comName": "com4",
"branches": [{
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 11896.4,
"branchName": "东竖井应急照明(主)",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 23459.22,
"branchName": "2#总柜",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 5059.89,
"branchName": "地下室应急负荷(主)",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 18036.61,
"branchName": "东竖井普通负荷",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 0.3,
"branchName": "消防电梯(副)",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 4567.51,
"branchName": "空调主机二",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 1431.58,
"branchName": "1#冷却塔",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 1933.21,
"branchName": "1-12#扶梯",
"onlineRate": "98.44",
"status":
}, {
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 5540.06,
"branchName": "4#冷却泵",
"onlineRate": "98.44",
"status":
}]
}],
"collectorName": "采集器01"
}, {
"collectorStatus": ,
"collectorOnlineRate": "",
"collectorId": ,
"coms": [{
"comId": ,
"comName": "COM2",
"branches": [{
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": -999.0,
"branchName": "消防电梯",
"onlineRate": "",
"status":
}]
}],
"collectorName": "采集器2"
}, {
"collectorStatus": ,
"collectorOnlineRate": "",
"collectorId": ,
"coms": [{
"comId": ,
"comName": "COM",
"branches": [{
"branchId": ,
"branchOrder": ,
"branchNumber": "",
"branchValue": 288.04,
"branchName": "东竖井应急照明(副)",
"onlineRate": "98.44",
"status":
}]
}],
"collectorName": "4#"
}, {
"collectorStatus": ,
"collectorOnlineRate": "",
"collectorId": ,
"coms": [],
"collectorName": ""
}]
},
"code": ,
"msg": "",
"errors": null
}
还有其它场景我就不一一列举了。
界面完整代码:
<template>
<div class="p-container">
<div class="sub-nav single">
<el-tabs v-model="activeName">
<el-tab-pane label="示意图" name="default">
<div class="u-layout-container metermon_content">
<div
v-if="meterMonitor!=null"
class="metermon_info"
ref="meter"
:style="{height:containHeight}"
>
<div class="metermon_list_img">
<div class="info_list_warp">
<ul class="left">
<li>正常</li>
<li>中断</li>
</ul>
<ul class="right">
<li>在线率10%以下</li>
<li>在线率10%~20%</li>
<li>在线率20%~80%</li>
<li>在线率80%~90%</li>
<li>在线率90%以上</li>
</ul>
</div>
<div class="top_img" :style="{'left':containerStyle.topImgLeft}">
<img src="../../../assets/images/meter/meter2.png" alt>
<div
class="line"
:class="'line'+(index+1)"
:style="{left:((2*index+1)/(2*meterMonitor.length))*248+'px'}"
v-for="(item , index) in meterMonitor"
:key="index"
></div>
</div>
<div class="metermon_warp">
<div style="position: absolute;">
<div class="top_line" v-bind:style="{left:style.left,width:style.width}"></div>
<div
class="metermon_left"
:class="'metermon_left'+index"
:style="{left:item.left+'px'}"
v-for="(item,index) in meterMonitor"
:key="item.collectorId"
>
<div class="left_top">
<img src="../../../assets/images/meter/meter1.png" alt class="fl">
<div
class="line"
:class="'line_'+(index1+1)"
:style="{left:((2*index1+1)/(2*item.coms.length))*100+'%'}"
v-for="(ele,index1) in item.coms"
:key="ele.comId"
></div>
</div>
<div class="collection_msg fl">
<span
class="cicle fl"
v-bind:class="getClassByStatus(item.collectorStatus)"
></span>
<span class="home_percent home c90 fl">{{item.collectorOnlineRate}}%</span>
<span
class="collection_name fl"
:title="item.collectorName"
>{{item.collectorName}}</span>
</div>
<div class="left_list_warp" :style="{width:item.coms.length*274+'px'}">
<dl
:class="'list'+(index1+1)"
class="left_list"
v-for="(ele,index1) in item.coms"
:key="ele.comId"
>
<dt>
{{ele.comName}}
<br>电表
</dt>
<dd v-for="(item2) in ele.meters" :key="item2.meterId">
<div
class="home_num home"
v-bind:class="getClassByStatus(item2.status)"
@click="getMeterDetails(timelist[0],4,item2)"
>{{item2.meterValue}}</div>
<div
class="home_percent home"
v-bind:class="getClassByRate(item2.onlineRate)"
>{{item2.onlineRate}}%</div>
<div class="home_info" :title="item2.meterName">{{item2.meterName}}</div>
</dd>
</dl>
</div>
</div>
</div>
</div>
</div>
</div>
<empty-data v-else msg="暂无监测数据" height="480px"></empty-data>
<el-dialog
v-dialogDrag
:visible.sync="dialogTableVisible"
:title="curTitle"
class="metermon_dialog"
>
<div class="dialog_info_list">
<ul class="left">
<li
:class="{acdate:item.active}"
@click="getMeterDetails(item,index+1)"
v-for="(item,index) in timelist"
:key="index"
>{{item.time}}</li>
</ul>
<div class="dateClass" v-if="showTime">
日期:
<el-date-picker
v-model="queryHistoryDate"
value-format="yyyy-MM-dd"
@change="timeChange"
type="date"
placeholder="请选择时间"
size="mini"
></el-date-picker>
<div class="fontClass">
<span style="color: red;">*</span>
<span>只显示3天内的数据</span>
</div>
</div>
<div class="right">
<span>优化建议:</span>
{{meterstatu}}
</div>
</div>
<el-table
:data="meterDetail"
stripe
header-row-class-name="metermon_table_header"
height="360"
>
<el-table-column prop="branchValue" label="表计读数(kWh)">
<template slot-scope="scope">{{scope.row.meterValue|zeroDefault}}</template>
</el-table-column>
<el-table-column prop="status" label="表计状态">
<template slot-scope="scope">{{StatusArray[scope.row.status]}}</template>
</el-table-column>
<el-table-column prop="reportTime" label="报告生成时间"></el-table-column>
</el-table>
<div class="dialog_info_close">
<el-button size="mini" round @click="dialogTableVisible=false">关闭</el-button>
</div>
</el-dialog>
</div>
</el-tab-pane>
</el-tabs>
</div>
</div>
</template> <script>
import datetimeUtils from "../../../utils/datetime-utils";
import { StatusArrays, getClassByRateFun } from './index.js';
import { getMeterMonitorData, getMeterMonitorHistoryData } from '../../../services/safety.js';
import EmptyData from '../../../components/form/EmptyData'; export default {
name: 'meterMonitoring',
components: {
EmptyData
},
data () {
return {
StatusArray: StatusArrays,
activeName: 'default',
containHeight: '780px',
timelist: [{ time: '今天', active: true, date: datetimeUtils.getPreDate(0) }, { time: '两天内', active: false, date: datetimeUtils.getPreDate(1) }, { time: '三天内', active: false, date: datetimeUtils.getPreDate(2) }, { time: '自定义', active: false, date: datetimeUtils.getPreDate(3) }],
meterDetail: [],
meterMonitor: [],
meterstatu: '',
gridData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}],
dialogTableVisible: false,
curMeterNumber: '', //当前选中分支编号
// 顶部项目回调对象
topProjectSelectSlotCbFun: {
nodeFunction: this.topFunction
},
curSelectItem: {},//当前选择支路对象
style: { width: '0px', left: '', marginLeft: 0 },
containerStyle: {
topImgLeft: '380px'
},
meterLeft: 0,//临时累加存值
curTitle: '', //弹窗标题
queryHistoryDate: datetimeUtils.getPreDate(3),//查询历史时间,默认前3天
showTime: false,//显示查询历史数据时间
}
},
created () {
this.queryType = this.$route.query.pmid;//接收参数-项目ID
this.getMeterMonitor();
},
mounted () {
var that = this;
that.$nextTick(() => {
let tableHeight = window.innerHeight - 200;
that.containHeight = tableHeight + 'px';
console.log('tableHeight:' + window.innerHeight + ':' + tableHeight)
})
},
watch: {
shopNumber (val) {
console.log('shopNumber', val)
this.getMeterMonitor();
}
},
computed: {
shopNumber () {
return this.$store.getters.shopNumber;
},
//根据在线率返回建议信息
metersTag: function () {
var _metersTag = '';
if (this.curSelectItem.onlineRate < 20) {
_metersTag = '建议更换';
} else if (this.curSelectItem.onlineRate >= 20 && this.curSelectItem.onlineRate <= 80) {
_metersTag = '建议及时关注';
} else if (this.curSelectItem.onlineRate > 80) {
_metersTag = '处于正常状态'
}
return _metersTag;
}
},
methods: {
//时间改变
timeChange (time) {
if (!time) {
this.$message.error("时间不能为空!")
return;
}
this.meterstatu = '设备三天内在线率' + this.curSelectItem.onlineRate + '%,' + this.metersTag;
this.getMeterDetailsFun(4);
},
//采集器left
metermonLeft (index, meterMonitor) {
if (index == 0) {
this.meterLeft = 0;
} else {
this.meterLeft += (meterMonitor[index - 1].coms.length == 0 ? 1 : meterMonitor[index - 1].coms.length) * 276 + 26;
}
console.log(meterMonitor.length)
// 85是采集器图片的左侧宽度 ,248是交换机图片的宽度
let pre = ((2 * index + 1) / (2 * meterMonitor.length)) * 248;
return 85 + this.meterLeft + pre;
},
/*获取表计数据*/
getMeterMonitor () {
this.common.updateLoadingStatus(true);
getMeterMonitorData(this.shopNumber).
then(res => {
console.log('res', res)
if (res.code == 200) {
if (res.data.length > 0) {
for (let i = 0; i < res.data.length; i++) {
res.data[i].left = this.metermonLeft(i, res.data);
}
this.meterMonitor = res.data;
} else {
this.meterMonitor = null;
}
} else {
this.$message.error(res.msg);
}
this.common.updateLoadingStatus(false);
this.calculateWidth();
}).catch(() => {
this.common.updateLoadingStatus(false);
});
},
//宽度计算
calculateWidth () {
var collectors = this.meterMonitor.length; //采集器数量 if (collectors > 0) {
let pre = collectors == 0 ? 0 : 1 / (2 * collectors) * 248;
let leftMartgin = 85 + pre;
let _lwidth = 174 + leftMartgin; //线左边宽度
let _lwidthStr = _lwidth - 1 + 'px'; //!important;
var startLeft = this.meterMonitor[0].left;
var endLeft = this.meterMonitor[this.meterMonitor.length - 1].left;
var _lineWidth = endLeft - startLeft + 'px'; //线的宽度:最后一个的left-最前面一个的left
//顶部线的布局
this.style.width = collectors <= 1 ? 0 : _lineWidth;
this.style.left = _lwidthStr;
//交换机位置布局
let _topImgLeft = 380;
this.containerStyle.topImgLeft = _topImgLeft + 'px';
} else {
this.style.width = '0px';
}
},
//根据在线率获取样式-颜色
getClassByRate (val) {
return getClassByRateFun(val);
},
//根据支路状态获取样式-颜色
getClassByStatus (status) {
return status == 1 ? "normal" : "abnormal";
},
getMeterDetailsFun (index) {
getMeterMonitorHistoryData({ dayType: index, shopNumber: this.shopNumber, meterNumber: this.curMeterNumber, queryTime: this.queryHistoryDate }).
then(res => {
if (res.code == 200) {
this.meterDetail = res.data.dataList;
} else {
this.$message.error(res.msg);
}
});
},
/*打开历史详情页面获取历史数据*/
getMeterDetails (item, index, selectItem) {
console.log("item:", item, "index:", index, "selectItem:", selectItem)
this.queryHistoryDate = datetimeUtils.getPreDate(3);
this.showTime = index == 4 ? true : false; //显示/隐藏 查询历史时间
if (selectItem) {
this.curTitle = selectItem.meterName + '历史数据';
this.curSelectItem = selectItem;
this.curMeterNumber = selectItem.meterNumber;
}
this.dialogTableVisible = true;
this.timelist.forEach((ele, index) => {
ele.active = false;
})
item.active = true;
let tag = (index != 4 ? item.time : '三天内') || '';
this.meterstatu = '设备' + tag + '在线率' + this.curSelectItem.onlineRate + '%,' + this.metersTag;
this.getMeterDetailsFun(index);
}
}
}
</script>
<style lang="scss" scoped>
.dateClass {
font-size: 14px;
height: 28px;
line-height: 28px;
margin-left: 30px;
.fontClass {
display: inline-block;
font-size: 10px;
color: gray;
}
.el-date-editor.el-input {
width: 150px;
border-radius: 14px;
font-size: 14px;
}
} .collection_msg {
left: 50%;
position: absolute;
margin-left: 50px;
width: 210px;
}
/*弹框*/
.metermon_dialog {
}
.metermon_dialog .dialog_info_close {
padding-top: 25px;
text-align: center;
}
.metermon_dialog .dialog_info_list {
width: 100%;
display: box;
display: -webkit-box;
display: flex;
margin-bottom: 22px;
}
.dialog_info_list .left {
width: 185px;
height: 28px;
line-height: 28px;
background: #fff;
border: 1px solid #c3c9d5;
border-radius: 14px;
display: box;
display: -webkit-box;
display: flex;
overflow: hidden;
}
.dialog_info_list .left li {
-webkit-box-flex: 1;
flex: 1;
text-align: center;
cursor: pointer;
font-size: 14px;
}
.dialog_info_list .left .acdate {
color: #fff;
background: #188fbf;
}
.dialog_info_list .left li:nth-of-type(1),
.dialog_info_list .left li:nth-of-type(2),
.dialog_info_list .left li:nth-of-type(3) {
border-right: 1px solid #c3c9d5;
} .dialog_info_list .right {
-webkit-box-flex: 1;
flex: 1;
text-align: right;
color: #3a3a3a;
}
.dialog_info_list .right span {
/*color:#188FBF*/
}
.metermon_content {
background: #fff;
height: 100%;
}
.metermon_info {
margin: 0px 0px 0px 0px;
min-height: 500px;
position: relative;
overflow-y: auto;
}
.metermon_info .info_list_warp {
font-size: 14px;
color: rgba(58, 58, 58, 1);
display: box;
display: -webkit-box;
display: flex;
}
.metermon_info .left {
margin-right: 20px;
margin-left: 25px;
}
.metermon_info {
.left,
.right {
margin-top: 15px;
}
}
.metermon_info .left li,
.metermon_info .right li,
.collection_msg .cicle {
position: relative;
padding-left: 20px;
height: 28px;
line-height: 28px;
}
.metermon_info .right li {
padding-left: 34px;
}
.metermon_info .left li:after,
.collection_msg .cicle:after {
content: '';
display: block;
width: 14px;
height: 14px;
background: rgba(75, 196, 132, 1);
border-radius: 50%;
position: absolute;
left: 0;
top: 50%;
margin-top: -7px;
}
.collection_msg .cicle.abnormal:after {
background: #f57272;
}
.collection_msg .cicle.normal:after {
background: rgba(75, 196, 132, 1);
}
.metermon_info .right li:after {
content: '';
display: block;
width: 23px;
height: 9px;
border: 2px solid #f71c1c;
border-radius: 7px;
position: absolute;
left: 0;
top: 50%;
margin-top: -7px;
}
.metermon_info .left li:last-child:after {
background: #f57272;
}
.metermon_info .right li:nth-of-type(2):after {
border-color: #de7e0d;
}
.metermon_info .right li:nth-of-type(3):after {
border-color: #5e47e4;
}
.metermon_info .right li:nth-of-type(4):after {
border-color: #1780d9;
}
.metermon_info .right li:nth-of-type(5):after {
border-color: #3fbc7a;
}
/*关系列表图*/
.metermon_info .metermon_list_img {
width: 100%;
position: relative;
// margin-top: 27px;
height: 100%;
}
.metermon_list_img .top_img {
width: 248px;
/* margin: 0 auto; */
position: absolute;
left: 50%;
transform: translateX(-50%);
top: 15px;
}
.metermon_list_img .top_img .line {
/* content:'';
display: block; */
width: 2px;
height: 80px;
background: #2274a4;
position: absolute;
/* left: 97px; */
top: 24px;
}
.metermon_list_img .metermon_warp {
width: 100%;
position: absolute;
top: 118px;
/*border-top:2px solid #2274A4;*/
}
.top_line {
display: block;
width: 100%;
height: 2px;
background: #2274a4;
position: absolute;
top: 0px;
}
/*左侧模块*/
.metermon_left {
position: absolute;
/* left: 50%;
transform: translateX(-50%); */
top: 60px;
width: 274px;
}
.metermon_left .left_top {
position: absolute;
left: 50%;
transform: translate(-50%);
}
.metermon_left .left_top span {
position: absolute;
left: 50%;
top: -16px;
transform: translateX(-50%);
color: #de5959;
font-size: 14px;
width: 100%;
}
.metermon_left .left_top:after {
content: '';
display: block;
width: 2px;
height: 62px;
background: #2274a4;
position: absolute;
right: 12px;
top: -60px;
}
.metermon_left .left_top .line {
width: 2px;
background: #3fbc7a;
position: absolute;
top: 29px;
height: 30px;
}
/*列表样式*/
.metermon_left .left_list_warp {
display: -webkit-box;
display: -webkit-flex;
margin-top: 58px;
}
.metermon_left .left_list {
width: 274px;
font-size: 12px;
border-left: 2px solid #3fbc7a;
padding-top: 30px;
border-top: 2px solid #3fbc7a;
/* position: absolute; */
}
.metermon_left .left_list dt {
color: #2274a4;
font-size: 14px;
padding-left: 12px;
margin-bottom: 6px;
}
.metermon_left .left_list dd {
display: box;
display: -webkit-box;
display: flex;
margin-bottom: 12px;
}
.metermon_left .left_list .home,
.collection_msg .home {
width: 90px;
height: 24px;
line-height: 24px;
text-align: center;
border-radius: 12px;
}
.metermon_left .left_list .home_num {
background: #3fbc7a;
border: 1px solid #3fbc7a;
color: #fff;
cursor: pointer;
}
.metermon_left .left_list .home_percent,
.collection_msg .home_percent {
border: 1px solid #3fbc7a;
color: #3fbc7a;
background: #fff;
}
.metermon_left .left_list .home_info {
height: 24px;
line-height: 24px;
color: #3a3a3a;
font-size: 14px;
margin-left: 10px;
width: 90px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} .metermon_right .left_top:after {
left: 30px;
}
.metermon_right .left_top:before {
width: 567px;
left: -535px;
}
</style>
<style>
.metermon_content .el-table th > .cell {
width: 100%;
}
.metermon_dialog .el-dialog__header {
padding: 0;
height: 40px;
line-height: 40px;
background: rgba(24, 129, 191, 1);
padding-left: 29px;
position: relative;
}
.metermon_dialog .el-dialog__header .el-dialog__title {
color: #fff;
font-size: 16px;
}
.metermon_dialog .el-dialog__header .el-dialog__headerbtn {
top: 50%;
transform: translateY(-50%);
}
.metermon_dialog .el-dialog__headerbtn .el-dialog__close {
font-size: 12px;
color: #fff;
cursor: pointer;
padding: 2px;
border: 1px solid #fff;
border-radius: 50%;
}
.metermon_dialog .metermon_table_header th {
background: rgba(241, 241, 241, 1);
font-size: 14px;
color: #3a3a3a;
}
.metermon_dialog
.el-table--striped
.el-table__body
tr.el-table__row--striped
td {
background: #f7fbfc;
/* border:none; */
}
.metermon_dialog .el-button--mini {
width: 90px;
font-size: 14px;
}
/*边框颜色*/
.metermon_left .left_list .home_percent.c1 {
border: 1px solid #f71c1c;
color: #f71c1c;
}
.metermon_left .left_list .home_percent.c10 {
border: 1px solid #de7e0d;
color: #de7e0d;
}
.metermon_left .left_list .home_percent.c20 {
border: 1px solid #5e47e4;
color: #5e47e4;
}
.metermon_left .left_list .home_percent.c80 {
border: 1px solid #1780d9;
color: #1780d9;
}
.metermon_left .left_list .home_percent.c90,
.collection_msg .home_percent.c90 {
border: 1px solid #3fbc7a;
color: #3fbc7a;
}
.metermon_left .left_list .home_num.abnormal {
background: #f57272;
border: 1px solid #f57272;
}
.metermon_left .left_list .home_num.normal {
background: rgba(75, 196, 132, 1);
border: 1px solid rgba(75, 196, 132, 1);
}
.collection_msg .collection_name {
height: 26px;
line-height: 26px;
margin-left: 4px;
width: 85px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>
本以为做前端,应该比较容易吧,没想到连续接的几个页面感觉都不容易,唉!连几个界面都搞得我如此费力,看来也不太适合做前端......可是现在却已经在背离.net的路上越走越远了...
vue实现表计监测界面的更多相关文章
- vue的表单编辑删除,保存取消功能
过年回来第一篇博客,可能说的不是很清楚,而且心情可能也不是特别的high,虽然今天是元宵,我还在办公室11.30在加班,但就是想把写过的代码记下来,怕以后可能真的忘了.(心将塞未塞,欲塞未满) VUE ...
- Vue.js表单校验;动画指令;避免内存泄露。
Vue.js表单校验: 动画指令:创建自定义的滚动指令. 避免内存泄露. 避免内存泄露 在单页面应用开发时SPA,用户无需刷新浏览器.所以javascript应用需要自行清理组件来防止内存占用不断增长 ...
- 12.Vue.js 表单
这节我们为大家介绍 Vue.js 表单上的应用. 你可以用 v-model 指令在表单控件元素上创建双向数据绑定. <div id="app"> <p>in ...
- vue 收集表单数据 (有错误的请各位大佬指点)
收集表单数据: 若: <input type="text"/>, 则v-model收集 的是value值,用户输入的就是value值. 若 ...
- vue b表单
你可以用 v-model 指令在表单控件元素上创建双向数据绑定. v-model 会根据控件类型自动选取正确的方法来更新元素. 输入框 实例中演示了 input 和 textarea 元素中使用 v- ...
- vue + vuex 表单处理
使用场景:在一个表单中,各项数据提交后需要重置表单中各<input>元素的值为空. 组件中关联: <template> <el-form ref="form&q ...
- Vue(六) 表单与 v-model
学习使用 v-model 指令完成表单数据双向绑定 基本用法 表单控件在实际业务较为常见,比如单选,多选.下拉选择.输入框等,用他们可以完成数据的录入.校验.提交等.Vue.js 提供了 v-mode ...
- 前端框架之Vue(8)-表单输入绑定
基础用法 你可以用 v-model 指令在表单 <input> . <textarea> 及 <select> 元素上创建双向数据绑定.它会根据控件类型自动选取正确 ...
- 使用vue做表单验证
<template> <Form ref="formInline" :model="formInline" :rules="rule ...
随机推荐
- [Swift]LeetCode228. 汇总区间 | Summary Ranges
Given a sorted integer array without duplicates, return the summary of its ranges. Example 1: Input: ...
- [Swift]LeetCode457. 环形数组循环 | Circular Array Loop
You are given an array of positive and negative integers. If a number n at an index is positive, the ...
- [SQL]LeetCode626. 换座位 | Exchange Seats
SQL架构 Create table If Not Exists seat(id )) Truncate table seat insert into seat (id, student) value ...
- Hystrix概念设计
1. Hystrix概念设计 1.1. 大纲 1.2. 基本的容错模式 1.3. 断路器模式 1.4. 舱壁隔离模式 1.5. 容错理念 凡事依赖都可能失败 凡事资源都有限制 网络并不可靠 延迟是应用 ...
- [Reversing.kr] Easy ELF Writeup
IDA打开,看到main()函数,当sub_8048451() 返回1 是flag正确. 跟踪函数. 脚本: #!usr/bin/env python #!coding=utf-8 __author_ ...
- 工作随笔—Java容器基础知识分享(持有对象)
1. 概述 通常,程序总是运行时才知道的根据某些条件去创建新对象.在此之前,不会知道所需对象的数量,甚至不知道确切的类型,为解决这个普遍的编程问题:需要在任意时刻和任意位置创建任意数量的对象,所以,就 ...
- ASP.NET Core 2.0 MVC项目实战
一.前言 毕业后入职现在的公司快有一个月了,公司主要的产品用的是C/S架构,再加上自己现在还在学习维护很老的delphi项目,还是有很多不情愿的.之前实习时主要是做.NET的B/S架构的项目,主要还是 ...
- Android--MediaRecorder录音录像
前言 Android除了支持播放多媒体文件之外,还可以从对应的硬件中捕获多媒体,比如从麦克风录音.从摄像头录像等.本篇博客讲解一下Android下如何通过MediaRecorder进行录音以及录像的步 ...
- 为了学好Java,我尝试了这 6 个方法
阅读本文大概需要 5 分钟. 教练,我想学Java! 怎么学Java,一个简单的命题,我自己也折腾了好几年,现在虽不能说是Java高手,但也算是小有所成,至少还不至于搞不懂一些基本概念和技术原理. 从 ...
- 【c#】RabbitMQ学习文档(六)RPC(远程调用)
远程过程调用(Remote Proceddure call[RPC]) (本实例都是使用的Net的客户端,使用C#编写) 在第二个教程中,我们学习了如何使用工作队列在多个工作实例之间分配耗时的任务. ...