@@ -710,45 +710,26 @@ export default {
710
710
return convertTree (tree)
711
711
},
712
712
713
- /**
714
- * Removes a node from an array of nodes
715
- * @property {String} nodeName - name of node to be removed
716
- * @property {String} cyclePoint - isodatTime of node to be removed
717
- * @property {Node[]} nodes - array of nodes included in the graph
718
- * @returns {Node[]} updated array of nodes included in the graph (with node removed)
719
- */
720
- removeNode (nodeName , cyclePoint , nodes ) {
721
- const nodeId = this .workflows [0 ].tokens .clone ({ cycle: cyclePoint, task: nodeName }).id
722
- const nodesFiltered = nodes .filter ((node ) => {
723
- return node .id !== nodeId
724
- })
725
- return nodesFiltered
726
- },
727
-
728
713
/**
729
714
* Creates an edge from the name and cycle of source and target nodes
730
- * @param {('noCollapsed'|'collapsedTarget'|'collapsedSource'|'collapsedSourceAndTarget')} edgeType
731
- * @param {string} sourceName - name of source node
732
- * @param {string} targetName - name of target node
733
- * @param {string} sourceCyclePoint - isodatTime of source node
734
- * @param {string} targetCyclePoint - isodatTime of target node
715
+ * @param {Object} param0 - the source and target node names and cycles
735
716
* @returns {[string, Edge]} the created edge
736
717
*/
737
- createEdge (edgeType , sourceName , targetName , sourceCyclePoint , targetCyclePoint ) {
738
- // adds a new edge object to 'edges' array
718
+ createEdge ({ sourceName, targetName, sourceCycle, targetCycle }) {
739
719
let src, tgt
740
- if (edgeType === ' noCollapsed' ) {
741
- src = ` ${ sourceCyclePoint} /${ sourceName} `
742
- tgt = ` ${ targetCyclePoint} /${ targetName} `
743
- } else if (edgeType === ' collapsedTarget' ) {
744
- src = ` ${ sourceCyclePoint} /${ sourceName} |${ targetName} `
745
- tgt = ` ${ sourceCyclePoint} /${ sourceName} |${ targetName} `
746
- } else if (edgeType === ' collapsedSource' ) {
747
- src = ` ${ sourceCyclePoint} |${ targetCyclePoint} /${ targetName} `
748
- tgt = ` ${ sourceCyclePoint} |${ targetCyclePoint} /${ targetName} `
749
- } else if (edgeType === ' collapsedSourceAndTarget' ) {
750
- src = ` ${ sourceName} |${ targetName} `
751
- tgt = ` ${ sourceName} |${ targetName} `
720
+ if (sourceName === sourceCycle && targetName === targetCycle) {
721
+ // both source & target collapsed by cycle point
722
+ src = tgt = ` ${ sourceCycle} |${ targetCycle} `
723
+ } else if (sourceName === sourceCycle) {
724
+ // source collapsed by cycle point
725
+ src = tgt = ` ${ sourceCycle} |${ targetCycle} /${ targetName} `
726
+ } else if (targetName === targetCycle) {
727
+ // target collapsed by cycle point
728
+ src = tgt = ` ${ sourceCycle} /${ sourceName} |${ targetCycle} `
729
+ } else {
730
+ // not collapsed by cycle point
731
+ src = ` ${ sourceCycle} /${ sourceName} `
732
+ tgt = ` ${ targetCycle} /${ targetName} `
752
733
}
753
734
const tokens = this .workflows [0 ].tokens .clone ({
754
735
cycle: ` $edge|${ src} |${ tgt} `
@@ -758,16 +739,14 @@ export default {
758
739
759
740
/**
760
741
* Removes source and target edges from the map of edges.
761
- * @param {string} task - task name of source node of edge to be removed
762
- * @param {string} cycle - cycle point of source node of edge to be removed
763
- * @param {Map<string, Edge>} edges - array of edges included in the graph
742
+ * @param {string} id - ID of source node of edge to be removed
743
+ * @param {Map<string, Edge>} edges - edges included in the graph
764
744
* @returns {Edge[]} removed edge store arrays
765
745
*/
766
- removeEdges (task , cycle , edges ) {
767
- const nodeID = this .workflows [0 ].tokens .clone ({ cycle, task }).id
746
+ removeEdges (id , edges ) {
768
747
const removed = []
769
748
for (const [edgeID , edge ] of edges) {
770
- if ([edge .source .id , edge .target .id ].includes (nodeID )) {
749
+ if ([edge .source .id , edge .target .id ].includes (id )) {
771
750
edges .delete (edgeID) && removed .push (edge)
772
751
}
773
752
}
@@ -1166,30 +1145,6 @@ export default {
1166
1145
this .panZoomWidget .zoom (relativeZoom * width / desiredWidth)
1167
1146
},
1168
1147
1169
- edgeHasCollapsedTargetAncestorOnly (edge ) {
1170
- const target = this .getCollapsedAncestor (edge .target .id )
1171
- if (target && ! this .getCollapsedAncestor (edge .source .id )) {
1172
- return target
1173
- }
1174
- },
1175
-
1176
- edgeHasCollapsedSourceAncestorOnly (edge ) {
1177
- const source = this .getCollapsedAncestor (edge .source .id )
1178
- if (source && ! this .getCollapsedAncestor (edge .target .id )) {
1179
- return source
1180
- }
1181
- },
1182
-
1183
- edgeHasCollapsedTargetandSourceAncestor (edge ) {
1184
- const target = this .getCollapsedAncestor (edge .target .id )
1185
- if (target) {
1186
- const source = this .getCollapsedAncestor (edge .source .id )
1187
- if (source) {
1188
- return { target, source }
1189
- }
1190
- }
1191
- },
1192
-
1193
1148
async refresh () {
1194
1149
// refresh the graph layout if required
1195
1150
if (this .updating ) {
@@ -1206,153 +1161,93 @@ export default {
1206
1161
const edges = this .getGraphEdges ()
1207
1162
1208
1163
// ----------------------------------------
1209
- const removedEdges = []
1210
-
1211
- // For all cycles...
1212
- for (const cycle of this .cycleArrayStore ) {
1213
- // ...loop through collapsed families...
1214
- for (const family of this .collapseFamily ) {
1164
+ for (const family of this .collapseFamily ) {
1165
+ for (const cycle of this .cycleArrayStore ) {
1215
1166
// ...get the node from the index...
1216
- const indexSearch = Object . values ( this .cylcTree .$index ). find (
1217
- ( node ) => node . name === family && node .tokens .cycle === cycle
1218
- )
1219
- if (! indexSearch ) continue
1167
+ const famNode = this .cylcTree .$index [
1168
+ this . workflows [ 0 ] .tokens .clone ({ cycle, task : family }). id
1169
+ ]
1170
+ if (! famNode ) continue
1220
1171
// ...now we have a node - we have to understand all its relations in the graph...
1221
1172
// ---------------REMOVE NODES BASED ON FAMILY------------
1222
1173
// must do this before removing nodes and edges based on cycle as
1223
1174
// cycle collapsing takes priority of families
1224
1175
// ...this node is collapsed so need to remove any of its children
1225
1176
// (nodes and edges) from the graph if it has any...
1226
- for (const { name } of this .allChildrenLookUp [indexSearch .id ]) {
1227
- if (name !== indexSearch . name ) {
1177
+ for (const { id } of this .allChildrenLookUp [famNode .id ]) {
1178
+ if (id !== famNode . id ) {
1228
1179
// REMOVE NODES
1229
- nodes = this . removeNode (name, cycle, nodes )
1180
+ nodes = nodes . filter (( node ) => node . id !== id )
1230
1181
// REMOVE EDGES
1231
1182
// if there is an edge with a source or target it needs removing
1232
- removedEdges .push (
1233
- ... this .removeEdges (name, cycle, edges),
1234
- )
1183
+ for (const edge of this .removeEdges (id, edges)) {
1184
+ // ---------------ADD EDGES BASED ON FAMILY------------
1185
+ // skip if one end of edge is in a collapsed cycle - deal with this later:
1186
+ if (this .collapseCycle .some (
1187
+ (x ) => x === edge .source .cycle || x === edge .target .cycle
1188
+ )) continue
1189
+
1190
+ // ...this node is collapsed so need to remove any of its children (nodes and edges) from the graph if it has any...
1191
+ const sourceName = this .getCollapsedAncestor (edge .source .id ) ?? edge .source .task
1192
+ const targetName = this .getCollapsedAncestor (edge .target .id ) ?? edge .target .task
1193
+ // prevent self-loop edges:
1194
+ if (sourceName === targetName && edge .source .cycle === edge .target .cycle ) continue
1195
+
1196
+ edges .set (
1197
+ ... this .createEdge ({
1198
+ sourceName,
1199
+ sourceCycle: edge .source .cycle ,
1200
+ targetName,
1201
+ targetCycle: edge .target .cycle ,
1202
+ })
1203
+ )
1204
+ }
1235
1205
}
1236
1206
}
1237
1207
// ...now we have removed any parts of child nodes that shouldnt be there we can add nodes and edges that should be...
1238
1208
// ---------------ADD NODES BASED ON FAMILY------------
1239
- if (! this .collapseCycle .includes (cycle) && ! this .getCollapsedAncestor (indexSearch .id )) {
1240
- nodes .push (indexSearch)
1241
- }
1242
-
1243
- // ...this node is collapsed so need to remove any of its children (nodes and edges) from the graph if it has any...
1244
- for (const { id: childID } of this .allChildrenLookUp [indexSearch .id ]) {
1245
- for (const edge of removedEdges .filter (({ source }) => source .id === childID)) {
1246
- if (! this .collapseCycle .includes (edge .source .cycle )) {
1247
- const collapsedSourceAncestor = this .edgeHasCollapsedSourceAncestorOnly (edge)
1248
- if (collapsedSourceAncestor) {
1249
- edges .set (
1250
- ... this .createEdge (' noCollapsed' , collapsedSourceAncestor, edge .target .task , edge .source .cycle , edge .target .cycle )
1251
- )
1252
- }
1253
-
1254
- if (! this .collapseCycle .includes (edge .target .cycle )) {
1255
- const collapsedAncestors = this .edgeHasCollapsedTargetandSourceAncestor (edge)
1256
- if (collapsedAncestors && (collapsedAncestors .source !== collapsedAncestors .target || edge .source .cycle !== edge .target .cycle )) {
1257
- edges .set (
1258
- ... this .createEdge (' noCollapsed' , collapsedAncestors .source , collapsedAncestors .target , edge .source .cycle , edge .target .cycle )
1259
- )
1260
- }
1261
- }
1262
- }
1263
- }
1264
- for (const edge of removedEdges .filter (({ target }) => target .id === childID)) {
1265
- if (! this .collapseCycle .includes (edge .target .cycle )) {
1266
- const collapsedTargetAncestor = this .edgeHasCollapsedTargetAncestorOnly (edge)
1267
- if (collapsedTargetAncestor) {
1268
- edges .set (
1269
- ... this .createEdge (' noCollapsed' , edge .source .task , collapsedTargetAncestor, edge .source .cycle , edge .target .cycle )
1270
- )
1271
- }
1272
-
1273
- if (! this .collapseCycle .includes (edge .source .cycle )) {
1274
- const collapsedAncestors = this .edgeHasCollapsedTargetandSourceAncestor (edge)
1275
- if (collapsedAncestors && (collapsedAncestors .source !== collapsedAncestors .target || edge .source .cycle !== edge .target .cycle )) {
1276
- edges .set (
1277
- ... this .createEdge (' noCollapsed' , collapsedAncestors .source , collapsedAncestors .target , edge .source .cycle , edge .target .cycle )
1278
- )
1279
- }
1280
- }
1281
- }
1282
- }
1209
+ if (! this .collapseCycle .includes (cycle) && ! this .getCollapsedAncestor (famNode .id )) {
1210
+ nodes .push (famNode)
1283
1211
}
1284
1212
}
1285
1213
}
1286
1214
for (const cycle of this .collapseCycle ) {
1287
- const indexSearch = Object .values (this .cylcTree .$index ).find ((node ) => {
1288
- return node .name === cycle
1289
- })
1290
- if (indexSearch) {
1291
- // ---------------REMOVE NODES BASED ON CYCLE POINT------------
1292
- for (const { name } of this .allChildrenLookUp [indexSearch .id ]) {
1293
- if (name !== indexSearch .name ) {
1294
- // REMOVE NODES
1295
- nodes = this .removeNode (name, cycle, nodes)
1296
- // REMOVE EDGES
1297
- // if there is an edge with a source or target it needs removing
1298
- removedEdges .push (
1299
- ... this .removeEdges (name, cycle, edges)
1300
- )
1301
- }
1302
- }
1303
- // ---------------ADD NODES BASED ON CYCLE POINT------------
1304
- nodes .push (indexSearch)
1305
- // next bit starts here
1306
- // ---------------ADD EDGES BASED ON CYCLE POINT------------
1307
- for (const { id: childID } of this .allChildrenLookUp [indexSearch .id ]) {
1308
- for (const edge of removedEdges .filter (({ source }) => source .id === childID)) {
1215
+ const cycleNode = this .cylcTree .$index [
1216
+ this .workflows [0 ].tokens .clone ({ cycle }).id
1217
+ ]
1218
+ if (! cycleNode) continue
1219
+ // ---------------REMOVE NODES BASED ON CYCLE POINT------------
1220
+ for (const { id } of this .allChildrenLookUp [cycleNode .id ]) {
1221
+ if (id !== cycleNode .id ) {
1222
+ // REMOVE NODES
1223
+ nodes = nodes .filter ((node ) => node .id !== id)
1224
+ // REMOVE EDGES
1225
+ // if there is an edge with a source or target it needs removing
1226
+ for (const edge of this .removeEdges (id, edges)) {
1227
+ // ---------------ADD EDGES BASED ON CYCLE POINT------------
1228
+ // prevent self-loop edges:
1309
1229
if (edge .source .cycle === edge .target .cycle ) continue
1310
- // edge has collapsed source cycle only
1311
- if (! this .collapseCycle .includes (edge .target .cycle ) && this .collapseCycle .includes (edge .source .cycle )) {
1312
- const collapsedTargetAncestor = this .getCollapsedAncestor (edge .target .id )
1313
- if (collapsedTargetAncestor) {
1314
- edges .set (
1315
- ... this .createEdge (' collapsedSource' , edge .source .cycle , collapsedTargetAncestor, edge .source .cycle , edge .target .cycle )
1316
- )
1317
- } else {
1318
- edges .set (
1319
- ... this .createEdge (' collapsedSource' , edge .source .cycle , edge .target .task , edge .source .cycle , edge .target .cycle )
1320
- )
1321
- }
1322
- }
1323
-
1324
- // edge has collapsed target and source cycle
1325
- if (this .collapseCycle .includes (edge .target .cycle ) && this .collapseCycle .includes (edge .source .cycle )) {
1326
- edges .set (
1327
- ... this .createEdge (' collapsedSourceAndTarget' , edge .source .cycle , edge .target .cycle , edge .source .cycle , edge .target .cycle )
1328
- )
1329
- }
1330
- }
1331
- for (const edge of removedEdges .filter (({ target }) => target .id === childID)) {
1332
- if (edge .source .cycle === edge .target .cycle ) continue
1333
- // edge has collapsed target cycle only
1334
- if (this .collapseCycle .includes (edge .target .cycle ) && ! this .collapseCycle .includes (edge .source .cycle )) {
1335
- const collapsedSourceAncestor = this .getCollapsedAncestor (edge .source .id )
1336
- if (collapsedSourceAncestor) {
1337
- edges .set (
1338
- ... this .createEdge (' collapsedTarget' , collapsedSourceAncestor, edge .target .cycle , edge .source .cycle , edge .target .cycle )
1339
- )
1340
- } else {
1341
- edges .set (
1342
- ... this .createEdge (' collapsedTarget' , edge .source .task , edge .target .cycle , edge .source .cycle , edge .target .cycle )
1343
- )
1344
- }
1345
- }
1346
1230
1347
- // edge has collapsed target and source cycle
1348
- if (this .collapseCycle .includes (edge .target .cycle ) && this .collapseCycle .includes (edge .source .cycle )) {
1349
- edges .set (
1350
- ... this .createEdge (' collapsedSourceAndTarget' , edge .source .cycle , edge .target .cycle , edge .source .cycle , edge .target .cycle )
1351
- )
1352
- }
1231
+ const sourceName = this .collapseCycle .includes (edge .source .cycle )
1232
+ ? edge .source .cycle
1233
+ : this .getCollapsedAncestor (edge .source .id ) ?? edge .source .task
1234
+ const targetName = this .collapseCycle .includes (edge .target .cycle )
1235
+ ? edge .target .cycle
1236
+ : this .getCollapsedAncestor (edge .target .id ) ?? edge .target .task
1237
+
1238
+ edges .set (
1239
+ ... this .createEdge ({
1240
+ sourceName,
1241
+ sourceCycle: edge .source .cycle ,
1242
+ targetName,
1243
+ targetCycle: edge .target .cycle ,
1244
+ })
1245
+ )
1353
1246
}
1354
1247
}
1355
1248
}
1249
+ // ---------------ADD NODES BASED ON CYCLE POINT------------
1250
+ nodes .push (cycleNode)
1356
1251
}
1357
1252
1358
1253
// ----------------------------------------
0 commit comments