@elyra/canvas 12.35.0 → 12.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/canvas-constants-766c12a9.js +2 -0
- package/dist/{canvas-constants-85883d4c.js.map → canvas-constants-766c12a9.js.map} +1 -1
- package/dist/canvas-constants-f4219d26.js +2 -0
- package/dist/{canvas-constants-d8652829.js.map → canvas-constants-f4219d26.js.map} +1 -1
- package/dist/canvas-controller-62b66fc8.js +2 -0
- package/dist/canvas-controller-62b66fc8.js.map +1 -0
- package/dist/canvas-controller-76f68572.js +2 -0
- package/dist/canvas-controller-76f68572.js.map +1 -0
- package/dist/common-canvas-339584b8.js +2 -0
- package/dist/common-canvas-339584b8.js.map +1 -0
- package/dist/common-canvas-c728f092.js +2 -0
- package/dist/common-canvas-c728f092.js.map +1 -0
- package/dist/common-canvas.es.js +1 -1
- package/dist/common-canvas.es.js.map +1 -1
- package/dist/common-canvas.js +1 -1
- package/dist/common-canvas.js.map +1 -1
- package/dist/common-properties-009d29d6.js +2 -0
- package/dist/common-properties-009d29d6.js.map +1 -0
- package/dist/common-properties-99d34523.js +2 -0
- package/dist/common-properties-99d34523.js.map +1 -0
- package/dist/context-menu-wrapper-624a1e7c.js +2 -0
- package/dist/context-menu-wrapper-624a1e7c.js.map +1 -0
- package/dist/context-menu-wrapper-ab018d6e.js +2 -0
- package/dist/context-menu-wrapper-ab018d6e.js.map +1 -0
- package/dist/{datarecord-metadata-v3-schema-531c7b07.js → datarecord-metadata-v3-schema-1f21696a.js} +2 -2
- package/dist/{datarecord-metadata-v3-schema-531c7b07.js.map → datarecord-metadata-v3-schema-1f21696a.js.map} +1 -1
- package/dist/{datarecord-metadata-v3-schema-28d4d7bb.js → datarecord-metadata-v3-schema-c2ad8862.js} +2 -2
- package/dist/{datarecord-metadata-v3-schema-28d4d7bb.js.map → datarecord-metadata-v3-schema-c2ad8862.js.map} +1 -1
- package/dist/flexible-table-4cf19e2e.js +2 -0
- package/dist/flexible-table-4cf19e2e.js.map +1 -0
- package/dist/flexible-table-8d10f5c9.js +2 -0
- package/dist/flexible-table-8d10f5c9.js.map +1 -0
- package/dist/{icon-909437d7.js → icon-5e06bfe1.js} +2 -2
- package/dist/{icon-909437d7.js.map → icon-5e06bfe1.js.map} +1 -1
- package/dist/{icon-de9c6b33.js → icon-8433d369.js} +2 -2
- package/dist/{icon-de9c6b33.js.map → icon-8433d369.js.map} +1 -1
- package/dist/{index-9960d3bf.js → index-2a61be58.js} +2 -2
- package/dist/{index-9960d3bf.js.map → index-2a61be58.js.map} +1 -1
- package/dist/{index-61e4a113.js → index-9a355ed6.js} +2 -2
- package/dist/{index-61e4a113.js.map → index-9a355ed6.js.map} +1 -1
- package/dist/lib/canvas-controller.es.js +1 -1
- package/dist/lib/canvas-controller.js +1 -1
- package/dist/lib/canvas.es.js +1 -1
- package/dist/lib/canvas.js +1 -1
- package/dist/lib/context-menu.es.js +1 -1
- package/dist/lib/context-menu.js +1 -1
- package/dist/lib/properties/field-picker.es.js +1 -1
- package/dist/lib/properties/field-picker.js +1 -1
- package/dist/lib/properties/flexible-table.es.js +1 -1
- package/dist/lib/properties/flexible-table.js +1 -1
- package/dist/lib/properties.es.js +1 -1
- package/dist/lib/properties.js +1 -1
- package/dist/styles/common-canvas.min.css +1 -1
- package/dist/styles/common-canvas.min.css.map +1 -1
- package/dist/{toolbar-cdb38f4a.js → toolbar-76733735.js} +2 -2
- package/dist/{toolbar-cdb38f4a.js.map → toolbar-76733735.js.map} +1 -1
- package/dist/{toolbar-3b5a592c.js → toolbar-85e1e463.js} +2 -2
- package/dist/{toolbar-3b5a592c.js.map → toolbar-85e1e463.js.map} +1 -1
- package/locales/common-canvas/locales/en.json +1 -1
- package/locales/common-canvas/locales/eo.json +1 -1
- package/package.json +3 -4
- package/src/common-canvas/canvas-controller.js +15 -6
- package/src/common-canvas/cc-contents.jsx +44 -6
- package/src/common-canvas/common-canvas-utils.js +9 -2
- package/src/common-canvas/common-canvas.scss +30 -3
- package/src/common-canvas/constants/canvas-constants.js +0 -6
- package/src/common-canvas/svg-canvas-d3.js +1 -3
- package/src/common-canvas/svg-canvas-d3.scss +0 -26
- package/src/common-canvas/svg-canvas-pipeline.js +6 -0
- package/src/common-canvas/svg-canvas-renderer.js +490 -2804
- package/src/common-canvas/svg-canvas-utils-drag-det-link.js +491 -0
- package/src/common-canvas/svg-canvas-utils-drag-new-link.js +595 -0
- package/src/common-canvas/svg-canvas-utils-drag-objects.js +832 -0
- package/src/common-canvas/svg-canvas-utils-external.js +82 -16
- package/src/common-canvas/svg-canvas-utils-zoom.js +780 -0
- package/src/common-properties/common-properties.jsx +2 -0
- package/src/common-properties/components/editor-form/editor-form.jsx +5 -1
- package/src/common-properties/properties-main/properties-main.jsx +2 -0
- package/src/context-menu/common-context-menu.jsx +57 -26
- package/src/context-menu/context-menu.scss +33 -53
- package/src/notification-panel/notification-panel.jsx +6 -1
- package/src/notification-panel/notification-panel.scss +14 -8
- package/src/palette/palette-content-list-item.jsx +23 -7
- package/src/palette/palette.scss +4 -4
- package/stats.html +1 -1
- package/dist/canvas-constants-85883d4c.js +0 -2
- package/dist/canvas-constants-d8652829.js +0 -2
- package/dist/canvas-controller-c9f3bef9.js +0 -2
- package/dist/canvas-controller-c9f3bef9.js.map +0 -1
- package/dist/canvas-controller-f7820ab0.js +0 -2
- package/dist/canvas-controller-f7820ab0.js.map +0 -1
- package/dist/common-canvas-487520d3.js +0 -2
- package/dist/common-canvas-487520d3.js.map +0 -1
- package/dist/common-canvas-e1591f51.js +0 -2
- package/dist/common-canvas-e1591f51.js.map +0 -1
- package/dist/common-properties-580436d7.js +0 -2
- package/dist/common-properties-580436d7.js.map +0 -1
- package/dist/common-properties-98a9a99f.js +0 -2
- package/dist/common-properties-98a9a99f.js.map +0 -1
- package/dist/context-menu-wrapper-19a1cf72.js +0 -2
- package/dist/context-menu-wrapper-19a1cf72.js.map +0 -1
- package/dist/context-menu-wrapper-c3a98c63.js +0 -2
- package/dist/context-menu-wrapper-c3a98c63.js.map +0 -1
- package/dist/extends-093996c9.js +0 -2
- package/dist/extends-093996c9.js.map +0 -1
- package/dist/extends-1b35a664.js +0 -2
- package/dist/extends-1b35a664.js.map +0 -1
- package/dist/flexible-table-b9c08069.js +0 -2
- package/dist/flexible-table-b9c08069.js.map +0 -1
- package/dist/flexible-table-ddd6132b.js +0 -2
- package/dist/flexible-table-ddd6132b.js.map +0 -1
|
@@ -0,0 +1,595 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2017-2023 Elyra Authors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/* eslint no-lonely-if: "off" */
|
|
18
|
+
|
|
19
|
+
import * as d3Drag from "d3-drag";
|
|
20
|
+
import * as d3Ease from "d3-ease";
|
|
21
|
+
import * as d3Selection from "d3-selection";
|
|
22
|
+
const d3 = Object.assign({}, d3Drag, d3Ease, d3Selection);
|
|
23
|
+
|
|
24
|
+
import Logger from "../logging/canvas-logger.js";
|
|
25
|
+
import CanvasUtils from "./common-canvas-utils.js";
|
|
26
|
+
import { ASSOCIATION_LINK, COMMENT_LINK, NODE_LINK,
|
|
27
|
+
LINK_TYPE_CURVE, LINK_TYPE_STRAIGHT, LINK_SELECTION_DETACHABLE,
|
|
28
|
+
PORT_OBJECT_CIRCLE, PORT_OBJECT_IMAGE }
|
|
29
|
+
from "./constants/canvas-constants.js";
|
|
30
|
+
|
|
31
|
+
// This utility files provides a drag handler which manages drag operations to
|
|
32
|
+
// create new links either between nodes or from a comment to a node.
|
|
33
|
+
|
|
34
|
+
export default class SVGCanvasUtilsDragNewLink {
|
|
35
|
+
constructor(renderer) {
|
|
36
|
+
this.ren = renderer;
|
|
37
|
+
|
|
38
|
+
this.logger = new Logger("SVGCanvasUtilsDragNewLink");
|
|
39
|
+
|
|
40
|
+
// Object to store variables for dynamically drawing a new link line. The
|
|
41
|
+
// existence of this object means a new link is being drawn. A null means
|
|
42
|
+
// no link is currently being drawn.
|
|
43
|
+
this.drawingNewLinkData = null;
|
|
44
|
+
|
|
45
|
+
// Create a drag handler for resizing and moving nodes and comments.
|
|
46
|
+
this.dragNewLinkHandler = d3.drag()
|
|
47
|
+
.on("start", this.dragStartNewLink.bind(this))
|
|
48
|
+
.on("drag", this.dragMoveNewLink.bind(this))
|
|
49
|
+
.on("end", this.dragEndNewLink.bind(this));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Returns the dragResizeObjectHandler
|
|
53
|
+
getDragNewLinkHandler() {
|
|
54
|
+
return this.dragNewLinkHandler;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Returns true if a new link is currently being dragged.
|
|
58
|
+
isDragging() {
|
|
59
|
+
return this.drawingNewLinkData;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Initialize new link creation info when a port node is dragged.
|
|
63
|
+
dragStartNewLink(d3Event, d) {
|
|
64
|
+
if (this.isEventForOutputPort(d3Event)) {
|
|
65
|
+
const node = this.getNodeForPort(d3Event);
|
|
66
|
+
this.startOutputPortNewLink(d, node);
|
|
67
|
+
|
|
68
|
+
} else if (this.isEventForInputPort(d3Event)) {
|
|
69
|
+
const node = this.getNodeForPort(d3Event);
|
|
70
|
+
this.startInputPortNewLink(d, node);
|
|
71
|
+
|
|
72
|
+
} else if (this.ren.activePipeline.getObjectTypeName(d) === "comment") {
|
|
73
|
+
this.startCommentNewLink(d);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Draws an appropriate new link line when a port is being dragged.
|
|
78
|
+
dragMoveNewLink(d3Event) {
|
|
79
|
+
this.drawNewLink(d3Event);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Completes the creation (or not) of a new link line when a port has
|
|
83
|
+
// finished being dragged.
|
|
84
|
+
dragEndNewLink(d3Event) {
|
|
85
|
+
this.completeNewLink(d3Event);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Return true if the d3Event passed in is for an input port.
|
|
89
|
+
isEventForInputPort(d3Event) {
|
|
90
|
+
return this.targetContainsClass(d3Event, "d3-node-port-input") ||
|
|
91
|
+
this.targetContainsClass(d3Event, "d3-node-port-input-assoc");
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Return true if the d3Event passed in is for an output port.
|
|
95
|
+
isEventForOutputPort(d3Event) {
|
|
96
|
+
return this.targetContainsClass(d3Event, "d3-node-port-output") ||
|
|
97
|
+
this.targetContainsClass(d3Event, "d3-node-port-output-assoc");
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Returns true if the d3Event contains a current target with the spcified class name.
|
|
101
|
+
targetContainsClass(d3Event, className) {
|
|
102
|
+
return d3Event.sourceEvent?.currentTarget?.classList?.contains(className);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Returns the node data for the target of the event passed in.
|
|
106
|
+
getNodeForPort(d3Event) {
|
|
107
|
+
return d3.select(d3Event.sourceEvent?.currentTarget?.parentNode).datum();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Initialize this.drawingNewLinkData when dragging a comment port.
|
|
111
|
+
startCommentNewLink(comment) {
|
|
112
|
+
this.drawingNewLinkData = {
|
|
113
|
+
srcObjId: comment.id,
|
|
114
|
+
action: COMMENT_LINK,
|
|
115
|
+
startPos: {
|
|
116
|
+
x: comment.x_pos - this.ren.canvasLayout.commentHighlightGap,
|
|
117
|
+
y: comment.y_pos - this.ren.canvasLayout.commentHighlightGap
|
|
118
|
+
},
|
|
119
|
+
linkArray: []
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Initialize this.drawingNewLinkData when dragging an input port. This gesture
|
|
124
|
+
// is only supported for association link creation.
|
|
125
|
+
startInputPortNewLink(port, node) {
|
|
126
|
+
if (this.ren.config.enableAssocLinkCreation) {
|
|
127
|
+
const srcNode = this.ren.activePipeline.getNode(node.id);
|
|
128
|
+
this.drawingNewLinkData = {
|
|
129
|
+
srcObjId: node.id,
|
|
130
|
+
srcPortId: port.id,
|
|
131
|
+
action: this.ren.config.enableAssocLinkCreation ? ASSOCIATION_LINK : NODE_LINK,
|
|
132
|
+
srcNode: srcNode,
|
|
133
|
+
startPos: { x: srcNode.x_pos + port.cx, y: srcNode.y_pos + port.cy },
|
|
134
|
+
portType: "input",
|
|
135
|
+
portObject: node.layout.inputPortObject,
|
|
136
|
+
portImage: node.layout.inputPortImage,
|
|
137
|
+
portWidth: node.layout.inputPortWidth,
|
|
138
|
+
portHeight: node.layout.inputPortHeight,
|
|
139
|
+
portRadius: this.ren.getPortRadius(srcNode),
|
|
140
|
+
minInitialLine: srcNode.layout.minInitialLine,
|
|
141
|
+
guideObject: node.layout.inputPortGuideObject,
|
|
142
|
+
guideImage: node.layout.inputPortGuideImage,
|
|
143
|
+
linkArray: []
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Initialize this.drawingNewLinkData when dragging an output port.
|
|
149
|
+
startOutputPortNewLink(port, node) {
|
|
150
|
+
const srcNode = this.ren.activePipeline.getNode(node.id);
|
|
151
|
+
if (!CanvasUtils.isSrcCardinalityAtMax(port.id, srcNode, this.ren.activePipeline.links)) {
|
|
152
|
+
this.drawingNewLinkData = {
|
|
153
|
+
srcObjId: node.id,
|
|
154
|
+
srcPortId: port.id,
|
|
155
|
+
action: this.ren.config.enableAssocLinkCreation ? ASSOCIATION_LINK : NODE_LINK,
|
|
156
|
+
srcNode: srcNode,
|
|
157
|
+
startPos: { x: srcNode.x_pos + port.cx, y: srcNode.y_pos + port.cy },
|
|
158
|
+
portType: "output",
|
|
159
|
+
portObject: node.layout.outputPortObject,
|
|
160
|
+
portImage: node.layout.outputPortImage,
|
|
161
|
+
portWidth: node.layout.outputPortWidth,
|
|
162
|
+
portHeight: node.layout.outputPortHeight,
|
|
163
|
+
portRadius: this.ren.getPortRadius(srcNode),
|
|
164
|
+
minInitialLine: srcNode.layout.minInitialLine,
|
|
165
|
+
guideObject: node.layout.outputPortGuideObject,
|
|
166
|
+
guideImage: node.layout.outputPortGuideImage,
|
|
167
|
+
linkArray: []
|
|
168
|
+
};
|
|
169
|
+
if (this.ren.config.enableHighlightUnavailableNodes) {
|
|
170
|
+
this.ren.setUnavailableTargetNodesHighlighting(srcNode, port.id, this.ren.activePipeline.links);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
drawNewLink(d3Event) {
|
|
176
|
+
if (this.ren.config.enableEditingActions === false || !this.drawingNewLinkData) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
this.ren.closeContextMenuIfOpen();
|
|
181
|
+
|
|
182
|
+
const transPos = this.ren.getTransformedMousePos(d3Event);
|
|
183
|
+
|
|
184
|
+
if (this.drawingNewLinkData.action === COMMENT_LINK) {
|
|
185
|
+
this.drawNewCommentLinkForPorts(transPos);
|
|
186
|
+
} else {
|
|
187
|
+
this.drawNewNodeLinkForPorts(transPos);
|
|
188
|
+
}
|
|
189
|
+
// Switch on an attribute to indicate a new link is being dragged
|
|
190
|
+
// towards and over a target node.
|
|
191
|
+
if (this.ren.config.enableHighlightNodeOnNewLinkDrag) {
|
|
192
|
+
this.setNewLinkOverNode(d3Event);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
drawNewCommentLinkForPorts(transPos) {
|
|
197
|
+
const srcComment = this.ren.activePipeline.getComment(this.drawingNewLinkData.srcObjId);
|
|
198
|
+
const startPos = this.ren.linkUtils.getNewStraightCommentLinkStartPos(srcComment, transPos);
|
|
199
|
+
const linkType = COMMENT_LINK;
|
|
200
|
+
|
|
201
|
+
this.drawingNewLinkData.linkArray = [{
|
|
202
|
+
"x1": startPos.x,
|
|
203
|
+
"y1": startPos.y,
|
|
204
|
+
"x2": transPos.x,
|
|
205
|
+
"y2": transPos.y,
|
|
206
|
+
"type": linkType }];
|
|
207
|
+
|
|
208
|
+
const connectionLineSel = this.ren.nodesLinksGrp.selectAll(".d3-new-connection-line");
|
|
209
|
+
const connectionGuideSel = this.ren.nodesLinksGrp.selectAll(".d3-new-connection-guide");
|
|
210
|
+
|
|
211
|
+
connectionLineSel
|
|
212
|
+
.data(this.drawingNewLinkData.linkArray)
|
|
213
|
+
.enter()
|
|
214
|
+
.append("path")
|
|
215
|
+
.attr("class", "d3-new-connection-line")
|
|
216
|
+
.attr("linkType", linkType)
|
|
217
|
+
.merge(connectionLineSel)
|
|
218
|
+
.attr("d", (d) => this.ren.linkUtils.getConnectorPathInfo(d).path);
|
|
219
|
+
|
|
220
|
+
connectionGuideSel
|
|
221
|
+
.data(this.drawingNewLinkData.linkArray)
|
|
222
|
+
.enter()
|
|
223
|
+
.append("circle")
|
|
224
|
+
.attr("class", "d3-new-connection-guide")
|
|
225
|
+
.attr("linkType", linkType)
|
|
226
|
+
.merge(connectionGuideSel)
|
|
227
|
+
.attr("cx", (d) => d.x2)
|
|
228
|
+
.attr("cy", (d) => d.y2)
|
|
229
|
+
.attr("r", this.ren.canvasLayout.commentPortRadius);
|
|
230
|
+
|
|
231
|
+
if (this.ren.canvasLayout.commentLinkArrowHead) {
|
|
232
|
+
const connectionArrowHeadSel = this.ren.nodesLinksGrp.selectAll(".d3-new-connection-arrow");
|
|
233
|
+
|
|
234
|
+
connectionArrowHeadSel
|
|
235
|
+
.data(this.drawingNewLinkData.linkArray)
|
|
236
|
+
.enter()
|
|
237
|
+
.append("path")
|
|
238
|
+
.attr("class", "d3-new-connection-arrow")
|
|
239
|
+
.attr("linkType", linkType)
|
|
240
|
+
.merge(connectionArrowHeadSel)
|
|
241
|
+
.attr("d", (d) => this.ren.getArrowHead(d))
|
|
242
|
+
.attr("transform", (d) => this.ren.getArrowHeadTransform(d));
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
drawNewNodeLinkForPorts(transPos) {
|
|
247
|
+
const linkType = this.ren.config.enableAssocLinkCreation ? ASSOCIATION_LINK : NODE_LINK;
|
|
248
|
+
|
|
249
|
+
let startPos;
|
|
250
|
+
if (this.ren.canvasLayout.linkType === LINK_TYPE_STRAIGHT) {
|
|
251
|
+
startPos = this.ren.linkUtils.getNewStraightNodeLinkStartPos(this.drawingNewLinkData.srcNode, transPos);
|
|
252
|
+
} else {
|
|
253
|
+
startPos = {
|
|
254
|
+
x: this.drawingNewLinkData.startPos.x,
|
|
255
|
+
y: this.drawingNewLinkData.startPos.y };
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
this.drawingNewLinkData.linkArray = [{
|
|
259
|
+
"x1": startPos.x,
|
|
260
|
+
"y1": startPos.y,
|
|
261
|
+
"x2": transPos.x,
|
|
262
|
+
"y2": transPos.y,
|
|
263
|
+
"originX": startPos.originX,
|
|
264
|
+
"originY": startPos.originY,
|
|
265
|
+
"type": linkType }];
|
|
266
|
+
|
|
267
|
+
if (this.ren.config.enableAssocLinkCreation) {
|
|
268
|
+
this.drawingNewLinkData.linkArray[0].assocLinkVariation =
|
|
269
|
+
this.ren.getNewLinkAssocVariation(
|
|
270
|
+
this.drawingNewLinkData.linkArray[0].x1,
|
|
271
|
+
this.drawingNewLinkData.linkArray[0].x2,
|
|
272
|
+
this.drawingNewLinkData.portType);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const pathInfo = this.ren.linkUtils.getConnectorPathInfo(
|
|
276
|
+
this.drawingNewLinkData.linkArray[0], this.drawingNewLinkData.minInitialLine);
|
|
277
|
+
|
|
278
|
+
const connectionLineSel = this.ren.nodesLinksGrp.selectAll(".d3-new-connection-line");
|
|
279
|
+
const connectionStartSel = this.ren.nodesLinksGrp.selectAll(".d3-new-connection-start");
|
|
280
|
+
const connectionGuideSel = this.ren.nodesLinksGrp.selectAll(".d3-new-connection-guide");
|
|
281
|
+
|
|
282
|
+
// For a straight node line, don't draw the new link line when the guide
|
|
283
|
+
// icon or object is inside the node boundary.
|
|
284
|
+
if (linkType === NODE_LINK &&
|
|
285
|
+
this.ren.canvasLayout.linkType === LINK_TYPE_STRAIGHT &&
|
|
286
|
+
this.ren.nodeUtils.isPointInNodeBoundary(transPos, this.drawingNewLinkData.srcNode)) {
|
|
287
|
+
this.removeNewLinkLine();
|
|
288
|
+
|
|
289
|
+
} else {
|
|
290
|
+
connectionLineSel
|
|
291
|
+
.data(this.drawingNewLinkData.linkArray)
|
|
292
|
+
.enter()
|
|
293
|
+
.append("path")
|
|
294
|
+
.attr("class", "d3-new-connection-line")
|
|
295
|
+
.attr("linkType", linkType)
|
|
296
|
+
.merge(connectionLineSel)
|
|
297
|
+
.attr("d", pathInfo.path)
|
|
298
|
+
.attr("transform", pathInfo.transform);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (this.ren.canvasLayout.linkType !== LINK_TYPE_STRAIGHT) {
|
|
302
|
+
connectionStartSel
|
|
303
|
+
.data(this.drawingNewLinkData.linkArray)
|
|
304
|
+
.enter()
|
|
305
|
+
.append(this.drawingNewLinkData.portObject)
|
|
306
|
+
.attr("class", "d3-new-connection-start")
|
|
307
|
+
.attr("linkType", linkType)
|
|
308
|
+
.merge(connectionStartSel)
|
|
309
|
+
.each((d, i, startSel) => {
|
|
310
|
+
// No need to draw the starting object of the new line if it is an image.
|
|
311
|
+
if (this.drawingNewLinkData.portObject === PORT_OBJECT_CIRCLE) {
|
|
312
|
+
d3.select(startSel[i])
|
|
313
|
+
.attr("cx", d.x1)
|
|
314
|
+
.attr("cy", d.y1)
|
|
315
|
+
.attr("r", this.drawingNewLinkData.portRadius);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
connectionGuideSel
|
|
321
|
+
.data(this.drawingNewLinkData.linkArray)
|
|
322
|
+
.enter()
|
|
323
|
+
.append(this.drawingNewLinkData.guideObject)
|
|
324
|
+
.attr("class", "d3-new-connection-guide")
|
|
325
|
+
.attr("linkType", linkType)
|
|
326
|
+
.merge(connectionGuideSel)
|
|
327
|
+
.each((d, i, guideSel) => {
|
|
328
|
+
if (this.drawingNewLinkData.guideObject === PORT_OBJECT_IMAGE) {
|
|
329
|
+
d3.select(guideSel[i])
|
|
330
|
+
.attr("xlink:href", this.drawingNewLinkData.guideImage)
|
|
331
|
+
.attr("x", d.x2 - (this.drawingNewLinkData.portWidth / 2))
|
|
332
|
+
.attr("y", d.y2 - (this.drawingNewLinkData.portHeight / 2))
|
|
333
|
+
.attr("width", this.drawingNewLinkData.portWidth)
|
|
334
|
+
.attr("height", this.drawingNewLinkData.portHeight)
|
|
335
|
+
.attr("transform", this.ren.getLinkImageTransform(d));
|
|
336
|
+
} else {
|
|
337
|
+
d3.select(guideSel[i])
|
|
338
|
+
.attr("cx", d.x2)
|
|
339
|
+
.attr("cy", d.y2)
|
|
340
|
+
.attr("r", this.drawingNewLinkData.portRadius);
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
removeNewLinkLine() {
|
|
346
|
+
this.ren.nodesLinksGrp.selectAll(".d3-new-connection-line").remove();
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Handles the completion of a new link being drawn from a source node.
|
|
350
|
+
completeNewLink(d3Event) {
|
|
351
|
+
if (this.ren.config.enableEditingActions === false || !this.drawingNewLinkData) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Save a local reference to this.drawingNewLinkData so we can set it to null before
|
|
356
|
+
// calling the canvas-controller. This means the this.drawingNewLinkData object will
|
|
357
|
+
// be null when the canvas is refreshed.
|
|
358
|
+
const drawingNewLinkData = this.drawingNewLinkData;
|
|
359
|
+
this.drawingNewLinkData = null;
|
|
360
|
+
|
|
361
|
+
if (this.ren.config.enableHighlightUnavailableNodes) {
|
|
362
|
+
this.ren.unsetUnavailableNodesHighlighting();
|
|
363
|
+
}
|
|
364
|
+
var trgNode = this.ren.getNodeAtMousePos(d3Event);
|
|
365
|
+
if (trgNode !== null) {
|
|
366
|
+
this.completeNewLinkOnNode(d3Event, trgNode, drawingNewLinkData);
|
|
367
|
+
} else {
|
|
368
|
+
if (this.ren.config.enableLinkSelection === LINK_SELECTION_DETACHABLE &&
|
|
369
|
+
drawingNewLinkData.action === NODE_LINK &&
|
|
370
|
+
!this.ren.config.enableAssocLinkCreation) {
|
|
371
|
+
this.completeNewDetachedLink(d3Event, drawingNewLinkData);
|
|
372
|
+
} else {
|
|
373
|
+
this.stopDrawingNewLink(drawingNewLinkData);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// Handles the completion of a new link when the end is dropped on a node.
|
|
379
|
+
completeNewLinkOnNode(d3Event, trgNode, drawingNewLinkData) {
|
|
380
|
+
// If we completed a connection remove the new line objects.
|
|
381
|
+
this.removeNewLink();
|
|
382
|
+
|
|
383
|
+
// Switch 'new link over node' highlighting off
|
|
384
|
+
if (this.ren.config.enableHighlightNodeOnNewLinkDrag) {
|
|
385
|
+
this.ren.setLinkOverNodeCancel();
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
if (trgNode !== null) {
|
|
389
|
+
const type = drawingNewLinkData.action;
|
|
390
|
+
if (type === NODE_LINK) {
|
|
391
|
+
const srcNode = this.ren.activePipeline.getNode(drawingNewLinkData.srcObjId);
|
|
392
|
+
const srcPortId = drawingNewLinkData.srcPortId;
|
|
393
|
+
const trgPortId = this.ren.getInputNodePortId(d3Event, trgNode);
|
|
394
|
+
|
|
395
|
+
if (CanvasUtils.isDataConnectionAllowed(srcPortId, trgPortId, srcNode, trgNode, this.ren.activePipeline.links)) {
|
|
396
|
+
this.ren.canvasController.editActionHandler({
|
|
397
|
+
editType: "linkNodes",
|
|
398
|
+
editSource: "canvas",
|
|
399
|
+
nodes: [{ "id": drawingNewLinkData.srcObjId, "portId": drawingNewLinkData.srcPortId }],
|
|
400
|
+
targetNodes: [{ "id": trgNode.id, "portId": trgPortId }],
|
|
401
|
+
type: type,
|
|
402
|
+
linkType: "data", // Added for historical purposes - for WML Canvas support
|
|
403
|
+
pipelineId: this.ren.activePipeline.id });
|
|
404
|
+
|
|
405
|
+
} else if (this.ren.config.enableLinkReplaceOnNewConnection &&
|
|
406
|
+
CanvasUtils.isDataLinkReplacementAllowed(srcPortId, trgPortId, srcNode, trgNode, this.ren.activePipeline.links)) {
|
|
407
|
+
const linksToTrgPort = CanvasUtils.getDataLinksConnectedTo(trgPortId, trgNode, this.ren.activePipeline.links);
|
|
408
|
+
// We only replace a link to a maxed out cardinality port if there
|
|
409
|
+
// is only one link. i.e. the input port cardinality is 0:1
|
|
410
|
+
if (linksToTrgPort.length === 1) {
|
|
411
|
+
this.ren.canvasController.editActionHandler({
|
|
412
|
+
editType: "linkNodesAndReplace",
|
|
413
|
+
editSource: "canvas",
|
|
414
|
+
nodes: [{ "id": drawingNewLinkData.srcObjId, "portId": drawingNewLinkData.srcPortId }],
|
|
415
|
+
targetNodes: [{ "id": trgNode.id, "portId": trgPortId }],
|
|
416
|
+
type: type,
|
|
417
|
+
pipelineId: this.pipelineId,
|
|
418
|
+
replaceLink: linksToTrgPort[0]
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
} else if (type === ASSOCIATION_LINK) {
|
|
424
|
+
const srcNode = this.ren.activePipeline.getNode(drawingNewLinkData.srcObjId);
|
|
425
|
+
|
|
426
|
+
if (CanvasUtils.isAssocConnectionAllowed(srcNode, trgNode, this.ren.activePipeline.links)) {
|
|
427
|
+
this.ren.canvasController.editActionHandler({
|
|
428
|
+
editType: "linkNodes",
|
|
429
|
+
editSource: "canvas",
|
|
430
|
+
nodes: [{ "id": drawingNewLinkData.srcObjId }],
|
|
431
|
+
targetNodes: [{ "id": trgNode.id }],
|
|
432
|
+
type: type,
|
|
433
|
+
pipelineId: this.ren.activePipeline.id });
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
} else {
|
|
437
|
+
if (CanvasUtils.isCommentLinkConnectionAllowed(drawingNewLinkData.srcObjId, trgNode.id, this.ren.activePipeline.links)) {
|
|
438
|
+
this.ren.canvasController.editActionHandler({
|
|
439
|
+
editType: "linkComment",
|
|
440
|
+
editSource: "canvas",
|
|
441
|
+
nodes: [drawingNewLinkData.srcObjId],
|
|
442
|
+
targetNodes: [trgNode.id],
|
|
443
|
+
type: COMMENT_LINK,
|
|
444
|
+
linkType: "comment", // Added for historical purposes - for WML Canvas support
|
|
445
|
+
pipelineId: this.ren.activePipeline.id });
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// Handles the completion of a new link when the end is dropped away from
|
|
452
|
+
// a node (when enableLinkSelection is set to LINK_SELECTION_DETACHABLE)
|
|
453
|
+
// which creates a new detached link.
|
|
454
|
+
completeNewDetachedLink(d3Event, drawingNewLinkData) {
|
|
455
|
+
// If we completed a connection remove the new line objects.
|
|
456
|
+
this.removeNewLink();
|
|
457
|
+
|
|
458
|
+
// Switch 'new link over node' highlighting off
|
|
459
|
+
if (this.ren.config.enableHighlightNodeOnNewLinkDrag) {
|
|
460
|
+
this.ren.setLinkOverNodeß();
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
const endPoint = this.ren.getTransformedMousePos(d3Event);
|
|
464
|
+
this.ren.canvasController.editActionHandler({
|
|
465
|
+
editType: "createDetachedLink",
|
|
466
|
+
editSource: "canvas",
|
|
467
|
+
srcNodeId: drawingNewLinkData.srcObjId,
|
|
468
|
+
srcNodePortId: drawingNewLinkData.srcPortId,
|
|
469
|
+
trgPos: endPoint,
|
|
470
|
+
type: NODE_LINK,
|
|
471
|
+
pipelineId: this.ren.activePipeline.id });
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
stopDrawingNewLink(drawingNewLinkData) {
|
|
475
|
+
// Switch 'new link over node' highlighting off
|
|
476
|
+
if (this.ren.config.enableHighlightNodeOnNewLinkDrag) {
|
|
477
|
+
this.ren.setLinkOverNodeCancel();
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
this.stopDrawingNewLinkForPorts(drawingNewLinkData);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
stopDrawingNewLinkForPorts(drawingNewLinkData) {
|
|
484
|
+
const saveX1 = drawingNewLinkData.linkArray[0].x1;
|
|
485
|
+
const saveY1 = drawingNewLinkData.linkArray[0].y1;
|
|
486
|
+
const saveX2 = drawingNewLinkData.linkArray[0].x2;
|
|
487
|
+
const saveY2 = drawingNewLinkData.linkArray[0].y2;
|
|
488
|
+
|
|
489
|
+
const saveNewLinkData = Object.assign({}, drawingNewLinkData);
|
|
490
|
+
|
|
491
|
+
// If we completed a connection successfully just remove the new line
|
|
492
|
+
// objects.
|
|
493
|
+
let newPath = "";
|
|
494
|
+
let duration = 350;
|
|
495
|
+
|
|
496
|
+
if (this.ren.canvasLayout.linkType === LINK_TYPE_CURVE) {
|
|
497
|
+
newPath = "M " + saveX1 + " " + saveY1 +
|
|
498
|
+
"C " + saveX2 + " " + saveY2 +
|
|
499
|
+
" " + saveX2 + " " + saveY2 +
|
|
500
|
+
" " + saveX2 + " " + saveY2;
|
|
501
|
+
|
|
502
|
+
} else if (this.ren.canvasLayout.linkType === LINK_TYPE_STRAIGHT) {
|
|
503
|
+
if (saveX1 < saveX2) {
|
|
504
|
+
duration = 0;
|
|
505
|
+
}
|
|
506
|
+
newPath = "M " + saveX1 + " " + saveY1 +
|
|
507
|
+
"L " + saveX2 + " " + saveY2 +
|
|
508
|
+
" " + saveX2 + " " + saveY2 +
|
|
509
|
+
" " + saveX2 + " " + saveY2;
|
|
510
|
+
|
|
511
|
+
} else {
|
|
512
|
+
newPath = "M " + saveX1 + " " + saveY1 +
|
|
513
|
+
"L " + saveX2 + " " + saveY2 +
|
|
514
|
+
"Q " + saveX2 + " " + saveY2 + " " + saveX2 + " " + saveY2 +
|
|
515
|
+
"L " + saveX2 + " " + saveY2 +
|
|
516
|
+
"Q " + saveX2 + " " + saveY2 + " " + saveX2 + " " + saveY2 +
|
|
517
|
+
"L " + saveX2 + " " + saveY2 +
|
|
518
|
+
"Q " + saveX2 + " " + saveY2 + " " + saveX2 + " " + saveY2 +
|
|
519
|
+
"L " + saveX2 + " " + saveY2 +
|
|
520
|
+
"Q " + saveX2 + " " + saveY2 + " " + saveX2 + " " + saveY2 +
|
|
521
|
+
"L " + saveX2 + " " + saveY2;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
this.ren.nodesLinksGrp.selectAll(".d3-new-connection-line")
|
|
525
|
+
.transition()
|
|
526
|
+
.duration(duration)
|
|
527
|
+
.attr("d", newPath)
|
|
528
|
+
.on("end", () => {
|
|
529
|
+
this.ren.nodesLinksGrp.selectAll(".d3-new-connection-arrow").remove();
|
|
530
|
+
|
|
531
|
+
this.ren.nodesLinksGrp.selectAll(".d3-new-connection-guide")
|
|
532
|
+
.transition()
|
|
533
|
+
.duration(1000)
|
|
534
|
+
.ease(d3.easeElastic)
|
|
535
|
+
// The lines below set all attributes for images AND circles even
|
|
536
|
+
// though some attributes will not be relevant. This is done
|
|
537
|
+
// because I could not get the .each() method to work here (which
|
|
538
|
+
// would be necessary to have an if statement based on guide object)
|
|
539
|
+
.attr("x", saveX1 - (saveNewLinkData.portWidth / 2))
|
|
540
|
+
.attr("y", saveY1 - (saveNewLinkData.portHeight / 2))
|
|
541
|
+
.attr("cx", saveX1)
|
|
542
|
+
.attr("cy", saveY1)
|
|
543
|
+
.attr("transform", null);
|
|
544
|
+
this.ren.nodesLinksGrp.selectAll(".d3-new-connection-line")
|
|
545
|
+
.transition()
|
|
546
|
+
.duration(1000)
|
|
547
|
+
.ease(d3.easeElastic)
|
|
548
|
+
.attr("d", "M " + saveX1 + " " + saveY1 +
|
|
549
|
+
"L " + saveX1 + " " + saveY1)
|
|
550
|
+
.on("end", this.removeNewLink.bind(this));
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
removeNewLink() {
|
|
555
|
+
this.ren.nodesLinksGrp.selectAll(".d3-new-connection-line").remove();
|
|
556
|
+
this.ren.nodesLinksGrp.selectAll(".d3-new-connection-start").remove();
|
|
557
|
+
this.ren.nodesLinksGrp.selectAll(".d3-new-connection-guide").remove();
|
|
558
|
+
this.ren.nodesLinksGrp.selectAll(".d3-new-connection-arrow").remove();
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// Switches on or off node highlighting depending on whether a node is
|
|
562
|
+
// close to teh new link being dragged.
|
|
563
|
+
setNewLinkOverNode(d3Event) {
|
|
564
|
+
const nodeNearMouse = this.ren.getNodeNearMousePos(d3Event, this.ren.canvasLayout.nodeProximity);
|
|
565
|
+
const highlightState = nodeNearMouse && this.isNewLinkAllowedToNode(nodeNearMouse);
|
|
566
|
+
this.ren.setHighlightingOverNode(highlightState, nodeNearMouse);
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// Returns true if a connection is allowed to the node passed in based on the
|
|
570
|
+
// this.drawingNewLinkData object which describes a new link being dragged.
|
|
571
|
+
isNewLinkAllowedToNode(node) {
|
|
572
|
+
if (this.drawingNewLinkData) {
|
|
573
|
+
if (this.drawingNewLinkData.action === NODE_LINK) {
|
|
574
|
+
const srcNode = this.drawingNewLinkData.srcNode;
|
|
575
|
+
const trgNode = node;
|
|
576
|
+
const srcNodePortId = this.drawingNewLinkData.srcPortId;
|
|
577
|
+
const trgNodePortId = CanvasUtils.getDefaultInputPortId(trgNode); // TODO - make specific to nodes.
|
|
578
|
+
return CanvasUtils.isDataConnectionAllowed(srcNodePortId, trgNodePortId, srcNode, trgNode, this.ren.activePipeline.links);
|
|
579
|
+
|
|
580
|
+
} else if (this.drawingNewLinkData.action === ASSOCIATION_LINK) {
|
|
581
|
+
const srcNode = this.drawingNewLinkData.srcNode;
|
|
582
|
+
const trgNode = node;
|
|
583
|
+
return CanvasUtils.isAssocConnectionAllowed(srcNode, trgNode, this.ren.activePipeline.links);
|
|
584
|
+
|
|
585
|
+
} else if (this.drawingNewLinkData.action === COMMENT_LINK) {
|
|
586
|
+
const srcObjId = this.drawingNewLinkData.srcObjId;
|
|
587
|
+
const trgNodeId = node.id;
|
|
588
|
+
return CanvasUtils.isCommentLinkConnectionAllowed(srcObjId, trgNodeId, this.ren.activePipeline.links);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
return false;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
}
|