node.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /**
  2. * BFS nodes and execute callback.
  3. */
  4. function bfs(node, callback) {
  5. const discovered = [node];
  6. while (discovered.length) {
  7. const currentNode = discovered.shift();
  8. callback && callback(currentNode);
  9. const children = currentNode.children || [];
  10. for (const child of children) {
  11. discovered.push(child);
  12. }
  13. }
  14. }
  15. /**
  16. * Hierarchy container.
  17. */
  18. export class Node {
  19. constructor(value = {}, type) {
  20. // The parent node.
  21. this.parentNode = null;
  22. // The children nodes.
  23. this.children = [];
  24. // The index of parent children.
  25. this.index = 0;
  26. this.type = type;
  27. this.value = value;
  28. }
  29. /**
  30. * Apply specified transform to current value. Mount the node
  31. * to replace the original one in the tree and then return it.
  32. */
  33. map(transform = (x) => x) {
  34. const newValue = transform(this.value);
  35. this.value = newValue;
  36. return this;
  37. }
  38. /**
  39. * Set or get the specified attribute. It the value is specified, update
  40. * the attribute of current value and return the node. Otherwise
  41. * return the the attribute of current value.
  42. */
  43. attr(key, value) {
  44. if (arguments.length === 1)
  45. return this.value[key];
  46. return this.map((v) => ((v[key] = value), v));
  47. }
  48. /**
  49. * Create a new node and append to children nodes.
  50. */
  51. append(Ctor) {
  52. const node = new Ctor({});
  53. node.children = [];
  54. this.push(node);
  55. return node;
  56. }
  57. push(node) {
  58. node.parentNode = this;
  59. node.index = this.children.length;
  60. this.children.push(node);
  61. return this;
  62. }
  63. /**
  64. * Remove current node from parentNode.
  65. */
  66. remove() {
  67. const parent = this.parentNode;
  68. if (parent) {
  69. const { children } = parent;
  70. const index = children.findIndex((item) => item === this);
  71. children.splice(index, 1);
  72. }
  73. return this;
  74. }
  75. getNodeByKey(key) {
  76. let targetNode = null;
  77. const callback = (node) => {
  78. if (key === node.attr('key')) {
  79. targetNode = node;
  80. }
  81. };
  82. bfs(this, callback);
  83. return targetNode;
  84. }
  85. getNodesByType(type) {
  86. const nodes = [];
  87. const callback = (node) => {
  88. if (type === node.type) {
  89. nodes.push(node);
  90. }
  91. };
  92. bfs(this, callback);
  93. return nodes;
  94. }
  95. getNodeByType(type) {
  96. let node = null;
  97. bfs(this, (current) => {
  98. if (node)
  99. return;
  100. if (type === current.type)
  101. node = current;
  102. });
  103. return node;
  104. }
  105. /**
  106. * Apply specified callback to the node value.
  107. */
  108. call(callback, ...params) {
  109. callback(this.map(), ...params);
  110. return this;
  111. }
  112. getRoot() {
  113. // Find the root chart and render.
  114. let root = this;
  115. while (root && root.parentNode) {
  116. root = root.parentNode;
  117. }
  118. return root;
  119. }
  120. }
  121. //# sourceMappingURL=node.js.map