@antv/layout 2.0.0-beta.0 → 2.0.0-beta.2

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 (114) hide show
  1. package/dist/index.js +322 -222
  2. package/dist/index.js.map +1 -1
  3. package/dist/index.min.js +2 -2
  4. package/dist/index.min.js.map +1 -1
  5. package/dist/worker.js +2 -2
  6. package/dist/worker.js.map +1 -1
  7. package/lib/algorithm/antv-dagre/index.js +8 -7
  8. package/lib/algorithm/antv-dagre/index.js.map +1 -1
  9. package/lib/algorithm/antv-dagre/rank/index.js +1 -1
  10. package/lib/algorithm/antv-dagre/types.d.ts +3 -14
  11. package/lib/algorithm/circular/index.js +8 -7
  12. package/lib/algorithm/circular/index.js.map +1 -1
  13. package/lib/algorithm/circular/types.d.ts +0 -16
  14. package/lib/algorithm/combo-combined/index.js +9 -7
  15. package/lib/algorithm/combo-combined/index.js.map +1 -1
  16. package/lib/algorithm/combo-combined/types.d.ts +6 -18
  17. package/lib/algorithm/concentric/index.js +10 -16
  18. package/lib/algorithm/concentric/index.js.map +1 -1
  19. package/lib/algorithm/concentric/types.d.ts +3 -17
  20. package/lib/algorithm/d3-force/index.js +16 -12
  21. package/lib/algorithm/d3-force/index.js.map +1 -1
  22. package/lib/algorithm/d3-force/types.d.ts +10 -24
  23. package/lib/algorithm/d3-force-3d/index.js +1 -1
  24. package/lib/algorithm/d3-force-3d/index.js.map +1 -1
  25. package/lib/algorithm/d3-force-3d/types.d.ts +5 -4
  26. package/lib/algorithm/dagre/index.js +10 -7
  27. package/lib/algorithm/dagre/index.js.map +1 -1
  28. package/lib/algorithm/dagre/types.d.ts +8 -14
  29. package/lib/algorithm/force/index.d.ts +1 -1
  30. package/lib/algorithm/force/index.js +56 -44
  31. package/lib/algorithm/force/index.js.map +1 -1
  32. package/lib/algorithm/force/types.d.ts +39 -36
  33. package/lib/algorithm/force-atlas2/index.d.ts +1 -1
  34. package/lib/algorithm/force-atlas2/index.js +8 -7
  35. package/lib/algorithm/force-atlas2/index.js.map +1 -1
  36. package/lib/algorithm/force-atlas2/types.d.ts +0 -14
  37. package/lib/algorithm/fruchterman/index.d.ts +1 -1
  38. package/lib/algorithm/fruchterman/index.js +8 -10
  39. package/lib/algorithm/fruchterman/index.js.map +1 -1
  40. package/lib/algorithm/fruchterman/simulation.js +2 -1
  41. package/lib/algorithm/fruchterman/simulation.js.map +1 -1
  42. package/lib/algorithm/fruchterman/types.d.ts +2 -1
  43. package/lib/algorithm/grid/index.d.ts +1 -1
  44. package/lib/algorithm/grid/index.js +29 -34
  45. package/lib/algorithm/grid/index.js.map +1 -1
  46. package/lib/algorithm/grid/types.d.ts +5 -24
  47. package/lib/algorithm/mds/index.js +1 -0
  48. package/lib/algorithm/mds/index.js.map +1 -1
  49. package/lib/algorithm/radial/index.js +8 -5
  50. package/lib/algorithm/radial/index.js.map +1 -1
  51. package/lib/algorithm/radial/radial-nonoverlap-force.js +2 -4
  52. package/lib/algorithm/radial/radial-nonoverlap-force.js.map +1 -1
  53. package/lib/algorithm/radial/types.d.ts +3 -16
  54. package/lib/algorithm/random/index.js +1 -0
  55. package/lib/algorithm/random/index.js.map +1 -1
  56. package/lib/algorithm/types.d.ts +16 -0
  57. package/lib/index.d.ts +7 -5
  58. package/lib/index.js +3 -1
  59. package/lib/index.js.map +1 -1
  60. package/lib/node_modules/@antv/expr/dist/index.esm.js +4 -0
  61. package/lib/node_modules/@antv/expr/dist/index.esm.js.map +1 -0
  62. package/lib/runtime/supervisor.js +26 -12
  63. package/lib/runtime/supervisor.js.map +1 -1
  64. package/lib/types/common.d.ts +17 -1
  65. package/lib/types/data.d.ts +1 -1
  66. package/lib/util/expr.d.ts +12 -0
  67. package/lib/util/expr.js +26 -0
  68. package/lib/util/expr.js.map +1 -0
  69. package/lib/util/format.d.ts +37 -0
  70. package/lib/util/format.js +61 -17
  71. package/lib/util/format.js.map +1 -1
  72. package/lib/util/order.d.ts +3 -4
  73. package/lib/util/order.js.map +1 -1
  74. package/lib/util/size.d.ts +2 -1
  75. package/lib/util/size.js +9 -1
  76. package/lib/util/size.js.map +1 -1
  77. package/lib/worker.js +309 -239
  78. package/lib/worker.js.map +1 -1
  79. package/package.json +2 -1
  80. package/src/algorithm/antv-dagre/index.ts +15 -12
  81. package/src/algorithm/antv-dagre/types.ts +3 -14
  82. package/src/algorithm/circular/index.ts +5 -4
  83. package/src/algorithm/circular/types.ts +0 -15
  84. package/src/algorithm/combo-combined/index.ts +21 -17
  85. package/src/algorithm/combo-combined/types.ts +6 -21
  86. package/src/algorithm/concentric/index.ts +18 -16
  87. package/src/algorithm/concentric/types.ts +2 -16
  88. package/src/algorithm/d3-force/index.ts +25 -18
  89. package/src/algorithm/d3-force/types.ts +9 -22
  90. package/src/algorithm/d3-force-3d/index.ts +1 -1
  91. package/src/algorithm/d3-force-3d/types.ts +5 -0
  92. package/src/algorithm/dagre/index.ts +9 -7
  93. package/src/algorithm/dagre/types.ts +7 -15
  94. package/src/algorithm/force/index.ts +64 -40
  95. package/src/algorithm/force/types.ts +76 -45
  96. package/src/algorithm/force-atlas2/index.ts +13 -15
  97. package/src/algorithm/force-atlas2/types.ts +0 -12
  98. package/src/algorithm/fruchterman/index.ts +7 -15
  99. package/src/algorithm/fruchterman/simulation.ts +2 -2
  100. package/src/algorithm/fruchterman/types.ts +5 -2
  101. package/src/algorithm/grid/index.ts +45 -46
  102. package/src/algorithm/grid/types.ts +6 -35
  103. package/src/algorithm/radial/index.ts +14 -6
  104. package/src/algorithm/radial/radial-nonoverlap-force.ts +11 -6
  105. package/src/algorithm/radial/types.ts +2 -15
  106. package/src/algorithm/types.ts +18 -0
  107. package/src/runtime/supervisor.ts +26 -11
  108. package/src/types/common.ts +22 -0
  109. package/src/types/data.ts +1 -1
  110. package/src/util/expr.ts +26 -0
  111. package/src/util/format.ts +71 -27
  112. package/src/util/index.ts +2 -0
  113. package/src/util/order.ts +3 -9
  114. package/src/util/size.ts +8 -0
