capdag 0.187.479 → 0.189.485

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 (2) hide show
  1. package/cap-fab-renderer.js +100 -2
  2. package/package.json +1 -1
@@ -379,8 +379,12 @@ function layoutForMode(mode) {
379
379
  };
380
380
  if (mode === 'browse') {
381
381
  return Object.assign({}, base, {
382
- 'elk.layered.spacing.nodeNodeBetweenLayers': 180,
383
- 'elk.spacing.nodeNode': 90,
382
+ 'elk.layered.spacing.nodeNodeBetweenLayers': 220,
383
+ 'elk.layered.spacing.edgeEdgeBetweenLayers': 44,
384
+ 'elk.layered.spacing.edgeNodeBetweenLayers': 52,
385
+ 'elk.spacing.edgeEdge': 34,
386
+ 'elk.spacing.edgeNode': 42,
387
+ 'elk.spacing.nodeNode': 118,
384
388
  });
385
389
  }
386
390
  if (mode === 'strand') {
@@ -547,6 +551,15 @@ function buildStylesheet() {
547
551
  'transition-duration': '0.2s',
548
552
  },
549
553
  },
554
+ {
555
+ selector: 'edge.crowded-edge',
556
+ style: {
557
+ 'curve-style': 'unbundled-bezier',
558
+ 'control-point-step-size': 'data(controlPointStepSize)',
559
+ 'control-point-distances': 'data(controlPointDistances)',
560
+ 'control-point-weights': 'data(controlPointWeights)',
561
+ },
562
+ },
550
563
  {
551
564
  selector: 'edge.highlighted',
552
565
  style: { 'width': 2.5, 'z-index': 999 },
@@ -690,6 +703,12 @@ function assertArray(value, path) {
690
703
  }
691
704
  }
692
705
 
706
+ function assertObject(value, path) {
707
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
708
+ throw new Error(`CapFabRenderer: ${path} must be an object`);
709
+ }
710
+ }
711
+
693
712
  function validateBrowseData(data) {
694
713
  assertArray(data, 'browse mode data');
695
714
  data.forEach((cap, idx) => {
@@ -961,6 +980,80 @@ function edgeHueColor(edgeIdx) {
961
980
  return `hsl(${hue}, 60%, 55%)`;
962
981
  }
963
982
 
983
+ function centeredOrdinal(index, total) {
984
+ if (!Number.isInteger(index) || !Number.isInteger(total) || total <= 0) {
985
+ throw new Error('CapFabRenderer: centeredOrdinal requires integer index/total');
986
+ }
987
+ return index - ((total - 1) / 2);
988
+ }
989
+
990
+ function crowdOffsets(index, total, step, maxAbs) {
991
+ if (total <= 1) return 0;
992
+ const raw = centeredOrdinal(index, total) * step;
993
+ if (maxAbs === undefined) return raw;
994
+ return Math.max(-maxAbs, Math.min(maxAbs, raw));
995
+ }
996
+
997
+ function annotateCrowdedBrowseEdges(edges) {
998
+ const bySource = new Map();
999
+ const byTarget = new Map();
1000
+
1001
+ for (const edge of edges) {
1002
+ if (!bySource.has(edge.source)) bySource.set(edge.source, []);
1003
+ bySource.get(edge.source).push(edge);
1004
+ if (!byTarget.has(edge.target)) byTarget.set(edge.target, []);
1005
+ byTarget.get(edge.target).push(edge);
1006
+ }
1007
+
1008
+ const stableSort = (a, b) => {
1009
+ const targetCmp = a.target.localeCompare(b.target);
1010
+ if (targetCmp !== 0) return targetCmp;
1011
+ const titleCmp = a.title.localeCompare(b.title);
1012
+ if (titleCmp !== 0) return titleCmp;
1013
+ return a.id.localeCompare(b.id);
1014
+ };
1015
+ const reverseStableSort = (a, b) => {
1016
+ const sourceCmp = a.source.localeCompare(b.source);
1017
+ if (sourceCmp !== 0) return sourceCmp;
1018
+ const titleCmp = a.title.localeCompare(b.title);
1019
+ if (titleCmp !== 0) return titleCmp;
1020
+ return a.id.localeCompare(b.id);
1021
+ };
1022
+
1023
+ for (const group of bySource.values()) group.sort(stableSort);
1024
+ for (const group of byTarget.values()) group.sort(reverseStableSort);
1025
+
1026
+ const sourceIndex = new Map();
1027
+ const targetIndex = new Map();
1028
+ for (const group of bySource.values()) {
1029
+ group.forEach((edge, idx) => sourceIndex.set(edge.id, idx));
1030
+ }
1031
+ for (const group of byTarget.values()) {
1032
+ group.forEach((edge, idx) => targetIndex.set(edge.id, idx));
1033
+ }
1034
+
1035
+ for (const edge of edges) {
1036
+ const sourceGroup = bySource.get(edge.source) || [edge];
1037
+ const targetGroup = byTarget.get(edge.target) || [edge];
1038
+ const sourceCount = sourceGroup.length;
1039
+ const targetCount = targetGroup.length;
1040
+ const crowdCount = Math.max(sourceCount, targetCount);
1041
+
1042
+ if (crowdCount <= 2) {
1043
+ edge.crowdedClass = '';
1044
+ continue;
1045
+ }
1046
+
1047
+ const sourceOffset = crowdOffsets(sourceIndex.get(edge.id), sourceCount, 18, 64);
1048
+ const targetOffset = crowdOffsets(targetIndex.get(edge.id), targetCount, 18, 64);
1049
+
1050
+ edge.crowdedClass = 'crowded-edge';
1051
+ edge.controlPointDistances = `${sourceOffset} ${targetOffset}`;
1052
+ edge.controlPointWeights = '0.22 0.78';
1053
+ edge.controlPointStepSize = 56;
1054
+ }
1055
+ }
1056
+
964
1057
  // --------- Browse mode builder ----------------------------------------------
965
1058
 
966
1059
  function buildBrowseGraphData(capabilities) {
@@ -1014,6 +1107,7 @@ function buildBrowseGraphData(capabilities) {
1014
1107
  edges.forEach((edge, i) => {
1015
1108
  edge.color = edgeHueColor(i);
1016
1109
  });
1110
+ annotateCrowdedBrowseEdges(edges);
1017
1111
 
1018
1112
  const nodes = Array.from(nodesMap.values());
1019
1113
  for (const node of nodes) {
@@ -1061,7 +1155,11 @@ function browseCytoscapeElements(built) {
1061
1155
  fullUrn: edge.capability.urn,
1062
1156
  capFabEdgeIndex: edge.capFabEdgeIndex,
1063
1157
  color: edge.color,
1158
+ controlPointStepSize: edge.controlPointStepSize || 56,
1159
+ controlPointDistances: edge.controlPointDistances || '0 0',
1160
+ controlPointWeights: edge.controlPointWeights || '0.22 0.78',
1064
1161
  },
1162
+ classes: edge.crowdedClass || '',
1065
1163
  };
1066
1164
  });
1067
1165
  return nodeElements.concat(edgeElements);
package/package.json CHANGED
@@ -40,5 +40,5 @@
40
40
  "pretest": "npm run build:parser",
41
41
  "test": "node capdag.test.js"
42
42
  },
43
- "version": "0.187.479"
43
+ "version": "0.189.485"
44
44
  }