@opentrace/components 0.1.1-rc.14 → 0.1.1-rc.30

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 (37) hide show
  1. package/dist/opentrace-components.cjs +141 -32
  2. package/dist/opentrace-components.cjs.map +1 -1
  3. package/dist/opentrace-components.js +142 -33
  4. package/dist/opentrace-components.js.map +1 -1
  5. package/dist/src/GraphCanvas.d.ts +22 -1
  6. package/dist/src/GraphCanvas.d.ts.map +1 -1
  7. package/dist/src/colors/linkColors.d.ts.map +1 -1
  8. package/dist/src/colors/nodeColors.d.ts.map +1 -1
  9. package/dist/src/config/graphLayout.d.ts +3 -2
  10. package/dist/src/config/graphLayout.d.ts.map +1 -1
  11. package/dist/src/graph/LayoutPipeline.d.ts.map +1 -1
  12. package/dist/src/graph/__tests__/optimizeWorker.test.d.ts +2 -0
  13. package/dist/src/graph/__tests__/optimizeWorker.test.d.ts.map +1 -0
  14. package/dist/src/graph/__tests__/spacingWorker.test.d.ts +2 -0
  15. package/dist/src/graph/__tests__/spacingWorker.test.d.ts.map +1 -0
  16. package/dist/src/graph/__tests__/useCommunities.test.d.ts +2 -0
  17. package/dist/src/graph/__tests__/useCommunities.test.d.ts.map +1 -0
  18. package/dist/src/graph/__tests__/useGraphFilters.test.d.ts +2 -0
  19. package/dist/src/graph/__tests__/useGraphFilters.test.d.ts.map +1 -0
  20. package/dist/src/graph/__tests__/useHighlights.test.d.ts +2 -0
  21. package/dist/src/graph/__tests__/useHighlights.test.d.ts.map +1 -0
  22. package/dist/src/graph/types.d.ts +2 -0
  23. package/dist/src/graph/types.d.ts.map +1 -1
  24. package/dist/src/graph/useGraphInstance.d.ts.map +1 -1
  25. package/dist/src/index.d.ts +2 -1
  26. package/dist/src/index.d.ts.map +1 -1
  27. package/dist/src/sigma/zoomToNodes.d.ts +7 -2
  28. package/dist/src/sigma/zoomToNodes.d.ts.map +1 -1
  29. package/dist/{useHighlights-BdiW6zWg.js → useHighlights-DbMfb0-p.js} +107 -62
  30. package/dist/useHighlights-DbMfb0-p.js.map +1 -0
  31. package/dist/{useHighlights-Xr_gYCcU.cjs → useHighlights-fRWg-A_c.cjs} +107 -62
  32. package/dist/useHighlights-fRWg-A_c.cjs.map +1 -0
  33. package/dist/utils.cjs +1 -1
  34. package/dist/utils.js +1 -1
  35. package/package.json +1 -1
  36. package/dist/useHighlights-BdiW6zWg.js.map +0 -1
  37. package/dist/useHighlights-Xr_gYCcU.cjs.map +0 -1
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const t = require("react");
5
- const useHighlights = require("./useHighlights-Xr_gYCcU.cjs");
5
+ const useHighlights = require("./useHighlights-fRWg-A_c.cjs");
6
6
  var _documentCurrentScript = typeof document !== "undefined" ? document.currentScript : null;
