@elyra/canvas 12.11.1 → 12.12.1

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.
Files changed (165) hide show
  1. package/dist/_baseForOwn-7d4e8506.js +2 -0
  2. package/dist/_baseForOwn-7d4e8506.js.map +1 -0
  3. package/dist/_baseForOwn-d38b560e.js +2 -0
  4. package/dist/_baseForOwn-d38b560e.js.map +1 -0
  5. package/dist/canvas-constants-34cdb7df.js +2 -0
  6. package/dist/canvas-constants-34cdb7df.js.map +1 -0
  7. package/dist/canvas-constants-3c09c7f6.js +2 -0
  8. package/dist/canvas-constants-3c09c7f6.js.map +1 -0
  9. package/dist/canvas-controller-851afae4.js +2 -0
  10. package/dist/canvas-controller-851afae4.js.map +1 -0
  11. package/dist/canvas-controller-b856cfa3.js +2 -0
  12. package/dist/canvas-controller-b856cfa3.js.map +1 -0
  13. package/dist/canvas-logger-815781bb.js.map +1 -1
  14. package/dist/canvas-logger-a0f1beaa.js.map +1 -1
  15. package/dist/common-canvas-65512584.js +2 -0
  16. package/dist/common-canvas-65512584.js.map +1 -0
  17. package/dist/common-canvas-a2d6b5af.js +2 -0
  18. package/dist/common-canvas-a2d6b5af.js.map +1 -0
  19. package/dist/common-canvas.es.js +1 -1
  20. package/dist/common-canvas.es.js.map +1 -1
  21. package/dist/common-canvas.js +1 -1
  22. package/dist/common-canvas.js.map +1 -1
  23. package/dist/common-properties-8727d6f9.js +2 -0
  24. package/dist/common-properties-8727d6f9.js.map +1 -0
  25. package/dist/common-properties-87fef545.js +2 -0
  26. package/dist/common-properties-87fef545.js.map +1 -0
  27. package/dist/{datarecord-metadata-v3-schema-d7ad05cd.js → datarecord-metadata-v3-schema-6b6384ff.js} +2 -2
  28. package/dist/{datarecord-metadata-v3-schema-d7ad05cd.js.map → datarecord-metadata-v3-schema-6b6384ff.js.map} +1 -1
  29. package/dist/{datarecord-metadata-v3-schema-bda88f2e.js → datarecord-metadata-v3-schema-81228a9a.js} +2 -2
  30. package/dist/{datarecord-metadata-v3-schema-bda88f2e.js.map → datarecord-metadata-v3-schema-81228a9a.js.map} +1 -1
  31. package/dist/en-7a0f1db1.js +2 -0
  32. package/dist/en-7a0f1db1.js.map +1 -0
  33. package/dist/en-8647c347.js +2 -0
  34. package/dist/en-8647c347.js.map +1 -0
  35. package/dist/{extends-39f57612.js → extends-cf86ca1c.js} +2 -2
  36. package/dist/{extends-39f57612.js.map → extends-cf86ca1c.js.map} +1 -1
  37. package/dist/extends-e9462902.js +7 -0
  38. package/dist/{extends-51d9ddcc.js.map → extends-e9462902.js.map} +1 -1
  39. package/dist/flexible-table-d4a68ebb.js +2 -0
  40. package/dist/flexible-table-d4a68ebb.js.map +1 -0
  41. package/dist/flexible-table-f0c164d2.js +2 -0
  42. package/dist/flexible-table-f0c164d2.js.map +1 -0
  43. package/dist/{icon-d6909a68.js → icon-c85b53bd.js} +2 -2
  44. package/dist/{icon-d6909a68.js.map → icon-c85b53bd.js.map} +1 -1
  45. package/dist/{icon-811ffddd.js → icon-caf4caca.js} +2 -2
  46. package/dist/{icon-811ffddd.js.map → icon-caf4caca.js.map} +1 -1
  47. package/dist/index-beefcd21.js +2 -0
  48. package/dist/index-beefcd21.js.map +1 -0
  49. package/dist/index-fb90b885.js +2 -0
  50. package/dist/index-fb90b885.js.map +1 -0
  51. package/dist/isArrayLikeObject-a9c7973b.js +2 -0
  52. package/dist/isArrayLikeObject-a9c7973b.js.map +1 -0
  53. package/dist/isArrayLikeObject-f3b27f64.js +2 -0
  54. package/dist/isArrayLikeObject-f3b27f64.js.map +1 -0
  55. package/dist/lib/canvas-controller.es.js +1 -1
  56. package/dist/lib/canvas-controller.js +1 -1
  57. package/dist/lib/canvas.es.js +1 -1
  58. package/dist/lib/canvas.js +1 -1
  59. package/dist/lib/command-stack.es.js +1 -1
  60. package/dist/lib/command-stack.es.js.map +1 -1
  61. package/dist/lib/command-stack.js +1 -1
  62. package/dist/lib/command-stack.js.map +1 -1
  63. package/dist/lib/context-menu.es.js +1 -1
  64. package/dist/lib/context-menu.es.js.map +1 -1
  65. package/dist/lib/context-menu.js +1 -1
  66. package/dist/lib/context-menu.js.map +1 -1
  67. package/dist/lib/properties/field-picker.es.js +1 -1
  68. package/dist/lib/properties/field-picker.js +1 -1
  69. package/dist/lib/properties/flexible-table.es.js +1 -1
  70. package/dist/lib/properties/flexible-table.js +1 -1
  71. package/dist/lib/properties.es.js +1 -1
  72. package/dist/lib/properties.js +1 -1
  73. package/dist/lib/tooltip.es.js +1 -1
  74. package/dist/lib/tooltip.es.js.map +1 -1
  75. package/dist/lib/tooltip.js +1 -1
  76. package/dist/lib/tooltip.js.map +1 -1
  77. package/dist/styles/common-canvas.min.css +1 -1
  78. package/dist/styles/common-canvas.min.css.map +1 -1
  79. package/dist/{toolbar-335252dd.js → toolbar-a5ec3435.js} +2 -2
  80. package/dist/{toolbar-85e6c77b.js.map → toolbar-a5ec3435.js.map} +1 -1
  81. package/dist/{toolbar-85e6c77b.js → toolbar-cca1d9a9.js} +2 -2
  82. package/dist/{toolbar-335252dd.js.map → toolbar-cca1d9a9.js.map} +1 -1
  83. package/locales/command-actions/locales/en.json +8 -8
  84. package/locales/command-actions/locales/eo.json +8 -8
  85. package/locales/common-canvas/locales/en.json +3 -1
  86. package/locales/common-canvas/locales/eo.json +2 -0
  87. package/package.json +9 -10
  88. package/src/command-actions/sizeAndPositionObjectsAction.js +5 -0
  89. package/src/command-stack/command-stack.js +16 -30
  90. package/src/command-stack/internal-stack.js +89 -0
  91. package/src/common-canvas/canvas-controller.js +41 -4
  92. package/src/common-canvas/cc-contents.jsx +6 -1
  93. package/src/common-canvas/cc-toolbar.jsx +14 -4
  94. package/src/common-canvas/common-canvas-utils.js +55 -1
  95. package/src/common-canvas/common-canvas.scss +3 -1
  96. package/src/common-canvas/constants/canvas-constants.js +12 -0
  97. package/src/common-canvas/svg-canvas-d3.js +8 -0
  98. package/src/common-canvas/svg-canvas-renderer.js +300 -77
  99. package/src/common-canvas/svg-canvas-utils-links.js +61 -26
  100. package/src/common-properties/actions/button/button.jsx +45 -13
  101. package/src/common-properties/actions/button/button.scss +4 -8
  102. package/src/common-properties/common-properties.jsx +2 -1
  103. package/src/common-properties/components/control-item/control-item.jsx +7 -1
  104. package/src/common-properties/components/field-picker/field-picker.jsx +7 -8
  105. package/src/common-properties/components/flexible-table/flexible-table.jsx +45 -10
  106. package/src/common-properties/components/virtualized-table/virtualized-table.jsx +72 -20
  107. package/src/common-properties/constants/constants.js +18 -0
  108. package/src/common-properties/controls/abstract-table.jsx +3 -3
  109. package/src/common-properties/controls/checkbox/checkbox.jsx +6 -0
  110. package/src/common-properties/controls/expression/expression-builder/expression-select-field-function.jsx +4 -2
  111. package/src/common-properties/controls/expression/expression.jsx +1 -1
  112. package/src/common-properties/controls/expression/expression.scss +2 -0
  113. package/src/common-properties/controls/multiselect/multiselect.jsx +4 -4
  114. package/src/common-properties/controls/someofselect/someofselect.jsx +1 -1
  115. package/src/common-properties/form/ActionInfo.js +3 -1
  116. package/src/common-properties/form/EditorForm.js +7 -3
  117. package/src/common-properties/properties-controller.js +2 -1
  118. package/src/common-properties/properties-main/properties-main.jsx +4 -2
  119. package/src/common-properties/util/L10nProvider.js +3 -0
  120. package/src/object-model/api-pipeline.js +7 -11
  121. package/src/object-model/config-utils.js +1 -0
  122. package/src/object-model/object-model.js +73 -22
  123. package/src/object-model/pipeline-in-handler.js +8 -0
  124. package/src/object-model/pipeline-out-handler.js +5 -0
  125. package/src/object-model/redux/canvas-store.js +16 -0
  126. package/src/object-model/redux/reducers/canvasinfo.js +12 -8
  127. package/src/object-model/redux/reducers/canvastoolbar.js +6 -0
  128. package/src/object-model/redux/reducers/nodes.js +11 -0
  129. package/src/toolbar/toolbar-action-item.jsx +2 -2
  130. package/src/tooltip/tooltip.jsx +30 -1
  131. package/src/tooltip/tooltip.scss +11 -0
  132. package/stats.html +1 -1
  133. package/dist/canvas-constants-7f93e705.js +0 -2
  134. package/dist/canvas-constants-7f93e705.js.map +0 -1
  135. package/dist/canvas-constants-ac5daafb.js +0 -2
  136. package/dist/canvas-constants-ac5daafb.js.map +0 -1
  137. package/dist/canvas-controller-09d0c333.js +0 -2
  138. package/dist/canvas-controller-09d0c333.js.map +0 -1
  139. package/dist/canvas-controller-c2793ca2.js +0 -2
  140. package/dist/canvas-controller-c2793ca2.js.map +0 -1
  141. package/dist/common-canvas-5b046a86.js +0 -2
  142. package/dist/common-canvas-5b046a86.js.map +0 -1
  143. package/dist/common-canvas-985cc0a2.js +0 -2
  144. package/dist/common-canvas-985cc0a2.js.map +0 -1
  145. package/dist/common-properties-4f471b2b.js +0 -2
  146. package/dist/common-properties-4f471b2b.js.map +0 -1
  147. package/dist/common-properties-9161cd27.js +0 -2
  148. package/dist/common-properties-9161cd27.js.map +0 -1
  149. package/dist/en-2ed89528.js +0 -2
  150. package/dist/en-2ed89528.js.map +0 -1
  151. package/dist/en-e93855cc.js +0 -2
  152. package/dist/en-e93855cc.js.map +0 -1
  153. package/dist/extends-51d9ddcc.js +0 -7
  154. package/dist/flexible-table-154a3359.js +0 -2
  155. package/dist/flexible-table-154a3359.js.map +0 -1
  156. package/dist/flexible-table-5e4a1e6d.js +0 -2
  157. package/dist/flexible-table-5e4a1e6d.js.map +0 -1
  158. package/dist/index-4fd90a14.js +0 -2
  159. package/dist/index-4fd90a14.js.map +0 -1
  160. package/dist/index-6d138021.js +0 -2
  161. package/dist/index-6d138021.js.map +0 -1
  162. package/dist/isArrayLikeObject-31e5e646.js +0 -2
  163. package/dist/isArrayLikeObject-31e5e646.js.map +0 -1
  164. package/dist/isArrayLikeObject-7c33c7fd.js +0 -2
  165. package/dist/isArrayLikeObject-7c33c7fd.js.map +0 -1
