添加编辑器组件和新的电路元件图片

main
suixy 1 month ago
parent a358835d9f
commit 7156424030

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

@ -1,9 +1,13 @@
<template>
<div style="width: 100%; height: 100vh">
<div class="top"></div>
<div class="top">
<el-button type="primary">保存</el-button>
<el-button type="info" @click="setPageData"></el-button>
</div>
<div class="left">
<el-divider content-position="left">基础</el-divider>
<el-card
class="moduleCard"
class="moduleCard1"
shadow="never"
:draggable="true"
@dragstart="onDragStart($event, 'line', {})"
@ -11,12 +15,14 @@
:body-style="{ padding: '4px 0' }"
>
<template #header>
<div style="position: absolute; top: 50%; transform: translateY(-50%); width: 64px; height: 1px; background-color: #0002"></div>
<div
style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 64px; height: 1px; background-color: #0002"
></div>
</template>
<div class="moduleText">线</div>
</el-card>
<el-card
class="moduleCard"
class="moduleCard1"
shadow="never"
:draggable="true"
@dragstart="onDragStart($event, 'text1', {})"
@ -24,10 +30,11 @@
:body-style="{ padding: '4px 0' }"
>
<template #header>
<div style="position: absolute; top: 50%; transform: translateY(-50%); width: 64px; height: 1px; background-color: #0002"></div>
<div style="text-align: center; line-height: 50px">文字</div>
</template>
<div class="moduleText">文字</div>
</el-card>
<el-divider content-position="left">元件</el-divider>
<el-card
class="moduleCard"
shadow="never"
@ -78,22 +85,27 @@
@node-double-click="logEvent('dblclick', $event)"
@dragover="onDragOver"
>
<Background :size="1" :gap="20" pattern-color="#BDBDBD" style="background-color: #fff" />
<Background
:size="1"
:gap="20"
:pattern-color="nodes.find((e) => (e.type = 'area'))?.data.style.patternColor || '#0000'"
:style="`background-color: ${nodes.find((e) => (e.type = 'area'))?.data.style.backgroundColor}`"
/>
<template #node-area="props">
<AreaNode v-bind="props" :pageData="{ width: '960px', height: '540px' }"></AreaNode>
</template>
<template #node-circuitComponent="props">
<CircuitComponentNode :monitorType="monitorType" v-bind="props" :networkData="dataTest" />
<CircuitComponentNode :monitorType="monitorType" v-bind="props" :networkData="deviceData" />
</template>
<template #node-deviceDataList="props">
<DeviceDataListNode :monitorType="monitorType" v-bind="props" :networkData="dataTest" :pNode="findNode(props.parentNodeId)" />
<DeviceDataListNode :monitorType="monitorType" v-bind="props" :networkData="deviceData" :nodes="nodes" />
</template>
<template #node-line="props">
<LineNode :monitorType="monitorType" v-bind="props" />
</template>
<template #node-text1="props">
<TextNode :monitorType="monitorType" v-bind="props" :networkData="dataTest" />
<TextNode :monitorType="monitorType" v-bind="props" :networkData="deviceData" />
</template>
</VueFlow>
</div>
@ -109,6 +121,16 @@
<el-form-item label="节点内容" label-width="120px" v-if="['text1'].includes(nodeType)">
<el-input v-model="nodeData.value" autocomplete="off" />
</el-form-item>
<el-form-item label="参数展示" label-width="120px" v-if="['circuitComponent'].includes(nodeType)">
<el-select multiple v-model="nodeData.infos" placeholder="选择">
<el-option
:key="key"
:label="monitorType.find((e) => e.value === key)?.label"
:value="key"
v-for="(value, key) in deviceData.find((e) => e.id === nodeData.id)?.options"
/>
</el-select>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
@ -116,8 +138,20 @@
</div>
</template>
</el-dialog>
<el-dialog draggable v-model="pageDataVisible" title="页面配置" width="500">
<el-form :model="pageData">
<el-form-item label="背景颜色" label-width="120px">
<el-color-picker v-model="pageData.backgroundColor" show-alpha />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="pageDataVisible = false">关闭</el-button>
</div>
</template>
</el-dialog>
<el-dialog :modal="false" :modal-penetrable="true" draggable v-model="nodeStyleVisible" title="节点配置" width="500">
<el-dialog :modal="false" :modal-penetrable="true" draggable v-model="nodeStyleVisible" title="节点样式配置" width="500">
<el-form :model="nodeStyle">
<el-form-item label="对齐方式" label-width="120px" v-if="Object.hasOwn(nodeStyle, 'align')">
<el-select v-model="nodeStyle.align" placeholder="Select">
@ -126,11 +160,23 @@
<el-option label="右对齐" value="right" />
</el-select>
</el-form-item>
<el-form-item label="冒号居中" label-width="120px" v-if="Object.hasOwn(nodeStyle, 'isColonCentered')">
<el-switch v-model="nodeStyle.isColonCentered" />
</el-form-item>
<el-form-item label="左右比例" label-width="120px" v-if="Object.hasOwn(nodeStyle, 'ratio') && nodeStyle.isColonCentered">
<el-slider v-model="nodeStyle.ratio" :min="1" :max="100" />
</el-form-item>
<el-form-item label="颜色" label-width="120px" v-if="Object.hasOwn(nodeStyle, 'color')">
<el-color-picker v-model="nodeStyle.color" show-alpha />
</el-form-item>
<el-form-item label="文字颜色" label-width="120px" v-if="Object.hasOwn(nodeStyle, 'color1')">
<el-color-picker v-model="nodeStyle.color1" show-alpha />
</el-form-item>
<el-form-item label="数值颜色" label-width="120px" v-if="Object.hasOwn(nodeStyle, 'color2')">
<el-color-picker v-model="nodeStyle.color2" show-alpha />
</el-form-item>
<el-form-item label="是否允许换行" label-width="120px" v-if="Object.hasOwn(nodeStyle, 'whiteSpace')">
<el-switch v-model="nodeStyle.whiteSpace" active-value="nowrap" inactive-value="normal" />
<el-switch v-model="nodeStyle.whiteSpace" active-value="normal" inactive-value="nowrap" />
</el-form-item>
<el-form-item label="线类型" label-width="120px" v-if="Object.hasOwn(nodeStyle, 'lineType')">
<el-select v-model="nodeStyle.lineType" placeholder="Select">
@ -156,6 +202,9 @@
<el-option label="下" value="bottom" />
</el-select>
</el-form-item>
<el-form-item label="字体大小" label-width="120px" v-if="Object.hasOwn(nodeStyle, 'fontSize')">
<el-slider v-model="nodeStyle.fontSize" :min="6" :max="40" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
@ -185,6 +234,7 @@ const pid = ref(`area_${uuidv4().replaceAll('-', '_')}`);
const nodes = ref([
{
id: pid.value,
class: 'no-click',
name: 'area',
type: 'area',
position: {
@ -193,17 +243,23 @@ const nodes = ref([
},
selectable: false,
draggable: false,
data: {}
data: {
style: {
backgroundColor: '#fff'
}
}
}
]);
const edges = ref([]);
const isSnapToGrid = ref(true);
const nodeOptionVisible = ref(false);
const nodeStyleVisible = ref(false);
const pageDataVisible = ref(false);
const nodeType = ref('');
const nodeData = ref({});
const nodeStyle = ref({});
const dataTest = ref([
const pageData = ref({});
const deviceData = ref([
{
id: 'test-1',
options: {
@ -229,7 +285,7 @@ const monitorType = ref([
]);
const { onDragStart, onDrop, onDragOver } = tool();
const { addEdges, updateNode, removeNodes, addNodes, onNodesChange, findNode } = useVueFlow({ id: 'flowA' });
const { addEdges, updateNode, removeNodes, addNodes, onNodesChange } = useVueFlow({ id: 'flowA' });
const logEvent = async (eventname, event) => {
switch (eventname) {
@ -261,9 +317,14 @@ onNodesChange((changes) => {
}
});
});
const setPageData = () => {
pageDataVisible.value = true;
pageData.value = nodes.value.find((e) => (e.type = 'area'))?.data.style;
console.log(pageData.value);
};
onMounted(() => {
let scale = 0;
const width = rightRef.value.getBoundingClientRect().width;
const width = window.innerWidth - 220;
rightRef.value.style.width = width + 'px';
rightRef.value.style.height = (width * 540) / 960 + 'px';
scale = width / 960;
@ -296,14 +357,38 @@ watch(
.top {
width: 100%;
height: 50px;
line-height: 50px;
text-align: right;
padding-right: 20px;
}
.left {
display: inline-block;
width: 200px;
height: 100%;
height: calc(100% - 50px);
vertical-align: top;
.moduleCard1 {
width: calc(50% - 4px);
display: inline-block;
height: 100px;
:deep(.el-card__header) {
width: 100%;
height: 50px;
position: relative;
padding: 0 !important;
}
:deep(.el-card__body) {
padding: 0 20px 0 20px !important;
.moduleText {
line-height: 50px;
text-align: center;
}
}
}
.moduleCard {
width: calc(50% - 4px);
display: inline-block;
@ -320,6 +405,7 @@ watch(
.moduleText {
line-height: 50px;
text-align: center;
}
}
}
@ -327,9 +413,16 @@ watch(
.right {
display: inline-block;
width: calc(100% - 200px - 20px);
height: 100%;
position: absolute;
left: 200px;
}
:deep(.el-divider__text) {
background-color: #f5f7fb;
}
</style>
<style>
.no-click {
pointer-events: none !important;
}
</style>

@ -11,7 +11,47 @@
pointerEvents: props.isView ? 'auto' : 'none'
}"
>
<template v-for="i in 4"></template>
<div
:key="k"
v-for="(i, k) in list"
:style="{
whiteSpace: props.data.style.whiteSpace || 'nowrap',
textAlign: props.data.style.isColonCentered ? 'none' : props.data.style.align || 'center'
}"
>
<span
:style="{
color: props.data.style.color1,
lineHeight: props.dimensions.height * props.ratioHeight + 'px',
fontSize: `${props.data.style.fontSize || 12}px`,
display: props.data.style.isColonCentered ? 'inline-block' : 'inline',
width: props.data.style.isColonCentered ? `calc(${props.data.style.ratio}% - ${(props.data.style.fontSize + 6) / 2}px)` : +'auto',
textAlign: props.data.style.isColonCentered ? props.data.style.align || 'center' : 'none'
}"
>{{ i.label || i.key }}</span
>
<span
:style="{
color: props.data.style.color1,
lineHeight: props.dimensions.height * props.ratioHeight + 'px',
width: `${(props.data.style.fontSize || 12) + 4}px`,
fontSize: `${props.data.style.fontSize || 12}px`
}"
style="text-align: center"
>:</span
>
<span
:style="{
color: props.data.style.color2,
lineHeight: props.dimensions.height * props.ratioHeight + 'px',
fontSize: `${props.data.style.fontSize || 12}px`,
display: props.data.style.isColonCentered ? 'inline-block' : 'inline',
width: props.data.style.isColonCentered ? `calc(${100 - props.data.style.ratio}% - ${(props.data.style.fontSize + 6) / 2}px)` : +'auto',
textAlign: props.data.style.isColonCentered ? props.data.style.align || 'center' : 'none'
}"
>{{ i.value }}</span
>
</div>
</div>
</div>
</template>
@ -39,6 +79,10 @@ const props = defineProps({
type: Object,
required: false
},
parentNodeId: {
type: String,
required: true
},
id: {
type: String,
required: true
@ -63,20 +107,44 @@ const props = defineProps({
type: Array,
required: false
},
nodes: {
type: Array,
required: false
},
pNode: {
type: Object,
required: true
},
monitorType: {
type: Array,
required: true
}
});
console.log(props);
const list = ref([{}]);
const list = ref([]);
const pNode = computed(() => props.nodes.find((n) => n.id === props.parentNodeId));
const getList = () => {
let deviceData = props.networkData.find((e) => e.id === pNode.value.data.options.id)?.options;
let options = pNode.value.data.options.infos;
console.log(deviceData);
console.log(options);
console.log(props.monitorType);
list.value =
options?.map((e, i) => {
let item = {};
item.label = props.monitorType.find((v) => v.value === e)?.label;
item.key = e;
item.value = deviceData[e];
console.log(item);
return item;
}) || [];
};
onMounted(() => {
getList();
});
watch(
props.pNode.data.options,
() => pNode.value,
(obj1, obj2) => {
if (JSON.stringify(obj1) !== JSON.stringify(obj2)) {
}
getList();
},
{ deep: true }
);

@ -36,6 +36,16 @@ const getStyle = (e) => {
whiteSpace: 'nowrap',
color: '#000'
};
} else if (e === 'deviceDataList') {
return {
ratio: 50,
align: 'center',
whiteSpace: 'nowrap',
isColonCentered: false,
fontSize: 12,
color1: '#000',
color2: '#000'
};
} else {
return {};
}
@ -49,6 +59,8 @@ const getNodeSize = (e) => {
return { width: 100, height: 20 };
} else if (e === 'text1') {
return { width: 100, height: 20 };
} else {
return { width: 100, height: 20 };
}
};
const nameEnum = {};

@ -12,8 +12,8 @@
style="position: absolute"
v-for="i in nodes"
:style="{
left: (i.position?.x / 960) * 100 + '%',
top: (i.position?.y / 540) * 100 + '%'
left: (getAbsolutePosition(i.id).x / 960) * 100 + '%',
top: (getAbsolutePosition(i.id).y / 540) * 100 + '%'
}"
>
<CircuitComponentNode :ratioWidth="ratioWidth" :ratioHeight="ratioHeight" v-bind="i" :is-view="true" v-if="i.type === 'circuitComponent'" />
@ -23,13 +23,21 @@
<div class="textFlow">
<div
style="position: absolute"
v-for="i in nodes"
v-for="i in nodes.filter((e) => ['text1', 'deviceDataList'].includes(e.type))"
:style="{
left: (i.position?.x / 960) * 100 + '%',
top: (i.position?.y / 540) * 100 + '%'
left: (getAbsolutePosition(i.id).x / 960) * 100 + '%',
top: (getAbsolutePosition(i.id).y / 540) * 100 + '%'
}"
>
<TextNode :ratioWidth="ratioWidth" :ratioHeight="ratioHeight" v-bind="i" :is-view="true" v-if="i.type === 'text1'" />
<DeviceDataListNode
:pNode="findNode(i.parentNodeId)"
:ratioWidth="ratioWidth"
:ratioHeight="ratioHeight"
v-bind="i"
:is-view="true"
v-if="i.type === 'deviceDataList'"
/>
</div>
</div>
</div>
@ -39,6 +47,7 @@
import CircuitComponentNode from './nodes/circuitComponent.vue';
import LineNode from './nodes/line.vue';
import TextNode from './nodes/text.vue';
import DeviceDataListNode from './nodes/deviceDataList.vue';
const nodes = ref([]);
const centerRef = ref(null);
@ -46,6 +55,30 @@ const ratioWidth = ref(1);
const ratioHeight = ref(1);
const scaleX = ref(1);
const scaleY = ref(1);
const getAbsolutePosition = (id) => {
const node = nodes.value.find((n) => n.id === id);
if (!node) return { x: 0, y: 0 };
let x = node.position.x;
let y = node.position.y;
let parentId = node.parentNode;
while (parentId) {
const parent = nodes.value.find((n) => n.id === parentId);
if (!parent) break;
x += parent.position.x;
y += parent.position.y;
parentId = parent.parentNode;
}
return { x, y };
};
const findNode = (id) => {
return nodes.value.find((n) => n.id === id) || {};
};
onMounted(() => {
nodes.value = JSON.parse(localStorage.getItem('NODES') || '[]');
const rect = centerRef.value.getBoundingClientRect();

Loading…
Cancel
Save