7
7
  function _toPrimitive$1(t2, r) {
8
8
  if ("object" != typeof t2 || !t2) return t2;
@@ -5253,7 +5253,7 @@ createEdgeCurveProgram({
5253
5253
  });
5254
5254
  const NODE_SIZE_MIN = 2;
5255
5255
  const NODE_SIZE_MAX = 8;
5256
- const NODE_SIZE_DEGREE_SCALE = 1.1;
5256
+ const NODE_SIZE_DEGREE_SCALE = 1;
5257
5257
  const NODE_SIZE_MULTIPLIERS = {
5258
5258
  Repository: 1,
5259
5259
  // All other STRUCTURAL_TYPES default to this:
@@ -5288,8 +5288,9 @@ const FA2_ADJUST_SIZES = true;
5288
5288
  const FA2_DURATION = 3e3;
5289
5289
  const NOVERLAP_MAX_ITERATIONS = 50;
5290
5290
  const NOVERLAP_RATIO = 1.5;
5291
- const NOVERLAP_MARGIN = 10;
5291
+ const NOVERLAP_MARGIN = 25;
5292
5292
  const NOVERLAP_EXPANSION = 1.5;
5293
+ const NOVERLAP_COMMUNITY_ITERATIONS = 20;
5293
5294
  const EDGE_PROGRAM_THRESHOLD = 5e4;
5294
5295
  const LABEL_RENDERED_SIZE_THRESHOLD = 8;
5295
5296
  const LABEL_SIZE = 12;
@@ -5319,6 +5320,7 @@ const DEFAULT_LAYOUT_CONFIG = {
5319
5320
  noverlapRatio: NOVERLAP_RATIO,
5320
5321
  noverlapMargin: NOVERLAP_MARGIN,
5321
5322
  noverlapExpansion: NOVERLAP_EXPANSION,
5323
+ noverlapCommunityIterations: NOVERLAP_COMMUNITY_ITERATIONS,
5322
5324
  louvainResolution: LOUVAIN_RESOLUTION,
5323
5325
  edgeProgramThreshold: 5e4,
5324
5326
  // Graph structure
@@ -5369,6 +5371,13 @@ function useGraphInstance({
5369
5371
  if (allNodes.length === 0) return;
5370
5372
  const { assignments, colorMap, names } = communityData;
5371
5373
  const { getNodeColor, getLinkColor, getCommunityColor } = layoutConfig;
5374
+ const degreeMap = /* @__PURE__ */ new Map();
5375
+ for (const link of allLinks) {
5376
+ const s = endpointId(link.source);
5377
+ const t2 = endpointId(link.target);
5378
+ degreeMap.set(s, (degreeMap.get(s) || 0) + 1);
5379
+ degreeMap.set(t2, (degreeMap.get(t2) || 0) + 1);
5380
+ }
5372
5381
  const nodeIdSet = /* @__PURE__ */ new Set();
5373
5382
  const serializedNodes = allNodes.map((node) => {
5374
5383
  nodeIdSet.add(node.id);
@@ -5376,13 +5385,17 @@ function useGraphInstance({
5376
5385
  const commColor = getCommunityColor(assignments, colorMap, node.id);
5377
5386
  const cid = assignments[node.id];
5378
5387
  const commName = cid !== void 0 ? names.get(cid) : void 0;
5388
+ const degree = degreeMap.get(node.id) || 0;
5389
+ const size = nodeSize(degree, node.type, structuralTypes);
5379
5390
  return {
5380
5391
  key: node.id,
5381
5392
  attributes: {
5382
5393
  label: node.name || node.id,
5394
+ _originalLabel: node.name || node.id,
5383
5395
  x: 0,
5384
5396
  y: 0,
5385
- size: nodeSize(0, node.type, structuralTypes),
5397
+ size,
5398
+ _baseSize: size,
5386
5399
  nodeType: node.type,
5387
5400
  _graphNode: node,
5388
5401
  _typeColor: typeColor,
@@ -6789,7 +6802,7 @@ const e = /* @__PURE__ */ useHighlights.getDefaultExportFromCjs(workerExports);
6789
6802
  function n(t2 = {}) {
6790
6803
  return c(e, t2);
6791
6804
  }
6792
- function zoomToNodes(sigma, nodeIds, duration = 600, padding = 0.1) {
6805
+ function zoomToNodes(sigma, nodeIds, duration = 600, padding = 0.2) {
6793
6806
  let minX = Infinity;
6794
6807
  let maxX = -Infinity;
6795
6808
  let minY = Infinity;
@@ -6806,21 +6819,29 @@ function zoomToNodes(sigma, nodeIds, duration = 600, padding = 0.1) {
6806
6819
  }
6807
6820
  if (count === 0) return;
6808
6821
  const camera = sigma.getCamera();
6809
- if (count === 1 || maxX - minX < 1 && maxY - minY < 1) {
6810
- camera.animate(
6811
- { x: (minX + maxX) / 2, y: (minY + maxY) / 2, ratio: 0.1 },
6812
- { duration }
6813
- );
6814
- return;
6815
- }
6816
6822
  const cx = (minX + maxX) / 2;
6817
6823
  const cy = (minY + maxY) / 2;
6824
+ if (count === 1 || maxX - minX < 1e-3 && maxY - minY < 1e-3) {
6825
+ camera.animate({ x: cx, y: cy, ratio: 0.1 }, { duration });
6826
+ return;
6827
+ }
6828
+ const refState = { x: 0.5, y: 0.5, ratio: 1, angle: 0 };
6818
6829
  const { width, height } = sigma.getDimensions();
6819
- const graphWidth = maxX - minX;
6820
- const graphHeight = maxY - minY;
6821
- const ratioX = graphWidth / (width * (1 - padding * 2));
6822
- const ratioY = graphHeight / (height * (1 - padding * 2));
6823
- const ratio = Math.max(ratioX, ratioY, 0.01);
6830
+ const topLeft = sigma.viewportToFramedGraph(
6831
+ { x: 0, y: 0 },
6832
+ { cameraState: refState }
6833
+ );
6834
+ const bottomRight = sigma.viewportToFramedGraph(
6835
+ { x: width, y: height },
6836
+ { cameraState: refState }
6837
+ );
6838
+ const fullW = Math.abs(bottomRight.x - topLeft.x);
6839
+ const fullH = Math.abs(topLeft.y - bottomRight.y);
6840
+ const bboxW = maxX - minX;
6841
+ const bboxH = maxY - minY;
6842
+ const scaleX = fullW > 0 ? bboxW / (fullW * (1 - 2 * padding)) : 1;
6843
+ const scaleY = fullH > 0 ? bboxH / (fullH * (1 - 2 * padding)) : 1;
6844
+ const ratio = Math.max(Math.max(scaleX, scaleY), 0.01);
6824
6845
  camera.animate({ x: cx, y: cy, ratio }, { duration });
6825
6846
  }
6826
6847
  function zoomToFit(sigma, duration = 400) {
@@ -7021,8 +7042,9 @@ function LayoutPipeline({
7021
7042
  });
7022
7043
  }
7023
7044
  const margin = layoutConfig.noverlapMargin * scale2;
7045
+ const iters = layoutConfig.noverlapCommunityIterations ?? 20;
7024
7046
  const nodeArr = [...subGraph.entries()];
7025
- for (let iter = 0; iter < 10; iter++) {
7047
+ for (let iter = 0; iter < iters; iter++) {
7026
7048
  for (let i = 0; i < nodeArr.length; i++) {
7027
7049
  const [, a] = nodeArr[i];
7028
7050
  for (let j2 = i + 1; j2 < nodeArr.length; j2++) {
@@ -7098,6 +7120,10 @@ function LayoutPipeline({
7098
7120
  }, [layoutReady, optimizeTick, layoutConfig, start, stop, sigma]);
7099
7121
  return null;
7100
7122
  }
7123
+ let _hoveredNodeKey = null;
7124
+ function setHoveredNodeKey(key) {
7125
+ _hoveredNodeKey = key;
7126
+ }
7101
7127
  let cached = null;
7102
7128
  function resolveThemeColors() {
7103
7129
  const root = document.documentElement;
@@ -7113,7 +7139,8 @@ function resolveThemeColors() {
7113
7139
  return cached;
7114
7140
  }
7115
7141
  function drawNodeHover(context, data, settings) {
7116
- data.key;
7142
+ const key = data.key;
7143
+ if (key && _hoveredNodeKey !== null && key !== _hoveredNodeKey) return;
7117
7144
  const size = settings.labelSize;
7118
7145
  const font = settings.labelFont;
7119
7146
  const weight = settings.labelWeight;
@@ -7213,18 +7240,35 @@ function GraphEventHandler({
7213
7240
  t.useEffect(() => {
7214
7241
  const container = sigma.getContainer();
7215
7242
  const graph = sigma.getGraph();
7243
+ const mouseCanvas = container.querySelector(
7244
+ ".sigma-mouse"
7245
+ );
7246
+ let overNode = false;
7247
+ let overEdge = false;
7248
+ function updateCursor() {
7249
+ const value = overNode || overEdge ? "pointer" : "grab";
7250
+ container.style.cursor = value;
7251
+ if (mouseCanvas) mouseCanvas.style.cursor = value;
7252
+ }
7253
+ updateCursor();
7216
7254
  const handlers = {
7217
- enterNode: () => {
7218
- container.style.cursor = "pointer";
7255
+ enterNode: ({ node }) => {
7256
+ setHoveredNodeKey(node);
7257
+ overNode = true;
7258
+ updateCursor();
7219
7259
  },
7220
7260
  leaveNode: () => {
7221
- container.style.cursor = "default";
7261
+ setHoveredNodeKey(null);
7262
+ overNode = false;
7263
+ updateCursor();
7222
7264
  },
7223
7265
  enterEdge: () => {
7224
- container.style.cursor = "pointer";
7266
+ overEdge = true;
7267
+ updateCursor();
7225
7268
  },
7226
7269
  leaveEdge: () => {
7227
- container.style.cursor = "default";
7270
+ overEdge = false;
7271
+ updateCursor();
7228
7272
  },
7229
7273
  clickNode: ({ node }) => {
7230
7274
  if (!onNodeClick) return;
@@ -7293,6 +7337,12 @@ const GraphCanvas = t.memo(
7293
7337
  selectedNodeId = null,
7294
7338
  hops = 2,
7295
7339
  getSubType = defaultGetSubType,
7340
+ highlightNodes: highlightNodesProp,
7341
+ highlightLinks: highlightLinksProp,
7342
+ labelNodes: labelNodesProp,
7343
+ availableSubTypes = EMPTY_SUB_TYPES,
7344
+ zIndex: zIndexEnabled = false,
7345
+ communityData: communityDataProp,
7296
7346
  onNodeClick,
7297
7347
  onEdgeClick,
7298
7348
  onStageClick,
@@ -7302,7 +7352,8 @@ const GraphCanvas = t.memo(
7302
7352
  } = props;
7303
7353
  const sigmaRef = t.useRef(null);
7304
7354
  const [optimizeTick, setOptimizeTick] = t.useState(0);
7305
- const communityData = useHighlights.useCommunities(nodes, links, layoutConfig);
7355
+ const internalCommunityData = useHighlights.useCommunities(nodes, links, layoutConfig);
7356
+ const communityData = communityDataProp ?? internalCommunityData;
7306
7357
  const filterState = t.useMemo(
7307
7358
  () => ({
7308
7359
  hiddenNodeTypes,
@@ -7323,10 +7374,10 @@ const GraphCanvas = t.memo(
7323
7374
  layoutReady,
7324
7375
  filterState,
7325
7376
  communityData.assignments,
7326
- EMPTY_SUB_TYPES,
7377
+ availableSubTypes,
7327
7378
  getSubType
7328
7379
  );
7329
- const highlights = useHighlights.useHighlights(
7380
+ const internalHighlights = useHighlights.useHighlights(
7330
7381
  graph,
7331
7382
  layoutReady,
7332
7383
  nodes,
@@ -7336,6 +7387,9 @@ const GraphCanvas = t.memo(
7336
7387
  hops,
7337
7388
  filterState
7338
7389
  );
7390
+ const effectiveHighlightNodes = highlightNodesProp ?? internalHighlights.highlightNodes;
7391
+ const effectiveHighlightLinks = highlightLinksProp ?? internalHighlights.highlightLinks;
7392
+ const effectiveLabelNodes = labelNodesProp ?? internalHighlights.labelNodes;
7339
7393
  const degreeMap = t.useMemo(() => {
7340
7394
  const map = /* @__PURE__ */ new Map();
7341
7395
  links.forEach((l) => {
@@ -7350,12 +7404,18 @@ const GraphCanvas = t.memo(
7350
7404
  const visualState = t.useMemo(
7351
7405
  () => ({
7352
7406
  colorMode,
7353
- highlightNodes: highlights.highlightNodes,
7354
- highlightLinks: highlights.highlightLinks,
7355
- labelNodes: highlights.labelNodes,
7407
+ highlightNodes: effectiveHighlightNodes,
7408
+ highlightLinks: effectiveHighlightLinks,
7409
+ labelNodes: effectiveLabelNodes,
7356
7410
  selectedNodeId: selectedNodeId ?? null
7357
7411
  }),
7358
- [colorMode, highlights, selectedNodeId]
7412
+ [
7413
+ colorMode,
7414
+ effectiveHighlightNodes,
7415
+ effectiveHighlightLinks,
7416
+ effectiveLabelNodes,
7417
+ selectedNodeId
7418
+ ]
7359
7419
  );
7360
7420
  useGraphVisuals(
7361
7421
  graph,
@@ -7365,6 +7425,34 @@ const GraphCanvas = t.memo(
7365
7425
  degreeMap,
7366
7426
  isLargeGraph
7367
7427
  );
7428
+ t.useEffect(() => {
7429
+ if (!zIndexEnabled) return;
7430
+ const container = sigmaRef.current?.getContainer?.();
7431
+ if (!container) return;
7432
+ const layers = [
7433
+ "sigma-edges",
7434
+ "sigma-edgeLabels",
7435
+ "sigma-nodes",
7436
+ "sigma-labels",
7437
+ "sigma-hovers",
7438
+ "sigma-hoverNodes",
7439
+ "sigma-mouse"
7440
+ ];
7441
+ const els = layers.map(
7442
+ (cls) => container.querySelector(`.${cls}`)
7443
+ );
7444
+ const hasSelection = effectiveHighlightNodes.size > 0;
7445
+ if (hasSelection) {
7446
+ const zMap = [2, 3, 1, 4, 6, 5, 7];
7447
+ els.forEach((el, i) => {
7448
+ if (el) el.style.zIndex = String(zMap[i]);
7449
+ });
7450
+ } else {
7451
+ els.forEach((el) => {
7452
+ if (el) el.style.zIndex = "";
7453
+ });
7454
+ }
7455
+ }, [zIndexEnabled, effectiveHighlightNodes]);
7368
7456
  const sigmaSettings = t.useMemo(
7369
7457
  () => ({
7370
7458
  defaultNodeType: "circle",
@@ -7380,9 +7468,10 @@ const GraphCanvas = t.memo(
7380
7468
  labelSize: LABEL_SIZE,
7381
7469
  defaultDrawNodeHover: drawNodeHover,
7382
7470
  allowInvalidContainer: true,
7471
+ zIndex: zIndexEnabled,
7383
7472
  zoomToSizeRatioFunction: (ratio) => Math.pow(ratio, ZOOM_SIZE_EXPONENT)
7384
7473
  }),
7385
- [isLargeGraph]
7474
+ [isLargeGraph, zIndexEnabled]
7386
7475
  );
7387
7476
  const handleSigmaReady = t.useCallback(
7388
7477
  (sigma) => {
@@ -7449,6 +7538,24 @@ const GraphCanvas = t.memo(
7449
7538
  },
7450
7539
  optimize: () => {
7451
7540
  setOptimizeTick((t2) => t2 + 1);
7541
+ },
7542
+ zoomIn: (duration = 300) => {
7543
+ if (sigmaRef.current) {
7544
+ const camera = sigmaRef.current.getCamera();
7545
+ camera.animatedZoom({ duration });
7546
+ }
7547
+ },
7548
+ zoomOut: (duration = 300) => {
7549
+ if (sigmaRef.current) {
7550
+ const camera = sigmaRef.current.getCamera();
7551
+ camera.animatedUnzoom({ duration });
7552
+ }
7553
+ },
7554
+ resetCamera: (duration = 400) => {
7555
+ if (sigmaRef.current) {
7556
+ const camera = sigmaRef.current.getCamera();
7557
+ camera.animatedReset({ duration });
7558
+ }
7452
7559
  }
7453
7560
  }),
7454
7561
  [nodes, links, hops, onNodeClick]
@@ -8689,6 +8796,7 @@ exports.FA2_ENABLED = FA2_ENABLED;
8689
8796
  exports.FA2_GRAVITY = FA2_GRAVITY;
8690
8797
  exports.FA2_SCALING_RATIO = FA2_SCALING_RATIO;
8691
8798
  exports.FilterPanel = FilterPanel;
8799
+ exports.Graph = GraphCanvas;
8692
8800
  exports.GraphBadge = GraphBadge;
8693
8801
  exports.GraphCanvas = GraphCanvas;
8694
8802
  exports.GraphLegend = GraphLegend;
@@ -8705,6 +8813,7 @@ exports.NODE_SIZE_MIN = NODE_SIZE_MIN;
8705
8813
  exports.NODE_SIZE_MULTIPLIERS = NODE_SIZE_MULTIPLIERS;
8706
8814
  exports.ZOOM_SIZE_EXPONENT = ZOOM_SIZE_EXPONENT;
8707
8815
  exports.drawNodeHover = drawNodeHover;
8816
+ exports.setHoveredNodeKey = setHoveredNodeKey;
8708
8817
  exports.useGraphInstance = useGraphInstance;
8709
8818
  exports.useGraphVisuals = useGraphVisuals;
8710
8819
  exports.zoomToFit = zoomToFit;