UNPKG

@visactor/openinula-vchart

Version:

The openinula version of VChart 4.x

99 lines (90 loc) 5.66 kB
import React, { useState, useEffect, useRef, useImperativeHandle } from "openinula"; import withContainer from "../containers/withContainer"; import RootChartContext from "../context/chart"; import { isEqual, isNil, pickWithout } from "@visactor/vutils"; import { toArray } from "../util"; import { REACT_PRIVATE_PROPS } from "../constants"; import { bindEventsToChart, CHART_EVENTS_KEYS, CHART_EVENTS } from "../eventsUtils"; import { initCustomTooltip } from "../components/tooltip/util"; const notSpecKeys = [ ...REACT_PRIVATE_PROPS, ...CHART_EVENTS_KEYS, "vchartConstructor", "vchartConstrouctor", "useSyncRender", "skipFunctionDiff", "onError", "onReady", "spec", "container", "options" ], getComponentId = (child, index) => `${child && child.type && (child.type.displayName || child.type.name)}-${index}`, parseSpecFromChildren = props => { const specFromChildren = {}; return toArray(props.children).map(((child, index) => { const parseSpec = child && child.type && child.type.parseSpec; if (parseSpec && child.props) { const specResult = parseSpec(isNil(child.props.componentId) ? Object.assign(Object.assign({}, child.props), { componentId: getComponentId(child, index) }) : child.props); specResult.isSingle ? specFromChildren[specResult.specName] = specResult.spec : (specFromChildren[specResult.specName] || (specFromChildren[specResult.specName] = []), specFromChildren[specResult.specName].push(specResult.spec)); } })), specFromChildren; }, BaseChart = React.forwardRef(((props, ref) => { const [updateId, setUpdateId] = useState(0), chartContext = useRef({}); useImperativeHandle(ref, (() => { var _a; return null === (_a = chartContext.current) || void 0 === _a ? void 0 : _a.chart; })); const hasSpec = !!props.spec, isUnmount = useRef(!1), prevSpec = useRef(pickWithout(props, notSpecKeys)), specFromChildren = useRef(null), eventsBinded = React.useRef(null), skipFunctionDiff = !!props.skipFunctionDiff, [tooltipNode, setTooltipNode] = useState(null), parseSpec = props => { let spec; spec = hasSpec && props.spec ? props.spec : Object.assign(Object.assign({}, prevSpec.current), specFromChildren.current); const tooltipSpec = initCustomTooltip(setTooltipNode, props, spec.tooltip); return tooltipSpec && (spec.tooltip = tooltipSpec), spec; }, handleChartRender = () => { if (!isUnmount.current) { if (!chartContext.current || !chartContext.current.chart) return; bindEventsToChart(chartContext.current.chart, props, eventsBinded.current, CHART_EVENTS), setUpdateId(updateId + 1), props.onReady && props.onReady(chartContext.current.chart, 0 === updateId); } }; return useEffect((() => { var _a; const newSpecFromChildren = hasSpec ? null : parseSpecFromChildren(props); if (!(null === (_a = chartContext.current) || void 0 === _a ? void 0 : _a.chart)) return hasSpec || (specFromChildren.current = newSpecFromChildren), (props => { var _a; const cs = new (null !== (_a = props.vchartConstructor) && void 0 !== _a ? _a : props.vchartConstrouctor)(parseSpec(props), Object.assign(Object.assign({}, props.options), { onError: props.onError, autoFit: !0, dom: props.container })); chartContext.current = Object.assign(Object.assign({}, chartContext.current), { chart: cs }), isUnmount.current = !1; })(props), chartContext.current.chart && (chartContext.current.chart.renderSync({ reuse: !1 }), handleChartRender()), void (eventsBinded.current = props); if (hasSpec) return void (isEqual(eventsBinded.current.spec, props.spec, { skipFunction: skipFunctionDiff }) || (eventsBinded.current = props, chartContext.current.chart.updateSpecSync(parseSpec(props), void 0, { morph: !1, enableExitAnimation: !1 }), handleChartRender())); const newSpec = pickWithout(props, notSpecKeys); isEqual(newSpec, prevSpec.current, { skipFunction: skipFunctionDiff }) && isEqual(newSpecFromChildren, specFromChildren.current) || (prevSpec.current = newSpec, specFromChildren.current = newSpecFromChildren, chartContext.current.chart.updateSpecSync(parseSpec(props), void 0, { morph: !1, enableExitAnimation: !1 }), handleChartRender()); }), [ props ]), useEffect((() => () => { chartContext && chartContext.current && chartContext.current.chart && (chartContext.current.chart.release(), chartContext.current.chart = null), eventsBinded.current = null, isUnmount.current = !0; }), []), React.createElement(RootChartContext.Provider, { value: chartContext.current }, toArray(props.children).map(((child, index) => { if ("string" == typeof child) return; const childId = getComponentId(child, index); return React.createElement(React.Fragment, { key: childId }, React.cloneElement(child, { updateId: updateId, componentId: childId })); })), tooltipNode); })); export const createChart = (componentName, defaultProps, callback) => { const Com = withContainer(BaseChart, componentName, (props => callback ? callback(props, defaultProps) : defaultProps ? Object.assign(props, defaultProps) : props)); return Com.displayName = componentName, Com; }; //# sourceMappingURL=BaseChart.js.map