UNPKG

@antv/f2

Version:

Charts for mobile visualization.

149 lines 4.78 kB
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; import { extendMap, px2hd as defaultPx2hd } from '../util'; import { isFunction, omit } from '@antv/util'; import computeLayout from './css-layout'; import getShapeAttrs from './shape'; import getAnimation from './animation'; import { ELEMENT_DELETE } from './elementStatus'; import createClipElement from './createClipElement'; // 转换成布局所需要的布局树 function createNodeTree(element, container, px2hd) { var key = element.key, ref = element.ref, _cache = element._cache, type = element.type, props = element.props, status = element.status, animation = element.animation; var children = extendMap(props.children, function (child) { return createNodeTree(child, container, px2hd); }); // const { style, attrs } = props; var style = px2hd(props.style); var attrs = px2hd(props.attrs); // 文本要自动计算文本的宽高, TODO, 后面再优化 if (type === 'text') { var shape = container.addShape(type, { attrs: _objectSpread({ x: 0, y: 0 }, attrs) }); var _shape$getBBox = shape.getBBox(), width = _shape$getBBox.width, height = _shape$getBBox.height; style = _objectSpread({ width: width, height: height }, style); // 无用,销毁掉 shape.remove(true); } return { key: key, ref: ref, _cache: _cache, type: type, props: props, children: children, status: status, animation: animation, // 处理px2hd之后的配置 style: style, attrs: attrs }; } function mergeLayout(parent, layout) { if (!parent || !layout) return layout; var parentLeft = parent.left, parentTop = parent.top; var left = layout.left, top = layout.top; return _objectSpread(_objectSpread({}, layout), {}, { left: parentLeft + left, top: parentTop + top }); } function createElement(node, container, parentLayout, animate) { var _node$_cache = node._cache, _cache = _node$_cache === void 0 ? {} : _node$_cache, ref = node.ref, type = node.type, props = node.props, attrs = node.attrs, originLayout = node.layout, renderChildren = node.renderChildren, nodeChildren = node.children, status = node.status, animation = node.animation; var layout = mergeLayout(parentLayout, originLayout); // 该元素上一次的attrs var lastAttrs = _cache.attrs; var elementAttrs = _objectSpread(_objectSpread(_objectSpread({}, getShapeAttrs(type, layout)), status === ELEMENT_DELETE ? lastAttrs : null), attrs); // 缓存这次新的attrs _cache.attrs = elementAttrs; if (elementAttrs.clip) { var clip = elementAttrs.clip; var clipConfig = isFunction(clip) ? clip(elementAttrs) : clip; elementAttrs.clip = createClipElement(clipConfig.type, clipConfig); } var element; if (type === 'group') { element = container.addGroup(_objectSpread(_objectSpread({}, omit(props, ['children'])), {}, { status: status, attrs: elementAttrs })); // 如果元素被删除了,就不会有renderChildren, 直接拿node.children渲染 var children = renderChildren ? renderChildren : nodeChildren; // 只有group才需要处理children if (children && children.length) { for (var i = 0, len = children.length; i < len; i++) { createElement(children[i], element, layout, animate); } } } else { element = container.addShape(type, _objectSpread(_objectSpread({}, props), {}, { status: status, attrs: elementAttrs })); } if (animate !== false) { element.set('animation', getAnimation(element, animation, elementAttrs, lastAttrs)); } if (ref) { ref.current = element; } return element; } // 过滤删除的元素,让其不参与布局计算 function filterDeleteElement(node) { var status = node.status, children = node.children; if (status === ELEMENT_DELETE) { return null; } if (!children || !children.length) { return node; } var newChildren = children.filter(function (child) { return !!filterDeleteElement(child); }); // 要保留引用 node.children = newChildren; node.renderChildren = children; return node; } function render(element, container, animate) { var px2hd = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : defaultPx2hd; if (!element) { return; } var nodeTree = createNodeTree(element, container, px2hd); var computeLayoutTree = filterDeleteElement(nodeTree); computeLayout(computeLayoutTree); return createElement(nodeTree, container, null, animate); } export { render }; export default (function (element, container, animate) { return render(element, container, animate); });