@data-ui/sparkline
Version:
React + d3 library for creating sparklines
120 lines (106 loc) • 3.67 kB
JavaScript
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
import PropTypes from 'prop-types';
import React from 'react';
import { quantile } from 'd3-array';
import Bar from '@vx/shape/build/shapes/Bar';
import { color } from '@data-ui/theme';
export var propTypes = {
band: PropTypes.oneOfType([PropTypes.shape({
from: PropTypes.shape({
// @TODO check that it's a length of 2
x: PropTypes.number,
y: PropTypes.number
}),
to: PropTypes.shape({
// @TODO check that it's a length of 2
x: PropTypes.number,
y: PropTypes.number
})
}), PropTypes.oneOf(['innerquartiles'])]),
fill: PropTypes.string,
fillOpacity: PropTypes.number,
stroke: PropTypes.string,
strokeWidth: PropTypes.number,
// all likely passed by the parent chart
data: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.object])),
getY: PropTypes.func,
xScale: PropTypes.func,
yScale: PropTypes.func
};
export var defaultProps = {
band: 'innerquartiles',
data: [],
fill: color.lightGray,
fillOpacity: 0.5,
getY: null,
stroke: 'transparent',
strokeWidth: 0,
xScale: null,
yScale: null
};
var BandLine =
/*#__PURE__*/
function (_React$PureComponent) {
_inheritsLoose(BandLine, _React$PureComponent);
function BandLine() {
return _React$PureComponent.apply(this, arguments) || this;
}
var _proto = BandLine.prototype;
_proto.render = function render() {
var _this$props = this.props,
band = _this$props.band,
data = _this$props.data,
fill = _this$props.fill,
fillOpacity = _this$props.fillOpacity,
getY = _this$props.getY,
stroke = _this$props.stroke,
strokeWidth = _this$props.strokeWidth,
xScale = _this$props.xScale,
yScale = _this$props.yScale;
if (!xScale || !yScale || !getY || !data.length) return null;
var _xScale$range = xScale.range(),
x0 = _xScale$range[0],
x1 = _xScale$range[1];
var _yScale$range = yScale.range(),
y1 = _yScale$range[0],
y0 = _yScale$range[1];
var x = 0;
var y = 0;
var width = 0;
var height = 0;
if (band === 'innerquartiles') {
var sortedData = [].concat(data).sort(function (a, b) {
return parseFloat(getY(a)) - parseFloat(getY(b));
});
var lowerQuartile = yScale(quantile(sortedData, 0.25, getY)); // eslint-disable-line no-magic-numbers
var upperQuartile = yScale(quantile(sortedData, 0.75, getY)); // eslint-disable-line no-magic-numbers
y = Math.min(lowerQuartile, upperQuartile);
height = Math.abs(upperQuartile - lowerQuartile);
x = x0;
width = x1 - x0;
} else {
// input points are assumed to be values so we must scale them
var yFrom = typeof band.from.y === 'undefined' ? y0 : yScale(band.from.y);
var yTo = typeof band.to.y === 'undefined' ? y1 : yScale(band.to.y);
y = Math.min(yFrom, yTo);
height = Math.abs(yFrom - yTo);
x = typeof band.from.x === 'undefined' ? x0 : xScale(band.from.x);
width = (typeof band.to.x === 'undefined' ? x1 : xScale(band.to.x)) - x;
}
return React.createElement(Bar, {
x: x,
y: y,
width: width,
height: height,
fill: fill,
fillOpacity: fillOpacity,
stroke: stroke,
strokeWidth: strokeWidth
});
};
return BandLine;
}(React.PureComponent);
BandLine.propTypes = propTypes;
BandLine.defaultProps = defaultProps;
BandLine.displayName = 'BandLine';
export default BandLine;