@sapui5/sap.suite.ui.commons 1.136.11 → 1.136.13
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/package.json +1 -1
- package/src/sap/suite/ui/commons/.library +1 -1
- package/src/sap/suite/ui/commons/AriaProperties.js +1 -1
- package/src/sap/suite/ui/commons/CalculationBuilder.js +1 -1
- package/src/sap/suite/ui/commons/CalculationBuilderExpression.js +1 -1
- package/src/sap/suite/ui/commons/CalculationBuilderFunction.js +1 -1
- package/src/sap/suite/ui/commons/CalculationBuilderGroup.js +1 -1
- package/src/sap/suite/ui/commons/CalculationBuilderItem.js +1 -1
- package/src/sap/suite/ui/commons/CalculationBuilderValidationResult.js +1 -1
- package/src/sap/suite/ui/commons/CalculationBuilderVariable.js +1 -1
- package/src/sap/suite/ui/commons/CloudFilePicker.js +1 -1
- package/src/sap/suite/ui/commons/MicroProcessFlow.js +1 -1
- package/src/sap/suite/ui/commons/MicroProcessFlowItem.js +1 -1
- package/src/sap/suite/ui/commons/TimelineRenderManager.js +8 -4
- package/src/sap/suite/ui/commons/flexibility/changeHandler/PropertyChangeMapper.js +1 -1
- package/src/sap/suite/ui/commons/imageeditor/CropCustomShapeHistoryItem.js +1 -1
- package/src/sap/suite/ui/commons/imageeditor/CropEllipseHistoryItem.js +1 -1
- package/src/sap/suite/ui/commons/imageeditor/CropRectangleHistoryItem.js +1 -1
- package/src/sap/suite/ui/commons/imageeditor/CustomSizeItem.js +1 -1
- package/src/sap/suite/ui/commons/imageeditor/FilterHistoryItem.js +1 -1
- package/src/sap/suite/ui/commons/imageeditor/FlipHistoryItem.js +1 -1
- package/src/sap/suite/ui/commons/imageeditor/HistoryItem.js +1 -1
- package/src/sap/suite/ui/commons/imageeditor/ImageEditor.js +1 -1
- package/src/sap/suite/ui/commons/imageeditor/ImageEditorContainer.js +1 -1
- package/src/sap/suite/ui/commons/imageeditor/ImageEditorResponsiveContainer.js +1 -1
- package/src/sap/suite/ui/commons/imageeditor/ResizeHistoryItem.js +1 -1
- package/src/sap/suite/ui/commons/imageeditor/RotateHistoryItem.js +1 -1
- package/src/sap/suite/ui/commons/library.js +100 -3
- package/src/sap/suite/ui/commons/messagebundle.properties +73 -12
- package/src/sap/suite/ui/commons/messagebundle_ar.properties +1 -1
- package/src/sap/suite/ui/commons/messagebundle_en_US_saprigi.properties +39 -5
- package/src/sap/suite/ui/commons/messagebundle_fr_CA.properties +1 -1
- package/src/sap/suite/ui/commons/messagebundle_hu.properties +1 -1
- package/src/sap/suite/ui/commons/messagebundle_id.properties +2 -2
- package/src/sap/suite/ui/commons/messagebundle_it.properties +1 -1
- package/src/sap/suite/ui/commons/messagebundle_pt.properties +1 -1
- package/src/sap/suite/ui/commons/messagebundle_ru.properties +1 -1
- package/src/sap/suite/ui/commons/networkgraph/ElementBase.js +19 -1
- package/src/sap/suite/ui/commons/networkgraph/Graph.js +590 -48
- package/src/sap/suite/ui/commons/networkgraph/GraphMap.js +25 -3
- package/src/sap/suite/ui/commons/networkgraph/GraphRenderer.js +19 -8
- package/src/sap/suite/ui/commons/networkgraph/KeyboardNavigator.js +367 -12
- package/src/sap/suite/ui/commons/networkgraph/Line.js +814 -22
- package/src/sap/suite/ui/commons/networkgraph/Node.js +573 -79
- package/src/sap/suite/ui/commons/networkgraph/Tooltip.js +4 -0
- package/src/sap/suite/ui/commons/networkgraph/Utils.js +249 -10
- package/src/sap/suite/ui/commons/networkgraph/layout/NoopLayout.js +77 -7
- package/src/sap/suite/ui/commons/networkgraph/util/ConnectionPathUtils.js +1174 -0
- package/src/sap/suite/ui/commons/networkgraph/util/CreateConnectionPopover.js +374 -0
- package/src/sap/suite/ui/commons/networkgraph/util/DependencyLayoutHelper.js +1017 -0
- package/src/sap/suite/ui/commons/networkgraph/util/DragDropManager.js +721 -0
- package/src/sap/suite/ui/commons/networkgraph/util/PortManager.js +582 -0
- package/src/sap/suite/ui/commons/statusindicator/Circle.js +1 -1
- package/src/sap/suite/ui/commons/statusindicator/CustomShape.js +1 -1
- package/src/sap/suite/ui/commons/statusindicator/DiscreteThreshold.js +1 -1
- package/src/sap/suite/ui/commons/statusindicator/FillingOption.js +1 -1
- package/src/sap/suite/ui/commons/statusindicator/LibraryShape.js +1 -1
- package/src/sap/suite/ui/commons/statusindicator/Path.js +1 -1
- package/src/sap/suite/ui/commons/statusindicator/PropertyThreshold.js +1 -1
- package/src/sap/suite/ui/commons/statusindicator/Rectangle.js +1 -1
- package/src/sap/suite/ui/commons/statusindicator/Shape.js +1 -1
- package/src/sap/suite/ui/commons/statusindicator/ShapeGroup.js +1 -1
- package/src/sap/suite/ui/commons/statusindicator/SimpleShape.js +1 -1
- package/src/sap/suite/ui/commons/statusindicator/StatusIndicator.js +1 -1
- package/src/sap/suite/ui/commons/taccount/TAccount.js +1 -1
- package/src/sap/suite/ui/commons/taccount/TAccountGroup.js +1 -1
- package/src/sap/suite/ui/commons/taccount/TAccountItem.js +1 -1
- package/src/sap/suite/ui/commons/taccount/TAccountItemProperty.js +1 -1
- package/src/sap/suite/ui/commons/taccount/TAccountPanel.js +1 -1
- package/src/sap/suite/ui/commons/themes/base/NetworkGraph.less +26 -13
- package/src/sap/suite/ui/commons/themes/base/NetworkGroup.less +4 -0
- package/src/sap/suite/ui/commons/themes/base/NetworkLine.less +58 -13
- package/src/sap/suite/ui/commons/themes/base/NetworkNode.less +251 -47
- package/src/sap/suite/ui/commons/themes/base/SemanticColorMixins.less +55 -0
|
@@ -31,7 +31,10 @@ sap.ui.define([
|
|
|
31
31
|
"sap/ui/performance/Measurement",
|
|
32
32
|
"sap/base/security/encodeXML",
|
|
33
33
|
"sap/m/ToggleButton",
|
|
34
|
+
"sap/m/BusyIndicator",
|
|
34
35
|
"sap/m/library",
|
|
36
|
+
"sap/m/IllustratedMessage",
|
|
37
|
+
"sap/m/IllustratedMessageType",
|
|
35
38
|
"sap/suite/ui/commons/util/FullScreenUtil",
|
|
36
39
|
"sap/ui/core/InvisibleMessage",
|
|
37
40
|
"sap/ui/core/library",
|
|
@@ -42,7 +45,10 @@ sap.ui.define([
|
|
|
42
45
|
"sap/ui/core/RenderManager",
|
|
43
46
|
"sap/ui/core/Theming",
|
|
44
47
|
'sap/ui/core/InvisibleText',
|
|
45
|
-
"./GraphRenderer"
|
|
48
|
+
"./GraphRenderer",
|
|
49
|
+
"./util/DragDropManager",
|
|
50
|
+
"./util/PortManager",
|
|
51
|
+
"sap/ui/core/IconPool"
|
|
46
52
|
], function (
|
|
47
53
|
library,
|
|
48
54
|
jQuery,
|
|
@@ -69,7 +75,10 @@ sap.ui.define([
|
|
|
69
75
|
Measurement,
|
|
70
76
|
encodeXML,
|
|
71
77
|
ToggleButton,
|
|
78
|
+
BusyIndicator,
|
|
72
79
|
MobileLibrary,
|
|
80
|
+
IllustratedMessage,
|
|
81
|
+
IllustratedMessageType,
|
|
73
82
|
FullScreenUtil,
|
|
74
83
|
InvisibleMessage,
|
|
75
84
|
coreLibrary,
|
|
@@ -80,7 +89,10 @@ sap.ui.define([
|
|
|
80
89
|
RenderManager,
|
|
81
90
|
Theming,
|
|
82
91
|
InvisibleText,
|
|
83
|
-
GraphRenderer
|
|
92
|
+
GraphRenderer,
|
|
93
|
+
DragDropManager,
|
|
94
|
+
PortManager,
|
|
95
|
+
IconPool
|
|
84
96
|
) {
|
|
85
97
|
"use strict";
|
|
86
98
|
|
|
@@ -89,7 +101,8 @@ sap.ui.define([
|
|
|
89
101
|
Orientation = library.networkgraph.Orientation,
|
|
90
102
|
LayoutRenderType = library.networkgraph.LayoutRenderType,
|
|
91
103
|
RenderType = library.networkgraph.RenderType,
|
|
92
|
-
SemanticColorType = library.SemanticColorType
|
|
104
|
+
SemanticColorType = library.SemanticColorType,
|
|
105
|
+
NodePorts = library.networkgraph.NodePorts;
|
|
93
106
|
|
|
94
107
|
var AGG_NODES = "nodes",
|
|
95
108
|
AGG_LINES = "lines",
|
|
@@ -136,6 +149,7 @@ sap.ui.define([
|
|
|
136
149
|
var Graph = SvgBase.extend("sap.suite.ui.commons.networkgraph.Graph", {
|
|
137
150
|
metadata: {
|
|
138
151
|
library: "sap.suite.ui.commons",
|
|
152
|
+
dnd: { draggable: false, droppable: true },
|
|
139
153
|
properties: {
|
|
140
154
|
/**
|
|
141
155
|
* The height of the graph. If this property is set to 'auto', the network graph will be resized to fit the height of its content, regardless of the height of the parent control.
|
|
@@ -205,15 +219,88 @@ sap.ui.define([
|
|
|
205
219
|
noDataText: {
|
|
206
220
|
type: "string", group: "Behavior", defaultValue: ""
|
|
207
221
|
},
|
|
222
|
+
/**
|
|
223
|
+
* Set this property to <code>true</code> to display a loading indicator while the data loads.
|
|
224
|
+
* @public
|
|
225
|
+
* @since 1.136.19
|
|
226
|
+
*/
|
|
227
|
+
loading: {
|
|
228
|
+
type: "boolean", group: "Behavior", defaultValue: false
|
|
229
|
+
},
|
|
230
|
+
/**
|
|
231
|
+
* Text that is displayed when the loading is set. <br> This property takes effect only when the <code>loading</code> property is set to <code>true</code>.
|
|
232
|
+
* @public
|
|
233
|
+
* @since 1.136.19
|
|
234
|
+
*/
|
|
235
|
+
loadingText: {
|
|
236
|
+
type: "string", group: "Behavior", defaultValue: ""
|
|
237
|
+
},
|
|
208
238
|
/**
|
|
209
239
|
* Adds delay in wheel scrolling to make zooming smooth.
|
|
210
240
|
* Only works when enableWheelZoom is set to true or 'ctrl' key is pressed while wheel scrolling.
|
|
211
241
|
* Add delay in milliseconds.
|
|
212
242
|
*
|
|
213
|
-
* @private
|
|
243
|
+
* @private
|
|
214
244
|
*/
|
|
215
245
|
_smoothWheelZoom: {
|
|
216
246
|
type: "int", group: "Behavior", defaultValue: 125, visibility: "hidden"
|
|
247
|
+
},
|
|
248
|
+
/**
|
|
249
|
+
* Enables the drag and drop of nodes. This property is ignored if the layout property is not set to noop.
|
|
250
|
+
* If set to <code>true</code>, nodes can be dragged and dropped within the graph.
|
|
251
|
+
* @public
|
|
252
|
+
* @since 1.136.19
|
|
253
|
+
*/
|
|
254
|
+
enableDragAndDrop: {
|
|
255
|
+
type: "boolean", group: "Behavior", defaultValue: false
|
|
256
|
+
},
|
|
257
|
+
/**
|
|
258
|
+
* Specifies the ports that are to be displayed on nodes. Ports are used for creating connections between nodes.
|
|
259
|
+
* Ports are available only when the layout algorithm is set to "NoopLayout", and when the drag and drop is enabled. Otherwise, this property is ignored.
|
|
260
|
+
* @public
|
|
261
|
+
* @since 1.136.19
|
|
262
|
+
*/
|
|
263
|
+
nodePorts: {
|
|
264
|
+
type: "sap.suite.ui.commons.networkgraph.NodePorts", group: "Behavior", defaultValue: NodePorts.None
|
|
265
|
+
},
|
|
266
|
+
/**
|
|
267
|
+
* This action button is used to create connections between nodes as an accessible alternative to node ports.
|
|
268
|
+
* The button is displayed on each node when the layout algorithm is set to "NoopLayout" and drag and drop is enabled.
|
|
269
|
+
* shows the 'Create Connection' action button on node.
|
|
270
|
+
* If set to <code>false</code>, the button remains hidden.
|
|
271
|
+
* Hide this button when you want to implement your own way of creating connections between nodes as an accessible alternative to node ports.
|
|
272
|
+
* @public
|
|
273
|
+
* @since 1.136.19
|
|
274
|
+
*/
|
|
275
|
+
showCreateConnectionButton: {
|
|
276
|
+
type: "boolean", group: "Behavior", defaultValue: true
|
|
277
|
+
},
|
|
278
|
+
/**
|
|
279
|
+
* Mapping of connection types to their display text keys or custom text values.
|
|
280
|
+
* This allows customization of how connection types are displayed in the connection creation popover.
|
|
281
|
+
* The mapping should be an object where keys are connection type values (LeftToLeft, LeftToRight, RightToLeft, RightToRight)
|
|
282
|
+
* and values are custom text that follows the correct format (e.g., "Start to End", "Source to Target").
|
|
283
|
+
* If the format is invalid or not provided, default values are used
|
|
284
|
+
* @public
|
|
285
|
+
* @since 1.136.19
|
|
286
|
+
*/
|
|
287
|
+
connectionTypeMapping: {
|
|
288
|
+
type: "object", group: "Behavior", defaultValue: {
|
|
289
|
+
"LeftToLeft": "Start to Start",
|
|
290
|
+
"LeftToRight": "Start to Finish",
|
|
291
|
+
"RightToLeft": "Finish to Start",
|
|
292
|
+
"RightToRight": "Finish to Finish"
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
/**
|
|
296
|
+
* Custom labels for element types displayed in the SearchField suggestions and Legend section headers.
|
|
297
|
+
* Supported keys: nodeLabel, nodeLabelPlural, lineLabel, lineLabelPlural, groupLabel, groupLabelPlural.
|
|
298
|
+
* Reverts to the default values for keys that are not set.
|
|
299
|
+
* @public
|
|
300
|
+
* @since 1.149
|
|
301
|
+
*/
|
|
302
|
+
labels: {
|
|
303
|
+
type: "object", group: "Appearance", defaultValue: {}
|
|
217
304
|
}
|
|
218
305
|
},
|
|
219
306
|
aggregations: {
|
|
@@ -264,7 +351,12 @@ sap.ui.define([
|
|
|
264
351
|
/**
|
|
265
352
|
* Controls or IDs that label this control. This association is used by screen reader software.
|
|
266
353
|
*/
|
|
267
|
-
ariaLabelledBy: { type: "sap.ui.core.Control", multiple: true, singularName: "ariaLabelledBy" }
|
|
354
|
+
ariaLabelledBy: { type: "sap.ui.core.Control", multiple: true, singularName: "ariaLabelledBy" },
|
|
355
|
+
/**
|
|
356
|
+
* Control or ID of an auxiliary control associated with this graph.
|
|
357
|
+
* @since 1.136.19
|
|
358
|
+
*/
|
|
359
|
+
associatedControl: { type: "sap.ui.core.Control", multiple: false, singularName: "associatedControl" }
|
|
268
360
|
},
|
|
269
361
|
events: {
|
|
270
362
|
/**
|
|
@@ -327,7 +419,79 @@ sap.ui.define([
|
|
|
327
419
|
term: { type: "string" },
|
|
328
420
|
key: { type: "string" }
|
|
329
421
|
}
|
|
330
|
-
}
|
|
422
|
+
},
|
|
423
|
+
/**
|
|
424
|
+
* This event is fired when a user drops a node in the graph.
|
|
425
|
+
* This event is available only when the layout algorithm is set to "NoopLayout" and the <code>enableDragAndDrop</code> property is set to <code>true</code>.
|
|
426
|
+
* @public
|
|
427
|
+
* @since 1.136.19
|
|
428
|
+
*/
|
|
429
|
+
nodeDropped: {
|
|
430
|
+
parameters: {
|
|
431
|
+
/**
|
|
432
|
+
* The node that was moved.
|
|
433
|
+
*/
|
|
434
|
+
node: { type: "sap.suite.ui.commons.networkgraph.Node" },
|
|
435
|
+
/**
|
|
436
|
+
* The new x coordinate of the node.
|
|
437
|
+
*/
|
|
438
|
+
newX: { type: "float" },
|
|
439
|
+
/**
|
|
440
|
+
* The new y coordinate of the node.
|
|
441
|
+
*/
|
|
442
|
+
newY: { type: "float" }
|
|
443
|
+
}
|
|
444
|
+
},
|
|
445
|
+
/**
|
|
446
|
+
* This event is fired when a new connection is created between two nodes by using node ports.
|
|
447
|
+
* @public
|
|
448
|
+
* @since 1.136.19
|
|
449
|
+
*/
|
|
450
|
+
connectionCreated: {
|
|
451
|
+
parameters: {
|
|
452
|
+
/**
|
|
453
|
+
* The key of the source node.
|
|
454
|
+
**/
|
|
455
|
+
from: { type: "string" },
|
|
456
|
+
/**
|
|
457
|
+
* The key of the target node.
|
|
458
|
+
**/
|
|
459
|
+
to: { type: "string" },
|
|
460
|
+
/**
|
|
461
|
+
* The connection type defining how the line connects the source and target nodes.
|
|
462
|
+
*/
|
|
463
|
+
connectionType: {type: "sap.suite.ui.commons.networkgraph.ConnectionType"},
|
|
464
|
+
/**
|
|
465
|
+
* The source node control instance.
|
|
466
|
+
**/
|
|
467
|
+
fromNode: { type: "sap.suite.ui.commons.networkgraph.Node" },
|
|
468
|
+
/**
|
|
469
|
+
* The target node control instance.
|
|
470
|
+
**/
|
|
471
|
+
toNode: { type: "sap.suite.ui.commons.networkgraph.Node" }
|
|
472
|
+
}
|
|
473
|
+
},
|
|
474
|
+
/**
|
|
475
|
+
* This event is fired when a user presses the delete key on a focused node or line.
|
|
476
|
+
* This event is available only when the layout algorithm is set to "NoopLayout" and the <code>enableDragAndDrop</code> property is set to <code>true</code>.
|
|
477
|
+
* @public
|
|
478
|
+
* @since 1.136.19
|
|
479
|
+
*/
|
|
480
|
+
itemDeleted: {
|
|
481
|
+
parameters: {
|
|
482
|
+
/**
|
|
483
|
+
* The item (node or line) that is to be deleted.
|
|
484
|
+
*/
|
|
485
|
+
item: { type: "sap.suite.ui.commons.networkgraph.ElementBase" }
|
|
486
|
+
}
|
|
487
|
+
},
|
|
488
|
+
/**
|
|
489
|
+
* Fired when the user requests to add a node via INSERT or Ctrl+Alt+N.
|
|
490
|
+
* Only available when NoopLayout is used and enableDragAndDrop is <code>true</code>.
|
|
491
|
+
* @public
|
|
492
|
+
* @since 1.136.19
|
|
493
|
+
*/
|
|
494
|
+
nodeAdded: {}
|
|
331
495
|
}
|
|
332
496
|
}
|
|
333
497
|
});
|
|
@@ -388,6 +552,9 @@ sap.ui.define([
|
|
|
388
552
|
// RTL mode - it's reset in 'onBeforeRendering' in case it changed runtime
|
|
389
553
|
this._bIsRtl = Localization.getRTL();
|
|
390
554
|
|
|
555
|
+
// Private variable for multiple directed arrows feature
|
|
556
|
+
this._enableMultipleDirectedArrows = false;
|
|
557
|
+
|
|
391
558
|
// element with focus
|
|
392
559
|
this._oFocus = null;
|
|
393
560
|
|
|
@@ -406,14 +573,83 @@ sap.ui.define([
|
|
|
406
573
|
// flag to check if the events has been added to the graph
|
|
407
574
|
this._bEventsAdded = false;
|
|
408
575
|
|
|
576
|
+
// illustrated message instance for empty state
|
|
577
|
+
this._oIllustratedMessage = null;
|
|
578
|
+
|
|
409
579
|
this._createToolbar();
|
|
410
580
|
|
|
581
|
+
/**
|
|
582
|
+
* Attach drag and drop events
|
|
583
|
+
*/
|
|
584
|
+
if (this.getDragDropConfig().length === 0) {
|
|
585
|
+
try {
|
|
586
|
+
DragDropManager.injectDnD(this);
|
|
587
|
+
} catch (error) {
|
|
588
|
+
Log.warning("Graph injectDnD issue: ", error);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
// Initialize PortManager with this graph instance
|
|
592
|
+
PortManager.setGraphInstance(this);
|
|
593
|
+
Core.ready(this._handleCoreInitialized.bind(this));
|
|
594
|
+
|
|
595
|
+
};
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* Handler for the core's init event. Attaches listener for localization changes.
|
|
599
|
+
* @private
|
|
600
|
+
*/
|
|
601
|
+
Graph.prototype._handleCoreInitialized = function () {
|
|
602
|
+
Localization.attachChange(this._handleLocalizationChanged.bind(this));
|
|
603
|
+
};
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* Handler for localization changes. Sets a pending flag when RTL mode changes so that
|
|
607
|
+
* node dimensions are re-measured after RTL CSS files finish loading.
|
|
608
|
+
* UI5 automatically re-renders all UIAreas on RTL change; the flag prevents premature
|
|
609
|
+
* layout calculation in onAfterRendering before CSS dimensions are stable.
|
|
610
|
+
* @private
|
|
611
|
+
*/
|
|
612
|
+
Graph.prototype._handleLocalizationChanged = function () {
|
|
613
|
+
const bNewRtl = Localization.getRTL();
|
|
614
|
+
if (this._bIsRtl !== bNewRtl) {
|
|
615
|
+
this._bIsRtl = bNewRtl;
|
|
616
|
+
this._bRtlMeasurementPending = true;
|
|
617
|
+
|
|
618
|
+
const fnOnApplied = function () {
|
|
619
|
+
Theming.detachApplied(fnOnApplied);
|
|
620
|
+
if (this._bRtlMeasurementPending) {
|
|
621
|
+
this._bRtlMeasurementPending = false;
|
|
622
|
+
this._measureAndLayout();
|
|
623
|
+
}
|
|
624
|
+
}.bind(this);
|
|
625
|
+
Theming.attachApplied(fnOnApplied);
|
|
626
|
+
}
|
|
627
|
+
};
|
|
628
|
+
|
|
629
|
+
Graph.prototype._measureAndLayout = function () {
|
|
630
|
+
var aNodes = this.getNodes();
|
|
631
|
+
aNodes.forEach(function (oNode) {
|
|
632
|
+
if (this._isUseNodeHtml()) {
|
|
633
|
+
oNode._setupDivDimensions();
|
|
634
|
+
} else {
|
|
635
|
+
oNode.calculateSizes();
|
|
636
|
+
oNode._setupWidthAndHeight();
|
|
637
|
+
}
|
|
638
|
+
}.bind(this));
|
|
639
|
+
this._bTriggerLayoutCalculation = true;
|
|
640
|
+
this._preprocessData();
|
|
411
641
|
};
|
|
412
642
|
|
|
413
643
|
Graph.prototype.onBeforeRendering = function () {
|
|
414
644
|
// indicates RTL
|
|
415
645
|
this._bIsRtl = Localization.getRTL();
|
|
416
646
|
|
|
647
|
+
// Check if the currently focused item has been destroyed and clear it
|
|
648
|
+
if (this._oFocus && this._oFocus.item && (this._oFocus.item.bIsDestroyed || this._oFocus.item.isDestroyed?.())) {
|
|
649
|
+
Log.info("NetworkGraph: Focused item was destroyed before rendering, clearing focus");
|
|
650
|
+
this._oFocus = null;
|
|
651
|
+
}
|
|
652
|
+
|
|
417
653
|
this.setBusy(false);
|
|
418
654
|
this.setBusyIndicatorDelay(0);
|
|
419
655
|
|
|
@@ -461,7 +697,6 @@ sap.ui.define([
|
|
|
461
697
|
this.$().addClass("sapSuiteUiCommonsNetworkGraphFullScreen");
|
|
462
698
|
}
|
|
463
699
|
|
|
464
|
-
|
|
465
700
|
if (aNodes.length === 0 || this._bIsInvalid || this.getNoData()) {
|
|
466
701
|
if (this._bIsInvalid) {
|
|
467
702
|
oRm.openStart("span");
|
|
@@ -523,29 +758,18 @@ sap.ui.define([
|
|
|
523
758
|
oRm.flush(this._$innerscroller[0], true, this._$innerscroller.children().length);
|
|
524
759
|
}
|
|
525
760
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
// call after rendering before layouter starts - can be handy when user custom renders
|
|
530
|
-
oNode._setupDivDimensions();
|
|
531
|
-
} else {
|
|
532
|
-
oNode.calculateSizes();
|
|
533
|
-
oNode._setupWidthAndHeight();
|
|
534
|
-
}
|
|
535
|
-
}.bind(this));
|
|
536
|
-
|
|
537
|
-
this._preprocessData();
|
|
538
|
-
Theming.detachApplied(fnProcess);
|
|
761
|
+
if (!this._bRtlMeasurementPending) {
|
|
762
|
+
this._measureAndLayout();
|
|
763
|
+
}
|
|
539
764
|
}.bind(this);
|
|
540
765
|
|
|
541
|
-
|
|
542
|
-
// else it will be called once theme is applied.
|
|
543
|
-
Theming.attachApplied(fnProcess);
|
|
766
|
+
fnProcess();
|
|
544
767
|
}
|
|
545
768
|
this.oInvisibleMessage = InvisibleMessage.getInstance();
|
|
546
769
|
oRm.destroy();
|
|
547
770
|
|
|
548
771
|
};
|
|
772
|
+
|
|
549
773
|
Graph.prototype.exit = function () {
|
|
550
774
|
// if (this.oHashChanger) {
|
|
551
775
|
// this.oHashChanger.destroy();
|
|
@@ -553,6 +777,20 @@ sap.ui.define([
|
|
|
553
777
|
if (this._oFullScreenUtil) {
|
|
554
778
|
this._oFullScreenUtil.cleanUpFullScreen(this);
|
|
555
779
|
}
|
|
780
|
+
|
|
781
|
+
// Clean up busy indicator
|
|
782
|
+
if (this._oBusyIndicator) {
|
|
783
|
+
this._oBusyIndicator.destroy();
|
|
784
|
+
this._oBusyIndicator = null;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
// Clean up illustrated message
|
|
788
|
+
if (this._oIllustratedMessage) {
|
|
789
|
+
this._oIllustratedMessage.destroy();
|
|
790
|
+
this._oIllustratedMessage = null;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
DragDropManager.removeDnD(this);
|
|
556
794
|
};
|
|
557
795
|
/* =========================================================== */
|
|
558
796
|
/* Pseudo events and event triggers */
|
|
@@ -583,6 +821,7 @@ sap.ui.define([
|
|
|
583
821
|
/**
|
|
584
822
|
* Returns <code>true</code> if the graph is in full screen mode.
|
|
585
823
|
* @public
|
|
824
|
+
* @returns {boolean} Returns whether the graph is in full screen mode.
|
|
586
825
|
*/
|
|
587
826
|
Graph.prototype.isFullScreen = function () {
|
|
588
827
|
return this._bIsFullScreen;
|
|
@@ -717,6 +956,33 @@ sap.ui.define([
|
|
|
717
956
|
return this._mNodes[sKey];
|
|
718
957
|
};
|
|
719
958
|
|
|
959
|
+
/**
|
|
960
|
+
* Re-rendering a node and all connected lines to update the positions of both the node and the lines.
|
|
961
|
+
* Note: This method should be used only when the layout algorithm is set to NoopLayout and enableDragAndDrop is set to true.
|
|
962
|
+
*
|
|
963
|
+
* @param {sap.suite.ui.commons.networkgraph.Node|string} vNode Node instance or node key
|
|
964
|
+
* @param {number} iX New X coordinate
|
|
965
|
+
* @param {number} iY New Y coordinate
|
|
966
|
+
* @returns {sap.suite.ui.commons.networkgraph.Graph} Reference to this for method chaining
|
|
967
|
+
* @public
|
|
968
|
+
* @since 1.136.19
|
|
969
|
+
*/
|
|
970
|
+
Graph.prototype.updateNodePosition = function (vNode, iX, iY) {
|
|
971
|
+
if (!this._isDnDEnabled()) {
|
|
972
|
+
return this;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
var oNode = typeof vNode === "string" ? this.getNodeByKey(vNode) : vNode;
|
|
976
|
+
|
|
977
|
+
if (!oNode) {
|
|
978
|
+
Log.warning("Node not found", "updateNodePosition", "sap.suite.ui.commons.networkgraph.Graph");
|
|
979
|
+
return this;
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
this.invalidate();
|
|
983
|
+
return this;
|
|
984
|
+
};
|
|
985
|
+
|
|
720
986
|
/**
|
|
721
987
|
* Sets a custom label for the legend.
|
|
722
988
|
* @param {object} mArguments Parameters for this method
|
|
@@ -753,6 +1019,13 @@ sap.ui.define([
|
|
|
753
1019
|
this._createLegend();
|
|
754
1020
|
};
|
|
755
1021
|
|
|
1022
|
+
Graph.prototype.setLabels = function (oValue) {
|
|
1023
|
+
this.setProperty("labels", oValue, true);
|
|
1024
|
+
this._createSearchSuggestItems();
|
|
1025
|
+
this._createLegend();
|
|
1026
|
+
return this;
|
|
1027
|
+
};
|
|
1028
|
+
|
|
756
1029
|
|
|
757
1030
|
/**
|
|
758
1031
|
* Zooms in or out of the graph.
|
|
@@ -791,7 +1064,7 @@ sap.ui.define([
|
|
|
791
1064
|
/**
|
|
792
1065
|
* Returns current zoom level.
|
|
793
1066
|
*
|
|
794
|
-
* @return {number}
|
|
1067
|
+
* @return {number} Current zoom level
|
|
795
1068
|
* @public
|
|
796
1069
|
*/
|
|
797
1070
|
Graph.prototype.getCurrentZoomLevel = function () {
|
|
@@ -811,6 +1084,31 @@ sap.ui.define([
|
|
|
811
1084
|
this._oZoomLevelInvisibleText.setText(oResourceBundle.getText("NETWORK_GRAPH_ZOOM_LEVEL") + ": " + this._getZoomText());
|
|
812
1085
|
};
|
|
813
1086
|
|
|
1087
|
+
/**
|
|
1088
|
+
* Restores keyboard focus to the last focused item in the graph, or falls back to the graph wrapper.
|
|
1089
|
+
* @private
|
|
1090
|
+
*/
|
|
1091
|
+
Graph.prototype._restoreFocusToGraph = function () {
|
|
1092
|
+
if (this._oFocus) {
|
|
1093
|
+
const oFocusToRestore = this._oFocus;
|
|
1094
|
+
// Force setFocus to re-apply even if the item hasn't changed.
|
|
1095
|
+
this._oFocus = null;
|
|
1096
|
+
this.setFocus(oFocusToRestore);
|
|
1097
|
+
} else {
|
|
1098
|
+
this.getFocusDomRef().focus();
|
|
1099
|
+
}
|
|
1100
|
+
};
|
|
1101
|
+
|
|
1102
|
+
/**
|
|
1103
|
+
* Gets the associated control linked to this graph instance using the 'associatedControl' association.
|
|
1104
|
+
* This can be any UI5 control that is related to the graph.
|
|
1105
|
+
* @returns {sap.ui.core.Control|null} The associated control instance or null if not set.
|
|
1106
|
+
* @public
|
|
1107
|
+
*/
|
|
1108
|
+
Graph.prototype.getAssociatedControl = function () {
|
|
1109
|
+
var sId = this.getAssociation("associatedControl");
|
|
1110
|
+
return sId ? Element.getElementById(sId) : null;
|
|
1111
|
+
};
|
|
814
1112
|
|
|
815
1113
|
/* =========================================================== */
|
|
816
1114
|
/* Private methods */
|
|
@@ -837,6 +1135,24 @@ sap.ui.define([
|
|
|
837
1135
|
};
|
|
838
1136
|
};
|
|
839
1137
|
|
|
1138
|
+
/**
|
|
1139
|
+
* Returns a busy indicator instance for loading states.
|
|
1140
|
+
* @returns {sap.m.BusyIndicator} BusyIndicator instance
|
|
1141
|
+
* @private
|
|
1142
|
+
*/
|
|
1143
|
+
Graph.prototype._getBusyIndicator = function () {
|
|
1144
|
+
var sText = this.getLoadingText() || oResourceBundle.getText("NETWORK_GRAPH_OPENING_CANVAS");
|
|
1145
|
+
|
|
1146
|
+
if (!this._oBusyIndicator) {
|
|
1147
|
+
this._oBusyIndicator = new BusyIndicator({ text: sText });
|
|
1148
|
+
this.addDependent(this._oBusyIndicator);
|
|
1149
|
+
} else {
|
|
1150
|
+
this._oBusyIndicator.setText(sText);
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
return this._oBusyIndicator;
|
|
1154
|
+
};
|
|
1155
|
+
|
|
840
1156
|
Graph.prototype._createTooltip = function () {
|
|
841
1157
|
var oTooltip = new Tooltip(this.getId() + "-tooltip");
|
|
842
1158
|
this.addDependent(oTooltip);
|
|
@@ -844,7 +1160,15 @@ sap.ui.define([
|
|
|
844
1160
|
oTooltip.attachEvent("afterClose", function () {
|
|
845
1161
|
var oFocus = this.getFocus();
|
|
846
1162
|
|
|
847
|
-
if (oFocus) {
|
|
1163
|
+
if (oFocus && oFocus.item) {
|
|
1164
|
+
// Check if the focused item is destroyed before trying to restore focus
|
|
1165
|
+
if (oFocus.item.bIsDestroyed || oFocus.item.isDestroyed?.()) {
|
|
1166
|
+
Log.info("NetworkGraph: Cannot restore focus on destroyed control after tooltip close");
|
|
1167
|
+
this._oFocus = null;
|
|
1168
|
+
return;
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
this._oFocus = null;
|
|
848
1172
|
this.setFocus(oFocus);
|
|
849
1173
|
|
|
850
1174
|
if (oFocus.button == "menu") {
|
|
@@ -858,12 +1182,91 @@ sap.ui.define([
|
|
|
858
1182
|
};
|
|
859
1183
|
|
|
860
1184
|
/**
|
|
1185
|
+
* Gets or creates an IllustratedMessage instance for displaying empty state.
|
|
1186
|
+
* This method reuses the same instance to avoid memory leaks.
|
|
1187
|
+
* The illustrated message content depends on whether drag-and-drop is enabled:
|
|
1188
|
+
* - When drag-and-drop is enabled: Shows "AddDimensions" illustration with plan-building message
|
|
1189
|
+
* - When drag-and-drop is disabled: Shows "NoChartData" illustration with custom or default no-data text
|
|
1190
|
+
*
|
|
1191
|
+
* @returns {sap.m.IllustratedMessage} The illustrated message instance for empty state
|
|
861
1192
|
* @private
|
|
862
1193
|
*/
|
|
1194
|
+
Graph.prototype._getIllustratedMessage = function () {
|
|
1195
|
+
// Helper function to get configuration based on current state
|
|
1196
|
+
var fnConfigureIllustratedMessage = function () {
|
|
1197
|
+
var sText = this.getNoDataText(),
|
|
1198
|
+
sTextInline = sText || oResourceBundle.getText("NETWORK_GRAPH_NO_DATA");
|
|
1199
|
+
|
|
1200
|
+
if (this._isDnDEnabled()) {
|
|
1201
|
+
return {
|
|
1202
|
+
illustrationType: IllustratedMessageType.AddDimensions,
|
|
1203
|
+
title: oResourceBundle.getText("NETWORK_GRAPH_DND_EMPTY_TITLE"),
|
|
1204
|
+
description: oResourceBundle.getText("NETWORK_GRAPH_DND_EMPTY_DESCRIPTION"),
|
|
1205
|
+
enableDefaultTitleAndDescription: false
|
|
1206
|
+
};
|
|
1207
|
+
} else {
|
|
1208
|
+
return {
|
|
1209
|
+
illustrationType: IllustratedMessageType.NoChartData,
|
|
1210
|
+
title: sTextInline,
|
|
1211
|
+
enableDefaultTitleAndDescription: false
|
|
1212
|
+
};
|
|
1213
|
+
}
|
|
1214
|
+
}.bind(this);
|
|
1215
|
+
|
|
1216
|
+
if (!this._oIllustratedMessage) {
|
|
1217
|
+
var oConfig = fnConfigureIllustratedMessage();
|
|
1218
|
+
this._oIllustratedMessage = new IllustratedMessage(oConfig);
|
|
1219
|
+
this.addDependent(this._oIllustratedMessage);
|
|
1220
|
+
} else {
|
|
1221
|
+
var oConfig = fnConfigureIllustratedMessage();
|
|
1222
|
+
this._oIllustratedMessage.setIllustrationType(oConfig.illustrationType);
|
|
1223
|
+
this._oIllustratedMessage.setTitle(oConfig.title);
|
|
1224
|
+
this._oIllustratedMessage.setDescription(oConfig.description);
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
return this._oIllustratedMessage;
|
|
1228
|
+
};
|
|
1229
|
+
|
|
1230
|
+
/**
|
|
1231
|
+
* @private
|
|
1232
|
+
* Defocuses the currently focused element.
|
|
1233
|
+
*/
|
|
863
1234
|
Graph.prototype.defocus = function () {
|
|
864
1235
|
this.$().find("." + this.FOCUS_CLASS).removeClass(this.FOCUS_CLASS);
|
|
865
1236
|
};
|
|
866
1237
|
|
|
1238
|
+
/**
|
|
1239
|
+
* Sets whether drag and drop is enabled.
|
|
1240
|
+
* @param {boolean} bEnabled Whether drag and drop should be enabled
|
|
1241
|
+
* @private
|
|
1242
|
+
*/
|
|
1243
|
+
Graph.prototype.setEnableDragAndDrop = function (bEnabled) {
|
|
1244
|
+
this.setProperty("enableDragAndDrop", bEnabled, true);
|
|
1245
|
+
|
|
1246
|
+
// Update zoom button visibility
|
|
1247
|
+
if (this._zoomIn && this._zoomOut && this._zoomToFitButton) {
|
|
1248
|
+
var bZoomVisible = !this._isDnDEnabled();
|
|
1249
|
+
this._zoomIn.setVisible(bZoomVisible);
|
|
1250
|
+
this._zoomOut.setVisible(bZoomVisible);
|
|
1251
|
+
this._zoomToFitButton.setVisible(bZoomVisible);
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
// remove the node ports when drag and drop is disabled
|
|
1255
|
+
if (!bEnabled) {
|
|
1256
|
+
PortManager.removeAllPorts();
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
return this;
|
|
1260
|
+
};
|
|
1261
|
+
|
|
1262
|
+
/**
|
|
1263
|
+
* @private
|
|
1264
|
+
* @returns {boolean} Returns whether drag and drop is enabled.
|
|
1265
|
+
*/
|
|
1266
|
+
Graph.prototype.getEnableDragAndDrop = function () {
|
|
1267
|
+
return this.getProperty("enableDragAndDrop");
|
|
1268
|
+
};
|
|
1269
|
+
|
|
867
1270
|
/**
|
|
868
1271
|
* Sets focus of the graph. Since one element at max can be focused at one time, handling of this belongs to the graph itself.
|
|
869
1272
|
* @param {object} oFocus Element (and optionally button) to focus
|
|
@@ -871,6 +1274,13 @@ sap.ui.define([
|
|
|
871
1274
|
* @private
|
|
872
1275
|
*/
|
|
873
1276
|
Graph.prototype.setFocus = function (oFocus, bIsClickOrEnter) {
|
|
1277
|
+
// Check if the focused item has been destroyed and clear it
|
|
1278
|
+
if (oFocus && oFocus.item && (oFocus.item.bIsDestroyed || oFocus.item.isDestroyed?.())) {
|
|
1279
|
+
Log.info("NetworkGraph: Cannot set focus on destroyed control, clearing focus");
|
|
1280
|
+
this._oFocus = null;
|
|
1281
|
+
return;
|
|
1282
|
+
}
|
|
1283
|
+
|
|
874
1284
|
// Identity redundant
|
|
875
1285
|
if (!oFocus && !this._oFocus ||
|
|
876
1286
|
oFocus && this._oFocus && oFocus.item === this._oFocus.item && oFocus.button === this._oFocus.button && oFocus.groupInFocused === this._oFocus.groupInFocused) {
|
|
@@ -880,12 +1290,12 @@ sap.ui.define([
|
|
|
880
1290
|
this._oFocus.item.isA("sap.suite.ui.commons.networkgraph.Node")))) {
|
|
881
1291
|
this._updateAccessibility(oFocus);
|
|
882
1292
|
}
|
|
883
|
-
|
|
884
|
-
|
|
1293
|
+
this._updateAccessibility(oFocus);
|
|
1294
|
+
return;
|
|
885
1295
|
}
|
|
886
1296
|
|
|
887
1297
|
this.defocus();
|
|
888
|
-
if (this.getFocusDomRef()) {
|
|
1298
|
+
if (this.getFocusDomRef() && !(oFocus && oFocus.button && oFocus.button.id && oFocus.button.id.indexOf("actionOverflow") !== -1)) {
|
|
889
1299
|
this.getFocusDomRef().focus();
|
|
890
1300
|
}
|
|
891
1301
|
|
|
@@ -925,7 +1335,7 @@ sap.ui.define([
|
|
|
925
1335
|
this._setAccessibilityTitle(oResourceBundle.getText("NETWORK_GRAPH_ACCESSIBILITY_CONTENT"));
|
|
926
1336
|
}.bind(this),
|
|
927
1337
|
fnBuildTitleForButton = function (sLabel) {
|
|
928
|
-
var sTitleLabel = sLabel + " " + oResourceBundle.getText("NETWORK_GRAPH_ACCESSIBILITY_ACTION_BUTTON")
|
|
1338
|
+
var sTitleLabel = sLabel + " " + oResourceBundle.getText("NETWORK_GRAPH_ACCESSIBILITY_ACTION_BUTTON");
|
|
929
1339
|
if (sLabel === "Expand/Collapse") {
|
|
930
1340
|
if (oFocus.item.getCollapsed()) {
|
|
931
1341
|
sTitleLabel = sTitleLabel + " " + oResourceBundle.getText("NETWORK_GRAPH_COLLAPSED");
|
|
@@ -1029,6 +1439,14 @@ sap.ui.define([
|
|
|
1029
1439
|
return this.getNodes().concat(this.getGroups());
|
|
1030
1440
|
};
|
|
1031
1441
|
|
|
1442
|
+
Graph.prototype._isNoopLayout = function () {
|
|
1443
|
+
return this._getLayoutAlgorithm().isA("sap.suite.ui.commons.networkgraph.layout.NoopLayout");
|
|
1444
|
+
};
|
|
1445
|
+
|
|
1446
|
+
Graph.prototype._isDnDEnabled = function() {
|
|
1447
|
+
return this._isNoopLayout() && this.getEnableDragAndDrop();
|
|
1448
|
+
};
|
|
1449
|
+
|
|
1032
1450
|
Graph.prototype._render = function () {
|
|
1033
1451
|
this._beforeRender();
|
|
1034
1452
|
|
|
@@ -1057,8 +1475,9 @@ sap.ui.define([
|
|
|
1057
1475
|
this.$background.width(iSvgWidth * this._fZoomLevel);
|
|
1058
1476
|
this.$background.height(iSvgHeight * this._fZoomLevel);
|
|
1059
1477
|
|
|
1478
|
+
var sScale = "";
|
|
1060
1479
|
if (this._isUseNodeHtml()) {
|
|
1061
|
-
|
|
1480
|
+
sScale = "scale(" + this._fZoomLevel + ")";
|
|
1062
1481
|
this.$("divnodes").css("transform", sScale);
|
|
1063
1482
|
}
|
|
1064
1483
|
|
|
@@ -1076,12 +1495,25 @@ sap.ui.define([
|
|
|
1076
1495
|
|
|
1077
1496
|
// While Expand/Collapse, focus will still remain to the button
|
|
1078
1497
|
if (this._oFocus && this._oFocus.button === Group.BUTTONS.COLLAPSE) {
|
|
1079
|
-
|
|
1498
|
+
// Check if the focused item still exists and is not destroyed
|
|
1499
|
+
if (this._oFocus.item && !this._oFocus.item.bIsDestroyed && !this._oFocus.item.isDestroyed?.()) {
|
|
1500
|
+
this._oFocus.item._setCollapseButtonFocus(true);
|
|
1501
|
+
} else {
|
|
1502
|
+
Log.info("NetworkGraph: Focused item was destroyed, clearing focus");
|
|
1503
|
+
this._oFocus = null;
|
|
1504
|
+
}
|
|
1080
1505
|
}
|
|
1081
1506
|
this._bIsLayedOut = true;
|
|
1082
1507
|
this._setupEvents();
|
|
1083
1508
|
this._setupKeyboardNavigation();
|
|
1084
|
-
|
|
1509
|
+
// Only restore focus if the focused item still exists and is not destroyed
|
|
1510
|
+
var oCurrentFocus = this.getFocus();
|
|
1511
|
+
if (oCurrentFocus && oCurrentFocus.item && (oCurrentFocus.item.bIsDestroyed || oCurrentFocus.item.isDestroyed?.())) {
|
|
1512
|
+
Log.info("NetworkGraph: Cannot restore focus on destroyed control, clearing focus");
|
|
1513
|
+
this._oFocus = null;
|
|
1514
|
+
} else {
|
|
1515
|
+
this.setFocus(oCurrentFocus);
|
|
1516
|
+
}
|
|
1085
1517
|
|
|
1086
1518
|
// when there is background image, busy is set false after image is loaded (own event)
|
|
1087
1519
|
// in case image was already loaded continue as usual
|
|
@@ -1092,6 +1524,10 @@ sap.ui.define([
|
|
|
1092
1524
|
|
|
1093
1525
|
if (!this._isSwimLane() && !this._isTwoColumnsLayout()) {
|
|
1094
1526
|
this.$("innerscroller").addClass(" sapSuiteUiCommonsNetworkGraphInnerScrollerCenter ");
|
|
1527
|
+
if (this._isDnDEnabled()) {
|
|
1528
|
+
// If NoopLayout is used, users must set certain styles to ensure precise coordinates setting.
|
|
1529
|
+
this.$("innerscroller").addClass("sapSuiteUiCommonsNetworkGraphInnerScrollerNoMargin");
|
|
1530
|
+
}
|
|
1095
1531
|
}
|
|
1096
1532
|
};
|
|
1097
1533
|
|
|
@@ -1315,6 +1751,8 @@ sap.ui.define([
|
|
|
1315
1751
|
oRm.openStart("g", this.getId() + "-svgbody");
|
|
1316
1752
|
oRm.openEnd();
|
|
1317
1753
|
fnRenderItems("lines", aLines, "sapSuiteUiCommonsNetworkLines");
|
|
1754
|
+
// Render line texts after all lines are rendered to handle overlaps
|
|
1755
|
+
this._renderAllLineTexts(aLines, oRm);
|
|
1318
1756
|
if (!this._isUseNodeHtml()) {
|
|
1319
1757
|
fnRenderItems("nodes", aNodes, "sapSuiteUiCommonsNetworkNodes");
|
|
1320
1758
|
}
|
|
@@ -1339,6 +1777,45 @@ sap.ui.define([
|
|
|
1339
1777
|
|
|
1340
1778
|
};
|
|
1341
1779
|
|
|
1780
|
+
/**
|
|
1781
|
+
* Renders text labels for all lines in a dedicated SVG group container.
|
|
1782
|
+
*
|
|
1783
|
+
* This method creates a batch rendering context for line labels, enabling
|
|
1784
|
+
* potential overlap handling and positioning optimizations. Labels are only
|
|
1785
|
+
* rendered for lines that meet all of the following conditions:
|
|
1786
|
+
* - The line has a labelName property value set
|
|
1787
|
+
* - The graph is using NoopLayout
|
|
1788
|
+
* - The line's arrowPosition is set to "Both"
|
|
1789
|
+
*
|
|
1790
|
+
* @param {sap.suite.ui.commons.networkgraph.Line[]} aLines Array of line objects to render text labels for
|
|
1791
|
+
* @param {sap.ui.core.RenderManager} oRm The RenderManager instance used for SVG rendering
|
|
1792
|
+
* @private
|
|
1793
|
+
*/
|
|
1794
|
+
Graph.prototype._renderAllLineTexts = function (aLines, oRm) {
|
|
1795
|
+
// Early return if line labels are disabled or NoopLayout is not active
|
|
1796
|
+
if (!this._isNoopLayout()) {
|
|
1797
|
+
return;
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1800
|
+
// Create a dedicated SVG group container for all line text labels
|
|
1801
|
+
// This enables batch processing and potential overlap handling
|
|
1802
|
+
oRm.openStart("g");
|
|
1803
|
+
oRm.attr("id", this.getId() + "-line-texts");
|
|
1804
|
+
oRm.class("sapSuiteUiCommonsNetworkLineTexts");
|
|
1805
|
+
oRm.openEnd();
|
|
1806
|
+
|
|
1807
|
+
// Iterate through all lines and render their text labels within the group
|
|
1808
|
+
// Only process lines that are valid, not ignored by layout, and visible
|
|
1809
|
+
aLines.forEach(function (oLine) {
|
|
1810
|
+
if (oLine && !oLine._isIgnored() && oLine.getVisible()) {
|
|
1811
|
+
oLine._renderLineText(oRm);
|
|
1812
|
+
}
|
|
1813
|
+
});
|
|
1814
|
+
|
|
1815
|
+
// Close the SVG group container
|
|
1816
|
+
oRm.close("g");
|
|
1817
|
+
};
|
|
1818
|
+
|
|
1342
1819
|
Graph.prototype._isProperKey = function (sKey) {
|
|
1343
1820
|
return sKey || (sKey === "0");
|
|
1344
1821
|
};
|
|
@@ -1419,7 +1896,11 @@ sap.ui.define([
|
|
|
1419
1896
|
}
|
|
1420
1897
|
}
|
|
1421
1898
|
|
|
1422
|
-
this._isUseNodeHtml()
|
|
1899
|
+
if (this._isUseNodeHtml()) {
|
|
1900
|
+
oNode._resetDimensions();
|
|
1901
|
+
} else {
|
|
1902
|
+
oNode._setupWidthAndHeight();
|
|
1903
|
+
}
|
|
1423
1904
|
oNode._clearChildren();
|
|
1424
1905
|
oNode._rendered = false;
|
|
1425
1906
|
|
|
@@ -1848,16 +2329,24 @@ sap.ui.define([
|
|
|
1848
2329
|
}
|
|
1849
2330
|
});
|
|
1850
2331
|
this._toolbar.addContent(this._zoomOut);
|
|
1851
|
-
|
|
2332
|
+
}
|
|
1852
2333
|
|
|
1853
2334
|
// fit to viewport
|
|
1854
|
-
this.
|
|
2335
|
+
this._zoomToFitButton = new OverflowToolbarButton({
|
|
1855
2336
|
type: ButtonType.Transparent,
|
|
1856
2337
|
icon: "sap-icon://popup-window",
|
|
1857
2338
|
tooltip: oResourceBundle.getText("NETWORK_GRAPH_ZOOMTOFIT"),
|
|
1858
2339
|
text: oResourceBundle.getText("NETWORK_GRAPH_ZOOMTOFIT"),
|
|
1859
2340
|
press: this._fitToScreen.bind(this)
|
|
1860
|
-
})
|
|
2341
|
+
});
|
|
2342
|
+
this._toolbar.addContent(this._zoomToFitButton);
|
|
2343
|
+
|
|
2344
|
+
// Hide zoom buttons if drag and drop is enabled
|
|
2345
|
+
if (this._isDnDEnabled()) {
|
|
2346
|
+
this._zoomIn.setVisible(false);
|
|
2347
|
+
this._zoomOut.setVisible(false);
|
|
2348
|
+
this._zoomToFitButton.setVisible(false);
|
|
2349
|
+
}
|
|
1861
2350
|
|
|
1862
2351
|
// toggle full screen
|
|
1863
2352
|
this._oFullScreenButton = new OverflowToolbarButton({
|
|
@@ -2139,7 +2628,9 @@ sap.ui.define([
|
|
|
2139
2628
|
|
|
2140
2629
|
$wrapper.on("mouseleave", this._endDragging.bind(this));
|
|
2141
2630
|
$wrapper.on("mouseup", this._mouseUp.bind(this));
|
|
2142
|
-
if (this.getEnableZoom()) {
|
|
2631
|
+
if (this.getEnableZoom() && !this._isDnDEnabled()) {
|
|
2632
|
+
// Disabling zooming capability in edit mode.
|
|
2633
|
+
// TODO: consider scaling when dragging and dropping nodes and update ghost image dimenstion and coordinates prediction, to allow zooming.
|
|
2143
2634
|
$wrapper.on("wheel", function (oEvent) {
|
|
2144
2635
|
if (this._wheel({
|
|
2145
2636
|
x: oEvent.originalEvent.clientX,
|
|
@@ -2197,6 +2688,7 @@ sap.ui.define([
|
|
|
2197
2688
|
this._oZoomLevelInvisibleText.setText(oResourceBundle.getText("NETWORK_GRAPH_ZOOM_LEVEL") + ": " + this._getZoomText());
|
|
2198
2689
|
return true;
|
|
2199
2690
|
}
|
|
2691
|
+
return false;
|
|
2200
2692
|
};
|
|
2201
2693
|
|
|
2202
2694
|
Graph.prototype._endDragging = function () {
|
|
@@ -2229,6 +2721,11 @@ sap.ui.define([
|
|
|
2229
2721
|
this._oPanning.dragging = true;
|
|
2230
2722
|
|
|
2231
2723
|
this._tooltip.instantClose();
|
|
2724
|
+
|
|
2725
|
+
// Remove all ports when deselecting
|
|
2726
|
+
if (PortManager._currentTriggerNodeKey !== null) {
|
|
2727
|
+
PortManager.removeAllPorts();
|
|
2728
|
+
}
|
|
2232
2729
|
};
|
|
2233
2730
|
|
|
2234
2731
|
Graph.prototype._mouseUp = function () {
|
|
@@ -2377,6 +2874,11 @@ sap.ui.define([
|
|
|
2377
2874
|
// indicates current count of suggestion items when they are rendered
|
|
2378
2875
|
this._oSuggestionItemsModel.setSizeLimit(SUGGESTION_ITEMS_LIMIT);
|
|
2379
2876
|
|
|
2877
|
+
const oLabels = this.getLabels() || {};
|
|
2878
|
+
const sNodeLabel = oLabels.nodeLabel || oResourceBundle.getText("NETWORK_GRAPH_NODE");
|
|
2879
|
+
const sLineLabel = oLabels.lineLabel || oResourceBundle.getText("NETWORK_GRAPH_LINE");
|
|
2880
|
+
const sGroupLabel = oLabels.groupLabel || oResourceBundle.getText("NETWORK_GRAPH_GROUP");
|
|
2881
|
+
|
|
2380
2882
|
aNodes.forEach(function (oNode) {
|
|
2381
2883
|
var sTitle = Utils.trimText(oNode.getTitle(), TITLE_LENGTH);
|
|
2382
2884
|
oData.items.push({
|
|
@@ -2384,7 +2886,7 @@ sap.ui.define([
|
|
|
2384
2886
|
type: SUGGESTIONS.Node,
|
|
2385
2887
|
icon: oNode.getIcon(),
|
|
2386
2888
|
key: oNode.getKey(),
|
|
2387
|
-
description: "(" +
|
|
2889
|
+
description: "(" + sNodeLabel + ")"
|
|
2388
2890
|
});
|
|
2389
2891
|
});
|
|
2390
2892
|
|
|
@@ -2397,7 +2899,7 @@ sap.ui.define([
|
|
|
2397
2899
|
text: oLine._createSuggestionHelpText(),
|
|
2398
2900
|
type: SUGGESTIONS.Line,
|
|
2399
2901
|
key: oLine._getLineId(),
|
|
2400
|
-
description: "(" +
|
|
2902
|
+
description: "(" + sLineLabel + ")"
|
|
2401
2903
|
});
|
|
2402
2904
|
}
|
|
2403
2905
|
});
|
|
@@ -2409,7 +2911,7 @@ sap.ui.define([
|
|
|
2409
2911
|
text: sTitle ? sTitle : oGroup.getKey(),
|
|
2410
2912
|
key: oGroup.getKey(),
|
|
2411
2913
|
type: SUGGESTIONS.Group,
|
|
2412
|
-
description: "(" +
|
|
2914
|
+
description: "(" + sGroupLabel + ")"
|
|
2413
2915
|
});
|
|
2414
2916
|
}
|
|
2415
2917
|
});
|
|
@@ -2453,7 +2955,13 @@ sap.ui.define([
|
|
|
2453
2955
|
fHeight = oItem._iHeight;
|
|
2454
2956
|
}
|
|
2455
2957
|
|
|
2456
|
-
|
|
2958
|
+
const fScrollLeft = ((fX + (fWidth ? fWidth : 0) / 2) * this._fZoomLevel) - (this.$scroller.width() / 2);
|
|
2959
|
+
|
|
2960
|
+
if (this._bIsRtl) {
|
|
2961
|
+
this.$scroller.get(0).scrollLeft = -fScrollLeft;
|
|
2962
|
+
} else {
|
|
2963
|
+
this.$scroller.get(0).scrollLeft = fScrollLeft;
|
|
2964
|
+
}
|
|
2457
2965
|
this.$scroller.get(0).scrollTop = ((fY + (fHeight ? fHeight : 0) / 2) * this._fZoomLevel) - (this.$scroller.height() / 2);
|
|
2458
2966
|
};
|
|
2459
2967
|
|
|
@@ -2474,6 +2982,14 @@ sap.ui.define([
|
|
|
2474
2982
|
iRight = iLeft + this.$scroller.width() / this._fZoomLevel,
|
|
2475
2983
|
iBottom = iTop + this.$scroller.height() / this._fZoomLevel;
|
|
2476
2984
|
|
|
2985
|
+
if (this._bIsRtl) {
|
|
2986
|
+
const iGraphWidth = this.$svg.width() / this._fZoomLevel;
|
|
2987
|
+
const iViewportWidth = this.$scroller.width() / this._fZoomLevel;
|
|
2988
|
+
const iScrollPosAbs = Math.abs(iLeft);
|
|
2989
|
+
iLeft = iGraphWidth - iScrollPosAbs - iViewportWidth;
|
|
2990
|
+
iRight = iLeft + iViewportWidth;
|
|
2991
|
+
}
|
|
2992
|
+
|
|
2477
2993
|
if (!oItem._isOnScreen(iLeft, iRight, iTop, iBottom)) {
|
|
2478
2994
|
if (oItem instanceof Node) {
|
|
2479
2995
|
iCenterX = oItem.getX() + oItem._iWidth / 2;
|
|
@@ -2488,7 +3004,14 @@ sap.ui.define([
|
|
|
2488
3004
|
}
|
|
2489
3005
|
|
|
2490
3006
|
if (iCenterX < iLeft || iCenterX > iRight) {
|
|
2491
|
-
|
|
3007
|
+
let iTargetScrollLeft = iCenterX * this._fZoomLevel - this.$scroller.width() / 2;
|
|
3008
|
+
|
|
3009
|
+
if (this._bIsRtl) {
|
|
3010
|
+
const iScrollRange = oScroller.scrollWidth - oScroller.clientWidth;
|
|
3011
|
+
iTargetScrollLeft = -(iScrollRange - iTargetScrollLeft);
|
|
3012
|
+
}
|
|
3013
|
+
|
|
3014
|
+
oScroller.scrollLeft = iTargetScrollLeft;
|
|
2492
3015
|
}
|
|
2493
3016
|
if (iCenterY < iTop || iCenterY > iBottom) {
|
|
2494
3017
|
oScroller.scrollTop = iCenterY * this._fZoomLevel - this.$scroller.height() / 2;
|
|
@@ -2553,7 +3076,7 @@ sap.ui.define([
|
|
|
2553
3076
|
if (fnHasStatus(oCollection)) {
|
|
2554
3077
|
oRm.openStart("div").class(sClass).openEnd();
|
|
2555
3078
|
oRm.openStart("label").class("sapSuiteUiCommonsNetworkGraphLegendTitle").openEnd();
|
|
2556
|
-
oRm.text(
|
|
3079
|
+
oRm.text(sTitle);
|
|
2557
3080
|
oRm.close("label");
|
|
2558
3081
|
oRm.close("div");
|
|
2559
3082
|
// get the status labels for sorting (some statuses can have custom labels)
|
|
@@ -2588,12 +3111,13 @@ sap.ui.define([
|
|
|
2588
3111
|
return;
|
|
2589
3112
|
}
|
|
2590
3113
|
|
|
3114
|
+
const oLabels = this.getLabels() || {};
|
|
2591
3115
|
fnProcessElements(this.getNodes(), oNodeStatuses, "sapSuiteUiCommonsNetworkGraphLegendTitleNode",
|
|
2592
|
-
"NETWORK_GRAPH_NODES", StatusType.Node);
|
|
3116
|
+
oLabels.nodeLabelPlural || oResourceBundle.getText("NETWORK_GRAPH_NODES"), StatusType.Node);
|
|
2593
3117
|
fnProcessElements(this.getLines(), oLineStatuses, "sapSuiteUiCommonsNetworkGraphLegendTitleLine",
|
|
2594
|
-
"NETWORK_GRAPH_LINES", StatusType.Line);
|
|
3118
|
+
oLabels.lineLabelPlural || oResourceBundle.getText("NETWORK_GRAPH_LINES"), StatusType.Line);
|
|
2595
3119
|
fnProcessElements(this.getGroups(), oGroupStatuses, "sapSuiteUiCommonsNetworkGraphLegendTitleLine",
|
|
2596
|
-
"NETWORK_GRAPH_GROUPS", StatusType.Group);
|
|
3120
|
+
oLabels.groupLabelPlural || oResourceBundle.getText("NETWORK_GRAPH_GROUPS"), StatusType.Group);
|
|
2597
3121
|
oRm.flush($legend[0]);
|
|
2598
3122
|
oRm.destroy();
|
|
2599
3123
|
// $legend.html(sHtml);
|
|
@@ -2753,8 +3277,15 @@ sap.ui.define([
|
|
|
2753
3277
|
};
|
|
2754
3278
|
|
|
2755
3279
|
Graph.prototype._isTopBottom = function () {
|
|
2756
|
-
return this.getOrientation() === Orientation.TopBottom
|
|
2757
|
-
|
|
3280
|
+
return this.getOrientation() === Orientation.TopBottom
|
|
3281
|
+
};
|
|
3282
|
+
|
|
3283
|
+
Graph.prototype._isBottomTop = function () {
|
|
3284
|
+
return this.getOrientation() === Orientation.BottomTop;
|
|
3285
|
+
};
|
|
3286
|
+
|
|
3287
|
+
Graph.prototype._isRightLeft = function () {
|
|
3288
|
+
return this.getOrientation() === Orientation.RightLeft;
|
|
2758
3289
|
};
|
|
2759
3290
|
|
|
2760
3291
|
/* =========================================================== */
|
|
@@ -2896,5 +3427,16 @@ sap.ui.define([
|
|
|
2896
3427
|
}
|
|
2897
3428
|
};
|
|
2898
3429
|
|
|
3430
|
+
/**
|
|
3431
|
+
* Checks if the current layout algorithm supports node ports functionality.
|
|
3432
|
+
* For now, only NoopLayout algorithms support node ports.
|
|
3433
|
+
*
|
|
3434
|
+
* @returns {boolean} True if the layout supports node ports, false otherwise
|
|
3435
|
+
* @private
|
|
3436
|
+
*/
|
|
3437
|
+
Graph.prototype._supportsNodePorts = function () {
|
|
3438
|
+
return this.getNodePorts() !== "None" && this._isDnDEnabled();
|
|
3439
|
+
};
|
|
3440
|
+
|
|
2899
3441
|
return Graph;
|
|
2900
3442
|
});
|