@@ -17,7 +17,6 @@
17
17
  /* eslint no-invalid-this: "off" */
18
18
  /* eslint brace-style: "off" */
19
19
  /* eslint no-lonely-if: "off" */
20
- /* eslint max-depth: "off" */
21
20
 
22
21
  // Import just the D3 modules that are needed and combine them as the 'd3' object.
23
22
  import * as d3Drag from "d3-drag";
@@ -27,7 +26,7 @@ import * as d3Fetch from "d3-fetch";
27
26
  import * as d3Zoom from "./d3-zoom-extension/src";
28
27
  const d3 = Object.assign({}, d3Drag, d3Ease, d3Selection, d3Fetch, d3Zoom);
29
28
 
30
- import { cloneDeep, escape as escapeText, get, set,
29
+ import { cloneDeep, escape as escapeText, forOwn, get,
31
30
  unescape as unescapeText } from "lodash";
32
31
  import { ASSOC_RIGHT_SIDE_CURVE, ASSOCIATION_LINK, NODE_LINK, COMMENT_LINK,
33
32
  ASSOC_VAR_CURVE_LEFT, ASSOC_VAR_CURVE_RIGHT, ASSOC_VAR_DOUBLE_BACK_RIGHT,
@@ -39,12 +38,12 @@ import { ASSOC_RIGHT_SIDE_CURVE, ASSOCIATION_LINK, NODE_LINK, COMMENT_LINK,
39
38
  TIP_TYPE_NODE, TIP_TYPE_PORT, TIP_TYPE_DEC, TIP_TYPE_LINK,
40
39
  INTERACTION_MOUSE, INTERACTION_TRACKPAD,
41
40
  USE_DEFAULT_ICON, USE_DEFAULT_EXT_ICON,
42
- SUPER_NODE, SNAP_TO_GRID_AFTER, SNAP_TO_GRID_DURING }
41
+ SUPER_NODE, SNAP_TO_GRID_AFTER, SNAP_TO_GRID_DURING,
42
+ NORTH, SOUTH, EAST, WEST }
43
43
  from "./constants/canvas-constants";
44
44
  import SUPERNODE_ICON from "../../assets/images/supernode.svg";
45
45
  import SUPERNODE_EXT_ICON from "../../assets/images/supernode_ext.svg";
46
46
  import Logger from "../logging/canvas-logger.js";
47
- import LocalStorage from "./local-storage.js";
48
47
  import CanvasUtils from "./common-canvas-utils.js";
49
48
  import SvgCanvasDisplay from "./svg-canvas-utils-display.js";
50
49
  import SvgCanvasNodes from "./svg-canvas-utils-nodes.js";
@@ -255,16 +254,12 @@ export default class SVGCanvasRenderer {
255
254
  this.addBackToParentFlowArrow(this.canvasSVG);
256
255
  }
257
256
 
258
- // If we are showing a sub-flow in full screen mode, zoom it to fit the
259
- // screen so it looks similar to the in-place sub-flow view unless there
260
- // is a saved zoom for this pipeline.
261
- if (this.dispUtils.isDisplayingSubFlowFullPage()) {
262
- if (!this.config.enableSaveZoom ||
263
- this.config.enableSaveZoom === "None" ||
264
- (this.config.enableSaveZoom === "LocalStorage" && !this.getSavedZoom()) ||
265
- (this.config.enableSaveZoom === "Pipelineflow" && !this.activePipeline.zoom)) {
266
- this.zoomToFit();
267
- }
257
+ // If we are showing a sub-flow in full screen mode and there
258
+ // is no saved zoom for this pipeline, zoom it to fit the
259
+ // screen so it looks similar to the in-place sub-flow view.
260
+ if (this.dispUtils.isDisplayingSubFlowFullPage() &&
261
+ !this.canvasController.getSavedZoom(this.pipelineId)) {
262
+ this.zoomToFit();
268
263
  }
269
264
 
270
265
  // If we are showing an in-place subflow make sure any already existing
@@ -624,6 +619,27 @@ export default class SVGCanvasRenderer {
624
619
  return this.dragging;
625
620
  }
626
621
 
622
+ // Returns true if the node should be resizeable. Expanded supernodes are
623
+ // always resizabele and all other nodes, except collapsed supernodes, are
624
+ // resizeable when enableResizableNodes is switched on.
625
+ isNodeResizable(node) {
626
+ if (!this.config.enableEditingActions ||
627
+ CanvasUtils.isSuperBindingNode(node) ||
628
+ CanvasUtils.isCollapsedSupernode(node) ||
629
+ (!this.config.enableResizableNodes && !CanvasUtils.isExpandedSupernode(node))) {
630
+ return false;
631
+ }
632
+ return true;
633
+ }
634
+
635
+ // Returns true if the node should have a resizing area. We should display
636
+ // a sizing area even for collapsed supernodes so it is available if/when
637
+ // the supernode is expanded
638
+ shouldDisplayNodeSizingArea(node) {
639
+ return !CanvasUtils.isSuperBindingNode(node) &&
640
+ (CanvasUtils.isSupernode(node) || this.config.enableResizableNodes);
641
+ }
642
+
627
643
  getAllNodeGroupsSelection() {
628
644
  return this.nodesLinksGrp.selectChildren(".d3-node-group");
629
645
  }
@@ -775,9 +791,16 @@ export default class SVGCanvasRenderer {
775
791
  const ghost = this.getGhostDimensions();
776
792
  const node = this.canvasController.convertNodeTemplate(nodeTemplate);
777
793
  node.layout = this.canvasController.getObjectModel().getNodeLayout();
778
- node.width = node.is_expanded ? node.expanded_width : ghost.width;
779
- node.height = node.is_expanded ? node.expanded_height : ghost.height;
780
-
794
+ if (node.is_expanded) {
795
+ node.width = node.expanded_width;
796
+ node.height = node.expanded_height;
797
+ } else if (node.isResized) {
798
+ node.width = node.resizeWidth;
799
+ node.height = node.resizeHeight;
800
+ } else {
801
+ node.width = ghost.width;
802
+ node.height = ghost.height;
803
+ }
781
804
  const nodeImage = this.getNodeImage(node);
782
805
  const nodeImageType = this.getImageType(nodeImage);
783
806
  const ghostDivSel = this.getGhostDivSel();
@@ -1551,18 +1574,7 @@ export default class SVGCanvasRenderer {
1551
1574
  // of 'save zoom' specified in the configuration and, if no saved zoom, was
1552
1575
  // provided pans the canvas area so it is always visible.
1553
1576
  restoreZoom() {
1554
- let newZoom = null;
1555
-
1556
- if (this.config.enableSaveZoom === "Pipelineflow" &&
1557
- this.activePipeline.zoom) {
1558
- newZoom = this.activePipeline.zoom;
1559
-
1560
- } else if (this.config.enableSaveZoom === "LocalStorage") {
1561
- const savedZoom = this.getSavedZoom();
1562
- if (savedZoom) {
1563
- newZoom = savedZoom;
1564
- }
1565
- }
1577
+ let newZoom = this.canvasController.getSavedZoom(this.pipelineId);
1566
1578
 
1567
1579
  // If there's no saved zoom, and enablePanIntoViewOnOpen is set, pan so
1568
1580
  // the canvas area (containing nodes and comments) is visible in the viewport.
@@ -1605,24 +1617,6 @@ export default class SVGCanvasRenderer {
1605
1617
  }
1606
1618
  }
1607
1619
 
1608
- // Saves the zoom object passed in for this pipeline in local storage.
1609
- setSavedZoom(zoom) {
1610
- const canvasSavedZoomValues = LocalStorage.get("canvasSavedZoomValues");
1611
- const savedZooms = canvasSavedZoomValues ? JSON.parse(canvasSavedZoomValues) : {};
1612
- set(savedZooms, [this.canvasInfo.id, this.pipelineId], zoom);
1613
- LocalStorage.set("canvasSavedZoomValues", JSON.stringify(savedZooms));
1614
- }
1615
-
1616
- // Returns the zoom for this pipeline saved in local storage
1617
- getSavedZoom() {
1618
- const canvasSavedZoomValues = LocalStorage.get("canvasSavedZoomValues");
1619
- if (canvasSavedZoomValues) {
1620
- const savedZoom = JSON.parse(canvasSavedZoomValues);
1621
- return get(savedZoom, [this.canvasInfo.id, this.pipelineId]);
1622
- }
1623
- return null;
1624
- }
1625
-
1626
1620
  zoomToFit() {
1627
1621
  const padding = this.getZoomToFitPadding();
1628
1622
  const canvasDimensions = this.getCanvasDimensionsAdjustedForScale(1, padding);
@@ -1688,6 +1682,14 @@ export default class SVGCanvasRenderer {
1688
1682
  }
1689
1683
  }
1690
1684
 
1685
+ isZoomedToMax() {
1686
+ return this.zoomTransform ? this.zoomTransform.k === this.maxScaleExtent : false;
1687
+ }
1688
+
1689
+ isZoomedToMin() {
1690
+ return this.zoomTransform ? this.zoomTransform.k === this.minScaleExtent : false;
1691
+ }
1692
+
1691
1693
  getZoomToReveal(nodeIDs, xPos, yPos) {
1692
1694
  const transformedSVGRect = this.getTransformedViewportDimensions();
1693
1695
  const nodes = this.activePipeline.getNodes(nodeIDs);
@@ -1882,24 +1884,18 @@ export default class SVGCanvasRenderer {
1882
1884
  this.canvasController.setSelections(selections, this.activePipeline.id);
1883
1885
  this.regionSelect = false;
1884
1886
 
1885
- } else if (this.dispUtils.isDisplayingFullPage()) {
1887
+ } else if (this.dispUtils.isDisplayingFullPage() && this.zoomChanged()) {
1886
1888
  // Set the internal zoom value for canvasSVG used by D3. This will be
1887
1889
  // used by d3Event next time a zoom action is initiated.
1888
1890
  this.canvasSVG.property("__zoom", this.zoomTransform);
1889
1891
 
1890
-
1891
- if (this.config.enableSaveZoom === "Pipelineflow") {
1892
- const data = {
1893
- editType: "setPipelineZoom",
1894
- editSource: "canvas",
1895
- zoom: this.zoomTransform,
1896
- pipelineId: this.activePipeline.id
1897
- };
1898
- this.canvasController.editActionHandler(data);
1899
-
1900
- } else if (this.config.enableSaveZoom === "LocalStorage") {
1901
- this.setSavedZoom(this.zoomTransform);
1902
- }
1892
+ const data = {
1893
+ editType: "setZoom",
1894
+ editSource: "canvas",
1895
+ zoom: this.zoomTransform,
1896
+ pipelineId: this.activePipeline.id
1897
+ };
1898
+ this.canvasController.editActionHandler(data);
1903
1899
  }
1904
1900
 
1905
1901
  // Remove the cursor overlay and reset the SVG background rectangle
@@ -1908,6 +1904,14 @@ export default class SVGCanvasRenderer {
1908
1904
  this.removeTempCursorOverlay();
1909
1905
  }
1910
1906
 
1907
+ // Returns true if the current zoom transform is different from the
1908
+ // zoom values at the beginning of the zoom action.
1909
+ zoomChanged() {
1910
+ return (this.zoomTransform.k !== this.zoomStartPoint.k ||
1911
+ this.zoomTransform.x !== this.zoomStartPoint.x ||
1912
+ this.zoomTransform.y !== this.zoomStartPoint.y);
1913
+ }
1914
+
1911
1915
  zoomCanvasBackground(d3Event) {
1912
1916
  this.regionSelect = false;
1913
1917
 
@@ -2513,7 +2517,7 @@ export default class SVGCanvasRenderer {
2513
2517
  }
2514
2518
 
2515
2519
  // Node Sizing Area.
2516
- newNodeGroups.filter((d) => CanvasUtils.isSupernode(d))
2520
+ newNodeGroups.filter((d) => this.shouldDisplayNodeSizingArea(d))
2517
2521
  .append("path")
2518
2522
  .attr("class", "d3-node-sizing")
2519
2523
  .call(this.attachNodeSizingListeners.bind(this));
@@ -2862,7 +2866,7 @@ export default class SVGCanvasRenderer {
2862
2866
  attachNodeSizingListeners(nodeGrps) {
2863
2867
  nodeGrps
2864
2868
  .on("mousedown", (d3Event, d) => {
2865
- if (CanvasUtils.isExpandedSupernode(d)) {
2869
+ if (this.isNodeResizable(d)) {
2866
2870
  this.nodeSizing = true;
2867
2871
  // Note - node resizing and finalization of size is handled by drag functions.
2868
2872
  this.addTempCursorOverlay(this.nodeSizingCursor);
@@ -2875,8 +2879,7 @@ export default class SVGCanvasRenderer {
2875
2879
  // pointer leaves the temporary overlay (which is removed) and enters
2876
2880
  // the node outline.
2877
2881
  .on("mousemove mouseenter", (d3Event, d) => {
2878
- if (this.config.enableEditingActions && // Only set cursor when we are able to edit nodes
2879
- CanvasUtils.isExpandedSupernode(d) &&
2882
+ if (this.isNodeResizable(d) &&
2880
2883
  !this.isRegionSelectOrSizingInProgress()) { // Don't switch sizing direction if we are already sizing
2881
2884
  let cursorType = "pointer";
2882
2885
  if (!this.isPointerCloseToBodyEdge(d3Event, d)) {
@@ -2886,6 +2889,9 @@ export default class SVGCanvasRenderer {
2886
2889
  }
2887
2890
  d3.select(d3Event.currentTarget).style("cursor", cursorType);
2888
2891
  }
2892
+ })
2893
+ .on("mouseleave", (d3Event, d) => {
2894
+ d3.select(d3Event.currentTarget).style("cursor", "pointer");
2889
2895
  });
2890
2896
  }
2891
2897
 
@@ -4688,7 +4694,7 @@ export default class SVGCanvasRenderer {
4688
4694
  }
4689
4695
 
4690
4696
  // Returns a path that will draw the shape for the rectangle node
4691
- // display. This is draw as a path rather than an SVG rectangle to make the
4697
+ // display. This is drawn as a path rather than an SVG rectangle to make the
4692
4698
  // calling code more generic.
4693
4699
  getRectangleNodeShapePath(data, highlightGap) {
4694
4700
  const gap = highlightGap ? highlightGap : 0;
@@ -5638,21 +5644,43 @@ export default class SVGCanvasRenderer {
5638
5644
  return cursorType;
5639
5645
  }
5640
5646
 
5647
+ // Returns the minimum allowed height for the node passed in. For supernodes
5648
+ // this means combining the bigger of the space for the inputs and output ports
5649
+ // with some space for the top of the display frame and the padding at the
5650
+ // bottom of the frame. Then the bigger of that height versus the default
5651
+ // supernode minimum height is retunred.
5652
+ getMinHeight(node) {
5653
+ if (CanvasUtils.isSupernode(node)) {
5654
+ const minHt = Math.max(node.inputPortsHeight, node.outputPortsHeight) +
5655
+ this.canvasLayout.supernodeTopAreaHeight + this.canvasLayout.supernodeSVGAreaPadding;
5656
+ return Math.max(this.canvasLayout.supernodeMinHeight, minHt);
5657
+ }
5658
+ return node.layout.defaultNodeHeight;
5659
+ }
5660
+
5661
+ // Returns the minimum allowed width for the node passed in.
5662
+ getMinWidth(node) {
5663
+ if (CanvasUtils.isSupernode(node)) {
5664
+ return this.canvasLayout.supernodeMinWidth;
5665
+ }
5666
+ return node.layout.defaultNodeWidth;
5667
+ }
5668
+
5641
5669
  // Sets the size and position of the node in the canvasInfo.nodes
5642
5670
  // array based on the position of the pointer during the resize action
5643
5671
  // then redraws the nodes and links (the link positions may move based
5644
5672
  // on the node size change).
5645
5673
  resizeNode(d3Event) {
5646
5674
  const oldSupernode = Object.assign({}, this.resizeObj);
5647
- const minSupernodeHeight = Math.max(this.resizeObj.inputPortsHeight, this.resizeObj.outputPortsHeight) +
5648
- this.canvasLayout.supernodeTopAreaHeight + this.canvasLayout.supernodeSVGAreaPadding;
5675
+ const minHeight = this.getMinHeight(this.resizeObj);
5676
+ const minWidth = this.getMinWidth(this.resizeObj);
5649
5677
 
5650
5678
  const delta = this.resizeObject(d3Event, this.resizeObj,
5651
- this.nodeSizingDirection, this.canvasLayout.supernodeMinWidth,
5652
- Math.max(this.canvasLayout.supernodeMinHeight, minSupernodeHeight));
5679
+ this.nodeSizingDirection, minWidth, minHeight);
5653
5680
 
5654
5681
  if (delta && (delta.x_pos !== 0 || delta.y_pos !== 0 || delta.width !== 0 || delta.height !== 0)) {
5655
- if (this.config.enableMoveNodesOnSupernodeResize) {
5682
+ if (CanvasUtils.isSupernode(this.resizeObj) &&
5683
+ this.config.enableMoveNodesOnSupernodeResize) {
5656
5684
  const objectsInfo = CanvasUtils.moveSurroundingObjects(
5657
5685
  oldSupernode,
5658
5686
  this.activePipeline.getNodesAndComments(),
@@ -5675,13 +5703,17 @@ export default class SVGCanvasRenderer {
5675
5703
  this.nodeSizingObjectsInfo = Object.assign(this.nodeSizingObjectsInfo, objectsInfo);
5676
5704
  this.nodeSizingLinksInfo = Object.assign(this.nodeSizingLinksInfo, linksInfo);
5677
5705
  }
5706
+
5678
5707
  this.displayComments();
5679
5708
  this.displayNodes();
5680
5709
  this.displayLinks();
5681
- if (this.dispUtils.isDisplayingSubFlow()) {
5682
- this.displayBindingNodesToFitSVG();
5710
+
5711
+ if (CanvasUtils.isSupernode(this.resizeObj)) {
5712
+ if (this.dispUtils.isDisplayingSubFlow()) {
5713
+ this.displayBindingNodesToFitSVG();
5714
+ }
5715
+ this.superRenderers.forEach((renderer) => renderer.displaySVGToFitSupernode());
5683
5716
  }
5684
- this.superRenderers.forEach((renderer) => renderer.displaySVGToFitSupernode());
5685
5717
  }
5686
5718
  }
5687
5719
 
@@ -5788,6 +5820,14 @@ export default class SVGCanvasRenderer {
5788
5820
  y_pos: this.resizeObj.y_pos
5789
5821
  };
5790
5822
 
5823
+ // If the node has been resized set the resize properties appropriately.
5824
+ if (this.resizeObjInitialInfo.width !== this.resizeObj.width ||
5825
+ this.resizeObjInitialInfo.height !== this.resizeObj.height) {
5826
+ this.nodeSizingObjectsInfo[this.resizeObj.id].isResized = true;
5827
+ this.nodeSizingObjectsInfo[this.resizeObj.id].resizeWidth = this.resizeObj.width;
5828
+ this.nodeSizingObjectsInfo[this.resizeObj.id].resizeHeight = this.resizeObj.height;
5829
+ }
5830
+
5791
5831
  this.canvasController.editActionHandler({
5792
5832
  editType: "resizeObjects",
5793
5833
  editSource: "canvas",
@@ -6278,6 +6318,11 @@ export default class SVGCanvasRenderer {
6278
6318
 
6279
6319
  buildLinksArray() {
6280
6320
  let linksArray = [];
6321
+
6322
+ if (this.canvasLayout.linkType === LINK_TYPE_STRAIGHT) {
6323
+ this.updateLinksForNodes();
6324
+ }
6325
+
6281
6326
  this.activePipeline.links.forEach((link) => {
6282
6327
  let linkObj = null;
6283
6328
 
@@ -6331,7 +6376,7 @@ export default class SVGCanvasRenderer {
6331
6376
  link.type === ASSOCIATION_LINK && this.config.enableAssocLinkType === ASSOC_RIGHT_SIDE_CURVE
6332
6377
  ? this.getAssocLinkVariation(srcObj, trgNode)
6333
6378
  : null;
6334
- const coords = this.linkUtils.getLinkCoords(link.type, srcObj, srcPortId, trgNode, trgPortId, assocLinkVariation);
6379
+ const coords = this.linkUtils.getLinkCoords(link, srcObj, srcPortId, trgNode, trgPortId, assocLinkVariation);
6335
6380
 
6336
6381
  link.assocLinkVariation = assocLinkVariation;
6337
6382
  link.srcPortId = srcPortId;
@@ -6364,7 +6409,7 @@ export default class SVGCanvasRenderer {
6364
6409
  } else {
6365
6410
  if (this.canvasLayout.linkType === LINK_TYPE_STRAIGHT) {
6366
6411
  const endPos = { x: link.trgPos.x_pos, y: link.trgPos.y_pos };
6367
- const startPos = this.linkUtils.getNewStraightNodeLinkStartPos(srcObj, endPos);
6412
+ const startPos = this.linkUtils.getNewStraightNodeLinkStartPos(srcObj, endPos, link.srcOriginInfo);
6368
6413
  coords.x1 = startPos.x;
6369
6414
  coords.y1 = startPos.y;
6370
6415
 
@@ -6385,7 +6430,7 @@ export default class SVGCanvasRenderer {
6385
6430
  } else {
6386
6431
  if (this.canvasLayout.linkType === LINK_TYPE_STRAIGHT) {
6387
6432
  const endPos = { x: link.srcPos.x_pos, y: link.srcPos.y_pos };
6388
- const startPos = this.linkUtils.getNewStraightNodeLinkStartPos(trgNode, endPos);
6433
+ const startPos = this.linkUtils.getNewStraightNodeLinkStartPos(trgNode, endPos, link.trgOriginInfo);
6389
6434
  coords.x2 = startPos.x;
6390
6435
  coords.y2 = startPos.y;
6391
6436
 
@@ -6564,6 +6609,184 @@ export default class SVGCanvasRenderer {
6564
6609
  });
6565
6610
  }
6566
6611
 
6612
+ // Updates the data links for all the nodes with two optional fields
6613
+ // (called srcOriginInfo and trgOriginInfo) based on the location of the
6614
+ // nodes the links go from and to. The info in these fields is used to
6615
+ // calculate the starting and ending position of straight line links.
6616
+ // This ensures that input and output links that go in a certain direction
6617
+ // (NORTH, SOUTH, EAST or WEST) are grouped together so they can be
6618
+ // separated out when straight lines are drawn between nodes.
6619
+ updateLinksForNodes() {
6620
+ this.activePipeline.nodes.forEach((n) => this.updateLinksForNode(n));
6621
+ }
6622
+
6623
+ // Updates the links going into and out of the node passed in with up to
6624
+ // two new fields (called srcOriginInfo and trgOriginInfo).
6625
+ updateLinksForNode(node) {
6626
+ const linksInfo = {};
6627
+ linksInfo.n = [];
6628
+ linksInfo.s = [];
6629
+ linksInfo.e = [];
6630
+ linksInfo.w = [];
6631
+
6632
+ // Update the linksInfo arrays for each direction: n, s, e and w.
6633
+ this.activePipeline.links.forEach((link) => {
6634
+ if (link.type === NODE_LINK) {
6635
+ if (link.trgNode && link.trgNode.id === node.id) {
6636
+ if (link.srcObj) {
6637
+ const dir = this.getDirAdjusted(link.trgNode, link.srcObj);
6638
+ linksInfo[dir].push({ type: "in", endNode: link.srcObj, link });
6639
+
6640
+ } else if (link.srcPos) {
6641
+ const dir = this.getDirToEndPos(link.trgNode, link.srcPos.x_pos, link.srcPos.y_pos);
6642
+ linksInfo[dir].push({ type: "in", x: link.srcPos.x_pos, y: link.srcPos.y_pos, link });
6643
+ }
6644
+
6645
+ } else if (link.srcObj && link.srcObj.id === node.id) {
6646
+ if (link.trgNode) {
6647
+ const dir = this.getDirAdjusted(link.srcObj, link.trgNode);
6648
+ linksInfo[dir].push({ type: "out", endNode: link.trgNode, link });
6649
+
6650
+ } else if (link.trgPos) {
6651
+ const dir = this.getDirToEndPos(link.srcObj, link.trgPos.x_pos, link.trgPos.y_pos);
6652
+ linksInfo[dir].push({ type: "out", x: link.trgPos.x_pos, y: link.trgPos.y_pos, link });
6653
+ }
6654
+ }
6655
+ }
6656
+ });
6657
+
6658
+ linksInfo.n = this.sortLinksInfo(linksInfo.n, NORTH);
6659
+ linksInfo.s = this.sortLinksInfo(linksInfo.s, SOUTH);
6660
+ linksInfo.e = this.sortLinksInfo(linksInfo.e, EAST);
6661
+ linksInfo.w = this.sortLinksInfo(linksInfo.w, WEST);
6662
+
6663
+ this.updateLinksInfo(linksInfo.n, NORTH);
6664
+ this.updateLinksInfo(linksInfo.s, SOUTH);
6665
+ this.updateLinksInfo(linksInfo.e, EAST);
6666
+ this.updateLinksInfo(linksInfo.w, WEST);
6667
+ }
6668
+
6669
+ // Returns the direction of a link from the start node to the end node
6670
+ // as either NORTH, SOUTH, EAST or WEST. Some direction combinations
6671
+ // have to be overriden to prevent link lines overlapping.
6672
+ getDirAdjusted(startNode, endNode) {
6673
+ let dir = this.getDirToNode(startNode, endNode);
6674
+
6675
+ // When start -> end is SOUTH and end -> start is WEST the returned direction
6676
+ // becomes EAST instead of SOUTH to prevent link lines overlapping.
6677
+ if (dir === SOUTH) {
6678
+ const dir2 = this.getDirToNode(endNode, startNode);
6679
+ if (dir2 === WEST) {
6680
+ dir = EAST;
6681
+ }
6682
+
6683
+ // When start -> end is NORTH and end -> start is EAST the returned direction
6684
+ // becomes WEST instead of NORTH to prevent link lines overlapping.
6685
+ } else if (dir === NORTH) {
6686
+ const dir2 = this.getDirToNode(endNode, startNode);
6687
+ if (dir2 === EAST) {
6688
+ dir = WEST;
6689
+ }
6690
+ }
6691
+ return dir;
6692
+ }
6693
+
6694
+ // Returns the direction (NORTH, SOUTH, EAST or WEST) from the start node
6695
+ // to the end node.
6696
+ getDirToNode(startNode, endNode) {
6697
+ const endX = this.nodeUtils.getNodeCenterPosX(endNode);
6698
+ const endY = this.nodeUtils.getNodeCenterPosY(endNode);
6699
+ return this.getDirToEndPos(startNode, endX, endY);
6700
+ }
6701
+
6702
+ // Returns the direction (NORTH, SOUTH, EAST or WEST) from the start node
6703
+ // to the end position endX, endY.
6704
+ getDirToEndPos(startNode, endX, endY) {
6705
+ const originX = this.nodeUtils.getNodeCenterPosX(startNode);
6706
+ const originY = this.nodeUtils.getNodeCenterPosY(startNode);
6707
+
6708
+ const x = startNode.x_pos;
6709
+ const y = startNode.y_pos;
6710
+ const w = startNode.width;
6711
+ const h = startNode.height;
6712
+
6713
+ return CanvasUtils.getDir(x, y, w, h, originX, originY, endX, endY);
6714
+ }
6715
+
6716
+ // Returns the linksDirArray passed in with the linkInfo objects in the
6717
+ // array ordered by the position of the end of each link line, depending on
6718
+ // the direction (dir) of the lines. This is achieved by spliting the links
6719
+ // into groups where links in the same group go to/from the same node.
6720
+ sortLinksInfo(linksDirArrayIn, dir) {
6721
+ let linksDirArray = linksDirArrayIn;
6722
+ if (linksDirArray.length > 1) {
6723
+ const groups = this.getLinkInfoGroups(linksDirArray);
6724
+
6725
+ forOwn(groups, (group) => {
6726
+ group.forEach((li, i) => {
6727
+ const node = li.endNode;
6728
+ const parts = group.length + 1;
6729
+
6730
+ if (dir === NORTH || dir === SOUTH) {
6731
+ li.x = node.x_pos + ((node.width / parts) * (i + 1));
6732
+ li.y = this.nodeUtils.getNodeCenterPosY(node);
6733
+ } else {
6734
+ li.x = this.nodeUtils.getNodeCenterPosX(node);
6735
+ li.y = node.y_pos + ((node.height / parts) * (i + 1));
6736
+ }
6737
+ });
6738
+ });
6739
+
6740
+ // For NORTH and SOUTH links we sort linksDirArray by the x co-ordinate
6741
+ // of the end of each link. For EAST and WEST we sort by the y
6742
+ // co-ordinate.
6743
+ if (dir === NORTH || dir === SOUTH) {
6744
+ linksDirArray = linksDirArray.sort((a, b) => (a.x > b.x ? 1 : -1));
6745
+ } else {
6746
+ linksDirArray = linksDirArray.sort((a, b) => (a.y > b.y ? 1 : -1));
6747
+ }
6748
+ }
6749
+ return linksDirArray;
6750
+ }
6751
+
6752
+ // Returns a 'groups' object where each field is index by a node ID and
6753
+ // contains an array of linkInfo objects that go to/from the node.
6754
+ getLinkInfoGroups(linksDirArray) {
6755
+ const groups = {};
6756
+ linksDirArray.forEach((li) => {
6757
+ // Only create groups for attached links.
6758
+ if (li.endNode) {
6759
+ if (!groups[li.endNode.id]) {
6760
+ groups[li.endNode.id] = [];
6761
+ }
6762
+ groups[li.endNode.id].push(li);
6763
+ }
6764
+ });
6765
+ return groups;
6766
+ }
6767
+
6768
+ // Updates the link objects referenced by the linkInfo objects in the
6769
+ // linksDirArray with info to specify the link direction (n, s, e or w),
6770
+ // plus the index and number of connections. This is used when
6771
+ // drawing straight lines to/from nodes to spread out the lines.
6772
+ updateLinksInfo(linksDirArray, dir) {
6773
+ linksDirArray.forEach((li, i) => {
6774
+ if (li.type === "out") {
6775
+ li.link.srcOriginInfo = {
6776
+ dir: dir,
6777
+ idx: i,
6778
+ len: linksDirArray.length
6779
+ };
6780
+ } else {
6781
+ li.link.trgOriginInfo = {
6782
+ dir: dir,
6783
+ idx: i,
6784
+ len: linksDirArray.length
6785
+ };
6786
+ }
6787
+ });
6788
+ }
6789
+
6567
6790
  // Returns a variation of association link to draw when a new link is being
6568
6791
  // drawn outwards from a port. startX is the beginning point of the line
6569
6792
  // at the port. endX is the position where the mouse is currently positioned.