已经好几个月没有更新博客了,因为最近太忙,忙得连写博客的时间都没有。上班赶项目开启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实现表计监测界面的更多相关文章

  1. vue的表单编辑删除,保存取消功能

    过年回来第一篇博客,可能说的不是很清楚,而且心情可能也不是特别的high,虽然今天是元宵,我还在办公室11.30在加班,但就是想把写过的代码记下来,怕以后可能真的忘了.(心将塞未塞,欲塞未满) VUE ...

  2. Vue.js表单校验;动画指令;避免内存泄露。

    Vue.js表单校验: 动画指令:创建自定义的滚动指令. 避免内存泄露. 避免内存泄露 在单页面应用开发时SPA,用户无需刷新浏览器.所以javascript应用需要自行清理组件来防止内存占用不断增长 ...

  3. 12.Vue.js 表单

    这节我们为大家介绍 Vue.js 表单上的应用. 你可以用 v-model 指令在表单控件元素上创建双向数据绑定. <div id="app"> <p>in ...

  4. vue 收集表单数据 (有错误的请各位大佬指点)

     收集表单数据:        若: <input type="text"/>, 则v-model收集 的是value值,用户输入的就是value值.        若 ...

  5. vue b表单

    你可以用 v-model 指令在表单控件元素上创建双向数据绑定. v-model 会根据控件类型自动选取正确的方法来更新元素. 输入框 实例中演示了 input 和 textarea 元素中使用 v- ...

  6. vue + vuex 表单处理

    使用场景:在一个表单中,各项数据提交后需要重置表单中各<input>元素的值为空. 组件中关联: <template> <el-form ref="form&q ...

  7. Vue(六) 表单与 v-model

    学习使用 v-model 指令完成表单数据双向绑定 基本用法 表单控件在实际业务较为常见,比如单选,多选.下拉选择.输入框等,用他们可以完成数据的录入.校验.提交等.Vue.js 提供了 v-mode ...

  8. 前端框架之Vue(8)-表单输入绑定

    基础用法 你可以用 v-model 指令在表单 <input> . <textarea> 及 <select> 元素上创建双向数据绑定.它会根据控件类型自动选取正确 ...

  9. 使用vue做表单验证

    <template> <Form ref="formInline" :model="formInline" :rules="rule ...

随机推荐

  1. [Swift]LeetCode228. 汇总区间 | Summary Ranges

    Given a sorted integer array without duplicates, return the summary of its ranges. Example 1: Input: ...

  2. [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 ...

  3. [SQL]LeetCode626. 换座位 | Exchange Seats

    SQL架构 Create table If Not Exists seat(id )) Truncate table seat insert into seat (id, student) value ...

  4. Hystrix概念设计

    1. Hystrix概念设计 1.1. 大纲 1.2. 基本的容错模式 1.3. 断路器模式 1.4. 舱壁隔离模式 1.5. 容错理念 凡事依赖都可能失败 凡事资源都有限制 网络并不可靠 延迟是应用 ...

  5. [Reversing.kr] Easy ELF Writeup

    IDA打开,看到main()函数,当sub_8048451() 返回1 是flag正确. 跟踪函数. 脚本: #!usr/bin/env python #!coding=utf-8 __author_ ...

  6. 工作随笔—Java容器基础知识分享(持有对象)

    1. 概述 通常,程序总是运行时才知道的根据某些条件去创建新对象.在此之前,不会知道所需对象的数量,甚至不知道确切的类型,为解决这个普遍的编程问题:需要在任意时刻和任意位置创建任意数量的对象,所以,就 ...

  7. ASP.NET Core 2.0 MVC项目实战

    一.前言 毕业后入职现在的公司快有一个月了,公司主要的产品用的是C/S架构,再加上自己现在还在学习维护很老的delphi项目,还是有很多不情愿的.之前实习时主要是做.NET的B/S架构的项目,主要还是 ...

  8. Android--MediaRecorder录音录像

    前言 Android除了支持播放多媒体文件之外,还可以从对应的硬件中捕获多媒体,比如从麦克风录音.从摄像头录像等.本篇博客讲解一下Android下如何通过MediaRecorder进行录音以及录像的步 ...

  9. 为了学好Java,我尝试了这 6 个方法

    阅读本文大概需要 5 分钟. 教练,我想学Java! 怎么学Java,一个简单的命题,我自己也折腾了好几年,现在虽不能说是Java高手,但也算是小有所成,至少还不至于搞不懂一些基本概念和技术原理. 从 ...

  10. 【c#】RabbitMQ学习文档(六)RPC(远程调用)

    远程过程调用(Remote Proceddure call[RPC]) (本实例都是使用的Net的客户端,使用C#编写) 在第二个教程中,我们学习了如何使用工作队列在多个工作实例之间分配耗时的任务. ...