microboard-temp 0.13.19 → 0.13.21

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,60 @@ 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
+ hasActiveComponents() {
54648
+ return this.activeComponents.size > 0;
54649
+ }
54650
+ wake() {
54651
+ if (this.activeComponents.size > 0 && this.tickTimer === null) {
54652
+ this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54623
54653
  }
54624
- this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54625
- this.syncTimer = setInterval(() => this.syncPositions(), this.SYNC_MS);
54626
54654
  }
54627
54655
  stop() {
54656
+ this.stopTimers();
54657
+ this.syncPositions();
54658
+ this.velocities.clear();
54659
+ this.lastSyncedPositions.clear();
54660
+ this.activeComponents.clear();
54661
+ }
54662
+ ensureRunning() {
54663
+ if (this.tickTimer === null) {
54664
+ this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54665
+ }
54666
+ if (this.syncTimer === null) {
54667
+ this.syncTimer = setInterval(() => this.syncPositions(), this.SYNC_MS);
54668
+ }
54669
+ }
54670
+ stopTimers() {
54628
54671
  if (this.tickTimer !== null) {
54629
54672
  clearInterval(this.tickTimer);
54630
54673
  this.tickTimer = null;
@@ -54633,9 +54676,56 @@ class ForceGraphEngine {
54633
54676
  clearInterval(this.syncTimer);
54634
54677
  this.syncTimer = null;
54635
54678
  }
54636
- this.syncPositions();
54637
- this.velocities.clear();
54638
- this.lastSyncedPositions.clear();
54679
+ }
54680
+ findComponentId(nodeId) {
54681
+ for (const [compId, { nodeIds }] of this.activeComponents) {
54682
+ if (nodeIds.has(nodeId))
54683
+ return compId;
54684
+ }
54685
+ return;
54686
+ }
54687
+ bfsComponent(startNodeId) {
54688
+ const visited = new Set;
54689
+ const queue = [startNodeId];
54690
+ const connectors = this.getConnectors();
54691
+ while (queue.length > 0) {
54692
+ const nodeId = queue.shift();
54693
+ if (visited.has(nodeId))
54694
+ continue;
54695
+ visited.add(nodeId);
54696
+ for (const connector of connectors) {
54697
+ const { startItem, endItem } = connector.getConnectedItems();
54698
+ if (startItem?.getId() === nodeId && endItem && !visited.has(endItem.getId())) {
54699
+ queue.push(endItem.getId());
54700
+ }
54701
+ if (endItem?.getId() === nodeId && startItem && !visited.has(startItem.getId())) {
54702
+ queue.push(startItem.getId());
54703
+ }
54704
+ }
54705
+ }
54706
+ return visited;
54707
+ }
54708
+ calibrateTargetGap(nodeIds) {
54709
+ let totalMaxDim = 0;
54710
+ let count = 0;
54711
+ for (const id of nodeIds) {
54712
+ const item = this.board.items.getById(id);
54713
+ if (!item)
54714
+ continue;
54715
+ const mbr = item.getMbr();
54716
+ totalMaxDim += Math.max(mbr.getWidth(), mbr.getHeight());
54717
+ count++;
54718
+ }
54719
+ const avgMaxDim = count > 0 ? totalMaxDim / count : 100;
54720
+ return avgMaxDim * 0.3 + conf.FG_TARGET_GAP;
54721
+ }
54722
+ getActiveNodeIds() {
54723
+ const all6 = new Set;
54724
+ for (const { nodeIds } of this.activeComponents.values()) {
54725
+ for (const id of nodeIds)
54726
+ all6.add(id);
54727
+ }
54728
+ return all6;
54639
54729
  }
54640
54730
  getNodes() {
54641
54731
  return this.board.items.listAll().filter((item) => !EXCLUDED_TYPES.has(item.itemType) && !item.transformation.isLocked);
@@ -54645,8 +54735,10 @@ class ForceGraphEngine {
54645
54735
  }
54646
54736
  tick() {
54647
54737
  const dt = this.TICK_MS / 1000;
54648
- const nodes = this.getNodes();
54649
- if (nodes.length < 2)
54738
+ const activeIds = this.getActiveNodeIds();
54739
+ const allNodes = this.getNodes();
54740
+ const nodes = allNodes.filter((item) => activeIds.has(item.getId()));
54741
+ if (nodes.length < 1)
54650
54742
  return;
54651
54743
  const snapMap = new Map;
54652
54744
  for (const item of nodes) {
@@ -54687,7 +54779,9 @@ class ForceGraphEngine {
54687
54779
  const dx = s2.cx - s1.cx;
54688
54780
  const dy = s2.cy - s1.cy;
54689
54781
  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;
54782
+ const compId = this.findComponentId(s1.id);
54783
+ const targetGap = compId ? this.activeComponents.get(compId)?.targetGap ?? conf.FG_TARGET_GAP : conf.FG_TARGET_GAP;
54784
+ const targetDist = (Math.max(s1.w, s1.h) + Math.max(s2.w, s2.h)) * 0.5 + targetGap;
54691
54785
  const stretch = dist - targetDist;
54692
54786
  const forceMag = stretch * conf.FG_SPRING_K;
54693
54787
  const fx = dx / dist * forceMag;
@@ -54705,10 +54799,13 @@ class ForceGraphEngine {
54705
54799
  continue;
54706
54800
  const dx = s2.cx - s1.cx;
54707
54801
  const dy = s2.cy - s1.cy;
54708
- const distSq = dx * dx + dy * dy + this.SOFTENING_SQ;
54709
- const repMag = conf.FG_REPULSION / distSq;
54710
- const fx = dx * repMag;
54711
- const fy = dy * repMag;
54802
+ const centerDist = Math.sqrt(dx * dx + dy * dy) + 0.001;
54803
+ const r1 = Math.max(s1.w, s1.h) * 0.5;
54804
+ const r2 = Math.max(s2.w, s2.h) * 0.5;
54805
+ const edgeDist = Math.max(centerDist - r1 - r2, 1);
54806
+ const repMag = conf.FG_REPULSION / (edgeDist * edgeDist + this.SOFTENING_SQ);
54807
+ const fx = dx / centerDist * repMag;
54808
+ const fy = dy / centerDist * repMag;
54712
54809
  ax.set(s1.id, (ax.get(s1.id) ?? 0) - fx);
54713
54810
  ay.set(s1.id, (ay.get(s1.id) ?? 0) - fy);
54714
54811
  ax.set(s2.id, (ax.get(s2.id) ?? 0) + fx);
@@ -54745,7 +54842,8 @@ class ForceGraphEngine {
54745
54842
  }
54746
54843
  }
54747
54844
  syncPositions() {
54748
- const nodes = this.getNodes();
54845
+ const activeIds = this.getActiveNodeIds();
54846
+ const nodes = this.getNodes().filter((item) => activeIds.has(item.getId()));
54749
54847
  if (nodes.length === 0)
54750
54848
  return;
54751
54849
  const movedItems = nodes.map((item) => {
@@ -54769,11 +54867,6 @@ class ForceGraphEngine {
54769
54867
  };
54770
54868
  this.board.events.emit(operation);
54771
54869
  }
54772
- wake() {
54773
- if (this.tickTimer === null && this.syncTimer !== null) {
54774
- this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54775
- }
54776
- }
54777
54870
  }
54778
54871
 
54779
54872
  // src/Board.ts
@@ -55849,20 +55942,22 @@ class Board {
55849
55942
  return this.gravity !== null;
55850
55943
  }
55851
55944
  forceGraph = null;
55852
- enableForceGraph() {
55853
- if (this.forceGraph)
55854
- return;
55855
- this.forceGraph = new ForceGraphEngine(this);
55856
- this.forceGraph.start();
55945
+ enableForceGraph(nodeId) {
55946
+ if (!this.forceGraph) {
55947
+ this.forceGraph = new ForceGraphEngine(this);
55948
+ }
55949
+ this.forceGraph.enableForGraph(nodeId);
55857
55950
  }
55858
- disableForceGraph() {
55951
+ disableForceGraph(nodeId) {
55859
55952
  if (!this.forceGraph)
55860
55953
  return;
55861
- this.forceGraph.stop();
55862
- this.forceGraph = null;
55954
+ this.forceGraph.disableForGraph(nodeId);
55955
+ if (!this.forceGraph.hasActiveComponents()) {
55956
+ this.forceGraph = null;
55957
+ }
55863
55958
  }
55864
- isForceGraphEnabled() {
55865
- return this.forceGraph !== null;
55959
+ isNodeInForceGraph(nodeId) {
55960
+ return this.forceGraph?.isNodeInActiveGraph(nodeId) ?? false;
55866
55961
  }
55867
55962
  wakeForceGraph() {
55868
55963
  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,60 @@ 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
+ hasActiveComponents() {
54648
+ return this.activeComponents.size > 0;
54649
+ }
54650
+ wake() {
54651
+ if (this.activeComponents.size > 0 && this.tickTimer === null) {
54652
+ this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54623
54653
  }
54624
- this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54625
- this.syncTimer = setInterval(() => this.syncPositions(), this.SYNC_MS);
54626
54654
  }
54627
54655
  stop() {
54656
+ this.stopTimers();
54657
+ this.syncPositions();
54658
+ this.velocities.clear();
54659
+ this.lastSyncedPositions.clear();
54660
+ this.activeComponents.clear();
54661
+ }
54662
+ ensureRunning() {
54663
+ if (this.tickTimer === null) {
54664
+ this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54665
+ }
54666
+ if (this.syncTimer === null) {
54667
+ this.syncTimer = setInterval(() => this.syncPositions(), this.SYNC_MS);
54668
+ }
54669
+ }
54670
+ stopTimers() {
54628
54671
  if (this.tickTimer !== null) {
54629
54672
  clearInterval(this.tickTimer);
54630
54673
  this.tickTimer = null;
@@ -54633,9 +54676,56 @@ class ForceGraphEngine {
54633
54676
  clearInterval(this.syncTimer);
54634
54677
  this.syncTimer = null;
54635
54678
  }
54636
- this.syncPositions();
54637
- this.velocities.clear();
54638
- this.lastSyncedPositions.clear();
54679
+ }
54680
+ findComponentId(nodeId) {
54681
+ for (const [compId, { nodeIds }] of this.activeComponents) {
54682
+ if (nodeIds.has(nodeId))
54683
+ return compId;
54684
+ }
54685
+ return;
54686
+ }
54687
+ bfsComponent(startNodeId) {
54688
+ const visited = new Set;
54689
+ const queue = [startNodeId];
54690
+ const connectors = this.getConnectors();
54691
+ while (queue.length > 0) {
54692
+ const nodeId = queue.shift();
54693
+ if (visited.has(nodeId))
54694
+ continue;
54695
+ visited.add(nodeId);
54696
+ for (const connector of connectors) {
54697
+ const { startItem, endItem } = connector.getConnectedItems();
54698
+ if (startItem?.getId() === nodeId && endItem && !visited.has(endItem.getId())) {
54699
+ queue.push(endItem.getId());
54700
+ }
54701
+ if (endItem?.getId() === nodeId && startItem && !visited.has(startItem.getId())) {
54702
+ queue.push(startItem.getId());
54703
+ }
54704
+ }
54705
+ }
54706
+ return visited;
54707
+ }
54708
+ calibrateTargetGap(nodeIds) {
54709
+ let totalMaxDim = 0;
54710
+ let count = 0;
54711
+ for (const id of nodeIds) {
54712
+ const item = this.board.items.getById(id);
54713
+ if (!item)
54714
+ continue;
54715
+ const mbr = item.getMbr();
54716
+ totalMaxDim += Math.max(mbr.getWidth(), mbr.getHeight());
54717
+ count++;
54718
+ }
54719
+ const avgMaxDim = count > 0 ? totalMaxDim / count : 100;
54720
+ return avgMaxDim * 0.3 + conf.FG_TARGET_GAP;
54721
+ }
54722
+ getActiveNodeIds() {
54723
+ const all6 = new Set;
54724
+ for (const { nodeIds } of this.activeComponents.values()) {
54725
+ for (const id of nodeIds)
54726
+ all6.add(id);
54727
+ }
54728
+ return all6;
54639
54729
  }
54640
54730
  getNodes() {
54641
54731
  return this.board.items.listAll().filter((item) => !EXCLUDED_TYPES.has(item.itemType) && !item.transformation.isLocked);
@@ -54645,8 +54735,10 @@ class ForceGraphEngine {
54645
54735
  }
54646
54736
  tick() {
54647
54737
  const dt = this.TICK_MS / 1000;
54648
- const nodes = this.getNodes();
54649
- if (nodes.length < 2)
54738
+ const activeIds = this.getActiveNodeIds();
54739
+ const allNodes = this.getNodes();
54740
+ const nodes = allNodes.filter((item) => activeIds.has(item.getId()));
54741
+ if (nodes.length < 1)
54650
54742
  return;
54651
54743
  const snapMap = new Map;
54652
54744
  for (const item of nodes) {
@@ -54687,7 +54779,9 @@ class ForceGraphEngine {
54687
54779
  const dx = s2.cx - s1.cx;
54688
54780
  const dy = s2.cy - s1.cy;
54689
54781
  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;
54782
+ const compId = this.findComponentId(s1.id);
54783
+ const targetGap = compId ? this.activeComponents.get(compId)?.targetGap ?? conf.FG_TARGET_GAP : conf.FG_TARGET_GAP;
54784
+ const targetDist = (Math.max(s1.w, s1.h) + Math.max(s2.w, s2.h)) * 0.5 + targetGap;
54691
54785
  const stretch = dist - targetDist;
54692
54786
  const forceMag = stretch * conf.FG_SPRING_K;
54693
54787
  const fx = dx / dist * forceMag;
@@ -54705,10 +54799,13 @@ class ForceGraphEngine {
54705
54799
  continue;
54706
54800
  const dx = s2.cx - s1.cx;
54707
54801
  const dy = s2.cy - s1.cy;
54708
- const distSq = dx * dx + dy * dy + this.SOFTENING_SQ;
54709
- const repMag = conf.FG_REPULSION / distSq;
54710
- const fx = dx * repMag;
54711
- const fy = dy * repMag;
54802
+ const centerDist = Math.sqrt(dx * dx + dy * dy) + 0.001;
54803
+ const r1 = Math.max(s1.w, s1.h) * 0.5;
54804
+ const r2 = Math.max(s2.w, s2.h) * 0.5;
54805
+ const edgeDist = Math.max(centerDist - r1 - r2, 1);
54806
+ const repMag = conf.FG_REPULSION / (edgeDist * edgeDist + this.SOFTENING_SQ);
54807
+ const fx = dx / centerDist * repMag;
54808
+ const fy = dy / centerDist * repMag;
54712
54809
  ax.set(s1.id, (ax.get(s1.id) ?? 0) - fx);
54713
54810
  ay.set(s1.id, (ay.get(s1.id) ?? 0) - fy);
54714
54811
  ax.set(s2.id, (ax.get(s2.id) ?? 0) + fx);
@@ -54745,7 +54842,8 @@ class ForceGraphEngine {
54745
54842
  }
54746
54843
  }
54747
54844
  syncPositions() {
54748
- const nodes = this.getNodes();
54845
+ const activeIds = this.getActiveNodeIds();
54846
+ const nodes = this.getNodes().filter((item) => activeIds.has(item.getId()));
54749
54847
  if (nodes.length === 0)
54750
54848
  return;
54751
54849
  const movedItems = nodes.map((item) => {
@@ -54769,11 +54867,6 @@ class ForceGraphEngine {
54769
54867
  };
54770
54868
  this.board.events.emit(operation);
54771
54869
  }
54772
- wake() {
54773
- if (this.tickTimer === null && this.syncTimer !== null) {
54774
- this.tickTimer = setInterval(() => this.tick(), this.TICK_MS);
54775
- }
54776
- }
54777
54870
  }
54778
54871
 
54779
54872
  // src/Board.ts
@@ -55849,20 +55942,22 @@ class Board {
55849
55942
  return this.gravity !== null;
55850
55943
  }
55851
55944
  forceGraph = null;
55852
- enableForceGraph() {
55853
- if (this.forceGraph)
55854
- return;
55855
- this.forceGraph = new ForceGraphEngine(this);
55856
- this.forceGraph.start();
55945
+ enableForceGraph(nodeId) {
55946
+ if (!this.forceGraph) {
55947
+ this.forceGraph = new ForceGraphEngine(this);
55948
+ }
55949
+ this.forceGraph.enableForGraph(nodeId);
55857
55950
  }
55858
- disableForceGraph() {
55951
+ disableForceGraph(nodeId) {
55859
55952
  if (!this.forceGraph)
55860
55953
  return;
55861
- this.forceGraph.stop();
55862
- this.forceGraph = null;
55954
+ this.forceGraph.disableForGraph(nodeId);
55955
+ if (!this.forceGraph.hasActiveComponents()) {
55956
+ this.forceGraph = null;
55957
+ }
55863
55958
  }
55864
- isForceGraphEnabled() {
55865
- return this.forceGraph !== null;
55959
+ isNodeInForceGraph(nodeId) {
55960
+ return this.forceGraph?.isNodeInActiveGraph(nodeId) ?? false;
55866
55961
  }
55867
55962
  wakeForceGraph() {
55868
55963
  this.forceGraph?.wake();