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

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 (110) hide show
  1. package/dist/index.js +296 -209
  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 +1 -1
  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/types.d.ts +3 -14
  10. package/lib/algorithm/circular/index.js +8 -7
  11. package/lib/algorithm/circular/index.js.map +1 -1
  12. package/lib/algorithm/circular/types.d.ts +0 -16
  13. package/lib/algorithm/combo-combined/index.js +9 -7
  14. package/lib/algorithm/combo-combined/index.js.map +1 -1
  15. package/lib/algorithm/combo-combined/types.d.ts +6 -18
  16. package/lib/algorithm/concentric/index.js +10 -16
  17. package/lib/algorithm/concentric/index.js.map +1 -1
  18. package/lib/algorithm/concentric/types.d.ts +3 -17
  19. package/lib/algorithm/d3-force/index.js +16 -12
  20. package/lib/algorithm/d3-force/index.js.map +1 -1
  21. package/lib/algorithm/d3-force/types.d.ts +10 -24
  22. package/lib/algorithm/d3-force-3d/index.js +1 -1
  23. package/lib/algorithm/d3-force-3d/index.js.map +1 -1
  24. package/lib/algorithm/d3-force-3d/types.d.ts +5 -4
  25. package/lib/algorithm/dagre/index.js +10 -7
  26. package/lib/algorithm/dagre/index.js.map +1 -1
  27. package/lib/algorithm/dagre/types.d.ts +8 -14
  28. package/lib/algorithm/force/index.d.ts +1 -1
  29. package/lib/algorithm/force/index.js +56 -44
  30. package/lib/algorithm/force/index.js.map +1 -1
  31. package/lib/algorithm/force/types.d.ts +39 -36
  32. package/lib/algorithm/force-atlas2/index.d.ts +1 -1
  33. package/lib/algorithm/force-atlas2/index.js +8 -7
  34. package/lib/algorithm/force-atlas2/index.js.map +1 -1
  35. package/lib/algorithm/force-atlas2/types.d.ts +0 -14
  36. package/lib/algorithm/fruchterman/index.d.ts +1 -1
  37. package/lib/algorithm/fruchterman/index.js +8 -10
  38. package/lib/algorithm/fruchterman/index.js.map +1 -1
  39. package/lib/algorithm/fruchterman/simulation.js +2 -1
  40. package/lib/algorithm/fruchterman/simulation.js.map +1 -1
  41. package/lib/algorithm/fruchterman/types.d.ts +2 -1
  42. package/lib/algorithm/grid/index.d.ts +1 -1
  43. package/lib/algorithm/grid/index.js +29 -34
  44. package/lib/algorithm/grid/index.js.map +1 -1
  45. package/lib/algorithm/grid/types.d.ts +5 -24
  46. package/lib/algorithm/mds/index.js +1 -0
  47. package/lib/algorithm/mds/index.js.map +1 -1
  48. package/lib/algorithm/radial/index.js +8 -5
  49. package/lib/algorithm/radial/index.js.map +1 -1
  50. package/lib/algorithm/radial/radial-nonoverlap-force.js +2 -4
  51. package/lib/algorithm/radial/radial-nonoverlap-force.js.map +1 -1
  52. package/lib/algorithm/radial/types.d.ts +3 -16
  53. package/lib/algorithm/random/index.js +1 -0
  54. package/lib/algorithm/random/index.js.map +1 -1
  55. package/lib/algorithm/types.d.ts +16 -0
  56. package/lib/index.d.ts +5 -3
  57. package/lib/index.js +3 -1
  58. package/lib/index.js.map +1 -1
  59. package/lib/node_modules/@antv/expr/dist/index.esm.js +4 -0
  60. package/lib/node_modules/@antv/expr/dist/index.esm.js.map +1 -0
  61. package/lib/types/common.d.ts +17 -1
  62. package/lib/types/data.d.ts +1 -1
  63. package/lib/util/expr.d.ts +12 -0
  64. package/lib/util/expr.js +26 -0
  65. package/lib/util/expr.js.map +1 -0
  66. package/lib/util/format.d.ts +37 -0
  67. package/lib/util/format.js +61 -17
  68. package/lib/util/format.js.map +1 -1
  69. package/lib/util/order.d.ts +3 -4
  70. package/lib/util/order.js.map +1 -1
  71. package/lib/util/size.d.ts +2 -1
  72. package/lib/util/size.js +9 -1
  73. package/lib/util/size.js.map +1 -1
  74. package/lib/worker.js +283 -227
  75. package/lib/worker.js.map +1 -1
  76. package/package.json +2 -1
  77. package/src/algorithm/antv-dagre/index.ts +15 -12
  78. package/src/algorithm/antv-dagre/types.ts +3 -14
  79. package/src/algorithm/circular/index.ts +5 -4
  80. package/src/algorithm/circular/types.ts +0 -15
  81. package/src/algorithm/combo-combined/index.ts +21 -17
  82. package/src/algorithm/combo-combined/types.ts +6 -21
  83. package/src/algorithm/concentric/index.ts +18 -16
  84. package/src/algorithm/concentric/types.ts +2 -16
  85. package/src/algorithm/d3-force/index.ts +25 -18
  86. package/src/algorithm/d3-force/types.ts +9 -22
  87. package/src/algorithm/d3-force-3d/index.ts +1 -1
  88. package/src/algorithm/d3-force-3d/types.ts +5 -0
  89. package/src/algorithm/dagre/index.ts +9 -7
  90. package/src/algorithm/dagre/types.ts +7 -15
  91. package/src/algorithm/force/index.ts +64 -40
  92. package/src/algorithm/force/types.ts +76 -45
  93. package/src/algorithm/force-atlas2/index.ts +13 -15
  94. package/src/algorithm/force-atlas2/types.ts +0 -12
  95. package/src/algorithm/fruchterman/index.ts +7 -15
  96. package/src/algorithm/fruchterman/simulation.ts +2 -2
  97. package/src/algorithm/fruchterman/types.ts +5 -2
  98. package/src/algorithm/grid/index.ts +45 -46
  99. package/src/algorithm/grid/types.ts +6 -35
  100. package/src/algorithm/radial/index.ts +14 -6
  101. package/src/algorithm/radial/radial-nonoverlap-force.ts +11 -6
  102. package/src/algorithm/radial/types.ts +2 -15
  103. package/src/algorithm/types.ts +18 -0
  104. package/src/types/common.ts +22 -0
  105. package/src/types/data.ts +1 -1
  106. package/src/util/expr.ts +26 -0
  107. package/src/util/format.ts +71 -27
  108. package/src/util/index.ts +2 -0
  109. package/src/util/order.ts +3 -9
  110. package/src/util/size.ts +8 -0
package/dist/index.js CHANGED
@@ -377,6 +377,156 @@
377
377
  }
378
378
  }
379
379
 
380
+ 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)}
381
+
382
+ /**
383
+ * Evaluate an expression if (and only if) it's a valid string expression.
384
+ * - Returns `undefined` when `expression` is not a string, empty, or invalid.
385
+ *
386
+ * @example
387
+ * evaluateExpression('x + y', { x: 10, y: 20 }) // 30
388
+ */
389
+ function evaluateExpression(expression, context) {
390
+ if (typeof expression !== 'string')
391
+ return undefined;
392
+ const source = expression.trim();
393
+ if (!source)
394
+ return undefined;
395
+ try {
396
+ A(source);
397
+ return N(source, context);
398
+ }
399
+ catch (_a) {
400
+ return undefined;
401
+ }
402
+ }
403
+
404
+ function parseSize(size) {
405
+ if (!size)
406
+ return [0, 0, 0];
407
+ if (isNumber(size))
408
+ return [size, size, size];
409
+ else if (Array.isArray(size) && size.length === 0)
410
+ return [0, 0, 0];
411
+ const [x, y = x, z = x] = size;
412
+ return [x, y, z];
413
+ }
414
+ function isSize(value) {
415
+ if (isNumber(value))
416
+ return true;
417
+ if (Array.isArray(value)) {
418
+ return value.every((item) => isNumber(item));
419
+ }
420
+ return false;
421
+ }
422
+
423
+ /**
424
+ * Format a value into a callable function when it is a string expression.
425
+ * - `string` => `(context) => evaluateExpression(string, context)`
426
+ * - `function` => returned as-is
427
+ * - other => returned as-is
428
+ */
429
+ function formatFn(value, argNames) {
430
+ if (typeof value === 'function')
431
+ return value;
432
+ if (typeof value === 'string') {
433
+ const expr = value;
434
+ return (...argv) => {
435
+ const ctx = {};
436
+ for (let i = 0; i < argNames.length; i++) {
437
+ ctx[argNames[i]] = argv[i];
438
+ }
439
+ return evaluateExpression(expr, ctx);
440
+ };
441
+ }
442
+ return () => value;
443
+ }
444
+ /**
445
+ * Format value with multiple types into a function that returns a number
446
+ * @param value The value to be formatted
447
+ * @param defaultValue The default value when value is invalid
448
+ * @returns A function that returns a number
449
+ */
450
+ function formatNumberFn(value, defaultValue, type = 'node') {
451
+ // If value is undefined, return default value function
452
+ if (isNil(value)) {
453
+ return () => defaultValue;
454
+ }
455
+ // If value is an expression, return a function that evaluates the expression
456
+ if (isString(value)) {
457
+ const numberFn = formatFn(value, [type]);
458
+ return (d) => {
459
+ const evaluated = numberFn(d);
460
+ if (isNumber(evaluated))
461
+ return evaluated;
462
+ return defaultValue;
463
+ };
464
+ }
465
+ // If value is a function, return it directly
466
+ if (isFunction(value)) {
467
+ return value;
468
+ }
469
+ // If value is a number, return a function that returns this number
470
+ if (isNumber(value)) {
471
+ return () => value;
472
+ }
473
+ // For other cases (undefined or invalid values), return default value function
474
+ return () => defaultValue;
475
+ }
476
+ /**
477
+ * Format size config with multiple types into a function that returns a size
478
+ * @param value The value to be formatted
479
+ * @param defaultValue The default value when value is invalid
480
+ * @param resultIsNumber Whether to return a number (max of width/height) or size array
481
+ * @returns A function that returns a size
482
+ */
483
+ function formatSizeFn(value, defaultValue = 10, type = 'node') {
484
+ // If value is undefined, return default value function
485
+ if (isNil(value)) {
486
+ return () => defaultValue;
487
+ }
488
+ // If value is an expression, return a function that evaluates the expression
489
+ if (isString(value)) {
490
+ const sizeFn = formatFn(value, [type]);
491
+ return (d) => {
492
+ const evaluated = sizeFn(d);
493
+ if (isSize(evaluated))
494
+ return evaluated;
495
+ return defaultValue;
496
+ };
497
+ }
498
+ // If value is a function, return it directly
499
+ if (isFunction(value)) {
500
+ return value;
501
+ }
502
+ // If value is a number, return a function that returns this number
503
+ if (isNumber(value)) {
504
+ return () => value;
505
+ }
506
+ // If value is an array, return max or the array itself
507
+ if (Array.isArray(value)) {
508
+ return () => value;
509
+ }
510
+ return () => defaultValue;
511
+ }
512
+ /**
513
+ * Format nodeSize and nodeSpacing into a function that returns the total size
514
+ * @param nodeSize The size of the node
515
+ * @param nodeSpacing The spacing around the node
516
+ * @param defaultNodeSize The default node size when value is invalid
517
+ * @param defaultNodeSpacing The default node spacing when value is invalid
518
+ * @returns A function that returns the total size (node size + spacing)
519
+ */
520
+ const formatNodeSizeFn = (nodeSize, nodeSpacing, defaultNodeSize = 10, defaultNodeSpacing = 0) => {
521
+ const nodeSpacingFunc = formatSizeFn(nodeSpacing, defaultNodeSpacing);
522
+ const nodeSizeFunc = formatSizeFn(nodeSize, defaultNodeSize);
523
+ return (d) => {
524
+ const [sizeW, sizeH, sizeD] = parseSize(nodeSizeFunc(d));
525
+ const [spacingW, spacingH, spacingD] = parseSize(nodeSpacingFunc(d));
526
+ return [sizeW + spacingW, sizeH + spacingH, sizeD + spacingD];
527
+ };
528
+ };
529
+
380
530
  /**
381
531
  * Floyd-Warshall algorithm to find shortest paths (but with no negative cycles).
382
532
  */
@@ -800,17 +950,6 @@
800
950
  return { x: point[0], y: point[1], z: (_a = point[2]) !== null && _a !== void 0 ? _a : 0 };
801
951
  }
802
952
 
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
953
  /**
815
954
  * Viewport configuration such as width, height and center point.
816
955
  */
@@ -826,71 +965,6 @@
826
965
  };
827
966
  };
828
967
 
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
968
  class GraphLib {
895
969
  constructor(data, options = {}) {
896
970
  this.edgeIdCounter = new Map();
@@ -5108,6 +5182,7 @@
5108
5182
 
5109
5183
  const DEFAULTS_LAYOUT_OPTIONS$8 = {
5110
5184
  nodeSize: 10,
5185
+ nodeSpacing: 0,
5111
5186
  rankdir: 'TB',
5112
5187
  nodesep: 50,
5113
5188
  ranksep: 50,
@@ -5132,27 +5207,27 @@
5132
5207
  }
5133
5208
  layout(options) {
5134
5209
  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,
5210
+ const { nodeSize, nodeSpacing, align, rankdir = 'TB', ranksep, nodesep, edgeLabelSpace, ranker = 'tight-tree', nodeOrder, begin, controlPoints, radial, sortByCombo,
5136
5211
  // focusNode,
5137
5212
  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);
5213
+ const ranksepfunc = formatNumberFn(ranksepFunc, ranksep !== null && ranksep !== void 0 ? ranksep : 50, 'node');
5214
+ const nodesepfunc = formatNumberFn(nodesepFunc, nodesep !== null && nodesep !== void 0 ? nodesep : 50, 'node');
5140
5215
  let horisep = nodesepfunc;
5141
5216
  let vertisep = ranksepfunc;
5142
5217
  if (rankdir === 'LR' || rankdir === 'RL') {
5143
5218
  horisep = ranksepfunc;
5144
5219
  vertisep = nodesepfunc;
5145
5220
  }
5146
- const nodeSizeFunc = formatSizeFn(nodeSize, DEFAULTS_LAYOUT_OPTIONS$8.nodeSize);
5147
5221
  // Create internal graph
5148
5222
  const g = new DagreGraph({ tree: [] });
5149
5223
  // copy graph to g
5150
5224
  const nodes = this.model.nodes();
5151
5225
  const edges = this.model.edges();
5226
+ const sizeFn = formatNodeSizeFn(nodeSize, nodeSpacing, DEFAULTS_LAYOUT_OPTIONS$8.nodeSize, DEFAULTS_LAYOUT_OPTIONS$8.nodeSpacing);
5152
5227
  nodes.forEach((node) => {
5153
5228
  var _a;
5154
5229
  const raw = node._original;
5155
- const size = parseSize(nodeSizeFunc(raw));
5230
+ const size = sizeFn(raw);
5156
5231
  const verti = vertisep(raw);
5157
5232
  const hori = horisep(raw);
5158
5233
  const width = size[0] + 2 * hori;
@@ -5434,7 +5509,7 @@
5434
5509
  return controlPoints;
5435
5510
  };
5436
5511
 
5437
- const DEFAULT_LAYOUT_OPTIONS = {
5512
+ const DEFAULT_LAYOUT_OPTIONS$1 = {
5438
5513
  radius: null,
5439
5514
  startRadius: null,
5440
5515
  endRadius: null,
@@ -5445,6 +5520,7 @@
5445
5520
  ordering: null,
5446
5521
  angleRatio: 1,
5447
5522
  nodeSize: 10,
5523
+ nodeSpacing: 0,
5448
5524
  };
5449
5525
  /**
5450
5526
  * <zh/> 环形布局
@@ -5457,7 +5533,7 @@
5457
5533
  this.id = 'circular';
5458
5534
  }
5459
5535
  getDefaultOptions() {
5460
- return DEFAULT_LAYOUT_OPTIONS;
5536
+ return DEFAULT_LAYOUT_OPTIONS$1;
5461
5537
  }
5462
5538
  layout() {
5463
5539
  return __awaiter(this, void 0, void 0, function* () {
@@ -5483,11 +5559,11 @@
5483
5559
  }
5484
5560
  let { radius, startRadius, endRadius } = this.options;
5485
5561
  const nodes = this.model.nodes();
5486
- const format = formatNodeSizeFn(nodeSize, nodeSpacing, DEFAULT_LAYOUT_OPTIONS.nodeSize);
5487
- if (!isNil(nodeSpacing)) {
5562
+ const sizeFn = formatNodeSizeFn(nodeSize, nodeSpacing, DEFAULT_LAYOUT_OPTIONS$1.nodeSize, DEFAULT_LAYOUT_OPTIONS$1.nodeSpacing);
5563
+ if (nodeSpacing) {
5488
5564
  let perimeter = 0;
5489
5565
  for (const node of nodes) {
5490
- perimeter += format(node._original);
5566
+ perimeter += Math.max(...sizeFn(node._original));
5491
5567
  }
5492
5568
  radius = perimeter / (2 * Math.PI);
5493
5569
  }
@@ -5564,17 +5640,10 @@
5564
5640
  applySingleNodeLayout(this.model, center);
5565
5641
  return;
5566
5642
  }
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
- }
5643
+ const { sortBy: propsSortBy, maxLevelDiff: propsMaxLevelDiff, sweep: propsSweep, clockwise, equidistant, preventOverlap, startAngle = DEFAULTS_LAYOUT_OPTIONS$7.startAngle, nodeSize, nodeSpacing, } = this.options;
5644
+ const sortBy = !propsSortBy || propsSortBy === 'degree'
5645
+ ? 'degree'
5646
+ : formatFn(propsSortBy, ['node']);
5578
5647
  if (sortBy === 'degree') {
5579
5648
  orderByDegree(this.model);
5580
5649
  }
@@ -5591,15 +5660,15 @@
5591
5660
  for (const node of nodes) {
5592
5661
  const v = sortBy === 'degree'
5593
5662
  ? this.model.degree(node.id)
5594
- : sortBy === null || sortBy === void 0 ? void 0 : sortBy(node._original);
5663
+ : sortBy(node._original);
5595
5664
  sortKeys.set(node.id, v);
5596
5665
  }
5597
5666
  const maxValueNode = this.model.firstNode();
5598
5667
  const maxLevelDiff = propsMaxLevelDiff || sortKeys.get(maxValueNode.id) / 4;
5599
- const nodeSizeFn = formatNodeSizeFn(nodeSize, nodeSpacing);
5668
+ const sizeFn = formatNodeSizeFn(nodeSize, nodeSpacing, DEFAULTS_LAYOUT_OPTIONS$7.nodeSize, DEFAULTS_LAYOUT_OPTIONS$7.nodeSpacing);
5600
5669
  const nodeDistances = new Map();
5601
5670
  for (const node of nodes) {
5602
- nodeDistances.set(node.id, nodeSizeFn(node._original));
5671
+ nodeDistances.set(node.id, Math.max(...sizeFn(node._original)));
5603
5672
  }
5604
5673
  // put the values into levels
5605
5674
  const levels = [{ nodes: [] }];
@@ -7325,9 +7394,7 @@
7325
7394
  }
7326
7395
 
7327
7396
  const DEFAULTS_LAYOUT_OPTIONS$6 = {
7328
- link: {
7329
- id: (d) => String(d.id),
7330
- },
7397
+ edgeId: 'edge.id',
7331
7398
  manyBody: {
7332
7399
  strength: -30,
7333
7400
  },
@@ -7582,7 +7649,9 @@
7582
7649
  if (options.manyBody === false)
7583
7650
  return undefined;
7584
7651
  return assignDefined({}, options.manyBody || {}, {
7585
- strength: options.nodeStrength,
7652
+ strength: options.nodeStrength
7653
+ ? formatFn(options.nodeStrength, ['node'])
7654
+ : undefined,
7586
7655
  distanceMin: options.distanceMin,
7587
7656
  distanceMax: options.distanceMax,
7588
7657
  theta: options.theta,
@@ -7615,9 +7684,13 @@
7615
7684
  if (options.link === false)
7616
7685
  return undefined;
7617
7686
  return assignDefined({}, options.link || {}, {
7618
- id: options.edgeId,
7619
- distance: options.linkDistance,
7620
- strength: options.edgeStrength,
7687
+ id: options.edgeId ? formatFn(options.edgeId, ['edge']) : undefined,
7688
+ distance: options.linkDistance
7689
+ ? formatFn(options.linkDistance, ['edge'])
7690
+ : undefined,
7691
+ strength: options.edgeStrength
7692
+ ? formatFn(options.edgeStrength, ['edge'])
7693
+ : undefined,
7621
7694
  iterations: options.edgeIterations,
7622
7695
  });
7623
7696
  }
@@ -7649,9 +7722,8 @@
7649
7722
  if (options.preventOverlap === false &&
7650
7723
  (options.collide === false || options.collide === undefined))
7651
7724
  return undefined;
7652
- const radius = options.nodeSize || options.nodeSpacing
7653
- ? (d) => formatNodeSizeFn(options.nodeSize, options.nodeSpacing)(d._original) / 2
7654
- : undefined;
7725
+ const sizeFn = formatNodeSizeFn(options.nodeSize, options.nodeSpacing, DEFAULTS_LAYOUT_OPTIONS$6.nodeSize, DEFAULTS_LAYOUT_OPTIONS$6.nodeSpacing);
7726
+ const radius = (d) => Math.max(...sizeFn(d._original)) / 2;
7655
7727
  return assignDefined({}, options.collide || {}, {
7656
7728
  radius: (options.collide && options.collide.radius) || radius,
7657
7729
  strength: options.collideStrength,
@@ -7792,7 +7864,7 @@
7792
7864
  ['centerY', center && center.y],
7793
7865
  ['template', 'force'],
7794
7866
  ['strength', clusterFociStrength],
7795
- ['groupBy', clusterBy],
7867
+ ['groupBy', clusterBy ? formatFn(clusterBy, ['node']) : undefined],
7796
7868
  ['nodes', this.model.nodes()],
7797
7869
  ['links', this.model.edges()],
7798
7870
  ['forceLinkDistance', clusterEdgeDistance],
@@ -9524,7 +9596,7 @@
9524
9596
  return {
9525
9597
  numDimensions: 3,
9526
9598
  link: {
9527
- id: (edge) => String(edge.id),
9599
+ id: (edge) => edge.id,
9528
9600
  },
9529
9601
  manyBody: {},
9530
9602
  center: {
@@ -23305,11 +23377,13 @@
23305
23377
  }
23306
23378
  });
23307
23379
  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);
23380
+ const edgeLabelSizeFn = formatSizeFn(edgeLabelSize, 0, 'edge');
23381
+ const edgeLabelOffsetFn = formatNumberFn(edgeLabelOffset, 10, 'edge');
23382
+ const edgeLabelPosFn = typeof edgeLabelPos === 'string'
23383
+ ? () => edgeLabelPos
23384
+ : formatFn(edgeLabelPos, ['edge']);
23385
+ const edgeMinLenFn = formatNumberFn(edgeMinLen, 1, 'edge');
23386
+ const edgeWeightFn = formatNumberFn(edgeWeight, 1, 'edge');
23313
23387
  this.model.forEachEdge((edge) => {
23314
23388
  const raw = edge._original;
23315
23389
  const [lw, lh] = parseSize(edgeLabelSizeFn(raw));
@@ -24359,28 +24433,43 @@
24359
24433
  */
24360
24434
  parseOptions(options) {
24361
24435
  const _ = Object.assign(Object.assign({}, options), normalizeViewport(options));
24436
+ // Format nodeClusterBy (for clustering / leafCluster)
24437
+ if (_.nodeClusterBy) {
24438
+ _.nodeClusterBy = formatFn(_.nodeClusterBy, ['node']);
24439
+ }
24362
24440
  // Format node mass
24363
24441
  if (!options.getMass) {
24364
- _.getMass = (d) => {
24365
- if (!d)
24442
+ _.getMass = (node) => {
24443
+ if (!node)
24366
24444
  return 1;
24367
24445
  const massWeight = 1;
24368
- const degree = this.model.degree(d.id, 'both');
24446
+ const degree = this.model.degree(node.id, 'both');
24369
24447
  return !degree || degree < 5 ? massWeight : degree * 5 * massWeight;
24370
24448
  };
24371
24449
  }
24450
+ else {
24451
+ _.getMass = formatNumberFn(options.getMass, 1);
24452
+ }
24453
+ // Format per-node center force callback
24454
+ if (options.getCenter) {
24455
+ const params = ['node', 'degree'];
24456
+ _.getCenter = formatFn(options.getCenter, params);
24457
+ }
24372
24458
  // Format node size
24373
- _.nodeSize = formatNodeSizeFn(options.nodeSize, options.nodeSpacing);
24459
+ const nodeSizeVec = formatNodeSizeFn(options.nodeSize, options.nodeSpacing);
24460
+ _.nodeSize = (node) => {
24461
+ if (!node)
24462
+ return 0;
24463
+ const [w, h, z] = nodeSizeVec(node);
24464
+ return Math.max(w, h, z);
24465
+ };
24374
24466
  // Format node / edge strengths
24375
24467
  _.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
- };
24468
+ ? formatFn(options.linkDistance, ['edge', 'source', 'target'])
24469
+ : (_, source, target) => 1 + _.nodeSize(source) + _.nodeSize(target);
24382
24470
  _.nodeStrength = formatNumberFn(options.nodeStrength, 1);
24383
- _.edgeStrength = formatNumberFn(options.edgeStrength, 1);
24471
+ _.edgeStrength = formatNumberFn(options.edgeStrength, 1, 'edge');
24472
+ _.clusterNodeStrength = formatNumberFn(options.clusterNodeStrength, 1);
24384
24473
  // Format centripetal options
24385
24474
  this.formatCentripetal(_);
24386
24475
  return _;
@@ -24389,23 +24478,30 @@
24389
24478
  * Format centripetal options
24390
24479
  */
24391
24480
  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;
24481
+ var _a, _b;
24482
+ const { dimensions, centripetalOptions, center, leafCluster, clustering, nodeClusterBy, } = options;
24483
+ const leafParams = ['node', 'nodes', 'edges'];
24484
+ const leafFn = formatFn(centripetalOptions === null || centripetalOptions === void 0 ? void 0 : centripetalOptions.leaf, leafParams);
24485
+ const singleFn = formatNumberFn(centripetalOptions === null || centripetalOptions === void 0 ? void 0 : centripetalOptions.single, 2);
24486
+ const othersFn = formatNumberFn(centripetalOptions === null || centripetalOptions === void 0 ? void 0 : centripetalOptions.others, 1);
24487
+ const centerRaw = (_a = centripetalOptions === null || centripetalOptions === void 0 ? void 0 : centripetalOptions.center) !== null && _a !== void 0 ? _a : ((_) => {
24488
+ return {
24489
+ x: center[0],
24490
+ y: center[1],
24491
+ z: dimensions === 3 ? center[2] : undefined,
24492
+ };
24493
+ });
24494
+ const centerFn = formatFn(centerRaw, [
24495
+ 'node',
24496
+ 'nodes',
24497
+ 'edges',
24498
+ 'width',
24499
+ 'height',
24500
+ ]);
24501
+ const basicCentripetal = Object.assign(Object.assign({}, centripetalOptions), { leaf: leafFn, single: singleFn, others: othersFn, center: centerFn });
24502
+ // If user provided centripetalOptions, normalize them even without clustering modes.
24503
+ if (centripetalOptions) {
24504
+ options.centripetalOptions = basicCentripetal;
24409
24505
  }
24410
24506
  let sameTypeLeafMap;
24411
24507
  let clusters;
@@ -24413,8 +24509,8 @@
24413
24509
  if (leafCluster && nodeClusterBy) {
24414
24510
  sameTypeLeafMap = this.getSameTypeLeafMap(nodeClusterBy);
24415
24511
  clusters =
24416
- Array.from(new Set((_a = this.model
24417
- .nodes()) === null || _a === void 0 ? void 0 : _a.map((node) => nodeClusterBy(node._original)))) || [];
24512
+ Array.from(new Set((_b = this.model
24513
+ .nodes()) === null || _b === void 0 ? void 0 : _b.map((node) => nodeClusterBy(node._original)))) || [];
24418
24514
  options.centripetalOptions = Object.assign({}, basicCentripetal, {
24419
24515
  single: () => 100,
24420
24516
  leaf: (node) => {
@@ -24487,17 +24583,6 @@
24487
24583
  },
24488
24584
  });
24489
24585
  }
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
24586
  }
24502
24587
  /**
24503
24588
  * Get same type leaf map for clustering
@@ -25333,9 +25418,9 @@
25333
25418
  }
25334
25419
  getSizes(nodeSize, nodeSpacing) {
25335
25420
  const result = {};
25421
+ const nodeSizeFn = formatNodeSizeFn(nodeSize, nodeSpacing, DEFAULTS_LAYOUT_OPTIONS$4.nodeSize, DEFAULTS_LAYOUT_OPTIONS$4.nodeSpacing);
25336
25422
  this.model.forEachNode((node) => {
25337
- const nodeSizeFn = formatNodeSizeFn(nodeSize, nodeSpacing);
25338
- result[node.id] = nodeSizeFn(node._original);
25423
+ result[node.id] = Math.max(...nodeSizeFn(node._original));
25339
25424
  });
25340
25425
  return result;
25341
25426
  }
@@ -25347,7 +25432,7 @@
25347
25432
  return this.simulation;
25348
25433
  }
25349
25434
  parseOptions(options = {}) {
25350
- const { barnesHut, prune, maxIteration, kr, kg, nodeSize, nodeSpacing } = options;
25435
+ const { barnesHut, prune, maxIteration, kr, kg } = options;
25351
25436
  const auto = {};
25352
25437
  const n = this.model.nodeCount();
25353
25438
  if (barnesHut === undefined && n > 250)
@@ -25382,7 +25467,7 @@
25382
25467
  else if (n > 500)
25383
25468
  auto.kg = 1;
25384
25469
  }
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) });
25470
+ return Object.assign(Object.assign(Object.assign({}, options), auto), normalizeViewport(options));
25386
25471
  }
25387
25472
  stop() {
25388
25473
  var _a;
@@ -25767,7 +25852,7 @@
25767
25852
  clusterGravity: 10,
25768
25853
  width: 300,
25769
25854
  height: 300,
25770
- nodeClusterBy: 'data.cluster',
25855
+ nodeClusterBy: 'node.cluster',
25771
25856
  dimensions: 2,
25772
25857
  };
25773
25858
  class FruchtermanLayout extends BaseLayoutWithIterations {
@@ -25779,15 +25864,12 @@
25779
25864
  getDefaultOptions() {
25780
25865
  return DEFAULTS_LAYOUT_OPTIONS$3;
25781
25866
  }
25782
- parseOptions(options) {
25867
+ parseOptions(options = {}) {
25783
25868
  const { clustering, nodeClusterBy } = this.options;
25784
25869
  const clusteringEnabled = clustering && !!nodeClusterBy;
25785
- const nodeClusterByFunc = typeof nodeClusterBy === 'string'
25786
- ? (node) => getNestedValue(node, nodeClusterBy)
25787
- : nodeClusterBy;
25788
- Object.assign((options || (options = {})), normalizeViewport(options), {
25870
+ Object.assign(options, normalizeViewport(options), {
25789
25871
  clustering: clusteringEnabled,
25790
- nodeClusterBy: nodeClusterByFunc,
25872
+ nodeClusterBy: formatFn(nodeClusterBy, ['node']),
25791
25873
  });
25792
25874
  return options;
25793
25875
  }
@@ -25842,6 +25924,19 @@
25842
25924
  }
25843
25925
  }
25844
25926
 
25927
+ const DEFAULT_LAYOUT_OPTIONS = {
25928
+ begin: [0, 0],
25929
+ preventOverlap: true,
25930
+ condense: false,
25931
+ rows: undefined,
25932
+ cols: undefined,
25933
+ position: undefined,
25934
+ sortBy: 'degree',
25935
+ nodeSize: 30,
25936
+ nodeSpacing: 10,
25937
+ width: 300,
25938
+ height: 300,
25939
+ };
25845
25940
  /**
25846
25941
  * <zh/> 网格布局
25847
25942
  *
@@ -25853,23 +25948,10 @@
25853
25948
  this.id = 'grid';
25854
25949
  }
25855
25950
  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
- };
25951
+ return DEFAULT_LAYOUT_OPTIONS;
25869
25952
  }
25870
- normalizeOptions(options = {}, model) {
25871
- var _a;
25872
- const { rows: propRows, cols: propCols } = options;
25953
+ parseOptions(options = {}, model) {
25954
+ const { rows: propRows, cols: propCols, position: propPosition, sortBy: propSortBy, } = options;
25873
25955
  const { width, height, center } = normalizeViewport(options);
25874
25956
  let rows = options.rows;
25875
25957
  let cols = options.cols;
@@ -25924,20 +26006,20 @@
25924
26006
  }
25925
26007
  }
25926
26008
  }
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,
26009
+ const sortBy = !propSortBy
26010
+ ? DEFAULT_LAYOUT_OPTIONS.sortBy
26011
+ : propSortBy === 'degree' || propSortBy === 'id'
26012
+ ? propSortBy
26013
+ : formatFn(propSortBy, ['nodeA', 'nodeB']);
26014
+ return Object.assign(Object.assign({}, options), { sortBy,
25933
26015
  rcs,
25934
26016
  center,
25935
26017
  width,
25936
- height });
26018
+ height, position: formatFn(propPosition, ['node']) });
25937
26019
  }
25938
26020
  layout() {
25939
26021
  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);
26022
+ const { begin, rcs, sortBy, width, height, condense, preventOverlap, nodeSpacing, nodeSize, position, } = this.parseOptions(this.options, this.model);
25941
26023
  const n = this.model.nodeCount();
25942
26024
  if (!n || n === 1) {
25943
26025
  applySingleNodeLayout(this.model, begin);
@@ -25955,14 +26037,9 @@
25955
26037
  let cellWidth = condense ? 0 : width / rcs.cols;
25956
26038
  let cellHeight = condense ? 0 : height / rcs.rows;
25957
26039
  if (preventOverlap) {
26040
+ const sizeFn = formatNodeSizeFn(nodeSize, nodeSpacing, DEFAULT_LAYOUT_OPTIONS.nodeSize, DEFAULT_LAYOUT_OPTIONS.nodeSpacing);
25958
26041
  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;
26042
+ const [w, h] = sizeFn(node._original);
25966
26043
  cellWidth = Math.max(cellWidth, w);
25967
26044
  cellHeight = Math.max(cellHeight, h);
25968
26045
  });
@@ -32045,8 +32122,8 @@ ${indent}columns: ${matrix.columns}
32045
32122
  vecx = 0.01 * sign;
32046
32123
  vecy = 0.01 * sign;
32047
32124
  }
32048
- const nodeSizeU = Math.max(...parseSize(nodeSizeFunc(nodeU._original)));
32049
- const nodeSizeV = Math.max(...parseSize(nodeSizeFunc(nodeV._original)));
32125
+ const nodeSizeU = Math.max(...nodeSizeFunc(nodeU._original));
32126
+ const nodeSizeV = Math.max(...nodeSizeFunc(nodeV._original));
32050
32127
  // these two nodes overlap
32051
32128
  if (vecLength < nodeSizeV / 2 + nodeSizeU / 2) {
32052
32129
  const common = (k * k) / vecLength;
@@ -32129,6 +32206,8 @@ ${indent}columns: ${matrix.columns}
32129
32206
  sortStrength: 10,
32130
32207
  strictRadial: true,
32131
32208
  unitRadius: null,
32209
+ nodeSize: 10,
32210
+ nodeSpacing: 0,
32132
32211
  };
32133
32212
  /**
32134
32213
  * <zh/> 径向布局
@@ -32197,7 +32276,7 @@ ${indent}columns: ${matrix.columns}
32197
32276
  });
32198
32277
  // stagger the overlapped nodes
32199
32278
  if (preventOverlap) {
32200
- const nodeSizeFunc = formatNodeSizeFn(nodeSize, nodeSpacing);
32279
+ const nodeSizeFunc = formatNodeSizeFn(nodeSize, nodeSpacing, DEFAULTS_LAYOUT_OPTIONS.nodeSize, DEFAULTS_LAYOUT_OPTIONS.nodeSpacing);
32201
32280
  const nonoverlapForceParams = {
32202
32281
  nodeSizeFunc,
32203
32282
  radiiMap,
@@ -32276,7 +32355,7 @@ ${indent}columns: ${matrix.columns}
32276
32355
  radiusScale[i] = radii[i] / unitRadius;
32277
32356
  const baseLink = (linkDistance + unitRadius) / 2;
32278
32357
  const sortCache = new Map();
32279
- const sortFn = typeof sortBy === 'function' ? sortBy : null;
32358
+ const sortFn = !sortBy || sortBy === 'data' ? null : formatFn(sortBy, ['node']);
32280
32359
  const isDataSort = sortBy === 'data';
32281
32360
  for (let i = 0; i < n; i++) {
32282
32361
  const row = distances[i];
@@ -32573,7 +32652,9 @@ ${indent}columns: ${matrix.columns}
32573
32652
  });
32574
32653
  }
32575
32654
  getLayoutConfig(combo) {
32576
- const { layout } = this.options;
32655
+ const layout = typeof this.options.layout === 'object'
32656
+ ? this.options.layout
32657
+ : formatFn(this.options.layout, ['comboId']);
32577
32658
  if (typeof layout === 'function') {
32578
32659
  const comboId = combo.id === ROOT_ID ? null : combo.id;
32579
32660
  return this.normalizeLayoutConfig(layout(comboId));
@@ -32581,7 +32662,7 @@ ${indent}columns: ${matrix.columns}
32581
32662
  return this.normalizeLayoutConfig(layout);
32582
32663
  }
32583
32664
  normalizeLayoutConfig(config) {
32584
- const base = Object.assign(Object.assign({ type: 'concentric' }, normalizeViewport(this.options)), { nodeSize: (d) => d.size, nodeSpacing: 0 });
32665
+ const base = Object.assign(Object.assign({ type: 'concentric' }, normalizeViewport(this.options)), { nodeSize: 'node.size', nodeSpacing: 0 });
32585
32666
  if (!config)
32586
32667
  return base;
32587
32668
  if (typeof config === 'string')
@@ -32668,7 +32749,7 @@ ${indent}columns: ${matrix.columns}
32668
32749
  if (!Number.isFinite(minX) || !Number.isFinite(minY)) {
32669
32750
  return { center: [0, 0], width: 0, height: 0 };
32670
32751
  }
32671
- const comboPaddingFn = formatNumberFn(this.options.comboPadding, 20);
32752
+ const comboPaddingFn = formatNumberFn(this.options.comboPadding, 20, 'combo');
32672
32753
  const padding = comboPaddingFn(combo._original);
32673
32754
  return {
32674
32755
  center: [(minX + maxX) / 2, (minY + maxY) / 2],
@@ -32684,10 +32765,10 @@ ${indent}columns: ${matrix.columns}
32684
32765
  getNodeSize(node, includeSpacing = true) {
32685
32766
  const { nodeSize, nodeSpacing } = this.options;
32686
32767
  const sizeFn = formatNodeSizeFn(nodeSize, includeSpacing ? nodeSpacing : 0);
32687
- return parseSize(sizeFn(node._original));
32768
+ return sizeFn(node._original);
32688
32769
  }
32689
32770
  getComboSize(combo, includeSpacing = true) {
32690
- const comboSpacingFn = formatNumberFn(this.options.comboSpacing, 0);
32771
+ const comboSpacingFn = formatNumberFn(this.options.comboSpacing, 0, 'combo');
32691
32772
  const spacing = includeSpacing ? comboSpacingFn(combo._original) : 0;
32692
32773
  const [width, height] = combo.size;
32693
32774
  return [width + spacing / 2, height + spacing / 2, 0];
@@ -32749,7 +32830,12 @@ ${indent}columns: ${matrix.columns}
32749
32830
  exports.Supervisor = Supervisor;
32750
32831
  exports.applySingleNodeLayout = applySingleNodeLayout;
32751
32832
  exports.assignDefined = assignDefined;
32833
+ exports.evaluateExpression = evaluateExpression;
32752
32834
  exports.floydWarshall = floydWarshall;
32835
+ exports.formatFn = formatFn;
32836
+ exports.formatNodeSizeFn = formatNodeSizeFn;
32837
+ exports.formatNumberFn = formatNumberFn;
32838
+ exports.formatSizeFn = formatSizeFn;
32753
32839
  exports.getAdjList = getAdjList;
32754
32840
  exports.getAdjMatrix = getAdjMatrix;
32755
32841
  exports.getEuclideanDistance = getEuclideanDistance;
@@ -32759,6 +32845,7 @@ ${indent}columns: ${matrix.columns}
32759
32845
  exports.initNodePosition = initNodePosition;
32760
32846
  exports.isArray = isArray;
32761
32847
  exports.isLayoutWithIterations = isLayoutWithIterations;
32848
+ exports.isSize = isSize;
32762
32849
  exports.johnson = johnson;
32763
32850
  exports.normalizeViewport = normalizeViewport;
32764
32851
  exports.orderByDegree = orderByDegree;