UNPKG

rumble-charts

Version:

Truly declarative React charts components

84 lines (81 loc) 4.23 kB
import { __rest, __assign } from './external/tslib/tslib.es6.js'; import React, { useState, useRef, useMemo, useEffect } from 'react'; import { timer } from 'd3-timer'; import { interpolate } from 'd3-interpolate'; import './helpers/colorFunc.js'; import 'd3-shape'; import { eases } from './helpers/eases.js'; import { isFunction } from './helpers/isFunction.js'; import { isString } from './helpers/isString.js'; import { isUndefined } from './helpers/isUndefined.js'; import { normalizeSeries } from './helpers/normalizeSeries.js'; import { omitBy } from './helpers/omitBy.js'; import { pick } from './helpers/pick.js'; import { proxyChildren } from './helpers/proxyChildren.js'; /** * Animates (actually interpolates) your `series` data. Very useful when you want to have * simple and nice transitions between data state. * * As a wrapper it takes `series` obtained from its parent and gives it to its children. * * By default, `interpolateProps` list contains all the common props: * ['series', 'maxX', 'maxY', 'minX', 'minY', 'layerWidth', 'layerHeight']. * Though, sometimes it makes a lot of sense to interpolate only `series`. Especially, when the * components wrapped by `<Animate>` are "jumping". Also, you can explicitly define `minY` as a prop * to make the limits stable (and therefore prevent the "jumping" effect) */ function Animate(props) { var _a = props.interpolateProps, interpolateProps = _a === void 0 ? ['series', 'maxX', 'maxY', 'minX', 'minY', 'layerWidth', 'layerHeight'] : _a, _b = props.duration, duration = _b === void 0 ? 500 : _b, _c = props.ease, ease = _c === void 0 ? 'linear' : _c, _d = props.tag, tag = _d === void 0 ? 'g' : _d, onStart = props.onStart, onEnd = props.onEnd, onCancel = props.onCancel, logFPS = props.logFPS, pickProps = __rest(props, ["interpolateProps", "duration", "ease", "tag", "onStart", "onEnd", "onCancel", "logFPS"]); var _e = useState(function () { return (__assign(__assign({}, pickProps), normalizeSeries(pickProps))); }), state = _e[0], setState = _e[1]; var prevPropsRef = useRef(props); var newPropsRef = useRef(); newPropsRef.current = useMemo(function () { var newProps = Object.keys(pickProps).reduce(function (newProps, propName) { var _a; if (pickProps[propName] !== ((_a = prevPropsRef.current) === null || _a === void 0 ? void 0 : _a[propName])) { newProps[propName] = pickProps[propName]; } return newProps; }, {}); return Object.keys(newProps).length > 0 ? newProps : null; }, [props !== prevPropsRef.current]) || newPropsRef.current; prevPropsRef.current = props; useEffect(function () { var newProps = newPropsRef.current; if (!newProps) { return; } var interpolate$1 = interpolate(pick(state, interpolateProps), pick(__assign(__assign({}, newProps), normalizeSeries(newProps)), interpolateProps)); var easeFunc = isString(ease) ? eases[ease] : (isFunction(ease) ? ease : eases['linear']); onStart && onStart(); var i = 0; var _timer = timer(function (p) { i++; if (p >= duration) { p = duration; setState(function (state) { return (__assign(__assign({}, state), interpolate$1(easeFunc(p / duration)))); }); onEnd && onEnd(); if (logFPS) { console.warn(i * (1000 / duration) + 'fps; ' + i + ' frames in ' + duration + 'ms'); } _timer.stop(); } else { setState(function (state) { return (__assign(__assign({}, state), interpolate$1(easeFunc(p / duration)))); }); } }); return function () { onCancel && onCancel(); _timer.stop(); }; }, [newPropsRef.current]); return React.createElement(tag, { className: pickProps.className }, proxyChildren(pickProps.children, omitBy(state, isUndefined), { layerWidth: state.layerWidth, layerHeight: state.layerHeight, scaleX: pickProps.scaleX, scaleY: pickProps.scaleY })); } export { Animate };