@data-ui/xy-chart
Version:
A package of charts with standard x- and y- axes. https://williaster.github.io/data-ui
241 lines (217 loc) • 7.36 kB
JavaScript
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
import PropTypes from 'prop-types';
import React from 'react';
import { color } from '@data-ui/theme';
import BaseBrush from '../utils/brush/Brush';
import { generalStyleShape, marginShape } from '../utils/propShapes';
import { scaleInvert, getDomainFromExtent } from '../utils/chartUtils';
var SAFE_PIXEL = 2;
export var propTypes = {
selectedBoxStyle: generalStyleShape,
xScale: PropTypes.func,
yScale: PropTypes.func,
innerHeight: PropTypes.number,
innerWidth: PropTypes.number,
onChange: PropTypes.func,
onBrushStart: PropTypes.func,
onBrushEnd: PropTypes.func,
onMouseMove: PropTypes.func,
onMouseLeave: PropTypes.func,
onClick: PropTypes.func,
margin: marginShape,
brushDirection: PropTypes.oneOf(['vertical', 'horizontal', 'both']),
resizeTriggerAreas: PropTypes.arrayOf(PropTypes.oneOf(['left', 'right', 'top', 'bottom', 'topLeft', 'topRight', 'bottomLeft', 'bottomRight'])),
brushRegion: PropTypes.oneOf(['xAxis', 'yAxis', 'chart']),
yAxisOrientation: PropTypes.oneOf(['left', 'right']),
xAxisOrientation: PropTypes.oneOf(['top', 'bottom']),
disableDraggingSelection: PropTypes.bool,
handleSize: PropTypes.number
};
var defaultProps = {
xScale: null,
yScale: null,
onChange: null,
innerHeight: 0,
innerWidth: 0,
selectedBoxStyle: {
fill: color.default,
fillOpacity: 0.2,
stroke: color.default,
strokeWidth: 1,
strokeOpacity: 0.8
},
margin: {
top: 0,
left: 0,
right: 0,
bottom: 0
},
handleSize: 4,
brushDirection: 'horizontal',
resizeTriggerAreas: ['left', 'right'],
brushRegion: 'chart',
yAxisOrientation: 'right',
xAxisOrientation: 'bottom',
onBrushStart: null,
onBrushEnd: null,
disableDraggingSelection: false,
onMouseMove: null,
onMouseLeave: null,
onClick: null
};
var Brush =
/*#__PURE__*/
function (_React$Component) {
_inheritsLoose(Brush, _React$Component);
function Brush(props) {
var _this;
_this = _React$Component.call(this, props) || this;
_this.BaseBrush = null;
_this.handleChange = _this.handleChange.bind(_assertThisInitialized(_assertThisInitialized(_this)));
_this.handleBrushStart = _this.handleBrushStart.bind(_assertThisInitialized(_assertThisInitialized(_this)));
_this.handleBrushEnd = _this.handleBrushEnd.bind(_assertThisInitialized(_assertThisInitialized(_this)));
_this.reset = _this.reset.bind(_assertThisInitialized(_assertThisInitialized(_this)));
return _this;
}
var _proto = Brush.prototype;
_proto.reset = function reset() {
this.BaseBrush.reset();
};
_proto.handleChange = function handleChange(brush) {
var onChange = this.props.onChange;
if (!onChange) return;
var x0 = brush.extent.x0;
if (x0 < 0 || typeof x0 === 'undefined') {
onChange(null);
return;
}
var domain = this.convertRangeToDomain(brush);
onChange(domain);
};
_proto.convertRangeToDomain = function convertRangeToDomain(brush) {
var _this$props = this.props,
xScale = _this$props.xScale,
yScale = _this$props.yScale;
var _brush$extent = brush.extent,
x0 = _brush$extent.x0,
x1 = _brush$extent.x1,
y0 = _brush$extent.y0,
y1 = _brush$extent.y1;
var xDomain = getDomainFromExtent(xScale, x0, x1, SAFE_PIXEL);
var yDomain = getDomainFromExtent(yScale, y0, y1, SAFE_PIXEL);
var domain = {
x0: xDomain.start,
x1: xDomain.end,
xValues: xDomain.values,
y0: yDomain.start,
y1: yDomain.end,
yValues: yDomain.values
};
return domain;
};
_proto.handleBrushStart = function handleBrushStart(point) {
var x = point.x,
y = point.y;
var _this$props2 = this.props,
onBrushStart = _this$props2.onBrushStart,
xScale = _this$props2.xScale,
yScale = _this$props2.yScale;
var invertedX = scaleInvert(xScale, x);
var invertedY = scaleInvert(yScale, y);
if (onBrushStart) {
onBrushStart({
x: xScale.invert ? invertedX : xScale.domain()[invertedX],
y: yScale.invert ? invertedY : yScale.domain()[invertedY]
});
}
};
_proto.handleBrushEnd = function handleBrushEnd(brush) {
var onBrushEnd = this.props.onBrushEnd;
if (!onBrushEnd) return;
var x0 = brush.extent.x0;
if (x0 < 0) {
onBrushEnd(null);
return;
}
var domain = this.convertRangeToDomain(brush);
onBrushEnd(domain);
};
_proto.render = function render() {
var _this2 = this;
var _this$props3 = this.props,
xScale = _this$props3.xScale,
yScale = _this$props3.yScale,
innerHeight = _this$props3.innerHeight,
innerWidth = _this$props3.innerWidth,
margin = _this$props3.margin,
brushDirection = _this$props3.brushDirection,
resizeTriggerAreas = _this$props3.resizeTriggerAreas,
brushRegion = _this$props3.brushRegion,
yAxisOrientation = _this$props3.yAxisOrientation,
xAxisOrientation = _this$props3.xAxisOrientation,
selectedBoxStyle = _this$props3.selectedBoxStyle,
disableDraggingSelection = _this$props3.disableDraggingSelection,
onMouseLeave = _this$props3.onMouseLeave,
onMouseMove = _this$props3.onMouseMove,
onClick = _this$props3.onClick,
handleSize = _this$props3.handleSize;
if (!xScale || !yScale) return null;
var brushRegionWidth;
var brushRegionHeight;
var left;
var top;
if (brushRegion === 'chart') {
left = 0;
top = 0;
brushRegionWidth = innerWidth;
brushRegionHeight = innerHeight;
} else if (brushRegion === 'yAxis') {
top = 0;
brushRegionHeight = innerHeight;
if (yAxisOrientation === 'right') {
left = innerWidth;
brushRegionWidth = margin.right;
} else {
left = -margin.left;
brushRegionWidth = margin.left;
}
} else {
left = 0;
brushRegionWidth = innerWidth;
if (xAxisOrientation === 'bottom') {
top = innerHeight;
brushRegionHeight = margin.bottom;
} else {
top = -margin.top;
brushRegionHeight = margin.top;
}
}
return React.createElement(BaseBrush, {
width: brushRegionWidth,
height: brushRegionHeight,
left: left,
top: top,
inheritedMargin: margin,
onChange: this.handleChange,
onBrushEnd: this.handleBrushEnd,
onBrushStart: this.handleBrushStart,
handleSize: handleSize,
resizeTriggerAreas: resizeTriggerAreas,
brushDirection: brushDirection,
selectedBoxStyle: selectedBoxStyle,
disableDraggingSelection: disableDraggingSelection,
onMouseLeave: onMouseLeave,
onMouseMove: onMouseMove,
onClick: onClick,
ref: function ref(el) {
_this2.BaseBrush = el;
}
});
};
return Brush;
}(React.Component);
Brush.propTypes = propTypes;
Brush.defaultProps = defaultProps;
Brush.displayName = 'Brush';
export default Brush;