package/dist/index.js CHANGED
@@ -4,7 +4,6 @@
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Layout = {}));
5
5
  })(this, (function (exports) { 'use strict';
6
6
 
7
- var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
8
7
  /******************************************************************************
9
8
  Copyright (c) Microsoft Corporation.
10
9
 
@@ -377,6 +376,156 @@
377
376
  }
378
377
  }
379
378
 
379
+ const e={abs:Math.abs,ceil:Math.ceil,floor:Math.floor,max:Math.max,min:Math.min,round:Math.round,sqrt:Math.sqrt,pow:Math.pow};class n extends Error{constructor(e,t,n){super(e),this.position=t,this.token=n,this.name="ExpressionError";}}var r;!function(e){e[e.STRING=0]="STRING",e[e.NUMBER=1]="NUMBER",e[e.BOOLEAN=2]="BOOLEAN",e[e.NULL=3]="NULL",e[e.IDENTIFIER=4]="IDENTIFIER",e[e.OPERATOR=5]="OPERATOR",e[e.FUNCTION=6]="FUNCTION",e[e.DOT=7]="DOT",e[e.BRACKET_LEFT=8]="BRACKET_LEFT",e[e.BRACKET_RIGHT=9]="BRACKET_RIGHT",e[e.PAREN_LEFT=10]="PAREN_LEFT",e[e.PAREN_RIGHT=11]="PAREN_RIGHT",e[e.COMMA=12]="COMMA",e[e.QUESTION=13]="QUESTION",e[e.COLON=14]="COLON",e[e.DOLLAR=15]="DOLLAR";}(r||(r={}));const o=new Set([32,9,10,13]),a$2=new Set([43,45,42,47,37,33,38,124,61,60,62]),s=new Map([["true",r.BOOLEAN],["false",r.BOOLEAN],["null",r.NULL]]),i=new Map([["===",true],["!==",true],["<=",true],[">=",true],["&&",true],["||",true],["+",true],["-",true],["*",true],["/",true],["%",true],["!",true],["<",true],[">",true]]),u=new Map([[46,r.DOT],[91,r.BRACKET_LEFT],[93,r.BRACKET_RIGHT],[40,r.PAREN_LEFT],[41,r.PAREN_RIGHT],[44,r.COMMA],[63,r.QUESTION],[58,r.COLON],[36,r.DOLLAR]]),c$2=new Map;for(const[e,t]of u.entries())c$2.set(e,{type:t,value:String.fromCharCode(e)});function p(e){return e>=48&&e<=57}function l(e){return e>=97&&e<=122||e>=65&&e<=90||95===e}function f(e){return l(e)||p(e)}function E(e){return a$2.has(e)}var h;!function(e){e[e.Program=0]="Program",e[e.Literal=1]="Literal",e[e.Identifier=2]="Identifier",e[e.MemberExpression=3]="MemberExpression",e[e.CallExpression=4]="CallExpression",e[e.BinaryExpression=5]="BinaryExpression",e[e.UnaryExpression=6]="UnaryExpression",e[e.ConditionalExpression=7]="ConditionalExpression";}(h||(h={}));const d=new Map([["||",2],["&&",3],["===",4],["!==",4],[">",5],[">=",5],["<",5],["<=",5],["+",6],["-",6],["*",7],["/",7],["%",7],["!",8]]),R={type:h.Literal,value:null},T={type:h.Literal,value:true},w={type:h.Literal,value:false},y$4=e=>{let t=0;const o=e.length,a=()=>t>=o?null:e[t],s=()=>e[t++],i=e=>{const t=a();return null!==t&&t.type===e},u=e=>e.type===r.OPERATOR?d.get(e.value)||-1:e.type===r.DOT||e.type===r.BRACKET_LEFT?9:e.type===r.QUESTION?1:-1,c=e=>{let o,u;if(s().type===r.DOT){if(!i(r.IDENTIFIER)){const e=a();throw new n("Expected property name",t,e?e.value:"<end of input>")}const e=s();o={type:h.Identifier,name:e.value},u=false;}else {if(o=l(0),!i(r.BRACKET_RIGHT)){const e=a();throw new n("Expected closing bracket",t,e?e.value:"<end of input>")}s(),u=true;}return {type:h.MemberExpression,object:e,property:o,computed:u}},p=()=>{const e=a();if(!e)throw new n("Unexpected end of input",t,"<end of input>");if(e.type===r.OPERATOR&&("!"===e.value||"-"===e.value)){s();const t=p();return {type:h.UnaryExpression,operator:e.value,argument:t,prefix:true}}switch(e.type){case r.NUMBER:return s(),{type:h.Literal,value:Number(e.value)};case r.STRING:return s(),{type:h.Literal,value:e.value};case r.BOOLEAN:return s(),"true"===e.value?T:w;case r.NULL:return s(),R;case r.IDENTIFIER:return s(),{type:h.Identifier,name:e.value};case r.FUNCTION:return (()=>{const e=s(),o=[];if(!i(r.PAREN_LEFT)){const e=a();throw new n("Expected opening parenthesis after function name",t,e?e.value:"<end of input>")}for(s();;){if(i(r.PAREN_RIGHT)){s();break}if(!a()){const e=a();throw new n("Expected closing parenthesis",t,e?e.value:"<end of input>")}if(o.length>0){if(!i(r.COMMA)){const e=a();throw new n("Expected comma between function arguments",t,e?e.value:"<end of input>")}s();}const e=l(0);o.push(e);}return {type:h.CallExpression,callee:{type:h.Identifier,name:e.value},arguments:o}})();case r.PAREN_LEFT:{s();const e=l(0);if(!i(r.PAREN_RIGHT)){const e=a();throw new n("Expected closing parenthesis",t,e?e.value:"<end of input>")}return s(),e}default:throw new n(`Unexpected token: ${e.type}`,t,e.value)}},l=(f=0)=>{let E=p();for(;t<o;){const o=e[t],p=u(o);if(p<=f)break;if(o.type!==r.QUESTION)if(o.type!==r.OPERATOR){if(o.type!==r.DOT&&o.type!==r.BRACKET_LEFT)break;E=c(E);}else {s();const e=l(p);E={type:h.BinaryExpression,operator:o.value,left:E,right:e};}else {s();const e=l(0);if(!i(r.COLON)){const e=a();throw new n("Expected : in conditional expression",t,e?e.value:"<end of input>")}s();const o=l(0);E={type:h.ConditionalExpression,test:E,consequent:e,alternate:o};}}return E},f=l();return {type:h.Program,body:f}},O=(e,t,r)=>{let o=t;r&&(o={...t,context:{...t.context,...r}});const a=e=>{switch(e.type){case h.Literal:return (e=>e.value)(e);case h.Identifier:return (e=>{if(!(e.name in o.context))throw new n(`Undefined variable: ${e.name}`);return o.context[e.name]})(e);case h.MemberExpression:return (e=>{const t=a(e.object);if(null==t)throw new n("Cannot access property of null or undefined");return t[e.computed?a(e.property):e.property.name]})(e);case h.CallExpression:return (e=>{const t=o.functions[e.callee.name];if(!t)throw new n(`Undefined function: ${e.callee.name}`);return t(...e.arguments.map((e=>a(e))))})(e);case h.BinaryExpression:return (e=>{if("&&"===e.operator){const t=a(e.left);return t?a(e.right):t}if("||"===e.operator){return a(e.left)||a(e.right)}const t=a(e.left),r=a(e.right);switch(e.operator){case "+":return t+r;case "-":return t-r;case "*":return t*r;case "/":return t/r;case "%":return t%r;case "===":return t===r;case "!==":return t!==r;case ">":return t>r;case ">=":return t>=r;case "<":return t<r;case "<=":return t<=r;default:throw new n(`Unknown operator: ${e.operator}`)}})(e);case h.UnaryExpression:return (e=>{const t=a(e.argument);if(e.prefix)switch(e.operator){case "!":return !t;case "-":if("number"!=typeof t)throw new n(`Cannot apply unary - to non-number: ${t}`);return -t;default:throw new n(`Unknown operator: ${e.operator}`)}throw new n(`Postfix operators are not supported: ${e.operator}`)})(e);case h.ConditionalExpression:return (e=>{const t=a(e.test);return a(t?e.consequent:e.alternate)})(e);default:throw new n(`Evaluation error: Unsupported node type: ${e.type}`)}};return a(e.body)};function A(t){const a=(e=>{const t=e,a=t.length,u=new Array(Math.ceil(a/3));let h=0,d=0;function R(e){const o=d+1;d++;let s="",i=false;for(;d<a;){const n=t.charCodeAt(d);if(n===e)return i||(s=t.substring(o,d)),d++,{type:r.STRING,value:s};92===n?(i||(s=t.substring(o,d),i=true),d++,s+=t[d]):i&&(s+=t[d]),d++;}throw new n(`Unterminated string starting with ${String.fromCharCode(e)}`,d,t.substring(Math.max(0,d-10),d))}function T(){const e=d;for(45===t.charCodeAt(d)&&d++;d<a&&p(t.charCodeAt(d));)d++;if(d<a&&46===t.charCodeAt(d))for(d++;d<a&&p(t.charCodeAt(d));)d++;const n=t.slice(e,d);return {type:r.NUMBER,value:n}}function w(){d++;const e=d;if(d<a&&l(t.charCodeAt(d)))for(d++;d<a&&f(t.charCodeAt(d));)d++;const n=t.slice(e,d);return {type:r.FUNCTION,value:n}}function y(){const e=d++;for(;d<a&&f(t.charCodeAt(d));)d++;const n=t.slice(e,d),o=s.get(n);return o?{type:o,value:n}:{type:r.IDENTIFIER,value:n}}function O(){if(d+2<a){const e=t.substring(d,d+3);if(i.has(e))return d+=3,{type:r.OPERATOR,value:e}}if(d+1<a){const e=t.substring(d,d+2);if(i.has(e))return d+=2,{type:r.OPERATOR,value:e}}const e=t[d];if(i.has(e))return d++,{type:r.OPERATOR,value:e};throw new n(`Unknown operator at position ${d}: ${t.substring(d,d+1)}`,d,t.substring(Math.max(0,d-10),d))}for(;d<a;){const e=t.charCodeAt(d);if(A=e,o.has(A)){d++;continue}const r=c$2.get(e);if(r)u[h++]=r,d++;else if(34!==e&&39!==e)if(p(e)||45===e&&d+1<a&&p(t.charCodeAt(d+1)))u[h++]=T();else if(64!==e)if(l(e))u[h++]=y();else {if(!E(e))throw new n(`Unexpected character: ${t[d]}`,d,t.substring(Math.max(0,d-10),d));u[h++]=O();}else u[h++]=w();else u[h++]=R(e);}var A;return h===u.length?u:u.slice(0,h)})(t),u=y$4(a),h=((e={},t={})=>({context:e,functions:t}))({},e);return (e={})=>O(u,h,e)}function N(e,t={}){return A(e)(t)}
380
+
381
+ /**
382
+ * Evaluate an expression if (and only if) it's a valid string expression.
383
+ * - Returns `undefined` when `expression` is not a string, empty, or invalid.
384
+ *
385
+ * @example
386
+ * evaluateExpression('x + y', { x: 10, y: 20 }) // 30
387
+ */
388
+ function evaluateExpression(expression, context) {
389
+ if (typeof expression !== 'string')
390
+ return undefined;
391
+ const source = expression.trim();
392
+ if (!source)
393
+ return undefined;
394
+ try {
395
+ A(source);
396
+ return N(source, context);
397
+ }
398
+ catch (_a) {
399
+ return undefined;
400
+ }
401
+ }
402
+
403
+ function parseSize(size) {
404
+ if (!size)
405
+ return [0, 0, 0];
406
+ if (isNumber(size))
407
+ return [size, size, size];
408
+ else if (Array.isArray(size) && size.length === 0)
409
+ return [0, 0, 0];
410
+ const [x, y = x, z = x] = size;
411
+ return [x, y, z];
412
+ }
413
+ function isSize(value) {
414
+ if (isNumber(value))
415
+ return true;
416
+ if (Array.isArray(value)) {
417
+ return value.every((item) => isNumber(item));
418
+ }
419
+ return false;
420
+ }
421
+
422
+ /**
423
+ * Format a value into a callable function when it is a string expression.
424
+ * - `string` => `(context) => evaluateExpression(string, context)`
425
+ * - `function` => returned as-is
426
+ * - other => returned as-is
427
+ */
428
+ function formatFn(value, argNames) {
429
+ if (typeof value === 'function')
430
+ return value;
431
+ if (typeof value === 'string') {
432
+ const expr = value;
433
+ return (...argv) => {
434
+ const ctx = {};
435
+ for (let i = 0; i < argNames.length; i++) {
436
+ ctx[argNames[i]] = argv[i];
437
+ }
438
+ return evaluateExpression(expr, ctx);
439
+ };
440
+ }
441
+ return () => value;
442
+ }
443
+ /**
444
+ * Format value with multiple types into a function that returns a number
445
+ * @param value The value to be formatted
446
+ * @param defaultValue The default value when value is invalid
447
+ * @returns A function that returns a number
448
+ */
449
+ function formatNumberFn(value, defaultValue, type = 'node') {
450
+ // If value is undefined, return default value function
451
+ if (isNil(value)) {
452
+ return () => defaultValue;
453
+ }
454
+ // If value is an expression, return a function that evaluates the expression
455
+ if (isString(value)) {
456
+ const numberFn = formatFn(value, [type]);
457
+ return (d) => {
458
+ const evaluated = numberFn(d);
459
+ if (isNumber(evaluated))
460
+ return evaluated;
461
+ return defaultValue;
462
+ };
463
+ }
464
+ // If value is a function, return it directly
465
+ if (isFunction(value)) {
466
+ return value;
467
+ }
468
+ // If value is a number, return a function that returns this number
469
+ if (isNumber(value)) {
470
+ return () => value;
471
+ }
472
+ // For other cases (undefined or invalid values), return default value function
473
+ return () => defaultValue;
474
+ }
475
+ /**
476
+ * Format size config with multiple types into a function that returns a size
477
+ * @param value The value to be formatted
478
+ * @param defaultValue The default value when value is invalid
479
+ * @param resultIsNumber Whether to return a number (max of width/height) or size array
480
+ * @returns A function that returns a size
481
+ */
482
+ function formatSizeFn(value, defaultValue = 10, type = 'node') {
483
+ // If value is undefined, return default value function
484
+ if (isNil(value)) {
485
+ return () => defaultValue;
486
+ }
487
+ // If value is an expression, return a function that evaluates the expression
488
+ if (isString(value)) {
489
+ const sizeFn = formatFn(value, [type]);
490
+ return (d) => {
491
+ const evaluated = sizeFn(d);
492
+ if (isSize(evaluated))
493
+ return evaluated;
494
+ return defaultValue;
495
+ };
496
+ }
497
+ // If value is a function, return it directly
498
+ if (isFunction(value)) {
499
+ return value;
500
+ }
501
+ // If value is a number, return a function that returns this number
502
+ if (isNumber(value)) {
503
+ return () => value;
504
+ }
505
+ // If value is an array, return max or the array itself
506
+ if (Array.isArray(value)) {
507
+ return () => value;
508
+ }
509
+ return () => defaultValue;
510
+ }
511
+ /**
512
+ * Format nodeSize and nodeSpacing into a function that returns the total size
513
+ * @param nodeSize The size of the node
514
+ * @param nodeSpacing The spacing around the node
515
+ * @param defaultNodeSize The default node size when value is invalid
516
+ * @param defaultNodeSpacing The default node spacing when value is invalid
517
+ * @returns A function that returns the total size (node size + spacing)
518
+ */
519
+ const formatNodeSizeFn = (nodeSize, nodeSpacing, defaultNodeSize = 10, defaultNodeSpacing = 0) => {
520
+ const nodeSpacingFunc = formatSizeFn(nodeSpacing, defaultNodeSpacing);
521
+ const nodeSizeFunc = formatSizeFn(nodeSize, defaultNodeSize);
522
+ return (d) => {
523
+ const [sizeW, sizeH, sizeD] = parseSize(nodeSizeFunc(d));
524
+ const [spacingW, spacingH, spacingD] = parseSize(nodeSpacingFunc(d));
525
+ return [sizeW + spacingW, sizeH + spacingH, sizeD + spacingD];
526
+ };
527
+ };
528
+
380
529
  /**
381
530
  * Floyd-Warshall algorithm to find shortest paths (but with no negative cycles).
382
531
  */
@@ -800,17 +949,6 @@
800
949
  return { x: point[0], y: point[1], z: (_a = point[2]) !== null && _a !== void 0 ? _a : 0 };
801
950
  }
802
951
 
803
- function parseSize(size) {
804
- if (!size)
805
- return [0, 0, 0];
806
- if (isNumber(size))
807
- return [size, size, size];
808
- else if (Array.isArray(size) && size.length === 0)
809
- return [0, 0, 0];
810
- const [x, y = x, z = x] = size;
811
- return [x, y, z];
812
- }
813
-
814
952
  /**
815
953
  * Viewport configuration such as width, height and center point.
816
954
  */
@@ -826,71 +964,6 @@
826
964
  };
827
965
  };
