Commit 1f4339e1 by 吴斌

update:两点间路径寻找

parent e759682e
......@@ -14,6 +14,9 @@
<div class="text-center m-4">
<el-button @click="showAddPropertyDialog">添加监听属性</el-button>
</div>
<div class="text-center m-4">
<el-button @click="analyseData">数据分析</el-button>
</div>
</div>
</div>
<div class="flex">
......@@ -68,7 +71,6 @@ import {
import {linkSelectionAdornmentTemplate, MultiArrowLink} from "./kit/LinkTemplateKit.ts";
import {Inspector} from "./kit/DataInspector.ts";
import {ElMessage} from "element-plus";
// import {drawSvg, svg_xml} from "./kit/parseXMLtoSVG.ts";
const categoryList: any = ref(null)
let myDiagram: any = null;
......@@ -83,7 +85,6 @@ function showAddPropertyDialog(){
if (node === null){
ElMessage.error("请先选择一个节点")
}
console.log(node.data)
propertyForm.value = {
key:'',
propertyList: Object.keys(node.data),
......@@ -91,7 +92,6 @@ function showAddPropertyDialog(){
showIfPresent: '',
readOnly: false,
}
console.log(propertyForm.value)
addProperty.value = true
}
......@@ -147,14 +147,16 @@ function initDiagram() {
new go.Binding("source", "img"),
new go.Binding('desiredSize', "img_size", go.Size.parse).makeTwoWay(go.Size.stringify)
),
GO(go.TextBlock, {margin: 4, text: "", editable: true, alignment: go.Spot.Top},
GO(go.TextBlock, {margin: 4, text: "", editable: true, alignment: go.Spot.Center, stroke:"blue", background:"white"},
new go.Binding("text", "name").makeTwoWay(),
new go.Binding('angle', "angle", v=>-v),
),
GO(go.TextBlock, {margin: 4, text: "", editable: true},
GO(go.TextBlock, {margin: 4, text: "", editable: true, alignment: go.Spot.Top},
new go.Binding("text", "press"),
new go.Binding("stroke", "",
function(data,_node) { return data.press>data.pressLimit?"red":"green"}
)
function(data,_node) { return data.press>10?"red":"green"}
),
new go.Binding('angle', "angle", v=>-v),
),
// four small named ports, one on each side:
makePort("T", go.Spot.Top, true, true),
......@@ -170,7 +172,25 @@ function initDiagram() {
},
},
{
toolTip:GO("ToolTip", GO(go.TextBlock, {margin: 4}, new go.Binding("text", "name")))
toolTip:GO("ToolTip",{background:"lightgray"},
GO(go.Panel, "Vertical",
GO(go.TextBlock, {margin: 4},
new go.Binding("text", "thick", v=>"厚度:"+v+'mm'),
new go.Binding("stroke", "",
function(data,_node) { return data.thick>10?"red":"green"})
),
GO(go.TextBlock, {margin: 4},
new go.Binding("text", "temperature", v=>"温度:"+v+'℃'),
new go.Binding("stroke", "",
function(data,_node) { return data.temperature>10?"red":"green"}),
),
GO(go.TextBlock, {margin: 4},
new go.Binding("text", "press", v=>"压力:"+v+'MPa'),
new go.Binding("stroke", "",
function(data,_node) { return data.press>10?"red":"green"}),
),
),
),
}
);
......@@ -180,9 +200,10 @@ function initDiagram() {
{relinkableFrom: true, relinkableTo: true, reshapable: true},
{routing: go.Link.AvoidsNodes, curve: go.Link.JumpGap, toShortLength: 4},
new go.Binding("points", "points").makeTwoWay(),
new go.Binding("stroke", "stroke").makeTwoWay(),
GO(go.Shape, // the link path shape
{isPanelMain: true, strokeWidth: 2},
new go.Binding("stroke", "color").makeTwoWay(),
new go.Binding("fill", "color"),
),
GO(go.TextBlock,
{ segmentIndex: 0, segmentOffset: new go.Point(NaN, NaN), segmentOrientation: go.Link.OrientUpright, editable:true, text:""},
......@@ -204,14 +225,21 @@ function initInfo() {
{
includesOwnProperties: false,
properties: {
"press": {show: Inspector.showIfNode, readOnly: true, name:"压力", unit:'MPa'},
//节点基本信息
"key": {show: Inspector.showIfPresent},
"name": {show: Inspector.showIfNode, name:'名称'},
"stroke": {show: Inspector.showIfPresent, type:'color', name:"颜色"},
"from":{show: Inspector.showIfPresent, name:"源", readOnly:true},
"to":{show: Inspector.showIfPresent, name:"目的", readOnly:true},
//连接线基本信息
"color": {show: Inspector.showIfLink, type:'color', name:"颜色"},
"from":{show: Inspector.showIfLink, name:"源", readOnly:true},
"to":{show: Inspector.showIfLink, name:"目的", readOnly:true},
"from_text": {show:Inspector.showIfLink, name:"源标签"},
"middle_text": {show:Inspector.showIfLink, name:"中间标签"},
"to_text": {show:Inspector.showIfLink, name:"目的标签"},
"thick":{show: Inspector.showIfNode, name:"厚度", unit:"mm"},
"temperature":{show: Inspector.showIfNode, name:"温度", unit:"℃"},
"press": {show: Inspector.showIfNode, name:"压力", unit:'MPa'},
"thing":{show: Inspector.showIfNode, name:"物料"},
}
});
}
......@@ -219,7 +247,6 @@ function initInfo() {
function addInspector(){
let value = propertyForm.value
inspector.properties[value.key] = {}
console.log(value)
if (value.showIfPresent === "true"){
inspector.properties[value.key].show = Inspector.showIfPresent
}
......@@ -237,53 +264,165 @@ function importData() {
{ "class": "GraphLinksModel",
"nodeDataArray": [
{"name":"压缩机","picture_category":"ammonia","img":"src/assets/models/ammonia/压缩机.svg","key":-7,"loc":"-460 120","angle":90,"img_size":"50 50"},
{"name":"冷却器-2","picture_category":"ammonia","img":"src/assets/models/ammonia/冷却器-2.svg","key":-6,"loc":"-320 120","img_size":"50 50","angle":180},
{"name":"换热器","picture_category":"ammonia","img":"src/assets/models/ammonia/换热器.svg","key":-3,"loc":"-170 130","img_size":"50 50"},
{"name":"换热器","picture_category":"ammonia","img":"src/assets/models/ammonia/换热器.svg","key":-4,"loc":"-170 230","img_size":"50 50"},
{"name":"氨分离罐","picture_category":"ammonia","img":"src/assets/models/ammonia/氨分离罐.svg","key":-1,"loc":"-170 340","angle":180,"img_size":"70 70"},
{"name":"冷却器-2","picture_category":"ammonia","img":"src/assets/models/ammonia/冷却器-2.svg","key":-6,"loc":"-310 120","img_size":"70 70","angle":180},
{"name":"换热器","picture_category":"ammonia","img":"src/assets/models/ammonia/换热器.svg","key":-3,"loc":"-170 130","img_size":"60 60"},
{"name":"换热器","picture_category":"ammonia","img":"src/assets/models/ammonia/换热器.svg","key":-4,"loc":"-170 250","img_size":"60 60","thick":0.9,"press":15,"temperature":20,"thing":""},
{"name":"氨分离罐","picture_category":"ammonia","img":"src/assets/models/ammonia/氨分离罐.svg","key":-1,"loc":"-170 370","angle":180,"img_size":"70 70","thick":0.88,"press":10,"temperature":20,"thing":""},
{"name":"冷却器-2","picture_category":"ammonia","img":"src/assets/models/ammonia/冷却器-2.svg","key":-8,"loc":"-170 0","img_size":"50 50","angle":270},
{"name":"冷却器","picture_category":"ammonia","img":"src/assets/models/ammonia/冷却器.svg","key":-5,"loc":"-310 -50","img_size":"50 60"},
{"name":"冷却器","picture_category":"ammonia","img":"src/assets/models/ammonia/冷却器.svg","key":-5,"loc":"-300 -50","img_size":"60 72"},
{"name":"氨分离罐","picture_category":"ammonia","img":"src/assets/models/ammonia/氨分离罐.svg","key":-9,"loc":"-460 -50","angle":270,"img_size":"90 90"},
{"name":"合成塔","picture_category":"ammonia","img":"src/assets/models/ammonia/合成塔.svg","key":-2,"loc":"-20 20","img_size":"240 240"},
{"name":"开工炉","picture_category":"ammonia","img":"src/assets/models/ammonia/开工炉.svg","key":-10,"loc":"200 20"}
{"name":"开工炉","picture_category":"ammonia","img":"src/assets/models/ammonia/开工炉.svg","key":-10,"loc":"200 20","thick":0.88,"press":10,"temperature":20,"thing":""}
],
"linkDataArray": [
{"from":-7,"to":-6,"points":[-435,120,-425,120,-390,120,-390,120,-355,120,-345,120],"from_text":"","to_text":"","middle_text":""},
{"to":-7,"points":[-581,120,-571,120,-533,120,-533,120,-495,120,-485,120],"from_text":"原料气","middle_text":"","to_text":""},
{"from":-4,"to":-3,"points":[-170,205,-170,195,-170,180,-170,180,-170,165,-170,155]},
{"from":-1,"to":-4,"points":[-170,305,-170,295,-170,280,-170,280,-170,265,-170,255]},
{"from":-6,"to":-1,"points":[-320,145,-320,155,-320,340,-267.5,340,-215,340,-205,340]},
{"from":-3,"to":-7,"points":[-195,130,-205,130,-204.734375,130,-204.734375,42,-460,42,-460,85,-460,95]},
{"from":-8,"to":-3,"points":[-170,25,-170,35,-170,65,-170,65,-170,95,-170,105]},
{"from":-3,"to":-5,"points":[-195,130,-205,130,-240,130,-240,-50,-275,-50,-285,-50]},
{"from":-5,"to":-9,"points":[-335,-50,-345,-50,-375,-50,-375,-50,-405,-50,-415,-50]},
{"from":-1,"to":-4,"points":[-170,335,-170,325,-170,307.5,-170,307.5,-170,290,-170,280]},
{"from":-6,"to":-1,"points":[-310,155,-310,165,-310,370,-262.5,370,-215,370,-205,370]},
{"from":-3,"to":-7,"points":[-200,130,-210,130,-212,130,-212,164,-356,164,-356,120,-425,120,-435,120]},
{"from":-8,"to":-3,"points":[-170,25,-170,35,-170,62.5,-170,62.5,-170,90,-170,100]},
{"from":-3,"to":-5,"points":[-200,130,-210,130,-235,130,-235,-50,-260,-50,-270,-50]},
{"from":-5,"to":-9,"points":[-330,-50,-340,-50,-372.5,-50,-372.5,-50,-405,-50,-415,-50]},
{"from":-9,"points":[-460,-95,-460,-105,-460,-117,-508,-117,-556,-117,-566,-117],"from_text":"","middle_text":"","to_text":"燃料气"},
{"from":-9,"points":[-460,-5,-460,5,-460,19,-513,19,-566,19,-576,19],"from_text":"","middle_text":"","to_text":"氨产品"},
{"from":-4,"to":-10,"points":[-145,230,-135,230,200,230,200,155,200,80,200,70]},
{"from":-4,"to":-2,"points":[-145,230,-135,230,-20,230,-20,190,-20,150,-20,140]},
{"from":-4,"to":-10,"points":[-140,250,-130,250,200,250,200,165,200,80,200,70]},
{"from":-4,"to":-2,"points":[-170,220,-170,210,-170,197,-20,197,-20,150,-20,140]},
{"from":-10,"to":-2,"points":[150,20,140,20,125,20,125,20,110,20,100,20]},
{"from":-8,"to":-2,"points":[-170,-25,-170,-35,-170,-166,-20,-166,-20,-110,-20,-100]},
{"from":-1,"points":[-170,375,-170,385,-170,386,-130,386,-91,386,-81,386]}
{"from":-1,"points":[-135,370,-125,370,-97.3671875,370,-97.3671875,370,-69.734375,370,-59.734375,370]}
]}
);
}
function exportData() {
console.log(myDiagram.model.toJson())
console.log(myDiagram.position)
// console.log(inspector.properties)
// console.log(myDiagram.position)
}
function analyseData(){
let selectedNodes = getSelectedNodes()
console.log("选择的节点", selectedNodes)
if (selectedNodes.length != 2){
ElMessage.error("只能选择两个节点")
return
}
let start_node = myDiagram.findNodeForKey(selectedNodes[0].key)
let end_node = myDiagram.findNodeForKey(selectedNodes[1].key)
findNodesAllWayBetween(start_node.data.key, end_node.data.key)
}
// 寻找两个节点间的所有路径
function findNodesAllWayBetween(startKey:number, endKey:number){
// 保存所有路径
let paths = [[startKey]],
// 搜索是否完成
flag:boolean = false,
nodeLinkMap = getMapData();
while(!flag){
// 保存当前路径的节点数量
let beforePathsNode = 0;
// 保存扩展后路径的节点数量
let afterPathsNode = 0;
// 计算扩展前的总路径节点数量
for (let path of paths){
beforePathsNode += path.length
}
for (let path of paths){
// 获取当前路径的最后一个节点
let lastNode = path[path.length-1]
// 如果最后一个节点是终点,则跳过,无需扩展
if (lastNode == endKey){
continue
}
// 获取当前路径最后一个节点的下一个节点
let nextNode = nodeLinkMap[lastNode].next
// 如果没有下一个节点,则跳过,无需扩展
if (nextNode.length ==0){
continue
}
// 如果只有一个节点,则将下一个节点直接加入当前路径
if (nextNode.length ==1 ){
path.push(nextNode[0])
}
// 如果有多个节点,则将当前路径分裂为多个路径
else{
for (let nextNodeKey of nextNode){
// 如果下一个节点已经在路径中,则跳过,无需扩展,避免循环
if (nextNodeKey in path){
continue
}
let newPath = path.slice(0)
newPath.push(nextNodeKey)
paths.push(newPath)
}
// 删除没有扩展的原路径
paths = paths.filter((item:any) => item != path
)
}
}
// 计算扩展后的总路径节点数量
for (let path of paths){
afterPathsNode += path.length
}
// 如果paths内元素数量没有增加,则搜索完成
if (beforePathsNode == afterPathsNode){
flag = true
// 删除没有找到终点的路径
paths = paths.filter((item:any) => item[item.length-1] == endKey)
}
}
return paths
}
function getSelectedNodes() {
let selectObjIterator = myDiagram.selection.iterator;
let resultNodes = [];
while (selectObjIterator.next()) {
let selectedObj = selectObjIterator.value;
if (selectedObj instanceof go.Node) {
resultNodes.push(selectedObj.data);
}
}
return resultNodes;
}
function getMapData() {
/*
* {key:{next:[], data:{}}}
*/
let model = myDiagram.model
let nodeDataArray = model.nodeDataArray
let linkDataArray = model.linkDataArray
let nodeMap = {}
nodeDataArray.forEach((item:any)=>{
nodeMap[item.key] = {next:[], data:item}
})
linkDataArray.forEach((item:any)=>{
let node = null;
if (item.from && item.to){
node = nodeMap[item.from]
node.next.push(item.to)
}
})
return nodeMap
}
function changePress(){
function changeData(){
let model = myDiagram.model
setInterval(()=>{
let nodeDataArray = myDiagram.model.nodeDataArray
nodeDataArray.forEach((item:any)=>{
if (item.category === "valve"){
if (item.picture_category === "ammonia"){
model.set(item, "press", Math.floor(Math.random()*100))
model.set(item, "thick", Math.random().toFixed(2)),
model.set(item, "temperature", Math.floor(Math.random()*10))
}
})
},1000)
},5000)
}
......@@ -292,7 +431,7 @@ onMounted(() => {
initDiagram();
initInfo();
importData();
changePress();
changeData();
})
</script>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment