microboard-temp 0.13.20 → 0.13.22

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.
@@ -54606,6 +54606,7 @@ class ForceGraphEngine {
54606
54606
  tickTimer = null;
54607
54607
  syncTimer = null;
54608
54608
  lastSyncedPositions = new Map;
54609
+ activeComponents = new Map;
54609
54610
  TICK_MS = 33;
54610
54611
  SYNC_MS = 300;
54611
54612
  SOFTENING_SQ = 100 * 100;
@@ -54613,18 +54614,74 @@ class ForceGraphEngine {
54613
54614
  constructor(board) {
54614
54615
  this.board = board;
54615
54616
  }
54616
- start() {
54617
- if (this.tickTimer !== null)
54617
+ enableForGraph(startNodeId) {
54618
+ if (this.isNodeInActiveGraph(startNodeId))
54618
54619
  return;
54619
- for (const item of this.getNodes()) {
54620
- const pos = item.transformation.getTranslation();
54621
- this.lastSyncedPositions.set(item.getId(), { x: pos.x, y: pos.y });
54622
- this.velocities.set(item.getId(), { vx: 0, vy: 0 });
54620
+ const nodeIds = this.bfsComponent(startNodeId);
54621
+ const targetGap = this.calibrateTargetGap(nodeIds);
54622
+ this.activeComponents.set(startNodeId, { nodeIds, targetGap });
54623
+ for (const id of nodeIds) {
54624
+ if (!this.velocities.has(id)) {
54625
+ this.velocities.set(id, { vx: 0, vy: 0 });
54626
+ }
54627
+ const item = this.board.items.getById(id);
54628
+ if (item && !this.lastSyncedPositions.has(id)) {
54629
+ const pos = item.transformation.getTranslation();
54630
+ this.lastSyncedPositions.set(id, { x: pos.x, y: pos.y });
54631
+ }
54632
+ }
54633
+ this.ensureRunning();
54634
+ }
54635
+ disableForGraph(nodeId) {
54636
+ const compId = this.findComponentId(nodeId);
54637
+ if (!compId)
54638
+ return;
54639
+ this.activeComponents.delete(compId);
54640
+ if (this.activeComponents.size === 0) {
54641
+ this.stopTimers();
54642
+ }
54643
+ }
54644
+ isNodeInActiveGraph(nodeId) {
54645
+ return !!this.findComponentId(nodeId);
54646
+ }
54647
+ getComponentTargetGap(nodeId) {
54648
+ const compId = this.findComponentId(nodeId);
54649
+ return compId ? this.activeComponents.get(compId)?.targetGap : undefined;
54650
+ }
54651
+ setComponentTargetGap(nodeId, gap) {
54652
+ const compId = this.findComponentId(nodeId);
54653
+ if (!compId)
54654
+ return;
54655
+ const comp = this.activeComponents.get(compId);
54656
+ if (!comp)
54657
+ return;
54658
+ comp.targetGap = gap;
54659
+ this.wake();
54660
+ }
54661
+ hasActiveComponents() {
54662
+ return this.activeComponents.size > 0;
54663
+ }
54664
+ wake() {
54665
+ if (this.activeComponents.size > 0 && this.tickTimer === null) {
54666
+ this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54623
54667
  }
54624
- this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54625
- this.syncTimer = setInterval(() => this.syncPositions(), this.SYNC_MS);
54626
54668
  }
54627
54669
  stop() {
54670
+ this.stopTimers();
54671
+ this.syncPositions();
54672
+ this.velocities.clear();
54673
+ this.lastSyncedPositions.clear();
54674
+ this.activeComponents.clear();
54675
+ }
54676
+ ensureRunning() {
54677
+ if (this.tickTimer === null) {
54678
+ this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54679
+ }
54680
+ if (this.syncTimer === null) {
54681
+ this.syncTimer = setInterval(() => this.syncPositions(), this.SYNC_MS);
54682
+ }
54683
+ }
54684
+ stopTimers() {
54628
54685
  if (this.tickTimer !== null) {
54629
54686
  clearInterval(this.tickTimer);
54630
54687
  this.tickTimer = null;
@@ -54633,9 +54690,56 @@ class ForceGraphEngine {
54633
54690
  clearInterval(this.syncTimer);
54634
54691
  this.syncTimer = null;
54635
54692
  }
54636
- this.syncPositions();
54637
- this.velocities.clear();
54638
- this.lastSyncedPositions.clear();
54693
+ }
54694
+ findComponentId(nodeId) {
54695
+ for (const [compId, { nodeIds }] of this.activeComponents) {
54696
+ if (nodeIds.has(nodeId))
54697
+ return compId;
54698
+ }
54699
+ return;
54700
+ }
54701
+ bfsComponent(startNodeId) {
54702
+ const visited = new Set;
54703
+ const queue = [startNodeId];
54704
+ const connectors = this.getConnectors();
54705
+ while (queue.length > 0) {
54706
+ const nodeId = queue.shift();
54707
+ if (visited.has(nodeId))
54708
+ continue;
54709
+ visited.add(nodeId);
54710
+ for (const connector of connectors) {
54711
+ const { startItem, endItem } = connector.getConnectedItems();
54712
+ if (startItem?.getId() === nodeId && endItem && !visited.has(endItem.getId())) {
54713
+ queue.push(endItem.getId());
54714
+ }
54715
+ if (endItem?.getId() === nodeId && startItem && !visited.has(startItem.getId())) {
54716
+ queue.push(startItem.getId());
54717
+ }
54718
+ }
54719
+ }
54720
+ return visited;
54721
+ }
54722
+ calibrateTargetGap(nodeIds) {
54723
+ let totalMaxDim = 0;
54724
+ let count = 0;
54725
+ for (const id of nodeIds) {
54726
+ const item = this.board.items.getById(id);
54727
+ if (!item)
54728
+ continue;
54729
+ const mbr = item.getMbr();
54730
+ totalMaxDim += Math.max(mbr.getWidth(), mbr.getHeight());
54731
+ count++;
54732
+ }
54733
+ const avgMaxDim = count > 0 ? totalMaxDim / count : 100;
54734
+ return avgMaxDim * 1.5;
54735
+ }
54736
+ getActiveNodeIds() {
54737
+ const all6 = new Set;
54738
+ for (const { nodeIds } of this.activeComponents.values()) {
54739
+ for (const id of nodeIds)
54740
+ all6.add(id);
54741
+ }
54742
+ return all6;
54639
54743
  }
54640
54744
  getNodes() {
54641
54745
  return this.board.items.listAll().filter((item) => !EXCLUDED_TYPES.has(item.itemType) && !item.transformation.isLocked);
@@ -54645,8 +54749,10 @@ class ForceGraphEngine {
54645
54749
  }
54646
54750
  tick() {
54647
54751
  const dt = this.TICK_MS / 1000;
54648
- const nodes = this.getNodes();
54649
- if (nodes.length < 2)
54752
+ const activeIds = this.getActiveNodeIds();
54753
+ const allNodes = this.getNodes();
54754
+ const nodes = allNodes.filter((item) => activeIds.has(item.getId()));
54755
+ if (nodes.length < 1)
54650
54756
  return;
54651
54757
  const snapMap = new Map;
54652
54758
  for (const item of nodes) {
@@ -54687,7 +54793,9 @@ class ForceGraphEngine {
54687
54793
  const dx = s2.cx - s1.cx;
54688
54794
  const dy = s2.cy - s1.cy;
54689
54795
  const dist = Math.sqrt(dx * dx + dy * dy) + 0.001;
54690
- const targetDist = (Math.max(s1.w, s1.h) + Math.max(s2.w, s2.h)) * 0.5 + conf.FG_TARGET_GAP;
54796
+ const compId = this.findComponentId(s1.id);
54797
+ const targetGap = compId ? this.activeComponents.get(compId)?.targetGap ?? conf.FG_TARGET_GAP : conf.FG_TARGET_GAP;
54798
+ const targetDist = (Math.max(s1.w, s1.h) + Math.max(s2.w, s2.h)) * 0.5 + targetGap;
54691
54799
  const stretch = dist - targetDist;
54692
54800
  const forceMag = stretch * conf.FG_SPRING_K;
54693
54801
  const fx = dx / dist * forceMag;
@@ -54748,7 +54856,8 @@ class ForceGraphEngine {
54748
54856
  }
54749
54857
  }
54750
54858
  syncPositions() {
54751
- const nodes = this.getNodes();
54859
+ const activeIds = this.getActiveNodeIds();
54860
+ const nodes = this.getNodes().filter((item) => activeIds.has(item.getId()));
54752
54861
  if (nodes.length === 0)
54753
54862
  return;
54754
54863
  const movedItems = nodes.map((item) => {
@@ -54772,11 +54881,6 @@ class ForceGraphEngine {
54772
54881
  };
54773
54882
  this.board.events.emit(operation);
54774
54883
  }
54775
- wake() {
54776
- if (this.tickTimer === null && this.syncTimer !== null) {
54777
- this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54778
- }
54779
- }
54780
54884
  }
54781
54885
 
54782
54886
  // src/Board.ts
@@ -55852,20 +55956,28 @@ class Board {
55852
55956
  return this.gravity !== null;
55853
55957
  }
55854
55958
  forceGraph = null;
55855
- enableForceGraph() {
55856
- if (this.forceGraph)
55857
- return;
55858
- this.forceGraph = new ForceGraphEngine(this);
55859
- this.forceGraph.start();
55959
+ enableForceGraph(nodeId) {
55960
+ if (!this.forceGraph) {
55961
+ this.forceGraph = new ForceGraphEngine(this);
55962
+ }
55963
+ this.forceGraph.enableForGraph(nodeId);
55860
55964
  }
55861
- disableForceGraph() {
55965
+ disableForceGraph(nodeId) {
55862
55966
  if (!this.forceGraph)
55863
55967
  return;
55864
- this.forceGraph.stop();
55865
- this.forceGraph = null;
55968
+ this.forceGraph.disableForGraph(nodeId);
55969
+ if (!this.forceGraph.hasActiveComponents()) {
55970
+ this.forceGraph = null;
55971
+ }
55972
+ }
55973
+ isNodeInForceGraph(nodeId) {
55974
+ return this.forceGraph?.isNodeInActiveGraph(nodeId) ?? false;
55975
+ }
55976
+ getForceGraphGap(nodeId) {
55977
+ return this.forceGraph?.getComponentTargetGap(nodeId);
55866
55978
  }
55867
- isForceGraphEnabled() {
55868
- return this.forceGraph !== null;
55979
+ setForceGraphGap(nodeId, gap) {
55980
+ this.forceGraph?.setComponentTargetGap(nodeId, gap);
55869
55981
  }
55870
55982
  wakeForceGraph() {
55871
55983
  this.forceGraph?.wake();
package/dist/cjs/index.js CHANGED
@@ -54606,6 +54606,7 @@ class ForceGraphEngine {
54606
54606
  tickTimer = null;
54607
54607
  syncTimer = null;
54608
54608
  lastSyncedPositions = new Map;
54609
+ activeComponents = new Map;
54609
54610
  TICK_MS = 33;
54610
54611
  SYNC_MS = 300;
54611
54612
  SOFTENING_SQ = 100 * 100;
@@ -54613,18 +54614,74 @@ class ForceGraphEngine {
54613
54614
  constructor(board) {
54614
54615
  this.board = board;
54615
54616
  }
54616
- start() {
54617
- if (this.tickTimer !== null)
54617
+ enableForGraph(startNodeId) {
54618
+ if (this.isNodeInActiveGraph(startNodeId))
54618
54619
  return;
54619
- for (const item of this.getNodes()) {
54620
- const pos = item.transformation.getTranslation();
54621
- this.lastSyncedPositions.set(item.getId(), { x: pos.x, y: pos.y });
54622
- this.velocities.set(item.getId(), { vx: 0, vy: 0 });
54620
+ const nodeIds = this.bfsComponent(startNodeId);
54621
+ const targetGap = this.calibrateTargetGap(nodeIds);
54622
+ this.activeComponents.set(startNodeId, { nodeIds, targetGap });
54623
+ for (const id of nodeIds) {
54624
+ if (!this.velocities.has(id)) {
54625
+ this.velocities.set(id, { vx: 0, vy: 0 });
54626
+ }
54627
+ const item = this.board.items.getById(id);
54628
+ if (item && !this.lastSyncedPositions.has(id)) {
54629
+ const pos = item.transformation.getTranslation();
54630
+ this.lastSyncedPositions.set(id, { x: pos.x, y: pos.y });
54631
+ }
54632
+ }
54633
+ this.ensureRunning();
54634
+ }
54635
+ disableForGraph(nodeId) {
54636
+ const compId = this.findComponentId(nodeId);
54637
+ if (!compId)
54638
+ return;
54639
+ this.activeComponents.delete(compId);
54640
+ if (this.activeComponents.size === 0) {
54641
+ this.stopTimers();
54642
+ }
54643
+ }
54644
+ isNodeInActiveGraph(nodeId) {
54645
+ return !!this.findComponentId(nodeId);
54646
+ }
54647
+ getComponentTargetGap(nodeId) {
54648
+ const compId = this.findComponentId(nodeId);
54649
+ return compId ? this.activeComponents.get(compId)?.targetGap : undefined;
54650
+ }
54651
+ setComponentTargetGap(nodeId, gap) {
54652
+ const compId = this.findComponentId(nodeId);
54653
+ if (!compId)
54654
+ return;
54655
+ const comp = this.activeComponents.get(compId);
54656
+ if (!comp)
54657
+ return;
54658
+ comp.targetGap = gap;
54659
+ this.wake();
54660
+ }
54661
+ hasActiveComponents() {
54662
+ return this.activeComponents.size > 0;
54663
+ }
54664
+ wake() {
54665
+ if (this.activeComponents.size > 0 && this.tickTimer === null) {
54666
+ this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54623
54667
  }
54624
- this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54625
- this.syncTimer = setInterval(() => this.syncPositions(), this.SYNC_MS);
54626
54668
  }
54627
54669
  stop() {
54670
+ this.stopTimers();
54671
+ this.syncPositions();
54672
+ this.velocities.clear();
54673
+ this.lastSyncedPositions.clear();
54674
+ this.activeComponents.clear();
54675
+ }
54676
+ ensureRunning() {
54677
+ if (this.tickTimer === null) {
54678
+ this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54679
+ }
54680
+ if (this.syncTimer === null) {
54681
+ this.syncTimer = setInterval(() => this.syncPositions(), this.SYNC_MS);
54682
+ }
54683
+ }
54684
+ stopTimers() {
54628
54685
  if (this.tickTimer !== null) {
54629
54686
  clearInterval(this.tickTimer);
54630
54687
  this.tickTimer = null;
@@ -54633,9 +54690,56 @@ class ForceGraphEngine {
54633
54690
  clearInterval(this.syncTimer);
54634
54691
  this.syncTimer = null;
54635
54692
  }
54636
- this.syncPositions();
54637
- this.velocities.clear();
54638
- this.lastSyncedPositions.clear();
54693
+ }
54694
+ findComponentId(nodeId) {
54695
+ for (const [compId, { nodeIds }] of this.activeComponents) {
54696
+ if (nodeIds.has(nodeId))
54697
+ return compId;
54698
+ }
54699
+ return;
54700
+ }
54701
+ bfsComponent(startNodeId) {
54702
+ const visited = new Set;
54703
+ const queue = [startNodeId];
54704
+ const connectors = this.getConnectors();
54705
+ while (queue.length > 0) {
54706
+ const nodeId = queue.shift();
54707
+ if (visited.has(nodeId))
54708
+ continue;
54709
+ visited.add(nodeId);
54710
+ for (const connector of connectors) {
54711
+ const { startItem, endItem } = connector.getConnectedItems();
54712
+ if (startItem?.getId() === nodeId && endItem && !visited.has(endItem.getId())) {
54713
+ queue.push(endItem.getId());
54714
+ }
54715
+ if (endItem?.getId() === nodeId && startItem && !visited.has(startItem.getId())) {
54716
+ queue.push(startItem.getId());
54717
+ }
54718
+ }
54719
+ }
54720
+ return visited;
54721
+ }
54722
+ calibrateTargetGap(nodeIds) {
54723
+ let totalMaxDim = 0;
54724
+ let count = 0;
54725
+ for (const id of nodeIds) {
54726
+ const item = this.board.items.getById(id);
54727
+ if (!item)
54728
+ continue;
54729
+ const mbr = item.getMbr();
54730
+ totalMaxDim += Math.max(mbr.getWidth(), mbr.getHeight());
54731
+ count++;
54732
+ }
54733
+ const avgMaxDim = count > 0 ? totalMaxDim / count : 100;
54734
+ return avgMaxDim * 1.5;
54735
+ }
54736
+ getActiveNodeIds() {
54737
+ const all6 = new Set;
54738
+ for (const { nodeIds } of this.activeComponents.values()) {
54739
+ for (const id of nodeIds)
54740
+ all6.add(id);
54741
+ }
54742
+ return all6;
54639
54743
  }
54640
54744
  getNodes() {
54641
54745
  return this.board.items.listAll().filter((item) => !EXCLUDED_TYPES.has(item.itemType) && !item.transformation.isLocked);
@@ -54645,8 +54749,10 @@ class ForceGraphEngine {
54645
54749
  }
54646
54750
  tick() {
54647
54751
  const dt = this.TICK_MS / 1000;
54648
- const nodes = this.getNodes();
54649
- if (nodes.length < 2)
54752
+ const activeIds = this.getActiveNodeIds();
54753
+ const allNodes = this.getNodes();
54754
+ const nodes = allNodes.filter((item) => activeIds.has(item.getId()));
54755
+ if (nodes.length < 1)
54650
54756
  return;
54651
54757
  const snapMap = new Map;
54652
54758
  for (const item of nodes) {
@@ -54687,7 +54793,9 @@ class ForceGraphEngine {
54687
54793
  const dx = s2.cx - s1.cx;
54688
54794
  const dy = s2.cy - s1.cy;
54689
54795
  const dist = Math.sqrt(dx * dx + dy * dy) + 0.001;
54690
- const targetDist = (Math.max(s1.w, s1.h) + Math.max(s2.w, s2.h)) * 0.5 + conf.FG_TARGET_GAP;
54796
+ const compId = this.findComponentId(s1.id);
54797
+ const targetGap = compId ? this.activeComponents.get(compId)?.targetGap ?? conf.FG_TARGET_GAP : conf.FG_TARGET_GAP;
54798
+ const targetDist = (Math.max(s1.w, s1.h) + Math.max(s2.w, s2.h)) * 0.5 + targetGap;
54691
54799
  const stretch = dist - targetDist;
54692
54800
  const forceMag = stretch * conf.FG_SPRING_K;
54693
54801
  const fx = dx / dist * forceMag;
@@ -54748,7 +54856,8 @@ class ForceGraphEngine {
54748
54856
  }
54749
54857
  }
54750
54858
  syncPositions() {
54751
- const nodes = this.getNodes();
54859
+ const activeIds = this.getActiveNodeIds();
54860
+ const nodes = this.getNodes().filter((item) => activeIds.has(item.getId()));
54752
54861
  if (nodes.length === 0)
54753
54862
  return;
54754
54863
  const movedItems = nodes.map((item) => {
@@ -54772,11 +54881,6 @@ class ForceGraphEngine {
54772
54881
  };
54773
54882
  this.board.events.emit(operation);
54774
54883
  }
54775
- wake() {
54776
- if (this.tickTimer === null && this.syncTimer !== null) {
54777
- this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54778
- }
54779
- }
54780
54884
  }
54781
54885
 
54782
54886
  // src/Board.ts
@@ -55852,20 +55956,28 @@ class Board {
55852
55956
  return this.gravity !== null;
55853
55957
  }
55854
55958
  forceGraph = null;
55855
- enableForceGraph() {
55856
- if (this.forceGraph)
55857
- return;
55858
- this.forceGraph = new ForceGraphEngine(this);
55859
- this.forceGraph.start();
55959
+ enableForceGraph(nodeId) {
55960
+ if (!this.forceGraph) {
55961
+ this.forceGraph = new ForceGraphEngine(this);
55962
+ }
55963
+ this.forceGraph.enableForGraph(nodeId);
55860
55964
  }
55861
- disableForceGraph() {
55965
+ disableForceGraph(nodeId) {
55862
55966
  if (!this.forceGraph)
55863
55967
  return;
55864
- this.forceGraph.stop();
55865
- this.forceGraph = null;
55968
+ this.forceGraph.disableForGraph(nodeId);
55969
+ if (!this.forceGraph.hasActiveComponents()) {
55970
+ this.forceGraph = null;
55971
+ }
55972
+ }
55973
+ isNodeInForceGraph(nodeId) {
55974
+ return this.forceGraph?.isNodeInActiveGraph(nodeId) ?? false;
55975
+ }
55976
+ getForceGraphGap(nodeId) {
55977
+ return this.forceGraph?.getComponentTargetGap(nodeId);
55866
55978
  }
55867
- isForceGraphEnabled() {
55868
- return this.forceGraph !== null;
55979
+ setForceGraphGap(nodeId, gap) {
55980
+ this.forceGraph?.setComponentTargetGap(nodeId, gap);
55869
55981
  }
55870
55982
  wakeForceGraph() {
55871
55983
  this.forceGraph?.wake();