添加树页面

master
夜笙歌 3 months ago
parent b12da9590a
commit 055f8bc1c1

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

@ -9,7 +9,7 @@ import defaultSettings from '@/settings'
NProgress.configure({ showSpinner: false })
const whiteList = ['/login', '/register', '/board']
const whiteList = ['/login', '/register', '/board', '/board1']
router.beforeEach((to, from, next) => {
NProgress.start()

@ -35,6 +35,8 @@ export const constantRoutes = [
path: '/board',
component: () => import('@/views/board/index.vue'),
hidden: true
}, {
path: '/board1', component: () => import('@/views/board/index1.vue'), hidden: true
},
{
path: '/redirect',

@ -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,123 @@
<template>
<div class="listItem">
<!-- 父节点标题 -->
<div class="listItemTitle" ref="listItemTitleRef">{{ itemData.monitorName }}</div>
<div class="line" :style="`height:${height}px;left:${width + 20 + 20}px`"></div>
<div class="line1" :style="`left:${width + 20 }px`"></div>
<div class="line2" v-if="!isRoot"></div>
<div class="children" v-if="itemData.children">
<ListItem :isRoot="false" v-for="i in itemData.children" :key="i.name" :itemData="i"/>
</div>
<DeviceList v-else-if="itemData.device" :devices="itemData.device"/>
</div>
</template>
<script>
import DeviceList from './DeviceList.vue'
export default {
name: 'ListItem',
components: {DeviceList},
props: ['itemData', 'isRoot'],
data() {
return {
height: 0,
width: 0
}
},
mounted() {
this.height = this.getVerticalDiff(this.$refs.listItemTitleRef)
this.width = this.getElementWidth(this.$refs.listItemTitleRef)
},
methods: {
getVerticalDiff(titleEl) {
if (!titleEl) return null;
const parentEl = titleEl.parentElement.querySelector('.children');
if (!parentEl) return null;
// children .listItemTitle
const listItems = parentEl.children;
const titles = [];
for (let item of listItems) {
const title = item.querySelector(':scope > .listItemTitle');
if (title) titles.push(title);
}
if (titles.length < 2) return null;
const containerRect = parentEl.getBoundingClientRect();
const firstRect = titles[0].getBoundingClientRect();
const lastRect = titles[titles.length - 1].getBoundingClientRect();
const firstCenterY = (firstRect.top + firstRect.height / 2) - containerRect.top;
const lastCenterY = (lastRect.top + lastRect.height / 2) - containerRect.top;
return Math.abs(lastCenterY - firstCenterY);
},
getElementWidth(el) {
if (!el) return null;
const rect = el.getBoundingClientRect();
return rect.width;
}
}
}
</script>
<style scoped lang="less">
.listItem {
display: flex;
flex-direction: row;
align-items: center;
padding: 20px;
position: relative;
.line {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 1px;
background: #fff;
}
.line1 {
position: absolute;
top: 50%;
transform: translateY(-50%);
height: 1px;
width: 20px;
background: #fff;
}
.line2 {
position: absolute;
top: 50%;
right: 100%;
transform: translate(100%, -50%);
height: 1px;
width: 20px;
background: #fff;
}
.listItemTitle {
padding: 6px 20px;
background: #333;
color: #fff;
border-radius: 6px;
margin-right: 20px;
white-space: nowrap;
}
.children {
display: flex;
flex-direction: column;
gap: 10px;
}
}
</style>

@ -69,7 +69,6 @@
<div class="table1">
<div class="h1">
<div class="scrollTable" style="font-weight: bold;width: calc(100% / 6);">
</div>
<div class="scrollTable" style="font-weight: bold;width: calc(100% / 6);">
A区
@ -503,9 +502,12 @@ export default {
label: {
show: true,
position: 'inside',
color: '#000'
color: '#000',
fontSize: 10
},
barWidth: '30px',
barWidth: '50%',
barMaxWidth: '60px',
barMinWidth: '30px',
data: barData.map(v => {
return v.data[e] || 0
}),
@ -685,7 +687,7 @@ export default {
.title {
position: absolute;
top: 2%;
left: 50.8%;
left: 50%;
color: #eee;
font-size: 2vw;
font-weight: 600;

@ -0,0 +1,320 @@
<template>
<div>
<div class="bg">
<div class="title">正道能源监控系统</div>
<div class="content">
<div class="list" v-for="item in list" :key="item.name">
<ListItem :itemData="item" :isRoot="true"></ListItem>
</div>
</div>
</div>
</div>
</template>
<script>
import Chart from "@/components/Charts/Chart.vue";
import * as echarts from 'echarts'
import {realTimeData} from "@/api/board";
import ListItem from "./components/listItem.vue";
export default {
name: 'Board1',
components: {
Chart,
ListItem
},
data() {
return {
list1: [
{
name: '根节点1',
children: [
{
name: '节点1',
children: [
{
name: '节点1-1',
id: '1-1',
device: [
{
name: '设备1',
data: [
{
name: '数据1',
value: '10',
units: "℃"
},
{
name: '数据2',
value: '20',
units: "℃"
}
]
},
{
name: '设备2',
data: [
{
name: '数据1',
value: '10',
units: "℃"
},
{
name: '数据2',
value: '20',
units: "℃"
}
]
}
]
},
{
name: '节点1-2',
device: [
{
name: '设备1',
data: [
{
name: '数据1',
value: '10',
units: "℃"
},
{
name: '数据2',
value: '20',
units: "℃"
}
]
},
{
name: '设备2',
data: [
{
name: '数据1',
value: '10',
units: "℃"
},
{
name: '数据2',
value: '20',
units: "℃"
}
]
}
]
}
]
},
{
name: '节点2',
children: [
{
name: '节点1-1',
id: '1-1',
device: [
{
name: '设备1',
data: [
{
name: '数据1',
value: '10',
units: "℃"
},
{
name: '数据2',
value: '20',
units: "℃"
}
]
},
{
name: '设备2',
data: [
{
name: '数据1',
value: '10',
units: "℃"
},
{
name: '数据2',
value: '20',
units: "℃"
}
]
}
]
},
{
name: '节点1-2',
device: [
{
name: '设备1',
data: [
{
name: '数据1',
value: '10',
units: "℃"
},
{
name: '数据2',
value: '20',
units: "℃"
}
]
},
{
name: '设备2',
data: [
{
name: '数据1',
value: '10',
units: "℃"
},
{
name: '数据2',
value: '20',
units: "℃"
}
]
}
]
}
]
}
]
},
{
name: '根节点2',
children: [
{
name: '节点2',
children: [
{
name: '节点2-1'
},
{
name: '节点2-2'
}
]
}
]
}
],
list: [],
}
},
async mounted() {
const fieldUnits = {
vA: 'V', vB: 'V', vC: 'V',
iA: 'A', iB: 'A', iC: 'A',
zxyg: '', fxyg: '',
};
const fieldFilter = ['vA', 'vB', 'vC', 'iA', 'iB', 'iC', 'glys', 'zxyg', 'fxyg', 'fluxFlow', 'waterFlow', 'steamFlow', 'temperature', 'press', 'density', 'purity'];
realTimeData({
monitorType: 2
}).then(res => {
console.log(res)
const tree = this.buildTree(res.data, 0, fieldUnits, fieldFilter);
this.list = tree
console.log(tree)
})
},
methods: {
buildTree(list, rootId = 0, fieldUnits = {}, fieldFilter = []) {
const map = new Map(list.map(item => [item.objId, {...item}]));
function processNode(node) {
// data
const isAmmeter = String(node.isAmmeter);
if (isAmmeter !== "0") {
const data = [];
for (const key of fieldFilter) {
if (node.hasOwnProperty(key) && node[key] !== null && node[key] !== undefined) {
data.push({value: node[key], units: fieldUnits[key] || ''});
delete node[key]; //
}
}
if (data.length) node.data = data;
}
//
const children = [];
const devices = [];
for (const child of list) {
if (child.parentId === node.objId) {
const childNode = map.get(child.objId);
processNode(childNode); //
// isAmmeter children device
if (String(childNode.isAmmeter) === "0") {
children.push(childNode);
} else {
devices.push(childNode);
}
}
}
if (children.length) node.children = children;
if (devices.length) node.device = devices;
//
if (node.children && node.children.length === 0) delete node.children;
if (node.device && node.device.length === 0) delete node.device;
}
const tree = [];
for (const item of list) {
if (item.parentId === rootId) {
const node = map.get(item.objId);
processNode(node);
tree.push(node);
}
}
return tree;
}
}
}
</script>
<style scoped lang="less">
.bg {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background-repeat: no-repeat;
background-size: 100% 100%;
background-image: url('~@/assets/board/bg1.jpg');
overflow: hidden;
}
.title {
position: absolute;
top: 2%;
left: 50%;
color: #eee;
font-size: 2vw;
font-weight: 600;
letter-spacing: 0.5vw;
transform: translateX(-50%);
}
.content {
position: absolute;
top: 10%;
left: 1%;
width: 98%;
height: 88%;
overflow: auto;
&::-webkit-scrollbar {
display: none;
}
.list {
}
}
</style>
Loading…
Cancel
Save