Commit bb04c09c by jlc

update:连接线上管道和设备信息面板

parent 675bc2f3
/*
* Copyright (C) 1998-2023 by Northwoods Software Corporation. All Rights Reserved.
*/
/*
* This is an extension and not part of the main GoJS library.
* Note that the API for this class may change with any version, even point releases.
* If you intend to use an extension in production, you should copy the code to your own source directory.
* Extensions can be found in the GoJS kit under the extensions or extensionsJSM folders.
* See the Extensions intro page (https://gojs.net/latest/intro/extensions.html) for more information.
*/
import go from 'gojs';
/**
* The LinkLabelOnPathDraggingTool class lets the user move a label on a {@link Link} while keeping the label on the link's path.
* This tool only works when the Link has a label marked by the "_isLinkLabel" property.
*
* If you want to experiment with this extension, try the <a href="../../extensionsJSM/LinkLabelOnPathDragging.html">Link Label On Path Dragging</a> sample.
* @category Tool Extension
*/
export class LinkLabelOnPathDraggingTool extends go.Tool {
/**
* The label being dragged.
*/
public label: go.GraphObject | null = null;
private _originalFraction: number = 0.0;
/**
* Constructs a LinkLabelOnPathDraggingTool and sets the name for the tool.
*/
constructor() {
super();
this.name = 'LinkLabelOnPathDragging';
}
/**
* From the GraphObject at the mouse point, search up the visual tree until we get to
* an object that has the "_isLinkLabel" property set to true and that is an immediate child of a Link Panel.
* @return {GraphObject} This returns null if no such label is at the mouse down point.
*/
public findLabel(): go.GraphObject | null {
const diagram = this.diagram;
const e = diagram.lastInput;
let elt = diagram.findObjectAt(e.documentPoint, null, null);
if (elt === null || (!(elt.part instanceof go.Link) && !((elt.part as any)['labeledLink'] instanceof go.Link))) return null;
while (elt !== null && elt.panel !== elt.part) {
elt = elt.panel;
}
if (elt === null) return null
// If it's not marked as "_isLinkLabel", don't consider it a label:
if (!(elt as any)['_isLinkLabel'] && !((elt.part as any)['_isLinkLabel'])) return null;
return elt;
}
/**
* This tool can only start if the mouse has moved enough so that it is not a click,
* and if the mouse down point is on a GraphObject "label" in a Link Panel,
* as determined by {@link #findLabel}.
*/
public override canStart(): boolean {
if (!super.canStart()) return false;
const diagram = this.diagram;
if (diagram === null) return false;
// require left button & that it has moved far enough away from the mouse down point, so it isn't a click
const e = diagram.lastInput;
if (!e.left) return false;
if (!this.isBeyondDragSize()) return false;
return this.findLabel() !== null;
}
/**
* Start a transaction, call findLabel and remember it as the "label" property,
* and remember the original values for the label's segment properties.
*/
public override doActivate(): void {
this.startTransaction('Shifted Label');
this.label = this.findLabel();
if (this.label !== null) {
this._originalFraction = this.label.segmentFraction;
}
super.doActivate();
}
/**
* Stop any ongoing transaction.
*/
public override doDeactivate(): void {
super.doDeactivate();
this.stopTransaction();
}
/**
* Clear any reference to a label element.
*/
public override doStop(): void {
this.label = null;
super.doStop();
}
/**
* Restore the label's original value for GraphObject.segment... properties.
*/
public override doCancel(): void {
if (this.label !== null) {
this.label.segmentFraction = this._originalFraction;
}
super.doCancel();
}
/**
* During the drag, call {@link #updateSegmentOffset} in order to set the segment... properties of the label.
*/
public override doMouseMove(): void {
if (!this.isActive) return;
this.updateSegmentOffset();
}
/**
* At the end of the drag, update the segment properties of the label and finish the tool,
* completing a transaction.
*/
public override doMouseUp(): void {
if (!this.isActive) return;
this.updateSegmentOffset();
this.transactionResult = 'Shifted Label';
this.stopTool();
}
/**
* Save the label's {@link GraphObject#segmentFraction}
* at the closest point to the mouse.
*/
public updateSegmentOffset(): void {
const lab = this.label;
if (lab === null) return;
// const link = lab.part;
// if (!(link instanceof go.Link) || link.path === null) return;
var path = null
if (lab.part instanceof go.Link) {
path = lab.part.path
} else if ((lab.part as any)['labeledLink'] instanceof go.Link) {
path = (lab.part as any)['labeledLink'].path
}
const last = this.diagram.lastInput.documentPoint;
// find the fractional distance along the link path closest to this point
// const path = link.path;
if (path.geometry === null) return;
const localpt = path.getLocalPoint(last);
if (lab.part instanceof go.Link) {
lab.segmentFraction = path.geometry.getFractionForPoint(localpt);
} else if ((lab.part as any)['labeledLink'] instanceof go.Link) {
(lab.part as any).segmentFraction = path.geometry.getFractionForPoint(localpt);
}
}
}
......@@ -36,12 +36,17 @@
<button @click="addPort('bottom')">添加下端口</button>
<button @click="addPort('left')">添加左端口</button>
<button @click="addPort('right')">添加右端口</button>
<button style="margin-left: 280px" @click="addDataPanel">创建数据面板</button>
</div>
<div v-else>
<button @click="addMark()">添加标定点</button>
</div>
</div>
</el-dialog>
<el-dialog v-model="pipeDialogVisible" title="添加管道">
<button @click="addPipe">添加管道</button>
</el-dialog>
</template>
<script setup lang="ts">
......@@ -49,15 +54,17 @@ import { onMounted, ref } from 'vue';
import go from 'gojs';
import { PortShiftingTool } from './extensions/PortShiftingTool';
import { ResizeMultipleTool } from './extensions/ResizeMultipleTool';
import { LinkLabelDraggingTool } from './extensions/LinkLabelDraggingTools';
// import { LinkLabelDraggingTool } from './extensions/LinkLabelDraggingTools';
import { NodeLabelDraggingTool } from './extensions/NodeLabelDraggingTool';
import { GuidedDraggingTool } from './extensions/GuidedDraggingTool';
import { RotateMultipleTool } from './extensions/RotateMultipleTool';
import { ElMessage } from 'element-plus';
import { LinkLabelOnPathDraggingTool } from './extensions/LinkLabelOnPathDraggingTool';
const $ = go.GraphObject.make;
var myDiagram: any;
const dialogVisible = ref(false)
const pipeDialogVisible = ref(false)
const changeModel = ref(true)
// 计算偏移量变量
......@@ -78,6 +85,7 @@ function toggleDivs(value: boolean) {
function initDiagram() {
myDiagram = $(go.Diagram, "diagramDiv", {
"undoManager.isEnabled": true,
// 'grid.visible': true, // 画布上面是否出现网格
"toolManager.mouseWheelBehavior": go.WheelMode.Zoom,
// contentAlignment: go.Spot.Center, // 元素位置移动后始终处于在画布正中间
resizingTool: new ResizeMultipleTool(), // 自定义ResizeMultipleTool()方法来设置元素大小的缩放
......@@ -92,7 +100,8 @@ function initDiagram() {
});
myDiagram.toolManager.mouseMoveTools.insertAt(0, new PortShiftingTool()); // 设置端口移动
myDiagram.toolManager.mouseMoveTools.insertAt(0, new LinkLabelDraggingTool()); // 设置链接上的文本可以移动
//myDiagram.toolManager.mouseMoveTools.insertAt(0, new LinkLabelDraggingTool()); // 设置链接上的文本可以移动
myDiagram.toolManager.mouseMoveTools.insertAt(0, new LinkLabelOnPathDraggingTool()); // 设置连接上的文本只能沿着连接移动
myDiagram.toolManager.mouseMoveTools.insertAt(0, new NodeLabelDraggingTool()); // 设置节点上的文本可以移动
myDiagram.nodeTemplate =
......@@ -414,7 +423,10 @@ function initDiagram() {
resizable: true,
rotatable: true,
cursor: 'move',
_isLinkLabel: true,
segmentIndex: NaN,
segmentFraction: 0.5,
visible: true,
_isLinkLabel: true
},
new go.Binding("location", "loc"),
new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify),
......@@ -763,49 +775,37 @@ function initDiagram() {
)
)
)
)
);
// 节点间的连线模板
myDiagram.linkTemplate =
$(go.Link,
{
$(go.Link,
{
routing: go.Routing.Orthogonal,
curve: go.Curve.JumpGap,
corner: 10,
adjusting: go.LinkAdjusting.Stretch,
reshapable: true // 设置连接线的形态是否可以被修改
},
$(go.Shape, // 链接线的样式
corner: 10,
adjusting: go.LinkAdjusting.End,
reshapable: true, // 设置连接线的形态是否可以被修改
resegmentable: true, // 设置连接线可以分段的编辑
selectable: true,
},
$(go.Shape, // 链接线的样式
{
strokeWidth: 1.5
strokeWidth: 1.5
}
),
$(go.Shape, // 箭头的样式
),
$(go.Shape, // 箭头的样式
{
toArrow: "standard",
stroke: null
}
),
$(go.Panel, "Auto",
{ cursor: "move" }, // 用户可以使用此链接标签执行某些操作的视觉提示
$(go.Shape, // 设置链接中的标签样式
{
fill: "lightgray",
stroke: null
}
),
$(go.TextBlock, "transition", // 设置链接中标签的文本样式
{
textAlign: "center",
font: "10pt helvetica, arial, sans-serif",
stroke: "black",
margin: 4,
editable: true // 设置标签文本是否可编辑
},
new go.Binding("text", "text").makeTwoWay()), // 文本数据双向绑定
new go.Binding("segmentOffset", "segmentOffset", go.Point.parse).makeTwoWay(go.Point.stringify)
)
);
),
{
doubleClick : function(){ // 在节点中鼠标左键双击打开添加管道弹出框
pipeDialogVisible.value = true;
}
},
);
// 数据面板的连线模板
myDiagram.linkTemplateMap.add('infoPanelLink',
......@@ -813,7 +813,7 @@ function initDiagram() {
{
selectable: true,
resegmentable: true,
routing: go.Routing.AvoidsNodes,
routing: go.Routing.Orthogonal,
curve: go.Curve.JumpGap,
toShortLength: 2,
adjusting: go.LinkAdjusting.End
......@@ -822,13 +822,12 @@ function initDiagram() {
$(go.Shape, { isPanelMain: true, strokeWidth: 2, stroke: 'gray' }),
$(go.Shape, { isPanelMain: true, strokeWidth: 2, stroke: 'black', name: "FLOW", strokeDashArray: [10, 10] }),
)
)
);
// 画布提示工具函数
function diagramInfo(model: any) {
return "Model:\n" + model.nodeDataArray.length + " nodes, " + model.linkDataArray.length + " links";
}
};
// 当未覆盖任何节点时,提供图表背景的工具提示
myDiagram.toolTip =
......@@ -903,22 +902,37 @@ function initDiagram() {
}).ofObject())
);
// 如果以信息面板端口为终点/起点的连接线,使用infoPanelLink类型的连接线
myDiagram.addDiagramListener("LinkDrawn", function(e: any) {
var link = e.subject;
var fromNode = link.fromNode;
var toNode = link.toNode;
// 检查连接的起点或终点是否是信息面板
if ((fromNode && fromNode.category === "infoPanel") || (toNode && toNode.category === "infoPanel")) {
// 设置连接的类别为 infoPanelLink
myDiagram.model.set(link.data, "category", "infoPanelLink");
}
});
const nodeDataArray = [
{ key: "add1", color: "lightyellow", loc: new go.Point(-150, 200), portArray: [{portId: "top0", portKey: "top"}, {portId: "left0", portKey: "left"}, {portId: "right0", portKey: "right"}, {portId: "bottom0", portKey: "bottom"}] },
{ key: "add2", color: "lightblue", loc: new go.Point(100, 50), category: "zhaChi", portArray: [{portId: "bottom0", portKey: "bottom"}] },
{ key: "add3", color: "lightblue", loc: new go.Point(300, 150), category: "zhaChi", portArray: [{portId: "bottom0", portKey: "bottom"}] },
{ key: "pipe1", color: "gray", loc: new go.Point(0, 100), category: "pipe", portArray: [{portId: "top0", portKey: "top"}], markArray: [{portId: "mark0"}]},
{ key: "管道信息面板", color: "red", loc: new go.Point(-80, -120), portArray: [{portId: "bottom0", portKey: "bottom"}], DCSArray: [{name: "流速", value: "20", unit: "m/s"}, {name: "温度", value: "30", unit: "℃"}], damageArray: [{damageName: "盐酸腐蚀", damageValue: "100%"}], alarmArray: [{alarmName: "警报"}], riskData: "高风险", category: "infoPanel"}
{ key: "pipe1信息面板", color: "red", loc: new go.Point(-80, -120), portArray: [{portId: "top0", portKey: "top"}, {portId: "left0", portKey: "left"}, {portId: "right0", portKey: "right"}, {portId: "bottom0", portKey: "bottom"}], DCSArray: [{name: "流速", value: "20", unit: "m/s"}, {name: "温度", value: "30", unit: "℃"}], damageArray: [{damageName: "盐酸腐蚀", damageValue: "100%"}], alarmArray: [{alarmName: "警报"}], riskData: "高风险", category: "infoPanel"}
];
const linkDataArray = [
{ from: "add1", fromPort: "top0", to: "add2", toPort: "bottom0", text: "1->2" },
{ from: "管道信息面板", fromPort: "bottom0", to: "pipe1", toPort: "top0", category: "infoPanelLink"}
{ from: "add1", fromPort: "top0", to: "add2", toPort: "bottom0", labelKeys: ["pipe1"] },
{ from: "add1", fromPort: "bottom0", to: "add3", toPort: "bottom0" },
{ from: "pipe1信息面板", fromPort: "bottom0", to: "pipe1", toPort: "top0", category: "infoPanelLink"}
];
myDiagram.model =
$(go.GraphLinksModel,
{
{
linkFromPortIdProperty: "fromPort",
linkToPortIdProperty: "toPort",
linkLabelKeysProperty: "labelKeys",
nodeDataArray: nodeDataArray,
linkDataArray: linkDataArray
}
......@@ -1145,6 +1159,55 @@ function damageDataShow() {
myDiagram.commitTransaction("changeDamageShowModel");
}
// 在连接线上添加管道
function addPipe() {
myDiagram.startTransaction("addPipeToLinks");
myDiagram.selection.each(function(link: any) {
if (link instanceof go.Link)
{
var newPipeNode =
{
key: "newPipe",
color: 'gray',
category: "pipe",
portArray: [],
markArray: []
};
// 添加节点到节点数据模型中
myDiagram.model.addNodeData(newPipeNode);
// 确保link.data有linkLabels属性
if (!link.data.linkLabels) {
link.data.linkLabels = [];
}
// 向连接中添加标签键,将新节点的唯一标识符(key数据)添加到连接线的labelKeys属性中,使节点显示在连接线上
myDiagram.model.addLabelKeyForLinkData(link.data, newPipeNode.key)
}
});
myDiagram.commitTransaction("addPipeToLinks");
}
// 创建设备的数据面板
function addDataPanel(){
myDiagram.startTransaction("addDataPanel");
myDiagram.selection.each((node: any) => {
if (!(node instanceof go.Node)) return;
const newDataPanel =
{
key: `${node.data.key}信息面板`,
color: "red",
portArray: [{portId: "top0", portKey: "top"}, {portId: "left0", portKey: "left"}, {portId: "right0", portKey: "right"}, {portId: "bottom0", portKey: "bottom"}],
DCSArray: [{name: "流速", value: "20", unit: "m/s"}, {name: "温度", value: "30", unit: "℃"}],
damageArray: [{damageName: "盐酸腐蚀", damageValue: "100%"}],
alarmArray: [{alarmName: "警报"}],
riskData: "高风险",
category: "infoPanel"
}
myDiagram.model.addNodeData(newDataPanel);
});
myDiagram.commitTransaction("addDataPanel");
}
onMounted(() => {
initDiagram()
});
......
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