修改组态化
parent
c1347b14d3
commit
320f56e77c
@ -0,0 +1,238 @@
|
||||
<template>
|
||||
<div
|
||||
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
|
||||
<NodeResizer color="#fff" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
|
||||
|
||||
<div class="custom-node"
|
||||
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">
|
||||
<div style="width: 100%;height: 100%" ref="chartRef" />
|
||||
</div>
|
||||
<Handle v-if="!props.isView" :id="`${props.id}.-t`" type="target" :position="Position.Left" />
|
||||
<div class="info">
|
||||
<el-icon color="#fff" @click="openMsgBox">
|
||||
<InfoFilled />
|
||||
</el-icon>
|
||||
</div>
|
||||
<el-dialog
|
||||
v-model="MsgBoxVisible"
|
||||
width="500"
|
||||
title="提示"
|
||||
append-to-body
|
||||
>
|
||||
<span>This is a message</span>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="MsgBoxVisible = false">关闭</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { InfoFilled } from '@element-plus/icons-vue';
|
||||
import { defineEmits, defineProps, ref } from 'vue';
|
||||
import { NodeResizer } from '@vue-flow/node-resizer';
|
||||
import { Handle, Position } from '@vue-flow/core';
|
||||
import * as echarts from 'echarts';
|
||||
|
||||
const MsgBoxVisible = ref(false);
|
||||
const props = defineProps({
|
||||
isView: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
inputData: {
|
||||
type: Object,
|
||||
required: false
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
isHideHandle: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
selected: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
dimensions: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
const chartRef = ref();
|
||||
let chart = null;
|
||||
const colorList = ['#9E87FF', '#73DDFF', '#fe9a8b', '#F56948', '#9E87FF'];
|
||||
const getOption = () => {
|
||||
return {
|
||||
title: {
|
||||
text: '设备运行数量',
|
||||
textStyle: {
|
||||
fontSize: 12,
|
||||
fontWeight: 400,
|
||||
color: '#fff'
|
||||
},
|
||||
left: '0',
|
||||
top: '5%'
|
||||
},
|
||||
legend: {
|
||||
icon: 'circle',
|
||||
top: '5%',
|
||||
right: '5%',
|
||||
itemWidth: 6,
|
||||
itemGap: 20,
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
label: {
|
||||
show: true,
|
||||
backgroundColor: '#fff',
|
||||
color: '#000',
|
||||
borderColor: 'rgba(0,0,0,0)',
|
||||
shadowColor: 'rgba(0,0,0,0)',
|
||||
shadowOffsetY: 0
|
||||
},
|
||||
lineStyle: {
|
||||
width: 0
|
||||
}
|
||||
},
|
||||
backgroundColor: '#fff',
|
||||
textStyle: {
|
||||
color: '#000'
|
||||
},
|
||||
padding: [10, 10],
|
||||
extraCssText: 'box-shadow: 1px 0 2px 0 rgba(163,163,163,0.5)'
|
||||
},
|
||||
grid: {
|
||||
top: '30%',
|
||||
bottom: '10%'
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
data: props.inputData?.time || [],
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#DCE2E8'
|
||||
}
|
||||
},
|
||||
axisTick: {
|
||||
show: true
|
||||
},
|
||||
axisLabel: {
|
||||
interval: 0,
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
},
|
||||
// 默认x轴字体大小
|
||||
fontSize: 12,
|
||||
// margin:文字到x轴的距离
|
||||
margin: 3
|
||||
},
|
||||
axisPointer: {
|
||||
label: {
|
||||
padding: [0, 0, 0, 0],
|
||||
margin: 0,
|
||||
// 移入时的字体大小
|
||||
fontSize: 12
|
||||
}
|
||||
},
|
||||
boundaryGap: true
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '数量',
|
||||
type: 'line',
|
||||
data: props.inputData?.value || [],
|
||||
symbolSize: 1,
|
||||
symbol: 'circle',
|
||||
smooth: true,
|
||||
yAxisIndex: 0,
|
||||
showSymbol: false,
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
|
||||
{
|
||||
offset: 0,
|
||||
color: '#9effff'
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: '#9E87FF'
|
||||
}
|
||||
]),
|
||||
shadowColor: 'rgba(158,135,255, 0.3)',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetY: 20
|
||||
},
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: colorList[0],
|
||||
borderColor: colorList[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
};
|
||||
const emit = defineEmits(['resize']);
|
||||
const resize = (e) => {
|
||||
chart.resize();
|
||||
emit('resize', e, props.id);
|
||||
};
|
||||
const openMsgBox = () => {
|
||||
MsgBoxVisible.value = true;
|
||||
};
|
||||
onMounted(() => {
|
||||
chart = echarts.init(chartRef.value, 'macarons');
|
||||
chart.setOption(getOption(), true);
|
||||
});
|
||||
watch(() => props.inputData, () => {
|
||||
chart.setOption(getOption(), true);
|
||||
}, { deep: true });
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.custom-node {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.info {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,209 @@
|
||||
<template>
|
||||
<div
|
||||
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
|
||||
<NodeResizer color="#000" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
|
||||
|
||||
<div class="custom-node" :style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">
|
||||
<div style="width: 100%;height: 100%" ref="chartRef" />
|
||||
</div>
|
||||
<Handle v-if="!props.isView" :id="`${props.id}.-t`" type="target" :position="Position.Left" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { defineEmits, defineProps, ref } from 'vue';
|
||||
import { NodeResizer } from '@vue-flow/node-resizer';
|
||||
import { Handle, Position } from '@vue-flow/core';
|
||||
import * as echarts from 'echarts';
|
||||
|
||||
const props = defineProps({
|
||||
isView: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
inputData: {
|
||||
type: Object,
|
||||
required: false
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
isHideHandle: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
selected: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
dimensions: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
const chartRef = ref();
|
||||
let chart = null;
|
||||
const colorList = ['#9E87FF', '#73DDFF', '#fe9a8b', '#F56948', '#9E87FF'];
|
||||
const getOption = () => {
|
||||
return {
|
||||
title: {
|
||||
text: '设备运行数量',
|
||||
textStyle: {
|
||||
fontSize: 12,
|
||||
fontWeight: 400,
|
||||
color: '#fff'
|
||||
},
|
||||
left: '0',
|
||||
top: '5%'
|
||||
},
|
||||
legend: {
|
||||
icon: 'circle',
|
||||
top: '5%',
|
||||
right: '5%',
|
||||
itemWidth: 6,
|
||||
itemGap: 20,
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
label: {
|
||||
show: true,
|
||||
backgroundColor: '#fff',
|
||||
color: '#000',
|
||||
borderColor: 'rgba(0,0,0,0)',
|
||||
shadowColor: 'rgba(0,0,0,0)',
|
||||
shadowOffsetY: 0
|
||||
},
|
||||
lineStyle: {
|
||||
width: 0
|
||||
}
|
||||
},
|
||||
backgroundColor: '#fff',
|
||||
textStyle: {
|
||||
color: '#000'
|
||||
},
|
||||
padding: [10, 10],
|
||||
extraCssText: 'box-shadow: 1px 0 2px 0 rgba(163,163,163,0.5)'
|
||||
},
|
||||
grid: {
|
||||
top: '30%',
|
||||
bottom: '10%'
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
data: props.inputData?.time || [],
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#DCE2E8'
|
||||
}
|
||||
},
|
||||
axisTick: {
|
||||
show: true
|
||||
},
|
||||
axisLabel: {
|
||||
interval: 0,
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
},
|
||||
// 默认x轴字体大小
|
||||
fontSize: 12,
|
||||
// margin:文字到x轴的距离
|
||||
margin: 3
|
||||
},
|
||||
axisPointer: {
|
||||
label: {
|
||||
padding: [0, 0, 0, 0],
|
||||
margin: 0,
|
||||
// 移入时的字体大小
|
||||
fontSize: 12
|
||||
}
|
||||
},
|
||||
boundaryGap: true
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '数量',
|
||||
type: 'line',
|
||||
data: props.inputData?.value || [],
|
||||
symbolSize: 1,
|
||||
symbol: 'circle',
|
||||
smooth: true,
|
||||
yAxisIndex: 0,
|
||||
showSymbol: false,
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
|
||||
{
|
||||
offset: 0,
|
||||
color: '#9effff'
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: '#9E87FF'
|
||||
}
|
||||
]),
|
||||
shadowColor: 'rgba(158,135,255, 0.3)',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetY: 20
|
||||
},
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: colorList[0],
|
||||
borderColor: colorList[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
};
|
||||
onMounted(() => {
|
||||
chart = echarts.init(chartRef.value, 'macarons');
|
||||
chart.setOption(getOption(), true);
|
||||
});
|
||||
watch(() => props.inputData, () => {
|
||||
chart.setOption(getOption(), true);
|
||||
}, { deep: true });
|
||||
const emit = defineEmits(['resize']);
|
||||
const resize = (e) => {
|
||||
chart.resize();
|
||||
emit('resize', e, props.id);
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.custom-node {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
</style>
|
@ -0,0 +1,94 @@
|
||||
<template>
|
||||
<div
|
||||
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
|
||||
<NodeResizer color="#000" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
|
||||
|
||||
<div class="custom-node" :style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">
|
||||
<el-button type="primary" :style="{width:props.dimensions.width +'px',height:props.dimensions.height+'px'}"
|
||||
:icon="Connection">设备运行数量
|
||||
</el-button>
|
||||
<span style="color:#fff">
|
||||
</span>
|
||||
</div>
|
||||
<Handle v-if="!props.isView" :id="`${props.id}.-t`" type="target" :position="Position.Left" />
|
||||
<Handle v-if="!props.isView" :id="`${props.id}.-s`" type="source" :position="Position.Right" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { defineEmits, defineProps, ref } from 'vue';
|
||||
import { NodeResizer } from '@vue-flow/node-resizer';
|
||||
import { Connection } from '@element-plus/icons-vue';
|
||||
import { Handle, Position } from '@vue-flow/core';
|
||||
import axios from 'axios';
|
||||
|
||||
const props = defineProps({
|
||||
isView: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
inputData: {
|
||||
type: Object,
|
||||
required: false
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
isHideHandle: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
selected: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
dimensions: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
const service = axios.create({
|
||||
baseURL: 'http://localhost:3000',
|
||||
timeout: 10000
|
||||
});
|
||||
const getOutputData = () => {
|
||||
service({
|
||||
method: 'post',
|
||||
url: '/test/getDevice',
|
||||
data: props.inputData
|
||||
}).then(res => {
|
||||
props.data.outputData = {
|
||||
time: res.data?.data?.map(e => e.time),
|
||||
value: res.data?.data?.map(e => e.value)
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getOutputData();
|
||||
});
|
||||
|
||||
let interval = setInterval(() => {
|
||||
getOutputData();
|
||||
}, 1000);
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
clearInterval(interval);
|
||||
interval = null;
|
||||
});
|
||||
const emit = defineEmits(['resize']);
|
||||
const resize = (e) => {
|
||||
emit('resize', e, props.id);
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.custom-node {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
</style>
|
@ -0,0 +1,65 @@
|
||||
<template>
|
||||
<div
|
||||
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
|
||||
<NodeResizer color="#000" v-if="!props.isView && !props.isHideHandle && props.selected" @resize="resize" />
|
||||
|
||||
<div class="custom-node" :style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">
|
||||
<el-input v-model="input" placeholder="输入值" style="width: 100%;height: 100%" />
|
||||
</div>
|
||||
<Handle v-if="!props.isView" :id="`${props.id}.-t`" type="target" :position="Position.Left" />
|
||||
<Handle v-if="!props.isView" :id="`${props.id}.-s`" type="source" :position="Position.Right" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { defineEmits, defineProps, ref } from 'vue';
|
||||
import { NodeResizer } from '@vue-flow/node-resizer';
|
||||
import { Handle, Position } from '@vue-flow/core';
|
||||
|
||||
const input = ref('');
|
||||
const props = defineProps({
|
||||
isView: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
inputData: {
|
||||
type: Object,
|
||||
required: false
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
isHideHandle: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
selected: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
dimensions: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
watch(() => input.value, () => {
|
||||
if (props.data?.options?.field) {
|
||||
props.data.outputData[props.data.options.field] = input.value;
|
||||
}
|
||||
}, { deep: true });
|
||||
const emit = defineEmits(['resize']);
|
||||
const resize = (e) => {
|
||||
emit('resize', e, props.id);
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.custom-node {
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
||||
|
@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<div
|
||||
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px'}">
|
||||
<NodeResizer color="#000" v-if="!props.isView && !props.isHideHandle && props.selected"
|
||||
@resize="resize" />
|
||||
|
||||
<div class="custom-node"
|
||||
:style="{width:props.dimensions.width+'px',height:props.dimensions.height+'px',pointerEvents:props.isView?'auto': 'none'}">
|
||||
<el-date-picker
|
||||
v-model="value"
|
||||
type="datetimerange"
|
||||
range-separator="到"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
style="width: 100%;height: 100%"
|
||||
/>
|
||||
</div>
|
||||
<Handle v-if="!props.isView" :id="`${props.id}.-t`" type="target" :position="Position.Left" />
|
||||
<Handle v-if="!props.isView" :id="`${props.id}.-s`" type="source" :position="Position.Right" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { defineEmits, defineProps, ref } from 'vue';
|
||||
import { NodeResizer } from '@vue-flow/node-resizer';
|
||||
import { Handle, Position } from '@vue-flow/core';
|
||||
|
||||
const value = ref('');
|
||||
const props = defineProps({
|
||||
isView: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
inputData: {
|
||||
type: Object,
|
||||
required: false
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
isHideHandle: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
selected: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
dimensions: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
watch(() => value, () => {
|
||||
if (props.data?.options?.startTimeId) {
|
||||
props.data.outputData[props.data.options.startTimeId || 'startTime'] = value.value[0];
|
||||
}
|
||||
if (props.data?.options?.endTimeId) {
|
||||
props.data.outputData[props.data.options.endTimeId || 'endTime'] = value.value[1];
|
||||
}
|
||||
}, { deep: true });
|
||||
const emit = defineEmits(['resize']);
|
||||
const resize = (e) => {
|
||||
emit('resize', e, props.id);
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.custom-node {
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,151 +0,0 @@
|
||||
<template>
|
||||
<div :style="`transform: rotate(${props.data.options?.rotate || 0}deg);cursor: progress;`">
|
||||
|
||||
<div class="custom-node" :style="{width:props.width}">
|
||||
</div>
|
||||
<NodeResizer :color="color || '#000' " v-if="!props.isHideHandle && props.selected" @resize="resize" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { defineEmits, defineProps, ref, watch } from 'vue';
|
||||
import { Handle, Position } from '@vue-flow/core';
|
||||
import { NodeResizer } from '@vue-flow/node-resizer';
|
||||
|
||||
const props = defineProps({
|
||||
color: {
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
isAlm: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
isHideHandle: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
selected: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
dimensions: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
deviceData: {
|
||||
type: Object,
|
||||
required: false
|
||||
}
|
||||
});
|
||||
const emit = defineEmits(['resize']);
|
||||
const resize = (e) => {
|
||||
emit('resize', e, props.id);
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.custom-node {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.counter {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.tsj-div {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
justify-self: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tsj {
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.icon-tishengji1 {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 0;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.deviceIdAndName {
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
left: 100%;
|
||||
width: 50%;
|
||||
top: 0%;
|
||||
white-space: pre-wrap;
|
||||
text-align: left;
|
||||
|
||||
}
|
||||
|
||||
.info {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 100%;
|
||||
transform: translateY(-50%);
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.value {
|
||||
display: inline-block;
|
||||
width: 2vw;
|
||||
height: 0.4vw;
|
||||
line-height: 0.4vw;
|
||||
font-size: 0.4vw;
|
||||
text-align: center;
|
||||
vertical-align: top;
|
||||
background-color: #00ff02;
|
||||
}
|
||||
|
||||
.unit {
|
||||
display: inline-block;
|
||||
width: 0.6vw;
|
||||
height: 0.4vw;
|
||||
line-height: 0.4vw;
|
||||
font-size: 0.4vw;
|
||||
text-align: center;
|
||||
vertical-align: top;
|
||||
background-color: #01a098;
|
||||
}
|
||||
|
||||
.alarmInfo {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 100%;
|
||||
transform: translate(-50%, -50%);
|
||||
text-align: center;
|
||||
font-size: 0.4vw;
|
||||
line-height: 0.6vw;
|
||||
white-space: nowrap;
|
||||
animation: colourSwitching 0.5s infinite;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@keyframes colourSwitching {
|
||||
0% {
|
||||
color: #ffff00;
|
||||
}
|
||||
50% {
|
||||
color: #ff0000;
|
||||
}
|
||||
100% {
|
||||
color: #ffff00;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<div style="pointer-events: none">
|
||||
<div class="custom-node">
|
||||
<div class="area" style="width:1910px;height:970px;border: 1px solid #fff"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineProps } from 'vue';
|
||||
|
||||
const props = defineProps({});
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -0,0 +1,381 @@
|
||||
<template>
|
||||
<div class="content" :style="{width:area.width+'px',height: area.height+'px'}">
|
||||
<div v-for="i in nodes" class="node" :style="{left:i.position?.x+'px',top: i.position?.y+'px'}">
|
||||
<template v-if="i.type === 'line'">
|
||||
<LineNode :isView="true" :inputData=getInputData(i.id) v-bind="i"></LineNode>
|
||||
</template>
|
||||
<template v-if="i.type === 'data'">
|
||||
<DataNode :isView="true" :inputData=getInputData(i.id) v-bind="i"></DataNode>
|
||||
</template>
|
||||
<template v-if="i.type === 'inputNode'">
|
||||
<InputNode :isView="true" :inputData=getInputData(i.id) v-bind="i"></InputNode>
|
||||
</template>
|
||||
<template v-if="i.type === 'time'">
|
||||
<TimeNode :isView="true" :inputData=getInputData(i.id) v-bind="i"></TimeNode>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import TimeNode from '@/views/boardGenerate/nodes/form/timeNode.vue';
|
||||
import DataNode from '@/views/boardGenerate/nodes/data/dataNode.vue';
|
||||
import LineNode from '@/views/boardGenerate/nodes/board/lineNode.vue';
|
||||
import InputNode from '@/views/boardGenerate/nodes/form/inputNode.vue';
|
||||
|
||||
const nodes = ref([
|
||||
{
|
||||
'id': 'area_474cfc79_4011_495e_9fb3_5e268ad09cfe',
|
||||
'type': 'area',
|
||||
'dimensions': { 'width': 1910, 'height': 970 },
|
||||
'computedPosition': { 'x': 0, 'y': 0, 'z': 0 },
|
||||
'handleBounds': { 'source': null, 'target': null },
|
||||
'selected': false,
|
||||
'dragging': false,
|
||||
'resizing': false,
|
||||
'initialized': false,
|
||||
'isParent': false,
|
||||
'position': { 'x': 0, 'y': 0 },
|
||||
'data': { 'label': 'area_474cfc79_4011_495e_9fb3_5e268ad09cfe' },
|
||||
'events': {},
|
||||
'name': 'area'
|
||||
},
|
||||
{
|
||||
'id': 'time_500c79d5_2a5a_4369_a37f_98a90f792547',
|
||||
'type': 'time',
|
||||
'dimensions': { 'width': 100, 'height': 100 },
|
||||
'computedPosition': { 'x': 106.65085072834671, 'y': 39.36769433739843, 'z': 0 },
|
||||
'handleBounds': {
|
||||
'source': [{
|
||||
'id': 'time_500c79d5_2a5a_4369_a37f_98a90f792547.-s',
|
||||
'type': 'source',
|
||||
'nodeId': 'time_500c79d5_2a5a_4369_a37f_98a90f792547',
|
||||
'position': 'right',
|
||||
'x': 97.00007501159526,
|
||||
'y': 47.00005927633669,
|
||||
'width': 6,
|
||||
'height': 6
|
||||
}],
|
||||
'target': [{
|
||||
'id': 'time_500c79d5_2a5a_4369_a37f_98a90f792547.-t',
|
||||
'type': 'target',
|
||||
'nodeId': 'time_500c79d5_2a5a_4369_a37f_98a90f792547',
|
||||
'position': 'left',
|
||||
'x': -2.9999932235447186,
|
||||
'y': 47.00005927633669,
|
||||
'width': 6,
|
||||
'height': 6
|
||||
}]
|
||||
},
|
||||
'selected': false,
|
||||
'dragging': false,
|
||||
'resizing': false,
|
||||
'initialized': false,
|
||||
'isParent': false,
|
||||
'position': { 'x': 106.65085072834671, 'y': 39.36769433739843 },
|
||||
'data': {
|
||||
'label': 'time_500c79d5_2a5a_4369_a37f_98a90f792547',
|
||||
'options': { 'startTimeId': 'startTime', 'endTimeId': 'endTime' },
|
||||
'outputData': {}
|
||||
},
|
||||
'events': {},
|
||||
'name': 'time'
|
||||
},
|
||||
{
|
||||
'id': 'data_b9663ba9_503c_449a_a24b_1d2cceaa3818',
|
||||
'type': 'data',
|
||||
'dimensions': { 'width': 200, 'height': 50 },
|
||||
'computedPosition': { 'x': 468.30045871559633, 'y': -251.0728211009174, 'z': 0 },
|
||||
'handleBounds': {
|
||||
'source': [{
|
||||
'id': 'data_b9663ba9_503c_449a_a24b_1d2cceaa3818.-s',
|
||||
'type': 'source',
|
||||
'nodeId': 'data_b9663ba9_503c_449a_a24b_1d2cceaa3818',
|
||||
'position': 'right',
|
||||
'x': 197.00014324673523,
|
||||
'y': 22.000023835240277,
|
||||
'width': 6,
|
||||
'height': 6
|
||||
}],
|
||||
'target': [{
|
||||
'id': 'data_b9663ba9_503c_449a_a24b_1d2cceaa3818.-t',
|
||||
'type': 'target',
|
||||
'nodeId': 'data_b9663ba9_503c_449a_a24b_1d2cceaa3818',
|
||||
'position': 'left',
|
||||
'x': -2.9999932235447186,
|
||||
'y': 22.000023835240277,
|
||||
'width': 6,
|
||||
'height': 6
|
||||
}]
|
||||
},
|
||||
'selected': false,
|
||||
'dragging': false,
|
||||
'resizing': false,
|
||||
'initialized': false,
|
||||
'isParent': false,
|
||||
'position': { 'x': 468.30045871559633, 'y': -251.0728211009174 },
|
||||
'data': {
|
||||
'label': 'data_b9663ba9_503c_449a_a24b_1d2cceaa3818',
|
||||
'options': {},
|
||||
'outputData': {
|
||||
'time': ['2025-01-01 00:00:00', '2025-01-03 00:00:00', '2025-01-05 00:00:00'],
|
||||
'value': [20, 30, 40]
|
||||
}
|
||||
},
|
||||
'events': {},
|
||||
'name': 'data'
|
||||
},
|
||||
{
|
||||
'id': 'line_77194e11_6df2_4e80_b9d7_816dac933f62',
|
||||
'type': 'line',
|
||||
'dimensions': { 'width': 300, 'height': 150 },
|
||||
'computedPosition': { 'x': 94.76924191953978, 'y': 216.41751167721483, 'z': 1000 },
|
||||
'handleBounds': {
|
||||
'source': null,
|
||||
'target': [{
|
||||
'id': 'line_77194e11_6df2_4e80_b9d7_816dac933f62.-t',
|
||||
'type': 'target',
|
||||
'nodeId': 'line_77194e11_6df2_4e80_b9d7_816dac933f62',
|
||||
'position': 'left',
|
||||
'x': -2.9999932235447186,
|
||||
'y': 72.00005795281027,
|
||||
'width': 6,
|
||||
'height': 6
|
||||
}]
|
||||
},
|
||||
'selected': true,
|
||||
'dragging': false,
|
||||
'resizing': false,
|
||||
'initialized': false,
|
||||
'isParent': false,
|
||||
'position': { 'x': 94.76924191953978, 'y': 216.41751167721483 },
|
||||
'data': { 'label': 'line_77194e11_6df2_4e80_b9d7_816dac933f62', 'options': {}, 'outputData': {} },
|
||||
'events': {},
|
||||
'name': 'line'
|
||||
}
|
||||
]);
|
||||
const edges = ref([
|
||||
{
|
||||
'id': 'time_500c79d5_2a5a_4369_a37f_98a90f792547---data_b9663ba9_503c_449a_a24b_1d2cceaa3818',
|
||||
'type': 'bezier',
|
||||
'source': 'time_500c79d5_2a5a_4369_a37f_98a90f792547',
|
||||
'target': 'data_b9663ba9_503c_449a_a24b_1d2cceaa3818',
|
||||
'sourceHandle': 'time_500c79d5_2a5a_4369_a37f_98a90f792547.-s',
|
||||
'data': {},
|
||||
'events': {},
|
||||
'label': '',
|
||||
'animated': true,
|
||||
'markerEnd': 'arrowclosed',
|
||||
'style': { 'stroke': '#409EFF' },
|
||||
'sourceNode': {
|
||||
'id': 'time_500c79d5_2a5a_4369_a37f_98a90f792547',
|
||||
'type': 'time',
|
||||
'dimensions': { 'width': 100, 'height': 100 },
|
||||
'computedPosition': { 'x': 106.65085072834671, 'y': 39.36769433739843, 'z': 0 },
|
||||
'handleBounds': {
|
||||
'source': [{
|
||||
'id': 'time_500c79d5_2a5a_4369_a37f_98a90f792547.-s',
|
||||
'type': 'source',
|
||||
'nodeId': 'time_500c79d5_2a5a_4369_a37f_98a90f792547',
|
||||
'position': 'right',
|
||||
'x': 97.00007501159526,
|
||||
'y': 47.00005927633669,
|
||||
'width': 6,
|
||||
'height': 6
|
||||
}],
|
||||
'target': [{
|
||||
'id': 'time_500c79d5_2a5a_4369_a37f_98a90f792547.-t',
|
||||
'type': 'target',
|
||||
'nodeId': 'time_500c79d5_2a5a_4369_a37f_98a90f792547',
|
||||
'position': 'left',
|
||||
'x': -2.9999932235447186,
|
||||
'y': 47.00005927633669,
|
||||
'width': 6,
|
||||
'height': 6
|
||||
}]
|
||||
},
|
||||
'selected': false,
|
||||
'dragging': false,
|
||||
'resizing': false,
|
||||
'initialized': false,
|
||||
'isParent': false,
|
||||
'position': { 'x': 106.65085072834671, 'y': 39.36769433739843 },
|
||||
'data': {
|
||||
'label': 'time_500c79d5_2a5a_4369_a37f_98a90f792547',
|
||||
'options': { 'startTimeId': 'startTime', 'endTimeId': 'endTime' },
|
||||
'outputData': {}
|
||||
},
|
||||
'events': {},
|
||||
'name': 'time'
|
||||
},
|
||||
'targetNode': {
|
||||
'id': 'data_b9663ba9_503c_449a_a24b_1d2cceaa3818',
|
||||
'type': 'data',
|
||||
'dimensions': { 'width': 200, 'height': 50 },
|
||||
'computedPosition': { 'x': 468.30045871559633, 'y': -251.0728211009174, 'z': 0 },
|
||||
'handleBounds': {
|
||||
'source': [{
|
||||
'id': 'data_b9663ba9_503c_449a_a24b_1d2cceaa3818.-s',
|
||||
'type': 'source',
|
||||
'nodeId': 'data_b9663ba9_503c_449a_a24b_1d2cceaa3818',
|
||||
'position': 'right',
|
||||
'x': 197.00014324673523,
|
||||
'y': 22.000023835240277,
|
||||
'width': 6,
|
||||
'height': 6
|
||||
}],
|
||||
'target': [{
|
||||
'id': 'data_b9663ba9_503c_449a_a24b_1d2cceaa3818.-t',
|
||||
'type': 'target',
|
||||
'nodeId': 'data_b9663ba9_503c_449a_a24b_1d2cceaa3818',
|
||||
'position': 'left',
|
||||
'x': -2.9999932235447186,
|
||||
'y': 22.000023835240277,
|
||||
'width': 6,
|
||||
'height': 6
|
||||
}]
|
||||
},
|
||||
'selected': false,
|
||||
'dragging': false,
|
||||
'resizing': false,
|
||||
'initialized': false,
|
||||
'isParent': false,
|
||||
'position': { 'x': 468.30045871559633, 'y': -251.0728211009174 },
|
||||
'data': {
|
||||
'label': 'data_b9663ba9_503c_449a_a24b_1d2cceaa3818',
|
||||
'options': {},
|
||||
'outputData': {
|
||||
'time': ['2025-01-01 00:00:00', '2025-01-03 00:00:00', '2025-01-05 00:00:00'],
|
||||
'value': [20, 30, 40]
|
||||
}
|
||||
},
|
||||
'events': {},
|
||||
'name': 'data'
|
||||
},
|
||||
'sourceX': 209.65092573994195,
|
||||
'sourceY': 89.36775361373512,
|
||||
'targetX': 465.3004654920516,
|
||||
'targetY': -226.0727972656771
|
||||
},
|
||||
{
|
||||
'id': 'data_b9663ba9_503c_449a_a24b_1d2cceaa3818---line_77194e11_6df2_4e80_b9d7_816dac933f62',
|
||||
'type': 'bezier',
|
||||
'source': 'data_b9663ba9_503c_449a_a24b_1d2cceaa3818',
|
||||
'target': 'line_77194e11_6df2_4e80_b9d7_816dac933f62',
|
||||
'sourceHandle': 'data_b9663ba9_503c_449a_a24b_1d2cceaa3818.-s',
|
||||
'data': {},
|
||||
'events': {},
|
||||
'label': '',
|
||||
'animated': true,
|
||||
'markerEnd': 'arrowclosed',
|
||||
'style': { 'stroke': '#409EFF' },
|
||||
'sourceNode': {
|
||||
'id': 'data_b9663ba9_503c_449a_a24b_1d2cceaa3818',
|
||||
'type': 'data',
|
||||
'dimensions': { 'width': 200, 'height': 50 },
|
||||
'computedPosition': { 'x': 468.30045871559633, 'y': -251.0728211009174, 'z': 0 },
|
||||
'handleBounds': {
|
||||
'source': [{
|
||||
'id': 'data_b9663ba9_503c_449a_a24b_1d2cceaa3818.-s',
|
||||
'type': 'source',
|
||||
'nodeId': 'data_b9663ba9_503c_449a_a24b_1d2cceaa3818',
|
||||
'position': 'right',
|
||||
'x': 197.00014324673523,
|
||||
'y': 22.000023835240277,
|
||||
'width': 6,
|
||||
'height': 6
|
||||
}],
|
||||
'target': [{
|
||||
'id': 'data_b9663ba9_503c_449a_a24b_1d2cceaa3818.-t',
|
||||
'type': 'target',
|
||||
'nodeId': 'data_b9663ba9_503c_449a_a24b_1d2cceaa3818',
|
||||
'position': 'left',
|
||||
'x': -2.9999932235447186,
|
||||
'y': 22.000023835240277,
|
||||
'width': 6,
|
||||
'height': 6
|
||||
}]
|
||||
},
|
||||
'selected': false,
|
||||
'dragging': false,
|
||||
'resizing': false,
|
||||
'initialized': false,
|
||||
'isParent': false,
|
||||
'position': { 'x': 468.30045871559633, 'y': -251.0728211009174 },
|
||||
'data': {
|
||||
'label': 'data_b9663ba9_503c_449a_a24b_1d2cceaa3818',
|
||||
'options': {},
|
||||
'outputData': {
|
||||
'time': ['2025-01-01 00:00:00', '2025-01-03 00:00:00', '2025-01-05 00:00:00'],
|
||||
'value': [20, 30, 40]
|
||||
}
|
||||
},
|
||||
'events': {},
|
||||
'name': 'data'
|
||||
},
|
||||
'targetNode': {
|
||||
'id': 'line_77194e11_6df2_4e80_b9d7_816dac933f62',
|
||||
'type': 'line',
|
||||
'dimensions': { 'width': 300, 'height': 150 },
|
||||
'computedPosition': { 'x': 94.76924191953978, 'y': 216.41751167721483, 'z': 1000 },
|
||||
'handleBounds': {
|
||||
'source': null,
|
||||
'target': [{
|
||||
'id': 'line_77194e11_6df2_4e80_b9d7_816dac933f62.-t',
|
||||
'type': 'target',
|
||||
'nodeId': 'line_77194e11_6df2_4e80_b9d7_816dac933f62',
|
||||
'position': 'left',
|
||||
'x': -2.9999932235447186,
|
||||
'y': 72.00005795281027,
|
||||
'width': 6,
|
||||
'height': 6
|
||||
}]
|
||||
},
|
||||
'selected': true,
|
||||
'dragging': false,
|
||||
'resizing': false,
|
||||
'initialized': false,
|
||||
'isParent': false,
|
||||
'position': { 'x': 94.76924191953978, 'y': 216.41751167721483 },
|
||||
'data': { 'label': 'line_77194e11_6df2_4e80_b9d7_816dac933f62', 'options': {}, 'outputData': {} },
|
||||
'events': {},
|
||||
'name': 'line'
|
||||
},
|
||||
'sourceX': 671.3006019623316,
|
||||
'sourceY': -226.0727972656771,
|
||||
'targetX': 91.76924869599506,
|
||||
'targetY': 291.4175696300251
|
||||
}
|
||||
]);
|
||||
const area = ref({
|
||||
width: 1910,
|
||||
height: 970
|
||||
});
|
||||
const getInputData = (e) => {
|
||||
let outputData = {};
|
||||
let nodeIds = edges.value.map(v => {
|
||||
if (v.target === e) {
|
||||
return v.source;
|
||||
}
|
||||
});
|
||||
nodes.value.forEach(v => {
|
||||
if (nodeIds.includes(v.id)) {
|
||||
outputData = {
|
||||
...outputData,
|
||||
...v.data.outputData
|
||||
};
|
||||
}
|
||||
});
|
||||
console.log(outputData);
|
||||
return outputData;
|
||||
};
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.content {
|
||||
position: absolute;
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.node {
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue