utils.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. "use strict";
  2. var __rest = (this && this.__rest) || function (s, e) {
  3. var t = {};
  4. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
  5. t[p] = s[p];
  6. if (s != null && typeof Object.getOwnPropertySymbols === "function")
  7. for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
  8. if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
  9. t[p[i]] = s[p[i]];
  10. }
  11. return t;
  12. };
  13. Object.defineProperty(exports, "__esModule", { value: true });
  14. exports.createEmptyPromise = exports.updateRoot = exports.optionsOf = exports.sizeOf = exports.valueOf = exports.normalizeRoot = exports.removeContainer = exports.normalizeContainer = exports.VIEW_KEYS = void 0;
  15. const util_1 = require("@antv/util");
  16. const size_1 = require("../utils/size");
  17. const mark_1 = require("./mark");
  18. const composition_1 = require("./composition");
  19. // Keys can specified by new Chart({...}).
  20. // Keys can bubble form mark-level options to view-level options.
  21. exports.VIEW_KEYS = [
  22. 'width',
  23. 'height',
  24. 'padding',
  25. 'paddingLeft',
  26. 'paddingRight',
  27. 'paddingBottom',
  28. 'paddingTop',
  29. 'inset',
  30. 'insetLeft',
  31. 'insetRight',
  32. 'insetTop',
  33. 'insetBottom',
  34. 'margin',
  35. 'marginLeft',
  36. 'marginRight',
  37. 'marginTop',
  38. 'marginBottom',
  39. 'autoFit',
  40. 'theme',
  41. 'title',
  42. ];
  43. function normalizeContainer(container) {
  44. if (container === undefined)
  45. return document.createElement('div');
  46. if (typeof container === 'string') {
  47. const node = document.getElementById(container);
  48. return node;
  49. }
  50. return container;
  51. }
  52. exports.normalizeContainer = normalizeContainer;
  53. function removeContainer(container) {
  54. const parent = container.parentNode;
  55. if (parent) {
  56. parent.removeChild(container);
  57. }
  58. }
  59. exports.removeContainer = removeContainer;
  60. function normalizeRoot(node) {
  61. if (node.type !== null)
  62. return node;
  63. const root = node.children[node.children.length - 1];
  64. for (const key of exports.VIEW_KEYS)
  65. root.attr(key, node.attr(key));
  66. return root;
  67. }
  68. exports.normalizeRoot = normalizeRoot;
  69. function valueOf(node) {
  70. return Object.assign(Object.assign({}, node.value), { type: node.type });
  71. }
  72. exports.valueOf = valueOf;
  73. function sizeOf(options, container) {
  74. const { autoFit } = options;
  75. if (autoFit)
  76. return (0, size_1.getContainerSize)(container);
  77. const { width = 640, height = 480 } = options;
  78. return { width, height };
  79. }
  80. exports.sizeOf = sizeOf;
  81. function optionsOf(node) {
  82. const root = normalizeRoot(node);
  83. const discovered = [root];
  84. const nodeValue = new Map();
  85. nodeValue.set(root, valueOf(root));
  86. while (discovered.length) {
  87. const node = discovered.pop();
  88. const value = nodeValue.get(node);
  89. const { children = [] } = node;
  90. for (const child of children) {
  91. const childValue = valueOf(child);
  92. const { children = [] } = value;
  93. children.push(childValue);
  94. discovered.push(child);
  95. nodeValue.set(child, childValue);
  96. value.children = children;
  97. }
  98. }
  99. return nodeValue.get(root);
  100. }
  101. exports.optionsOf = optionsOf;
  102. function isMark(type) {
  103. return new Set(Object.keys(mark_1.mark)).has(type);
  104. }
  105. function normalizeRootOptions(node, options, previousType) {
  106. const { type: oldType } = node;
  107. const { type = previousType || oldType } = options;
  108. if (type === 'view')
  109. return options;
  110. if (typeof type !== 'string')
  111. return options;
  112. if (!isMark(type))
  113. return options;
  114. const view = { type: 'view' };
  115. const mark = Object.assign({}, options);
  116. for (const key of exports.VIEW_KEYS) {
  117. if (mark[key] !== undefined) {
  118. view[key] = mark[key];
  119. delete mark[key];
  120. }
  121. }
  122. return Object.assign(Object.assign({}, view), { children: [mark] });
  123. }
  124. function typeCtor(type) {
  125. const node = Object.assign(Object.assign({}, mark_1.mark), composition_1.composition);
  126. const ctor = node[type];
  127. if (!ctor)
  128. throw new Error(`Unknown mark: ${type}.`);
  129. return ctor;
  130. }
  131. // Create node from options.
  132. function createNode(options) {
  133. const { type, children } = options, value = __rest(options, ["type", "children"]);
  134. if (typeof type !== 'string')
  135. return;
  136. const Ctor = typeCtor(type);
  137. const node = new Ctor();
  138. node.value = value;
  139. return node;
  140. }
  141. // Update node by options.
  142. function updateNode(node, newOptions) {
  143. const { type, children } = newOptions, value = __rest(newOptions, ["type", "children"]);
  144. if (node.type === type || type === undefined) {
  145. // Update node.
  146. node.value = (0, util_1.deepMix)(node.value, value);
  147. }
  148. else if (typeof type === 'string') {
  149. // Transform node.
  150. node.type = type;
  151. node.value = value;
  152. }
  153. }
  154. // Create a nested node tree from newOptions, and append it to the parent.
  155. function appendNode(parent, newOptions) {
  156. if (!parent)
  157. return;
  158. const discovered = [[parent, newOptions]];
  159. while (discovered.length) {
  160. const [parent, nodeOptions] = discovered.shift();
  161. const node = createNode(nodeOptions);
  162. if (Array.isArray(parent.children))
  163. parent.push(node);
  164. const { children } = nodeOptions;
  165. if (Array.isArray(children)) {
  166. for (const child of children) {
  167. discovered.push([node, child]);
  168. }
  169. }
  170. }
  171. }
  172. // Update node tree from options.
  173. function updateRoot(node, options, definedType) {
  174. const rootOptions = normalizeRootOptions(node, options, definedType);
  175. const discovered = [[null, node, rootOptions]];
  176. while (discovered.length) {
  177. const [parent, oldNode, newNode] = discovered.shift();
  178. // If there is no oldNode, create a node tree directly.
  179. if (!oldNode) {
  180. appendNode(parent, newNode);
  181. }
  182. else if (!newNode) {
  183. oldNode.remove();
  184. }
  185. else {
  186. updateNode(oldNode, newNode);
  187. const { children: newChildren } = newNode;
  188. const { children: oldChildren } = oldNode;
  189. if (Array.isArray(newChildren) && Array.isArray(oldChildren)) {
  190. // Only update node specified in newChildren,
  191. // the extra oldChildren will remain still.
  192. const n = Math.max(newChildren.length, oldChildren.length);
  193. for (let i = 0; i < n; i++) {
  194. const newChild = newChildren[i];
  195. const oldChild = oldChildren[i];
  196. discovered.push([oldNode, oldChild, newChild]);
  197. }
  198. }
  199. }
  200. }
  201. }
  202. exports.updateRoot = updateRoot;
  203. function createEmptyPromise() {
  204. let reject;
  205. let resolve;
  206. const cloned = new Promise((res, rej) => {
  207. resolve = res;
  208. reject = rej;
  209. });
  210. return [cloned, resolve, reject];
  211. }
  212. exports.createEmptyPromise = createEmptyPromise;
  213. //# sourceMappingURL=utils.js.map