@data-ui/histogram
Version:
React + d3 library for creating histograms
122 lines (119 loc) • 4.14 kB
JavaScript
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;