UNPKG

@data-ui/histogram

Version:

React + d3 library for creating histograms

148 lines (146 loc) 4.52 kB
import PropTypes from 'prop-types'; import React from 'react'; import { NodeGroup } from 'react-move'; import { AreaClosed, LinePath } from '@vx/shape'; import { curveBasis } from '@vx/curve'; import { Group } from '@vx/group'; import { chartTheme } from '@data-ui/theme'; var propTypes = { densityData: PropTypes.arrayOf(PropTypes.object).isRequired, // @TODO shape fill: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), fillOpacity: PropTypes.oneOfType([PropTypes.func, PropTypes.number]), getX: PropTypes.func.isRequired, getY: PropTypes.func.isRequired, horizontal: PropTypes.bool, keyAccessor: PropTypes.func, showArea: PropTypes.bool, showLine: PropTypes.bool, stroke: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), strokeDasharray: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), strokeLinecap: PropTypes.oneOf(['butt', 'square', 'round', 'inherit']), strokeWidth: PropTypes.oneOfType([PropTypes.func, PropTypes.number]), xScale: PropTypes.func.isRequired, yScale: PropTypes.func.isRequired }; var defaultProps = { fill: chartTheme.colors.default, fillOpacity: 0.3, horizontal: false, showArea: true, showLine: true, stroke: chartTheme.colors.default, strokeWidth: 2, strokeDasharray: null, strokeLinecap: 'round', keyAccessor: function keyAccessor(d) { return d.id; } }; var INDEX_DELAY_MULTIPLIER = 10; function AnimatedDensitySeries(_ref) { var densityData = _ref.densityData, fill = _ref.fill, fillOpacity = _ref.fillOpacity, horizontal = _ref.horizontal, keyAccessor = _ref.keyAccessor, getX = _ref.getX, getY = _ref.getY, showArea = _ref.showArea, showLine = _ref.showLine, stroke = _ref.stroke, strokeWidth = _ref.strokeWidth, strokeDasharray = _ref.strokeDasharray, strokeLinecap = _ref.strokeLinecap, xScale = _ref.xScale, yScale = _ref.yScale; var maxY = Math.max.apply(Math, yScale.range()); return React.createElement(NodeGroup, { data: densityData, keyAccessor: keyAccessor, start: function start(d) { if (horizontal) return { x: 0, y: yScale.invert ? yScale(getY(d)) : getY(d) }; return { x: xScale.invert ? xScale(getX(d)) : getX(d), y: maxY }; }, enter: function enter(d, i) { return { x: [xScale.invert ? xScale(getX(d)) : getX(d)], y: [yScale.invert ? yScale(getY(d)) : getY(d)], fill: [d.fill || fill], stroke: [d.stroke || stroke], timing: { duration: 300, delay: INDEX_DELAY_MULTIPLIER * i } }; }, update: function update(d, i) { return { x: [xScale.invert ? xScale(getX(d)) : getX(d)], y: [yScale.invert ? yScale(getY(d)) : getY(d)], fill: [d.fill || fill], stroke: [d.stroke || stroke], timing: { duration: 300, delay: INDEX_DELAY_MULTIPLIER * i } }; }, leave: function leave(d, i) { return { x: xScale.invert ? xScale(getX(d)) : getX(d), y: horizontal ? 0 : maxY, timing: { duration: 300, delay: INDEX_DELAY_MULTIPLIER / 2 * i } }; } }, function (modifiedData) { return React.createElement(Group, { style: { pointerEvents: 'none' } }, showArea && React.createElement(AreaClosed, { data: modifiedData, x: function x(d) { return xScale.invert ? xScale.invert(d.state.x) : d.state.x; }, y: function y(d) { return yScale.invert ? yScale.invert(d.state.y) : d.state.y; }, xScale: xScale, yScale: yScale, fill: fill, fillOpacity: fillOpacity, stroke: "transparent", strokeWidth: strokeWidth, curve: curveBasis }), showLine && strokeWidth > 0 && React.createElement(LinePath, { data: modifiedData, x: function x(d) { return xScale.invert ? xScale.invert(d.state.x) : d.state.x; }, y: function y(d) { return yScale.invert ? yScale.invert(d.state.y) : d.state.y; }, xScale: xScale, yScale: yScale, stroke: stroke, strokeWidth: strokeWidth, strokeDasharray: strokeDasharray, strokeLinecap: strokeLinecap, curve: curveBasis, glyph: null })); }); } AnimatedDensitySeries.propTypes = propTypes; AnimatedDensitySeries.defaultProps = defaultProps; export default AnimatedDensitySeries;