828
966
 
829
- /**
830
- * Format value with multiple types into a function that returns a number
831
- * @param value The value to be formatted
832
- * @param defaultValue The default value when value is invalid
833
- * @returns A function that returns a number
834
- */
835
- function formatNumberFn(value, defaultValue) {
836
- // If value is a function, return it directly
837
- if (isFunction(value)) {
838
- return value;
839
- }
840
- // If value is a number, return a function that returns this number
841
- if (isNumber(value)) {
842
- return () => value;
843
- }
844
- // For other cases (undefined or invalid values), return default value function
845
- return () => defaultValue;
846
- }
847
- /**
848
- * Format size config with multiple types into a function that returns a size
849
- * @param value The value to be formatted
850
- * @param defaultValue The default value when value is invalid
851
- * @param resultIsNumber Whether to return a number (max of width/height) or size array
852
- * @returns A function that returns a size
853
- */
854
- function formatSizeFn(value, defaultValue = 10) {
855
- // If value is undefined, return default value function
856
- if (!value) {
857
- return () => defaultValue;
858
- }
859
- // If value is a function, return it directly
860
- if (isFunction(value)) {
861
- return value;
862
- }
863
- // If value is a number, return a function that returns this number
864
- if (isNumber(value)) {
865
- return () => value;
866
- }
867
- // If value is an array, return max or the array itself
868
- if (Array.isArray(value)) {
869
- return () => value;
870
- }
871
- // If value is an object with width and height
872
- if (isObject$1(value) && value.width && value.height) {
873
- return () => [value.width, value.height];
874
- }
875
- return () => defaultValue;
876
- }
877
- /**
878
- * Format nodeSize and nodeSpacing into a function that returns the total size
879
- * @param nodeSize The size of the node
880
- * @param nodeSpacing The spacing around the node
881
- * @param defaultNodeSize The default node size when value is invalid
882
- * @returns A function that returns the total size (node size + spacing)
883
- */
884
- const formatNodeSizeFn = (nodeSize, nodeSpacing, defaultNodeSize = 10) => {
885
- const nodeSpacingFunc = formatNumberFn(nodeSpacing, 0);
886
- const nodeSizeFunc = formatSizeFn(nodeSize, defaultNodeSize);
887
- return (node) => {
888
- const size = nodeSizeFunc(node);
889
- const spacing = nodeSpacingFunc(node);
890
- return Math.max(...parseSize(size)) + spacing;
891
- };
892
- };
893
-
894
967
  class GraphLib {
895
968
  constructor(data, options = {}) {
896
969
  this.edgeIdCounter = new Map();
@@ -1590,23 +1663,37 @@
1590
1663
  * Resolve worker script path which works in both ESM and UMD environments
1591
1664
  */
1592
1665
  resolveWorkerPath() {
1593
- if (typeof ({ url: (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)) }) !== 'undefined' && (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href))) {
1594
- const currentUrl = new URL((typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)));
1595
- // e.g. `.../lib/runtime/supervisor.js` -> `.../lib/worker.js`
1596
- const asRoot = currentUrl.href.replace(/\/runtime\/[^/]+\.js$/, '/worker.js');
1597
- if (asRoot !== currentUrl.href)
1598
- return asRoot;
1599
- // Fallback: keep legacy behavior (same directory)
1600
- return currentUrl.href.replace(/\/[^/]+\.js$/, '/worker.js');
1601
- }
1602
- if (typeof document !== 'undefined') {
1666
+ const scriptUrl = (() => {
1667
+ if (typeof document === 'undefined')
1668
+ return null;
1669
+ const currentScript = document.currentScript;
1670
+ if (currentScript === null || currentScript === void 0 ? void 0 : currentScript.src)
1671
+ return currentScript.src;
1603
1672
  const scripts = document.getElementsByTagName('script');
1604
1673
  for (let i = scripts.length - 1; i >= 0; i--) {
1605
1674
  const src = scripts[i].src;
1606
- if (src && (src.includes('index.js') || src.includes('index.min.js'))) {
1607
- return src.replace(/index(\.min)?\.js/, 'worker.js');
1675
+ if (!src)
1676
+ continue;
1677
+ if (src.includes('index.js') || src.includes('index.min.js')) {
1678
+ return src;
1608
1679
  }
1609
1680
  }
1681
+ return null;
1682
+ })();
1683
+ if (scriptUrl) {
1684
+ if (scriptUrl.includes('index.js') || scriptUrl.includes('index.min.js')) {
1685
+ const asIndex = scriptUrl.replace(/index(\.min)?\.(m?js)(\?.*)?$/, 'worker.js');
1686
+ if (asIndex !== scriptUrl)
1687
+ return asIndex;
1688
+ }
1689
+ // e.g. `.../lib/runtime/supervisor.js` -> `.../lib/worker.js`
1690
+ const asRoot = scriptUrl.replace(/\/runtime\/[^/]+\.(m?js)(\?.*)?$/, '/worker.js');
1691
+ if (asRoot !== scriptUrl)
1692
+ return asRoot;
1693
+ // Fallback: keep legacy behavior (same directory)
1694
+ const asSibling = scriptUrl.replace(/\/[^/]+\.(m?js)(\?.*)?$/, '/worker.js');
1695
+ if (asSibling !== scriptUrl)
1696
+ return asSibling;
1610
1697
  }
1611
1698
  return './worker.js';
1612
1699
  }
@@ -5108,6 +5195,7 @@
5108
5195
 
5109
5196
  const DEFAULTS_LAYOUT_OPTIONS$8 = {
5110
5197
  nodeSize: 10,
5198
+ nodeSpacing: 0,
5111
5199
  rankdir: 'TB',
5112
5200
  nodesep: 50,
5113
5201
  ranksep: 50,
@@ -5132,27 +5220,27 @@
5132
5220
  }
5133
5221
  layout(options) {
5134
5222
  return __awaiter(this, void 0, void 0, function* () {
5135
- const { nodeSize, align, rankdir = 'TB', ranksep, nodesep, edgeLabelSpace, ranker = 'tight-tree', nodeOrder, begin, controlPoints, radial, sortByCombo,
5223
+ const { nodeSize, nodeSpacing, align, rankdir = 'TB', ranksep, nodesep, edgeLabelSpace, ranker = 'tight-tree', nodeOrder, begin, controlPoints, radial, sortByCombo,
5136
5224
  // focusNode,
5137
5225
  preset, ranksepFunc, nodesepFunc, } = options;
5138
- const ranksepfunc = formatNumberFn(ranksepFunc, ranksep !== null && ranksep !== void 0 ? ranksep : 50);
5139
- const nodesepfunc = formatNumberFn(nodesepFunc, nodesep !== null && nodesep !== void 0 ? nodesep : 50);
5226
+ const ranksepfunc = formatNumberFn(ranksepFunc, ranksep !== null && ranksep !== void 0 ? ranksep : 50, 'node');
5227
+ const nodesepfunc = formatNumberFn(nodesepFunc, nodesep !== null && nodesep !== void 0 ? nodesep : 50, 'node');
5140
5228
  let horisep = nodesepfunc;
5141
5229
  let vertisep = ranksepfunc;
5142
5230
  if (rankdir === 'LR' || rankdir === 'RL') {
5143
5231
  horisep = ranksepfunc;
5144
5232
  vertisep = nodesepfunc;
5145
5233
  }
5146
- const nodeSizeFunc = formatSizeFn(nodeSize, DEFAULTS_LAYOUT_OPTIONS$8.nodeSize);
5147
5234
  // Create internal graph
5148
5235
  const g = new DagreGraph({ tree: [] });
5149
5236
  // copy graph to g
5150
5237
  const nodes = this.model.nodes();
5151
5238
  const edges = this.model.edges();
5239
+ const sizeFn = formatNodeSizeFn(nodeSize, nodeSpacing, DEFAULTS_LAYOUT_OPTIONS$8.nodeSize, DEFAULTS_LAYOUT_OPTIONS$8.nodeSpacing);
5152
5240
  nodes.forEach((node) => {
5153
5241
  var _a;
5154
5242
  const raw = node._original;
5155
- const size = parseSize(nodeSizeFunc(raw));
5243
+ const size = sizeFn(raw);
5156
5244
  const verti = vertisep(raw);
5157
5245
  const hori = horisep(raw);
5158
5246
  const width = size[0] + 2 * hori;
@@ -5434,7 +5522,7 @@
5434
5522
  return controlPoints;
5435
5523
  };
5436
5524
 
5437
- const DEFAULT_LAYOUT_OPTIONS = {
5525
+ const DEFAULT_LAYOUT_OPTIONS$1 = {
5438
5526
  radius: null,
5439
5527
  startRadius: null,
5440
5528
  endRadius: null,
@@ -5445,6 +5533,7 @@
5445
5533
  ordering: null,
5446
5534
  angleRatio: 1,
5447
5535
  nodeSize: 10,
5536
+ nodeSpacing: 0,
5448
5537
  };
5449
5538
  /**
5450
5539
  * <zh/> 环形布局
@@ -5457,7 +5546,7 @@
5457
5546
  this.id = 'circular';
5458
5547
  }
5459
5548
  getDefaultOptions() {
5460
- return DEFAULT_LAYOUT_OPTIONS;
5549
+ return DEFAULT_LAYOUT_OPTIONS$1;
5461
5550
  }
5462
5551
  layout() {
5463
5552
  return __awaiter(this, void 0, void 0, function* () {
@@ -5483,11 +5572,11 @@
5483
5572
  }
5484
5573
  let { radius, startRadius, endRadius } = this.options;
5485
5574
  const nodes = this.model.nodes();
5486
- const format = formatNodeSizeFn(nodeSize, nodeSpacing, DEFAULT_LAYOUT_OPTIONS.nodeSize);
5487
- if (!isNil(nodeSpacing)) {
5575
+ const sizeFn = formatNodeSizeFn(nodeSize, nodeSpacing, DEFAULT_LAYOUT_OPTIONS$1.nodeSize, DEFAULT_LAYOUT_OPTIONS$1.nodeSpacing);
5576
+ if (nodeSpacing) {
5488
5577
  let perimeter = 0;
5489
5578
  for (const node of nodes) {
5490
- perimeter += format(node._original);
5579
+ perimeter += Math.max(...sizeFn(node._original));
5491
5580
  }
5492
5581
  radius = perimeter / (2 * Math.PI);
5493
5582
  }
@@ -5564,17 +5653,10 @@
5564
5653
  applySingleNodeLayout(this.model, center);
5565
5654
  return;
5566
5655
  }
5567
- const { sortBy: propsSortBy, maxLevelDiff: propsMaxLevelDiff, sweep: propsSweep, clockwise, equidistant, preventOverlap, startAngle = DEFAULTS_LAYOUT_OPTIONS$7.startAngle, nodeSize = DEFAULTS_LAYOUT_OPTIONS$7.nodeSize, nodeSpacing, } = this.options;
5568
- let sortBy = propsSortBy;
5569
- if (propsSortBy && typeof propsSortBy === 'function') {
5570
- const testNode = this.model.firstNode();
5571
- const testValue = propsSortBy(testNode._original);
5572
- if (typeof testValue !== 'number')
5573
- sortBy = 'degree';
5574
- }
5575
- else {
5576
- sortBy = 'degree';
5577
- }
5656
+ const { sortBy: propsSortBy, maxLevelDiff: propsMaxLevelDiff, sweep: propsSweep, clockwise, equidistant, preventOverlap, startAngle = DEFAULTS_LAYOUT_OPTIONS$7.startAngle, nodeSize, nodeSpacing, } = this.options;
5657
+ const sortBy = !propsSortBy || propsSortBy === 'degree'
5658
+ ? 'degree'
5659
+ : formatFn(propsSortBy, ['node']);
5578
5660
  if (sortBy === 'degree') {
5579
5661
  orderByDegree(this.model);
5580
5662
  }
@@ -5591,15 +5673,15 @@
5591
5673
  for (const node of nodes) {
5592
5674
  const v = sortBy === 'degree'
5593
5675
  ? this.model.degree(node.id)
5594
- : sortBy === null || sortBy === void 0 ? void 0 : sortBy(node._original);
5676
+ : sortBy(node._original);
5595
5677
  sortKeys.set(node.id, v);
5596
5678
  }
5597
5679
  const maxValueNode = this.model.firstNode();
5598
5680
  const maxLevelDiff = propsMaxLevelDiff || sortKeys.get(maxValueNode.id) / 4;
5599
- const nodeSizeFn = formatNodeSizeFn(nodeSize, nodeSpacing);
5681
+ const sizeFn = formatNodeSizeFn(nodeSize, nodeSpacing, DEFAULTS_LAYOUT_OPTIONS$7.nodeSize, DEFAULTS_LAYOUT_OPTIONS$7.nodeSpacing);
5600
5682
  const nodeDistances = new Map();
5601
5683
  for (const node of nodes) {
5602
- nodeDistances.set(node.id, nodeSizeFn(node._original));
5684
+ nodeDistances.set(node.id, Math.max(...sizeFn(node._original)));
5603
5685
  }
5604
5686
  // put the values into levels
5605
5687
  const levels = [{ nodes: [] }];
@@ -7325,9 +7407,7 @@
7325
7407
  }
7326
7408
 
7327
7409
  const DEFAULTS_LAYOUT_OPTIONS$6 = {
7328
- link: {
7329
- id: (d) => String(d.id),
7330
- },
7410
+ edgeId: 'edge.id',
7331
7411
  manyBody: {
7332
7412
  strength: -30,
7333
7413
  },
@@ -7582,7 +7662,9 @@
7582
7662
  if (options.manyBody === false)
7583
7663
  return undefined;
7584
7664
  return assignDefined({}, options.manyBody || {}, {
7585
- strength: options.nodeStrength,
7665
+ strength: options.nodeStrength
7666
+ ? formatFn(options.nodeStrength, ['node'])
7667
+ : undefined,
7586
7668
  distanceMin: options.distanceMin,
7587
7669
  distanceMax: options.distanceMax,
7588
7670
  theta: options.theta,
@@ -7615,9 +7697,13 @@
7615
7697
  if (options.link === false)
7616
7698
  return undefined;
7617
7699
  return assignDefined({}, options.link || {}, {
7618
- id: options.edgeId,
7619
- distance: options.linkDistance,
7620
- strength: options.edgeStrength,
7700
+ id: options.edgeId ? formatFn(options.edgeId, ['edge']) : undefined,
7701
+ distance: options.linkDistance
7702
+ ? formatFn(options.linkDistance, ['edge'])
7703
+ : undefined,
7704
+ strength: options.edgeStrength
7705
+ ? formatFn(options.edgeStrength, ['edge'])
7706
+ : undefined,
7621
7707
  iterations: options.edgeIterations,
7622
7708
  });
7623
7709
  }
@@ -7649,9 +7735,8 @@
7649
7735
  if (options.preventOverlap === false &&
7650
7736
  (options.collide === false || options.collide === undefined))
7651
7737
  return undefined;
7652
- const radius = options.nodeSize || options.nodeSpacing
7653
- ? (d) => formatNodeSizeFn(options.nodeSize, options.nodeSpacing)(d._original) / 2
7654
- : undefined;
7738
+ const sizeFn = formatNodeSizeFn(options.nodeSize, options.nodeSpacing, DEFAULTS_LAYOUT_OPTIONS$6.nodeSize, DEFAULTS_LAYOUT_OPTIONS$6.nodeSpacing);
7739
+ const radius = (d) => Math.max(...sizeFn(d._original)) / 2;
7655
7740
  return assignDefined({}, options.collide || {}, {
7656
7741
  radius: (options.collide && options.collide.radius) || radius,
7657
7742
  strength: options.collideStrength,
@@ -7792,7 +7877,7 @@
7792
7877
  ['centerY', center && center.y],
7793
7878
  ['template', 'force'],
7794
7879
  ['strength', clusterFociStrength],
7795
- ['groupBy', clusterBy],
7880
+ ['groupBy', clusterBy ? formatFn(clusterBy, ['node']) : undefined],
7796
7881
  ['nodes', this.model.nodes()],
7797
7882
  ['links', this.model.edges()],
7798
7883
  ['forceLinkDistance', clusterEdgeDistance],
@@ -9524,7 +9609,7 @@
9524
9609
  return {
9525
9610
  numDimensions: 3,
9526
9611
  link: {
9527
- id: (edge) => String(edge.id),
9612
+ id: (edge) => edge.id,
9528
9613
  },
9529
9614
  manyBody: {},
9530
9615
  center: {
@@ -23305,11 +23390,13 @@
23305
23390
  }
23306
23391
  });
23307
23392
  const { edgeLabelSize, edgeLabelOffset, edgeLabelPos, edgeMinLen, edgeWeight, } = this.options;
23308
- const edgeLabelSizeFn = formatSizeFn(edgeLabelSize, 0);
23309
- const edgeLabelOffsetFn = formatNumberFn(edgeLabelOffset, 10);
23310
- const edgeLabelPosFn = typeof edgeLabelPos === 'function' ? edgeLabelPos : () => edgeLabelPos;
23311
- const edgeMinLenFn = formatNumberFn(edgeMinLen, 1);
23312
- const edgeWeightFn = formatNumberFn(edgeWeight, 1);
23393
+ const edgeLabelSizeFn = formatSizeFn(edgeLabelSize, 0, 'edge');
23394
+ const edgeLabelOffsetFn = formatNumberFn(edgeLabelOffset, 10, 'edge');
23395
+ const edgeLabelPosFn = typeof edgeLabelPos === 'string'
23396
+ ? () => edgeLabelPos
23397
+ : formatFn(edgeLabelPos, ['edge']);
23398
+ const edgeMinLenFn = formatNumberFn(edgeMinLen, 1, 'edge');
23399
+ const edgeWeightFn = formatNumberFn(edgeWeight, 1, 'edge');
23313
23400
  this.model.forEachEdge((edge) => {
23314
23401
  const raw = edge._original;
23315
23402
  const [lw, lh] = parseSize(edgeLabelSizeFn(raw));
@@ -24359,28 +24446,43 @@
24359
24446
  */
24360
24447
  parseOptions(options) {
24361
24448
  const _ = Object.assign(Object.assign({}, options), normalizeViewport(options));
24449
+ // Format nodeClusterBy (for clustering / leafCluster)
24450
+ if (_.nodeClusterBy) {
24451
+ _.nodeClusterBy = formatFn(_.nodeClusterBy, ['node']);
24452
+ }
24362
24453
  // Format node mass
24363
24454
  if (!options.getMass) {
24364
- _.getMass = (d) => {
24365
- if (!d)
24455
+ _.getMass = (node) => {
24456
+ if (!node)
24366
24457
  return 1;
24367
24458
  const massWeight = 1;
24368
- const degree = this.model.degree(d.id, 'both');
24459
+ const degree = this.model.degree(node.id, 'both');
24369
24460
  return !degree || degree < 5 ? massWeight : degree * 5 * massWeight;
24370
24461
  };
24371
24462
  }
24463
+ else {
24464
+ _.getMass = formatNumberFn(options.getMass, 1);
24465
+ }
24466
+ // Format per-node center force callback
24467
+ if (options.getCenter) {
24468
+ const params = ['node', 'degree'];
24469
+ _.getCenter = formatFn(options.getCenter, params);
24470
+ }
24372
24471
  // Format node size
24373
- _.nodeSize = formatNodeSizeFn(options.nodeSize, options.nodeSpacing);
24472
+ const nodeSizeVec = formatNodeSizeFn(options.nodeSize, options.nodeSpacing);
24473
+ _.nodeSize = (node) => {
24474
+ if (!node)
24475
+ return 0;
24476
+ const [w, h, z] = nodeSizeVec(node);
24477
+ return Math.max(w, h, z);
24478
+ };
24374
24479
  // Format node / edge strengths
24375
24480
  _.linkDistance = options.linkDistance
24376
- ? formatNumberFn(options.linkDistance, 1)
24377
- : (edge) => {
24378
- return (1 +
24379
- _.nodeSize(this.model.node(edge.source)._original) +
24380
- _.nodeSize(this.model.node(edge.target)._original));
24381
- };
24481
+ ? formatFn(options.linkDistance, ['edge', 'source', 'target'])
24482
+ : (_, source, target) => 1 + _.nodeSize(source) + _.nodeSize(target);
24382
24483
  _.nodeStrength = formatNumberFn(options.nodeStrength, 1);
24383
- _.edgeStrength = formatNumberFn(options.edgeStrength, 1);
24484
+ _.edgeStrength = formatNumberFn(options.edgeStrength, 1, 'edge');
24485
+ _.clusterNodeStrength = formatNumberFn(options.clusterNodeStrength, 1);
24384
24486
  // Format centripetal options
24385
24487
  this.formatCentripetal(_);
24386
24488
  return _;
@@ -24389,23 +24491,30 @@
24389
24491
  * Format centripetal options
24390
24492
  */
24391
24493
  formatCentripetal(options) {
24392
- var _a;
24393
- const { dimensions, centripetalOptions, center, clusterNodeStrength, leafCluster, clustering, nodeClusterBy, } = options;
24394
- // Basic centripetal settings
24395
- const basicCentripetal = centripetalOptions || {
24396
- leaf: 2,
24397
- single: 2,
24398
- others: 1,
24399
- center: (_) => {
24400
- return {
24401
- x: center[0],
24402
- y: center[1],
24403
- z: dimensions === 3 ? center[2] : undefined,
24404
- };
24405
- },
24406
- };
24407
- if (typeof clusterNodeStrength !== 'function') {
24408
- options.clusterNodeStrength = () => clusterNodeStrength;
24494
+ var _a, _b;
24495
+ const { dimensions, centripetalOptions, center, leafCluster, clustering, nodeClusterBy, } = options;
24496
+ const leafParams = ['node', 'nodes', 'edges'];
24497
+ const leafFn = formatFn(centripetalOptions === null || centripetalOptions === void 0 ? void 0 : centripetalOptions.leaf, leafParams);
24498
+ const singleFn = formatNumberFn(centripetalOptions === null || centripetalOptions === void 0 ? void 0 : centripetalOptions.single, 2);
24499
+ const othersFn = formatNumberFn(centripetalOptions === null || centripetalOptions === void 0 ? void 0 : centripetalOptions.others, 1);
24500
+ const centerRaw = (_a = centripetalOptions === null || centripetalOptions === void 0 ? void 0 : centripetalOptions.center) !== null && _a !== void 0 ? _a : ((_) => {
24501
+ return {
24502
+ x: center[0],
24503
+ y: center[1],
24504
+ z: dimensions === 3 ? center[2] : undefined,
24505
+ };
24506
+ });
24507
+ const centerFn = formatFn(centerRaw, [
24508
+ 'node',
24509
+ 'nodes',
24510
+ 'edges',
24511
+ 'width',
24512
+ 'height',
24513
+ ]);
24514
+ const basicCentripetal = Object.assign(Object.assign({}, centripetalOptions), { leaf: leafFn, single: singleFn, others: othersFn, center: centerFn });
24515
+ // If user provided centripetalOptions, normalize them even without clustering modes.
24516
+ if (centripetalOptions) {
24517
+ options.centripetalOptions = basicCentripetal;
24409
24518
  }
24410
24519
  let sameTypeLeafMap;
24411
24520
  let clusters;
@@ -24413,8 +24522,8 @@
24413
24522
  if (leafCluster && nodeClusterBy) {
24414
24523
  sameTypeLeafMap = this.getSameTypeLeafMap(nodeClusterBy);
24415
24524
  clusters =
24416
- Array.from(new Set((_a = this.model
24417
- .nodes()) === null || _a === void 0 ? void 0 : _a.map((node) => nodeClusterBy(node._original)))) || [];
24525
+ Array.from(new Set((_b = this.model
24526
+ .nodes()) === null || _b === void 0 ? void 0 : _b.map((node) => nodeClusterBy(node._original)))) || [];
24418
24527
  options.centripetalOptions = Object.assign({}, basicCentripetal, {
24419
24528
  single: () => 100,
24420
24529
  leaf: (node) => {
@@ -24487,17 +24596,6 @@
24487
24596
  },
24488
24597
  });
24489
24598
  }
24490
- // Normalize functions
24491
- const { leaf, single, others } = options.centripetalOptions || {};
24492
- if (leaf && typeof leaf !== 'function') {
24493
- options.centripetalOptions.leaf = () => leaf;
24494
- }
24495
- if (single && typeof single !== 'function') {
24496
- options.centripetalOptions.single = () => single;
24497
- }
24498
- if (others && typeof others !== 'function') {
24499
- options.centripetalOptions.others = () => others;
24500
- }
24501
24599
  }
24502
24600
  /**
24503
24601
  * Get same type leaf map for clustering
@@ -25333,9 +25431,9 @@
25333
25431
  }
25334
25432
  getSizes(nodeSize, nodeSpacing) {
25335
25433
  const result = {};
25434
+ const nodeSizeFn = formatNodeSizeFn(nodeSize, nodeSpacing, DEFAULTS_LAYOUT_OPTIONS$4.nodeSize, DEFAULTS_LAYOUT_OPTIONS$4.nodeSpacing);
25336
25435
  this.model.forEachNode((node) => {
25337
- const nodeSizeFn = formatNodeSizeFn(nodeSize, nodeSpacing);
25338
- result[node.id] = nodeSizeFn(node._original);
25436
+ result[node.id] = Math.max(...nodeSizeFn(node._original));
25339
25437
  });
25340
25438
  return result;
25341
25439
  }
@@ -25347,7 +25445,7 @@
25347
25445
  return this.simulation;
25348
25446
  }
25349
25447
  parseOptions(options = {}) {
25350
- const { barnesHut, prune, maxIteration, kr, kg, nodeSize, nodeSpacing } = options;
25448
+ const { barnesHut, prune, maxIteration, kr, kg } = options;
25351
25449
  const auto = {};
25352
25450
  const n = this.model.nodeCount();
25353
25451
  if (barnesHut === undefined && n > 250)
@@ -25382,7 +25480,7 @@
25382
25480
  else if (n > 500)
25383
25481
  auto.kg = 1;
25384
25482
  }
25385
- return Object.assign(Object.assign(Object.assign(Object.assign({}, options), auto), normalizeViewport(options)), { nodeSize: formatSizeFn(nodeSize, DEFAULTS_LAYOUT_OPTIONS$4.nodeSize), nodeSpacing: formatNumberFn(nodeSpacing, DEFAULTS_LAYOUT_OPTIONS$4.nodeSpacing) });
25483
+ return Object.assign(Object.assign(Object.assign({}, options), auto), normalizeViewport(options));
25386
25484
  }
25387
25485
  stop() {
25388
25486
  var _a;
@@ -25767,7 +25865,7 @@
25767
25865
  clusterGravity: 10,
25768
25866
  width: 300,
25769
25867
  height: 300,
25770
- nodeClusterBy: 'data.cluster',
25868
+ nodeClusterBy: 'node.cluster',
25771
25869
  dimensions: 2,
25772
25870
  };
25773
25871
  class FruchtermanLayout extends BaseLayoutWithIterations {
@@ -25779,15 +25877,12 @@
25779
25877
  getDefaultOptions() {
25780
25878
  return DEFAULTS_LAYOUT_OPTIONS$3;
25781
25879
  }
25782
- parseOptions(options) {
25880
+ parseOptions(options = {}) {
25783
25881
  const { clustering, nodeClusterBy } = this.options;
25784
25882
  const clusteringEnabled = clustering && !!nodeClusterBy;
25785
- const nodeClusterByFunc = typeof nodeClusterBy === 'string'
25786
- ? (node) => getNestedValue(node, nodeClusterBy)
25787
- : nodeClusterBy;
25788
- Object.assign((options || (options = {})), normalizeViewport(options), {
25883
+ Object.assign(options, normalizeViewport(options), {
25789
25884
  clustering: clusteringEnabled,
25790
- nodeClusterBy: nodeClusterByFunc,
25885
+ nodeClusterBy: formatFn(nodeClusterBy, ['node']),
25791
25886
  });
25792
25887
  return options;
25793
25888
  }
@@ -25842,6 +25937,19 @@
25842
25937
  }
25843
25938
  }
25844
25939
 
25940
+ const DEFAULT_LAYOUT_OPTIONS = {
25941
+ begin: [0, 0],
25942
+ preventOverlap: true,
25943
+ condense: false,
25944
+ rows: undefined,
25945
+ cols: undefined,
25946
+ position: undefined,
25947
+ sortBy: 'degree',
25948
+ nodeSize: 30,
25949
+ nodeSpacing: 10,
25950
+ width: 300,
25951
+ height: 300,
25952
+ };
25845
25953
  /**
25846
25954
  * <zh/> 网格布局
25847
25955
  *
@@ -25853,23 +25961,10 @@
25853
25961
  this.id = 'grid';
25854
25962
  }
25855
25963
  getDefaultOptions() {
25856
- return {
25857
- begin: [0, 0],
25858
- preventOverlap: true,
25859
- preventOverlapPadding: 10,
25860
- condense: false,
25861
- rows: undefined,
25862
- cols: undefined,
25863
- position: undefined,
25864
- sortBy: 'degree',
25865
- nodeSize: 30,
25866
- width: 300,
25867
- height: 300,
25868
- };
25964
+ return DEFAULT_LAYOUT_OPTIONS;
25869
25965
  }
25870
- normalizeOptions(options = {}, model) {
25871
- var _a;
25872
- const { rows: propRows, cols: propCols } = options;
25966
+ parseOptions(options = {}, model) {
25967
+ const { rows: propRows, cols: propCols, position: propPosition, sortBy: propSortBy, } = options;
25873
25968
  const { width, height, center } = normalizeViewport(options);
25874
25969
  let rows = options.rows;
25875
25970
  let cols = options.cols;
@@ -25924,20 +26019,20 @@
25924
26019
  }
25925
26020
  }
25926
26021
  }
25927
- const preventOverlap = options.preventOverlap || options.nodeSpacing !== undefined;
25928
- const nodeSpacing = formatNumberFn(options.nodeSpacing, 10);
25929
- const nodeSize = formatSizeFn(options.nodeSize, 30);
25930
- return Object.assign(Object.assign({}, options), { begin: options.begin || [0, 0], sortBy: options.sortBy || 'degree', preventOverlapPadding: (_a = options.preventOverlapPadding) !== null && _a !== void 0 ? _a : 0, preventOverlap,
25931
- nodeSpacing,
25932
- nodeSize,
26022
+ const sortBy = !propSortBy
26023
+ ? DEFAULT_LAYOUT_OPTIONS.sortBy
26024
+ : propSortBy === 'degree' || propSortBy === 'id'
26025
+ ? propSortBy
26026
+ : formatFn(propSortBy, ['nodeA', 'nodeB']);
26027
+ return Object.assign(Object.assign({}, options), { sortBy,
25933
26028
  rcs,
25934
26029
  center,
25935
26030
  width,
25936
- height });
26031
+ height, position: formatFn(propPosition, ['node']) });
25937
26032
  }
25938
26033
  layout() {
25939
26034
  return __awaiter(this, void 0, void 0, function* () {
25940
- const { begin, rcs, sortBy, width, height, condense, preventOverlapPadding, preventOverlap, nodeSpacing, nodeSize, position, } = this.normalizeOptions(this.options, this.model);
26035
+ const { begin, rcs, sortBy, width, height, condense, preventOverlap, nodeSpacing, nodeSize, position, } = this.parseOptions(this.options, this.model);
25941
26036
  const n = this.model.nodeCount();
25942
26037
  if (!n || n === 1) {
25943
26038
  applySingleNodeLayout(this.model, begin);
@@ -25955,14 +26050,9 @@
25955
26050
  let cellWidth = condense ? 0 : width / rcs.cols;
25956
26051
  let cellHeight = condense ? 0 : height / rcs.rows;
25957
26052
  if (preventOverlap) {
26053
+ const sizeFn = formatNodeSizeFn(nodeSize, nodeSpacing, DEFAULT_LAYOUT_OPTIONS.nodeSize, DEFAULT_LAYOUT_OPTIONS.nodeSpacing);
25958
26054
  this.model.forEachNode((node) => {
25959
- const nodeData = node._original;
25960
- const [nodeW, nodeH] = parseSize(nodeSize(nodeData) || 30);
25961
- const p = nodeSpacing !== undefined
25962
- ? nodeSpacing(nodeData)
25963
- : preventOverlapPadding;
25964
- const w = nodeW + p;
25965
- const h = nodeH + p;
26055
+ const [w, h] = sizeFn(node._original);
25966
26056
  cellWidth = Math.max(cellWidth, w);
25967
26057
  cellHeight = Math.max(cellHeight, h);
25968
26058
  });
@@ -32045,8 +32135,8 @@ ${indent}columns: ${matrix.columns}
32045
32135
  vecx = 0.01 * sign;
32046
32136
  vecy = 0.01 * sign;
32047
32137
  }
32048
- const nodeSizeU = Math.max(...parseSize(nodeSizeFunc(nodeU._original)));
32049
- const nodeSizeV = Math.max(...parseSize(nodeSizeFunc(nodeV._original)));
32138
+ const nodeSizeU = Math.max(...nodeSizeFunc(nodeU._original));
32139
+ const nodeSizeV = Math.max(...nodeSizeFunc(nodeV._original));
32050
32140
  // these two nodes overlap
32051
32141
  if (vecLength < nodeSizeV / 2 + nodeSizeU / 2) {
32052
32142
  const common = (k * k) / vecLength;
@@ -32129,6 +32219,8 @@ ${indent}columns: ${matrix.columns}
32129
32219
  sortStrength: 10,
32130
32220
  strictRadial: true,
32131
32221
  unitRadius: null,
32222
+ nodeSize: 10,
32223
+ nodeSpacing: 0,
32132
32224
  };
32133
32225
  /**
32134
32226
  * <zh/> 径向布局
@@ -32197,7 +32289,7 @@ ${indent}columns: ${matrix.columns}
32197
32289
  });
32198
32290
  // stagger the overlapped nodes
32199
32291
  if (preventOverlap) {
32200
- const nodeSizeFunc = formatNodeSizeFn(nodeSize, nodeSpacing);
32292
+ const nodeSizeFunc = formatNodeSizeFn(nodeSize, nodeSpacing, DEFAULTS_LAYOUT_OPTIONS.nodeSize, DEFAULTS_LAYOUT_OPTIONS.nodeSpacing);
32201
32293
  const nonoverlapForceParams = {
32202
32294
  nodeSizeFunc,
32203
32295
  radiiMap,
@@ -32276,7 +32368,7 @@ ${indent}columns: ${matrix.columns}
32276
32368
  radiusScale[i] = radii[i] / unitRadius;
32277
32369
  const baseLink = (linkDistance + unitRadius) / 2;
32278
32370
  const sortCache = new Map();
32279
- const sortFn = typeof sortBy === 'function' ? sortBy : null;
32371
+ const sortFn = !sortBy || sortBy === 'data' ? null : formatFn(sortBy, ['node']);
32280
32372
  const isDataSort = sortBy === 'data';
32281
32373
  for (let i = 0; i < n; i++) {
32282
32374
  const row = distances[i];
@@ -32573,7 +32665,9 @@ ${indent}columns: ${matrix.columns}
32573
32665
  });
32574
32666
  }
32575
32667
  getLayoutConfig(combo) {
32576
- const { layout } = this.options;
32668
+ const layout = typeof this.options.layout === 'object'
32669
+ ? this.options.layout
32670
+ : formatFn(this.options.layout, ['comboId']);
32577
32671
  if (typeof layout === 'function') {
32578
32672
  const comboId = combo.id === ROOT_ID ? null : combo.id;
32579
32673
  return this.normalizeLayoutConfig(layout(comboId));
@@ -32581,7 +32675,7 @@ ${indent}columns: ${matrix.columns}
32581
32675
  return this.normalizeLayoutConfig(layout);
32582
32676
  }
32583
32677
  normalizeLayoutConfig(config) {
32584
- const base = Object.assign(Object.assign({ type: 'concentric' }, normalizeViewport(this.options)), { nodeSize: (d) => d.size, nodeSpacing: 0 });
32678
+ const base = Object.assign(Object.assign({ type: 'concentric' }, normalizeViewport(this.options)), { nodeSize: 'node.size', nodeSpacing: 0 });
32585
32679
  if (!config)
32586
32680
  return base;
32587
32681
  if (typeof config === 'string')
@@ -32668,7 +32762,7 @@ ${indent}columns: ${matrix.columns}
32668
32762
  if (!Number.isFinite(minX) || !Number.isFinite(minY)) {
32669
32763
  return { center: [0, 0], width: 0, height: 0 };
32670
32764
  }
32671
- const comboPaddingFn = formatNumberFn(this.options.comboPadding, 20);
32765
+ const comboPaddingFn = formatNumberFn(this.options.comboPadding, 20, 'combo');
32672
32766
  const padding = comboPaddingFn(combo._original);
32673
32767
  return {
32674
32768
  center: [(minX + maxX) / 2, (minY + maxY) / 2],
@@ -32684,10 +32778,10 @@ ${indent}columns: ${matrix.columns}
32684
32778
  getNodeSize(node, includeSpacing = true) {
32685
32779
  const { nodeSize, nodeSpacing } = this.options;
32686
32780
  const sizeFn = formatNodeSizeFn(nodeSize, includeSpacing ? nodeSpacing : 0);
32687
- return parseSize(sizeFn(node._original));
32781
+ return sizeFn(node._original);
32688
32782
  }
32689
32783
  getComboSize(combo, includeSpacing = true) {
32690
- const comboSpacingFn = formatNumberFn(this.options.comboSpacing, 0);
32784
+ const comboSpacingFn = formatNumberFn(this.options.comboSpacing, 0, 'combo');
32691
32785
  const spacing = includeSpacing ? comboSpacingFn(combo._original) : 0;
32692
32786
  const [width, height] = combo.size;
32693
32787
  return [width + spacing / 2, height + spacing / 2, 0];
@@ -32749,7 +32843,12 @@ ${indent}columns: ${matrix.columns}
32749
32843
  exports.Supervisor = Supervisor;
32750
32844
  exports.applySingleNodeLayout = applySingleNodeLayout;
32751
32845
  exports.assignDefined = assignDefined;
32846
+ exports.evaluateExpression = evaluateExpression;
32752
32847
  exports.floydWarshall = floydWarshall;
32848
+ exports.formatFn = formatFn;
32849
+ exports.formatNodeSizeFn = formatNodeSizeFn;
32850
+ exports.formatNumberFn = formatNumberFn;
32851
+ exports.formatSizeFn = formatSizeFn;
32753
32852
  exports.getAdjList = getAdjList;
32754
32853
  exports.getAdjMatrix = getAdjMatrix;
32755
32854
  exports.getEuclideanDistance = getEuclideanDistance;
@@ -32759,6 +32858,7 @@ ${indent}columns: ${matrix.columns}
32759
32858
  exports.initNodePosition = initNodePosition;
32760
32859
  exports.isArray = isArray;
32761
32860
  exports.isLayoutWithIterations = isLayoutWithIterations;
32861
+ exports.isSize = isSize;
32762
32862
  exports.johnson = johnson;
32763
32863
  exports.normalizeViewport = normalizeViewport;
32764
32864
  exports.orderByDegree = orderByDegree;