@modernrelay/orbit-core 0.16.0 → 0.17.0

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.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { DIAGNOSTIC_SAMPLE_CAP, resolveSimulation, encodeStringTable, collectTransfers, deriveClusters, resolveClusterCenters, clusterCentroids, EnvelopeSequencer, RequestLedger } from './chunk-DCY66QZS.js';
2
- export { DEFAULT_CLUSTER_CENTER_RADIUS, DEFAULT_LAYOUT_SEED, DIAGNOSTIC_SAMPLE_CAP, SIMULATION_PRESETS, acceptColumnar, clusterCentroids, collectTransfers, decodeStringTable, deriveClusters, encodeStringTable, generateClusterCenters, judgeEpoch, resolveClusterCenters, resolveSimulation } from './chunk-DCY66QZS.js';
1
+ import { DIAGNOSTIC_SAMPLE_CAP, resolveSimulation, encodeStringTable, collectTransfers, deriveClusters, resolveClusterCenters, clusterCentroids, EnvelopeSequencer, RequestLedger } from './chunk-IOC3RWQY.js';
2
+ export { DEFAULT_CLUSTER_CENTER_RADIUS, DEFAULT_LAYOUT_SEED, DIAGNOSTIC_SAMPLE_CAP, SIMULATION_PRESETS, acceptColumnar, clusterCentroids, collectTransfers, decodeStringTable, deriveClusters, encodeStringTable, generateClusterCenters, judgeEpoch, resolveClusterCenters, resolveSimulation } from './chunk-IOC3RWQY.js';
3
3
  import { createStore } from 'zustand/vanilla';
4
4
 
5
5
  // src/errors.ts
@@ -2471,6 +2471,61 @@ function selectLabelCandidates(args) {
2471
2471
  }
2472
2472
  return degreeOf !== void 0 ? degreeOf(i) : 0;
2473
2473
  };
2474
+ const declutter = config.overlap !== "allow" && project !== void 0;
2475
+ const configuredPad = config.overlapPadding ?? 2;
2476
+ const pad = Number.isFinite(configuredPad) ? Math.max(0, configuredPad) : 2;
2477
+ const CELL = 64;
2478
+ const CHAR_W = 7;
2479
+ const BOX_H = 18;
2480
+ const keptBoxes = [];
2481
+ const cells = /* @__PURE__ */ new Map();
2482
+ const cellKey = (cx, cy) => cx * 100003 + cy;
2483
+ const boxOf = (i, text) => {
2484
+ const x = positions[2 * i];
2485
+ const y = positions[2 * i + 1];
2486
+ if (x === void 0 || y === void 0 || Number.isNaN(x) || Number.isNaN(y)) return null;
2487
+ const sPt = project([x, y]);
2488
+ if (sPt === null) return null;
2489
+ const w = CHAR_W * text.length + 8 + 2 * pad;
2490
+ const h = BOX_H + 2 * pad;
2491
+ return [sPt[0] - w / 2, sPt[1] - h / 2, sPt[0] + w / 2, sPt[1] + h / 2];
2492
+ };
2493
+ const collides = (b) => {
2494
+ const cx0 = Math.floor(b[0] / CELL);
2495
+ const cy0 = Math.floor(b[1] / CELL);
2496
+ const cx1 = Math.floor(b[2] / CELL);
2497
+ const cy1 = Math.floor(b[3] / CELL);
2498
+ for (let cx = cx0; cx <= cx1; cx++) {
2499
+ for (let cy = cy0; cy <= cy1; cy++) {
2500
+ const bucket = cells.get(cellKey(cx, cy));
2501
+ if (bucket === void 0) continue;
2502
+ for (const q of bucket) {
2503
+ const x0 = keptBoxes[q];
2504
+ const y0 = keptBoxes[q + 1];
2505
+ const x1 = keptBoxes[q + 2];
2506
+ const y1 = keptBoxes[q + 3];
2507
+ if (b[0] < x1 && b[2] > x0 && b[1] < y1 && b[3] > y0) return true;
2508
+ }
2509
+ }
2510
+ }
2511
+ return false;
2512
+ };
2513
+ const claim = (b) => {
2514
+ const q = keptBoxes.length;
2515
+ keptBoxes.push(b[0], b[1], b[2], b[3]);
2516
+ const cx0 = Math.floor(b[0] / CELL);
2517
+ const cy0 = Math.floor(b[1] / CELL);
2518
+ const cx1 = Math.floor(b[2] / CELL);
2519
+ const cy1 = Math.floor(b[3] / CELL);
2520
+ for (let cx = cx0; cx <= cx1; cx++) {
2521
+ for (let cy = cy0; cy <= cy1; cy++) {
2522
+ const key = cellKey(cx, cy);
2523
+ const bucket = cells.get(key);
2524
+ if (bucket === void 0) cells.set(key, [q]);
2525
+ else bucket.push(q);
2526
+ }
2527
+ }
2528
+ };
2474
2529
  const out = [];
2475
2530
  const chosen = /* @__PURE__ */ new Set();
2476
2531
  let overloadCount = 0;
@@ -2489,7 +2544,12 @@ function selectLabelCandidates(args) {
2489
2544
  for (let j = 0; j < take; j++) {
2490
2545
  const i = forcedIdx[j];
2491
2546
  chosen.add(i);
2492
- out.push({ id: scene.idByIndex[i], text: textOf(i), forced: true });
2547
+ const text = textOf(i);
2548
+ if (declutter) {
2549
+ const b = boxOf(i, text);
2550
+ if (b !== null) claim(b);
2551
+ }
2552
+ out.push({ id: scene.idByIndex[i], text, forced: true });
2493
2553
  }
2494
2554
  }
2495
2555
  if (aboveLod && out.length < k) {
@@ -2499,10 +2559,17 @@ function selectLabelCandidates(args) {
2499
2559
  ranked.push({ i, w: weightOf(i) });
2500
2560
  }
2501
2561
  ranked.sort((a, b) => b.w - a.w || a.i - b.i);
2502
- const need = k - out.length;
2503
- for (let j = 0; j < need && j < ranked.length; j++) {
2562
+ for (let j = 0; j < ranked.length && out.length < k; j++) {
2504
2563
  const i = ranked[j].i;
2505
- out.push({ id: scene.idByIndex[i], text: textOf(i), forced: false });
2564
+ const text = textOf(i);
2565
+ if (declutter) {
2566
+ const b = boxOf(i, text);
2567
+ if (b !== null) {
2568
+ if (collides(b)) continue;
2569
+ claim(b);
2570
+ }
2571
+ }
2572
+ out.push({ id: scene.idByIndex[i], text, forced: false });
2506
2573
  }
2507
2574
  }
2508
2575
  return { placements: out, overloadCount };