@antv/g2
Version:
the Grammar of Graphics in Javascript
262 lines • 9.27 kB
JavaScript
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createEmptyPromise = exports.updateRoot = exports.optionsOf = exports.sizeOf = exports.valueOf = exports.normalizeRoot = exports.removeContainer = exports.normalizeContainer = exports.MIN_CHART_HEIGHT = exports.MIN_CHART_WIDTH = exports.CALLBACK_NODE = exports.REMOVE_FLAG = exports.VIEW_KEYS = void 0;
const util_1 = require("@antv/util");
const size_1 = require("../utils/size");
const helper_1 = require("../utils/helper");
const node_1 = require("./node");
// Keys can specified by new Chart({...}).
// Keys can bubble form mark-level options to view-level options.
exports.VIEW_KEYS = [
'width',
'height',
'depth',
'padding',
'paddingLeft',
'paddingRight',
'paddingBottom',
'paddingTop',
'inset',
'insetLeft',
'insetRight',
'insetTop',
'insetBottom',
'margin',
'marginLeft',
'marginRight',
'marginTop',
'marginBottom',
'autoFit',
'theme',
'title',
];
exports.REMOVE_FLAG = '__remove__';
exports.CALLBACK_NODE = '__callback__';
/** Minimum chart width */
exports.MIN_CHART_WIDTH = 1;
/** Minimum chart height */
exports.MIN_CHART_HEIGHT = 1;
function normalizeContainer(container) {
if (container === undefined) {
const container = document.createElement('div');
container[exports.REMOVE_FLAG] = true;
return container;
}
if (typeof container === 'string') {
const node = document.getElementById(container);
return node;
}
return container;
}
exports.normalizeContainer = normalizeContainer;
function removeContainer(container) {
const parent = container.parentNode;
if (parent) {
parent.removeChild(container);
}
}
exports.removeContainer = removeContainer;
function normalizeRoot(node) {
if (node.type !== null)
return node;
const root = node.children[node.children.length - 1];
for (const key of exports.VIEW_KEYS)
root.attr(key, node.attr(key));
return root;
}
exports.normalizeRoot = normalizeRoot;
function valueOf(node) {
return Object.assign(Object.assign({}, node.value), { type: node.type });
}
exports.valueOf = valueOf;
function sizeOf(options, container) {
const { width, height, autoFit, depth = 0 } = options;
let effectiveWidth = 640;
let effectiveHeight = 480;
if (autoFit) {
const { width: containerWidth, height: containerHeight } = (0, size_1.getContainerSize)(container);
effectiveWidth = containerWidth || effectiveWidth;
effectiveHeight = containerHeight || effectiveHeight;
}
effectiveWidth = width || effectiveWidth;
effectiveHeight = height || effectiveHeight;
return {
width: Math.max((0, util_1.isNumber)(effectiveWidth) ? effectiveWidth : exports.MIN_CHART_WIDTH, exports.MIN_CHART_WIDTH),
height: Math.max((0, util_1.isNumber)(effectiveHeight) ? effectiveHeight : exports.MIN_CHART_HEIGHT, exports.MIN_CHART_HEIGHT),
depth,
};
}
exports.sizeOf = sizeOf;
function optionsOf(node) {
const root = normalizeRoot(node);
const discovered = [root];
const nodeValue = new Map();
nodeValue.set(root, valueOf(root));
while (discovered.length) {
const node = discovered.pop();
const value = nodeValue.get(node);
const { children = [] } = node;
for (const child of children) {
if (child.type === exports.CALLBACK_NODE) {
value.children = child.value;
}
else {
const childValue = valueOf(child);
const { children = [] } = value;
children.push(childValue);
discovered.push(child);
nodeValue.set(child, childValue);
value.children = children;
}
}
}
return nodeValue.get(root);
}
exports.optionsOf = optionsOf;
function isMark(type, mark) {
if (typeof type === 'function')
return true;
return new Set(Object.keys(mark)).has(type);
}
function isComposition(type, composition) {
return (typeof type !== 'function' && new Set(Object.keys(composition)).has(type));
}
function normalizeRootOptions(node, options, previousType, marks, composition) {
const { type: oldType } = node;
const { type = previousType || oldType } = options;
if (isComposition(type, composition)) {
for (const key of exports.VIEW_KEYS) {
if (node.attr(key) !== undefined && options[key] === undefined) {
options[key] = node.attr(key);
}
}
return options;
}
if (isMark(type, marks)) {
const view = { type: 'view' };
const mark = Object.assign({}, options);
for (const key of exports.VIEW_KEYS) {
if (mark[key] !== undefined) {
view[key] = mark[key];
delete mark[key];
}
}
return Object.assign(Object.assign({}, view), { children: [mark] });
}
return options;
}
function typeCtor(type, mark, composition) {
if (typeof type === 'function')
return mark.mark;
const node = Object.assign(Object.assign({}, mark), composition);
const ctor = node[type];
if (!ctor)
throw new Error(`Unknown mark: ${type}.`);
return ctor;
}
// Create node from options.
function createNode(options, mark, composition) {
if (typeof options === 'function') {
const node = new node_1.Node();
node.value = options;
node.type = exports.CALLBACK_NODE;
return node;
}
const { type, children } = options, value = __rest(options, ["type", "children"]);
const Ctor = typeCtor(type, mark, composition);
const node = new Ctor();
node.value = value;
// @ts-ignore
node.type = type;
return node;
}
// Update node by options.
function updateNode(node, newOptions) {
const { type, children } = newOptions, value = __rest(newOptions, ["type", "children"]);
if (node.type === type || type === undefined) {
// Update node.
(0, helper_1.deepAssign)(node.value, value);
}
else if (typeof type === 'string') {
// Transform node.
node.type = type;
node.value = value;
}
}
// Create a nested node tree from newOptions, and append it to the parent.
function appendNode(parent, newOptions, mark, composition) {
if (!parent)
return;
const discovered = [[parent, newOptions]];
while (discovered.length) {
const [parent, nodeOptions] = discovered.shift();
const node = createNode(nodeOptions, mark, composition);
if (Array.isArray(parent.children))
parent.push(node);
const { children } = nodeOptions;
if (Array.isArray(children)) {
for (const child of children) {
discovered.push([node, child]);
}
}
else if (typeof children === 'function') {
discovered.push([node, children]);
}
}
}
// Update node tree from options.
function updateRoot(node, options, definedType, mark, composition) {
const rootOptions = normalizeRootOptions(node, options, definedType, mark, composition);
const discovered = [[null, node, rootOptions]];
while (discovered.length) {
const [parent, oldNode, newNode] = discovered.shift();
// If there is no oldNode, create a node tree directly.
if (!oldNode) {
appendNode(parent, newNode, mark, composition);
}
else if (!newNode) {
oldNode.remove();
}
else {
updateNode(oldNode, newNode);
const { children: newChildren } = newNode;
const { children: oldChildren } = oldNode;
if (Array.isArray(newChildren) && Array.isArray(oldChildren)) {
// Only update node specified in newChildren,
// the extra oldChildren will remain still.
const n = Math.max(newChildren.length, oldChildren.length);
for (let i = 0; i < n; i++) {
const newChild = newChildren[i];
const oldChild = oldChildren[i];
discovered.push([oldNode, oldChild, newChild]);
}
}
else if (typeof newChildren === 'function') {
discovered.push([oldNode, null, newChildren]);
}
}
}
}
exports.updateRoot = updateRoot;
function createEmptyPromise() {
let reject;
let resolve;
const cloned = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return [cloned, resolve, reject];
}
exports.createEmptyPromise = createEmptyPromise;
//# sourceMappingURL=utils.js.map
;