添加看板
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 197 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 499 B |
|
After Width: | Height: | Size: 1.4 KiB |
@ -0,0 +1,64 @@
|
|||||||
|
<template>
|
||||||
|
<div ref="chartRef" class="chart-container"></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
|
||||||
|
const chartRef = ref(null);
|
||||||
|
let chart = null;
|
||||||
|
|
||||||
|
const setOption = (option) => {
|
||||||
|
if (!chart) return;
|
||||||
|
chart.setOption(option);
|
||||||
|
};
|
||||||
|
|
||||||
|
const init = () => {
|
||||||
|
if (!chartRef.value) return;
|
||||||
|
|
||||||
|
const { width, height } = chartRef.value.getBoundingClientRect();
|
||||||
|
if (width === 0 || height === 0) return;
|
||||||
|
|
||||||
|
if (!chart) {
|
||||||
|
chart = echarts.init(chartRef.value, null, { renderer: 'canvas' });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optionCache.value) {
|
||||||
|
chart.setOption(optionCache.value, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const optionCache = ref(null);
|
||||||
|
|
||||||
|
const setData = (opt) => {
|
||||||
|
optionCache.value = opt;
|
||||||
|
init();
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
nextTick(() => {
|
||||||
|
init();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 监听大小变化
|
||||||
|
const ro = new ResizeObserver(() => {
|
||||||
|
if (chart) chart.resize();
|
||||||
|
});
|
||||||
|
ro.observe(chartRef.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
if (chart) chart.dispose();
|
||||||
|
});
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
setData
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.chart-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,95 @@
|
|||||||
|
<template>
|
||||||
|
<div class="deviceList">
|
||||||
|
<div class="deviceItem" v-for="d in devices" :key="d.id">
|
||||||
|
<div class="line"></div>
|
||||||
|
<div class="title">
|
||||||
|
{{ d.monitorCode }}
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<div class="name">
|
||||||
|
{{ d.monitorName }}
|
||||||
|
</div>
|
||||||
|
<div class="list" v-for="i in d.data">
|
||||||
|
<div class="value">{{ i.value }}</div>
|
||||||
|
<div class="units">{{ i.units }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'DeviceList',
|
||||||
|
props: ['devices'],
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
.deviceList {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row; /* 横向排列设备 */
|
||||||
|
gap: 20px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.line {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
right: 100%;
|
||||||
|
transform: translate(100%, -50%);
|
||||||
|
height: 1px;
|
||||||
|
width: 20px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deviceItem {
|
||||||
|
padding: 6px 20px;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 6px;
|
||||||
|
white-space: nowrap;
|
||||||
|
min-width: 100px;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
text-align: center;
|
||||||
|
border: 1px solid #fff;
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
border: 1px solid #fff;
|
||||||
|
|
||||||
|
.name {
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
text-align: center;
|
||||||
|
border-bottom: 1px solid #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list {
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
.value {
|
||||||
|
display: inline-block;
|
||||||
|
min-width: 100px;
|
||||||
|
margin-right: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.units {
|
||||||
|
display: inline-block;
|
||||||
|
min-width: 50px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,293 @@
|
|||||||
|
<template>
|
||||||
|
<div class="content">
|
||||||
|
<div class="bg"></div>
|
||||||
|
<div class="title">RFID中间件监控平台</div>
|
||||||
|
<div class="topTitle" style="left: 13%">设备数量:</div>
|
||||||
|
<div class="topTitle" style="left: 37.5%">在线数量:</div>
|
||||||
|
<div class="topTitle" style="left: 62%">离线数量:</div>
|
||||||
|
<div class="topTitle" style="left: 86.5%">告警数量:</div>
|
||||||
|
<div class="topNum" style="left: 17%; color: #127feb">66</div>
|
||||||
|
<div class="topNum" style="left: 41.5%; color: #49e1f5">66</div>
|
||||||
|
<div class="topNum" style="left: 66%; color: #d8ee30">66</div>
|
||||||
|
<div class="topNum" style="left: 90.5%; color: #901f43">66</div>
|
||||||
|
<div class="successRate">
|
||||||
|
<Chart ref="successRateRef"></Chart>
|
||||||
|
</div>
|
||||||
|
<div class="scrollTable">
|
||||||
|
<div class="th" :style="{ backgroundImage: `url(${thbg})` }">
|
||||||
|
<div class="td" style="width: 25%">时间</div>
|
||||||
|
<div class="td" style="width: 15%">设备名称</div>
|
||||||
|
<div class="td" style="width: 30%">位置</div>
|
||||||
|
<div class="td" style="width: 10%">等级</div>
|
||||||
|
<div class="td" style="width: 20%">告警行为</div>
|
||||||
|
</div>
|
||||||
|
<vue3ScrollSeamless
|
||||||
|
:limitMoveNum="1"
|
||||||
|
:step="1"
|
||||||
|
:hover="true"
|
||||||
|
:dataList="tableData"
|
||||||
|
style="overflow: hidden; height: calc(100% - 3.5vw); margin-top: 0.2vw"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-for="(item, index) in tableData"
|
||||||
|
:key="index"
|
||||||
|
class="tr"
|
||||||
|
style="margin-top: 8px; line-height: 2.4vw"
|
||||||
|
:style="{ backgroundImage: `url(${trbg})` }"
|
||||||
|
>
|
||||||
|
<div class="td" style="width: 25%; line-height: 2.4vw">{{ item.time }}</div>
|
||||||
|
<div class="td" style="width: 15%; line-height: 2vw">{{ item.name }}</div>
|
||||||
|
<div class="td" style="width: 30%; line-height: 2vw; font-size: 0.6vw">{{ item.lo }}</div>
|
||||||
|
<div class="td" style="width: 10%; line-height: 2vw">{{ item.level }}</div>
|
||||||
|
<div class="td" style="width: 20%; line-height: 2vw">{{ item.item1 }}</div>
|
||||||
|
</div>
|
||||||
|
</vue3ScrollSeamless>
|
||||||
|
</div>
|
||||||
|
<div class="center">
|
||||||
|
<ListItem :isRoot="false" v-for="i in centerData" :key="i.name" :itemData="i" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import Chart from '@/components/Chart/chart.vue';
|
||||||
|
import thbg from '@/assets/chart/thbg.png';
|
||||||
|
import trbg from '@/assets/chart/trbg.png';
|
||||||
|
import { vue3ScrollSeamless } from 'vue3-scroll-seamless';
|
||||||
|
import ListItem from './listItem.vue';
|
||||||
|
|
||||||
|
const successRateRef = ref(null);
|
||||||
|
const tableData = ref([
|
||||||
|
{
|
||||||
|
time: '2016-06-05',
|
||||||
|
name: '带束层2',
|
||||||
|
lo: '半钢成型A4机台',
|
||||||
|
level: '次要',
|
||||||
|
item1: '设备离线'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: '2016-06-05',
|
||||||
|
name: '带束层2',
|
||||||
|
lo: '半钢成型A4机台',
|
||||||
|
level: '次要',
|
||||||
|
item1: '设备离线'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: '2016-06-05',
|
||||||
|
name: '带束层2',
|
||||||
|
lo: '半钢成型A4机台',
|
||||||
|
level: '次要',
|
||||||
|
item1: '设备离线'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: '2016-06-05',
|
||||||
|
name: '带束层2',
|
||||||
|
lo: '半钢成型A4机台',
|
||||||
|
level: '次要',
|
||||||
|
item1: '设备离线'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: '2016-06-05',
|
||||||
|
name: '带束层2',
|
||||||
|
lo: '半钢成型A4机台',
|
||||||
|
level: '次要',
|
||||||
|
item1: '设备离线'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: '2016-06-05',
|
||||||
|
name: '带束层2',
|
||||||
|
lo: '半钢成型A4机台',
|
||||||
|
level: '次要',
|
||||||
|
item1: '设备离线'
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
const centerData = ref({
|
||||||
|
isAmmeter: '1',
|
||||||
|
monitorCode: '111',
|
||||||
|
monitorName: '123',
|
||||||
|
deviceData: [
|
||||||
|
{
|
||||||
|
value: '11',
|
||||||
|
units: 'kg'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
isAmmeter: '1',
|
||||||
|
monitorCode: '111',
|
||||||
|
monitorName: '123',
|
||||||
|
deviceData: [
|
||||||
|
{
|
||||||
|
value: '11',
|
||||||
|
units: 'kg'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
onMounted(() => {
|
||||||
|
successRateRef.value.setData({
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
backgroundColor: 'rgba(0,0,0,.6)',
|
||||||
|
borderWidth: 0,
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
top: '',
|
||||||
|
icon: 'path://M512.798285 0.399142C230.604561 0.399142 1.895927 229.107776 1.895927 511.301501s228.708634 510.902358 510.902358 510.902358 510.902358-228.708634 510.902358-510.902358S794.992009 0.399142 512.798285 0.399142z m0 878.712142C309.634769 879.111284 144.988501 714.465017 144.988501 511.301501S309.634769 143.491717 512.798285 143.491717s367.809784 164.646268 367.809784 367.809784-164.646268 367.809784-367.809784 367.809783z',
|
||||||
|
itemWidth: 10,
|
||||||
|
itemHeight: 10,
|
||||||
|
itemGap: 10,
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: 8
|
||||||
|
}
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: ['1/1', '1/2', '1/3', '1/4', '1/5', '1/6', '1/7', '1/8', '1/9', '1/10', '1/11', '1/12', '1/13', '1/14', '1/15', '1/16', '1/17', '1/18']
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
top: 30,
|
||||||
|
left: 30,
|
||||||
|
right: 30,
|
||||||
|
bottom: 30
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
splitLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
type: 'value'
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '需求数量',
|
||||||
|
data: [9, 8, 6.5, 7.2, 6.7, 7.4, 8.2, 9, 8, 6.5, 7.2, 6.7, 7.4, 8.2, 9, 8, 6.5, 5],
|
||||||
|
type: 'line',
|
||||||
|
symbol: 'circle',
|
||||||
|
symbolSize: 5,
|
||||||
|
itemStyle: {
|
||||||
|
color: '#368CDC'
|
||||||
|
},
|
||||||
|
lineStyle: {
|
||||||
|
color: '#368CDC'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '缺陷数量',
|
||||||
|
data: [3, 9, 4, 3, 11, 8, 10, 3, 9, 4, 3, 11, 8, 10, 3, 9, 4, 3],
|
||||||
|
type: 'line',
|
||||||
|
symbol: 'circle',
|
||||||
|
symbolSize: 5,
|
||||||
|
itemStyle: {
|
||||||
|
color: '#39FFF4'
|
||||||
|
},
|
||||||
|
lineStyle: {
|
||||||
|
color: '#39FFF4'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style scoped lang="less">
|
||||||
|
.content {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
font-family: 'Source Han Sans', 'Noto Sans CJK SC', '思源黑体', sans-serif;
|
||||||
|
|
||||||
|
.bg {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-image: url('@/assets/chart/bg.jpg');
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
position: absolute;
|
||||||
|
top: 2vw;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
font-size: 2.1vw;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.2vw;
|
||||||
|
color: #7ae7f8;
|
||||||
|
background: linear-gradient(to bottom, #ffffff 0%, #7ae7f8 100%);
|
||||||
|
background-clip: text;
|
||||||
|
color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topTitle {
|
||||||
|
position: absolute;
|
||||||
|
top: 16.7%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
color: #eee;
|
||||||
|
font-size: 1.4vw;
|
||||||
|
letter-spacing: 0.2vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topNum {
|
||||||
|
position: absolute;
|
||||||
|
top: 16.7%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
color: #eee;
|
||||||
|
font-size: 1.5vw;
|
||||||
|
letter-spacing: 0.2vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.successRate {
|
||||||
|
position: absolute;
|
||||||
|
top: 30.7%;
|
||||||
|
left: 75.6%;
|
||||||
|
width: 20.6%;
|
||||||
|
height: 28.5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollTable {
|
||||||
|
position: absolute;
|
||||||
|
top: 64.7%;
|
||||||
|
left: 75.6%;
|
||||||
|
width: 20.6%;
|
||||||
|
height: 28.5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.th {
|
||||||
|
height: 3.3vw;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
font-size: 1vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tr {
|
||||||
|
height: 2.4vw;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
font-size: 0.8vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.td {
|
||||||
|
display: inline-block;
|
||||||
|
line-height: 3.3vw;
|
||||||
|
color: #fff;
|
||||||
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
position: absolute;
|
||||||
|
top: 24.5%;
|
||||||
|
left: 19.6%;
|
||||||
|
width: 53%;
|
||||||
|
height: 69%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||