Commit 6f4acbc2 by jlc

update:通过扩展移动端口和调节节点大小

parent f93688f4
......@@ -11,7 +11,8 @@
<!-- <panel></panel> -->
<!-- <contextMenu></contextMenu> -->
<!-- <firstProject></firstProject> -->
<port></port>
<!-- <port></port> -->
<dynamicPort></dynamicPort>
</template>
<script setup lang="ts">
......@@ -27,7 +28,8 @@
// import panel from './components/panel.vue';
// import contextMenu from './components/contextMenu.vue';
// import firstProject from './stageAchievements/firstProject.vue';
import port from './components/port.vue';
// import port from './components/port.vue';
import dynamicPort from './stageAchievements/dynamicPort.vue';
</script>
<style scoped>
......
<template>
<div id="diagramDiv" style="width: 100%; height: 900px; background-color: #DAE4E4;"></div>
</template>
<script setup lang="ts">
import { onMounted } from 'vue';
import * as go from 'gojs';
import { PortShiftingTool } from './extensions/PortShiftingTool';
import { ResizeMultipleTool } from './extensions/ResizeMultipleTool';
const $ = go.GraphObject.make;
var myDiagram: any;
function initDiagram() {
myDiagram = $(go.Diagram, "diagramDiv", {
"undoManager.isEnabled": true,
"toolManager.mouseWheelBehavior": go.WheelMode.Zoom,
resizingTool: new ResizeMultipleTool(), // 自定义ResizeMultipleTool()方法来设置元素大小的缩放
});
myDiagram.toolManager.mouseMoveTools.insertAt(0, new PortShiftingTool()); // 设置端口移动
myDiagram.nodeTemplate =
$(go.Node, "Spot",
{
resizable: true
},
new go.Binding("location", "loc"),
new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify), // 进行元素位置信息的绑定
$(go.Shape, "RoundedRectangle",
{
// width: 65,
// height: 65,
fill: "white",
strokeWidth: 0
},
new go.Binding("fill", "color")
),
$(go.TextBlock,
{
margin: 10,
textAlign: 'center',
font: 'bold 14px Segoe UI,sans-serif',
stroke: '#484848',
editable: true
},
new go.Binding('text', 'key').makeTwoWay()
),
$(go.Shape, "Rectangle",
{
width: 6,
height: 6,
portId: "Top",
fromSpot: go.Spot.Top, // 从端口顶部发出连接
toSpot: go.Spot.Top, // 从端口顶部接收连接
fromLinkable: true,
toLinkable: true,
cursor: 'pointer',
alignment: new go.Spot(0.5, 0)
}
),
$(go.Shape, "Rectangle",
{
width: 6,
height: 6,
portId: "Left",
fromSpot: go.Spot.Left,
toSpot: go.Spot.Left,
fromLinkable: true,
toLinkable: true,
cursor: 'pointer',
alignment: new go.Spot(0, 0.5)
}
),
$(go.Shape, "Rectangle",
{
width: 6,
height: 6,
portId: "Bottom",
fromSpot: go.Spot.Bottom,
toSpot: go.Spot.Bottom,
fromLinkable: true,
toLinkable: true,
cursor: 'pointer',
alignment: new go.Spot(0.5, 1)
}
)
);
myDiagram.linkTemplate =
$(go.Link,
{
routing:go.Routing.AvoidsNodes,
curve: go.Curve.JumpGap,
corner: 3,
fromPortId: "from",
toPortId: "to",
relinkableTo: true, // 允许连接线尾部重新连接
relinkableFrom: true, // 允许连接线头部重新链接
},
$(go.Shape),
$(go.Shape, { toArrow: "Standard" })
);
// myDiagram.layout = $(go.LayeredDigraphLayout, { columnSpacing: 10 });
const nodeDataArray = [
{ key: "Add1", loc: new go.Point(0, 0), color: "lightgray" },
{ key: "Add2", loc: new go.Point(-180, 180), color: "lightblue" },
{ key: "Subtract1", loc: new go.Point(100, 250), color: "lightgreen" }
];
const linkDataArray = [
{ from: "Add1", fromPort: "Bottom", to: "Subtract1", toPort: "Top" },
{ from: "Add2", fromPort: "Bottom", to: "Subtract1", toPort: "Left" }
];
myDiagram.model =
$(go.GraphLinksModel,
{
linkFromPortIdProperty: "fromPort",
linkToPortIdProperty: "toPort",
nodeDataArray: nodeDataArray,
linkDataArray: linkDataArray
}
);
}
onMounted(() => {
initDiagram()
});
</script>
\ No newline at end of file
/*
* Copyright (C) 1998-2024 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 * as go from 'gojs';
/**
* The PortShiftingTool class lets a user move a port on a {@link go.Node}.
*
* This tool only works when the Node has a port (any GraphObject) marked with
* a non-null and non-empty portId that is positioned in a Spot Panel,
* and the user holds down the Shift key.
* It works by modifying that port's {@link go.GraphObject.alignment} property.
*
* If you want to experiment with this extension, try the <a href="../../samples/PortShifting.html">Port Shifting</a> sample.
* @category Tool Extension
*/
export class PortShiftingTool extends go.Tool {
/**
* The port being shifted.
*/
port: go.GraphObject | null;
private _originalAlignment: go.Spot;
/**
* Constructs a PortShiftingTool and sets the name for the tool.
*/
constructor(init?: Partial<PortShiftingTool>) {
super();
this.name = 'PortShifting';
this.port = null;
this._originalAlignment = go.Spot.Default;
if (init) Object.assign(this, init);
}
/**
* 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 "port" in a Spot Panel,
* as determined by {@link findPort}.
*/
override canStart(): boolean {
const diagram = this.diagram;
if (!super.canStart()) 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 || !e.shift) return false;
if (!this.isBeyondDragSize()) return false;
return this.findPort() !== null;
}
/**
* From the {@link go.GraphObject} at the mouse point, search up the visual tree until we get to
* an object that has the {@link go.GraphObject.portId} property set to a non-empty string, that is in a Spot Panel,
* and that is not the main element of the panel (typically the first element).
* @returns This returns null if no such port is at the mouse down point.
*/
findPort(): go.GraphObject | null {
const diagram = this.diagram;
const e = diagram.firstInput;
let elt = diagram.findObjectAt(e.documentPoint, null, null);
if (elt === null || !(elt.part instanceof go.Node)) return null;
while (elt !== null && elt.panel !== null) {
if (elt.panel.type === go.Panel.Spot &&
elt.panel.findMainElement() !== elt &&
elt.portId !== null &&
elt.portId !== '') return elt;
elt = elt.panel;
}
return null;
}
/**
* Start a transaction, call {@link findPort} and remember it as the "port" property,
* and remember the original value for the port's {@link go.GraphObject.alignment} property.
*/
override doActivate(): void {
this.startTransaction('Shifted Label');
this.port = this.findPort();
if (this.port !== null) {
this._originalAlignment = this.port.alignment.copy();
}
super.doActivate();
}
/**
* Stop any ongoing transaction.
*/
override doDeactivate(): void {
super.doDeactivate();
this.stopTransaction();
}
/**
* Clear any reference to a port element.
*/
override doStop(): void {
this.port = null;
super.doStop();
}
/**
* Restore the port's original value for GraphObject.alignment.
*/
override doCancel(): void {
if (this.port !== null) {
this.port.alignment = this._originalAlignment;
}
super.doCancel();
}
/**
* During the drag, call {@link updateAlignment} in order to set the {@link go.GraphObject.alignment} of the port.
*/
override doMouseMove(): void {
if (!this.isActive) return;
this.updateAlignment();
}
/**
* At the end of the drag, update the alignment of the port and finish the tool,
* completing a transaction.
*/
override doMouseUp(): void {
if (!this.isActive) return;
this.updateAlignment();
this.transactionResult = 'Shifted Label';
this.stopTool();
}
/**
* Save the port's {@link go.GraphObject.alignment} as a fractional Spot in the Spot Panel
* that the port is in. Thus if the main element changes size, the relative positions
* of the ports will be maintained. But that does assume that the port must remain
* inside the main element -- it cannot wander away from the node.
* This does not modify the port's {@link go.GraphObject.alignmentFocus} property.
*/
updateAlignment(): void {
if (this.port === null || this.port.panel === null) return;
const last = this.diagram.lastInput.documentPoint;
const main = this.port.panel.findMainElement();
if (main === null) return;
const tl = main.getDocumentPoint(go.Spot.TopLeft);
const br = main.getDocumentPoint(go.Spot.BottomRight);
const x = Math.max(0, Math.min((last.x - tl.x) / (br.x - tl.x), 1));
const y = Math.max(0, Math.min((last.y - tl.y) / (br.y - tl.y), 1));
this.port.alignment = new go.Spot(x, y);
}
}
/*
* Copyright (C) 1998-2024 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 * as go from 'gojs';
/**
* The ResizeMultipleTool class lets the user resize multiple objects at once.
*
* If you want to experiment with this extension, try the <a href="../../samples/ResizeMultiple.html">Resize Multiple</a> sample.
* @category Tool Extension
*/
export class ResizeMultipleTool extends go.ResizingTool {
/**
* Constructs a ResizeMultipleTool and sets the name for the tool.
*/
constructor(init?: Partial<ResizeMultipleTool>) {
super();
this.name = 'ResizeMultiple';
if (init) Object.assign(this, init);
}
/**
* Overrides {@link go.ResizingTool.resize} to resize all selected objects to the same size.
* @param newr - the intended new rectangular bounds for each Part's {@link go.Part.resizeObject}.
*/
override resize(newr: go.Rect): void {
const diagram = this.diagram;
diagram.selection.each((part) => {
if (part instanceof go.Link) return; // only Nodes and simple Parts
const obj = part.resizeObject;
// calculate new location
const pos = part.position.copy();
const angle = obj.getDocumentAngle();
const sc = obj.getDocumentScale();
const radAngle = (Math.PI * angle) / 180;
const angleCos = Math.cos(radAngle);
const angleSin = Math.sin(radAngle);
const deltaWidth = newr.width - obj.naturalBounds.width;
const deltaHeight = newr.height - obj.naturalBounds.height;
const angleBottom = angle > 0 && angle < 180 ? 1 : 0;
const angleLeft = angle > 90 && angle < 270 ? 1 : 0;
const angleTop = angle > 180 && angle < 360 ? 1 : 0;
pos.x +=
sc *
((newr.x + deltaWidth * angleLeft) * angleCos -
(newr.y + deltaHeight * angleBottom) * angleSin);
pos.y +=
sc *
((newr.x + deltaWidth * angleTop) * angleSin +
(newr.y + deltaHeight * angleLeft) * angleCos);
obj.desiredSize = newr.size;
part.move(pos);
});
}
}
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