UNPKG

@data-ui/histogram

Version:

React + d3 library for creating histograms

122 lines (119 loc) 4.14 kB
import PropTypes from 'prop-types'; import React from 'react'; import { chartTheme } from '@data-ui/theme'; import { Group } from '@vx/group'; import { Bar } from '@vx/shape'; import AnimatedBarSeries from './animated/AnimatedBarSeries'; import callOrValue from '../utils/callOrValue'; import { binnedDataShape } from '../utils/propShapes'; export var propTypes = { animated: PropTypes.bool, rawData: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string])), // eslint-disable-line react/no-unused-prop-types binnedData: binnedDataShape, fill: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), fillOpacity: PropTypes.oneOfType([PropTypes.func, PropTypes.number]), horizontal: PropTypes.bool, stroke: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), strokeWidth: PropTypes.oneOfType([PropTypes.func, PropTypes.number]), valueKey: PropTypes.string, onClick: PropTypes.func, // likely injected by parent Histogram binScale: PropTypes.func, valueScale: PropTypes.func, onMouseMove: PropTypes.func, onMouseLeave: PropTypes.func }; export var defaultProps = { animated: true, rawData: [], binnedData: [], binScale: null, fill: chartTheme.colors.default, fillOpacity: 0.7, horizontal: false, onClick: null, onMouseMove: null, onMouseLeave: null, stroke: '#FFFFFF', strokeWidth: 1, valueKey: 'count', valueScale: null }; function BarSeries(_ref) { var animated = _ref.animated, binnedData = _ref.binnedData, binScale = _ref.binScale, fill = _ref.fill, fillOpacity = _ref.fillOpacity, horizontal = _ref.horizontal, onClick = _ref.onClick, onMouseMove = _ref.onMouseMove, onMouseLeave = _ref.onMouseLeave, stroke = _ref.stroke, strokeWidth = _ref.strokeWidth, valueKey = _ref.valueKey, valueScale = _ref.valueScale; if (!binScale || !valueScale || !binnedData || binnedData.length === 0) return null; var maxBarLength = Math.max.apply(Math, valueScale.range()); return React.createElement(Group, null, animated && React.createElement(AnimatedBarSeries, { binnedData: binnedData, binScale: binScale, horizontal: horizontal, fill: fill, fillOpacity: fillOpacity, onClick: onClick, onMouseMove: onMouseMove, onMouseLeave: onMouseLeave, stroke: stroke, strokeWidth: strokeWidth, valueKey: valueKey, valueScale: valueScale }), !animated && binnedData.map(function (d, i) { var binPosition = binScale(d.bin || (horizontal ? d.bin1 : d.bin0)); var barLength = horizontal ? valueScale(d[valueKey]) : maxBarLength - valueScale(d[valueKey]); var barWidth = binScale.bandwidth ? binScale.bandwidth() // categorical : Math.abs(binScale(binnedData[i].bin1) - binScale(binnedData[i].bin0)); // numeric var color = d.fill || callOrValue(fill, d, i); return React.createElement(Bar, { key: "bar-" + binPosition, x: horizontal ? 0 : binPosition, y: horizontal ? binPosition : maxBarLength - barLength, width: horizontal ? barLength : barWidth, height: horizontal ? barWidth : barLength, fill: color, fillOpacity: typeof fillOpacity === 'undefined' ? callOrValue(fillOpacity, d, i) : fillOpacity, stroke: d.stroke || callOrValue(stroke, d, i), strokeWidth: d.strokeWidth || callOrValue(strokeWidth, d, i), onClick: onClick && function () { return function (event) { onClick({ event: event, data: binnedData, datum: d, color: color, index: i }); }; }, onMouseMove: onMouseMove && function () { return function (event) { onMouseMove({ event: event, data: binnedData, datum: d, color: color, index: i }); }; }, onMouseLeave: onMouseLeave && function () { return onMouseLeave; } }); })); } BarSeries.propTypes = propTypes; BarSeries.defaultProps = defaultProps; BarSeries.displayName = 'BarSeries'; export default BarSeries;