UNPKG

@data-ui/xy-chart

Version:

A package of charts with standard x- and y- axes. https://williaster.github.io/data-ui

495 lines (450 loc) 14.8 kB
"use strict"; exports.__esModule = true; exports.default = void 0; var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _group = require("@vx/group"); var _shape = require("@vx/shape"); var _BrushHandle = _interopRequireDefault(require("./BrushHandle")); var _BrushCorner = _interopRequireDefault(require("./BrushCorner")); var _BrushSelection = _interopRequireDefault(require("./BrushSelection")); var _drag = require("../drag"); var _propShapes = require("../propShapes"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } 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; } var propTypes = { brushDirection: _propTypes.default.oneOf(['horizontal', 'vertical', 'both']), width: _propTypes.default.number.isRequired, height: _propTypes.default.number.isRequired, left: _propTypes.default.number.isRequired, top: _propTypes.default.number.isRequired, inheritedMargin: _propShapes.marginShape, onChange: _propTypes.default.func, handleSize: _propTypes.default.number, resizeTriggerAreas: _propTypes.default.arrayOf(_propTypes.default.oneOf(['left', 'right', 'top', 'bottom', 'topLeft', 'topRight', 'bottomLeft', 'bottomRight'])), onBrushStart: _propTypes.default.func, onBrushEnd: _propTypes.default.func, selectedBoxStyle: _propShapes.generalStyleShape.isRequired, onMouseLeave: _propTypes.default.func, onMouseUp: _propTypes.default.func, onMouseMove: _propTypes.default.func, onClick: _propTypes.default.func, clickSensitivity: _propTypes.default.number, disableDraggingSelection: _propTypes.default.bool }; var defaultProps = { brushDirection: 'both', inheritedMargin: { left: 0, top: 0, right: 0, bottom: 0 }, onChange: null, handleSize: 4, resizeTriggerAreas: ['left', 'right'], onBrushStart: null, onBrushEnd: null, onMouseLeave: null, onMouseUp: null, onMouseMove: null, onClick: null, disableDraggingSelection: false, clickSensitivity: 200 }; var Brush = /*#__PURE__*/ function (_React$Component) { _inheritsLoose(Brush, _React$Component); function Brush(props) { var _this; _this = _React$Component.call(this, props) || this; var width = props.width, height = props.height; _this.state = { start: { x: 0, y: 0 }, end: { x: 0, y: 0 }, extent: { x0: 0, x1: 0, y0: 0, y1: 0 }, bounds: { x0: 0, x1: width, y0: 0, y1: height } }; _this.width = _this.width.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.height = _this.height.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.handles = _this.handles.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.corners = _this.corners.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.update = _this.update.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.reset = _this.reset.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.handleDragStart = _this.handleDragStart.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.handleDragMove = _this.handleDragMove.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.handleDragEnd = _this.handleDragEnd.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.getExtent = _this.getExtent.bind(_assertThisInitialized(_assertThisInitialized(_this))); _this.mouseUpTime = 0; _this.mouseDownTime = 0; return _this; } var _proto = Brush.prototype; _proto.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { var _this2 = this; if (['width', 'height'].some(function (prop) { return _this2.props[prop] !== nextProps[prop]; } // eslint-disable-line react/destructuring-assignment )) { this.setState(function () { return { bounds: { x0: 0, x1: nextProps.width, y0: 0, y1: nextProps.height } }; }); } }; _proto.getExtent = function getExtent(start, end) { var _this$props = this.props, brushDirection = _this$props.brushDirection, width = _this$props.width, height = _this$props.height; var x0 = brushDirection === 'vertical' ? 0 : Math.min(start.x, end.x); var x1 = brushDirection === 'vertical' ? width : Math.max(start.x, end.x); var y0 = brushDirection === 'horizontal' ? 0 : Math.min(start.y, end.y); var y1 = brushDirection === 'horizontal' ? height : Math.max(start.y, end.y); return { x0: x0, x1: x1, y0: y0, y1: y1 }; }; _proto.handleDragStart = function handleDragStart(draw) { var _this$props2 = this.props, onBrushStart = _this$props2.onBrushStart, left = _this$props2.left, top = _this$props2.top, inheritedMargin = _this$props2.inheritedMargin; var start = { x: draw.x + draw.dx - left - inheritedMargin.left, y: draw.y + draw.dy - top - inheritedMargin.top }; var end = _extends({}, start); if (onBrushStart) { onBrushStart(start); } this.update(function (prevBrush) { return _extends({}, prevBrush, { start: start, end: end, extent: { x0: -1, x1: -1, y0: -1, y1: -1 }, isBrushing: true }); }); }; _proto.handleDragMove = function handleDragMove(draw) { var _this3 = this; var _this$props3 = this.props, left = _this$props3.left, top = _this$props3.top, inheritedMargin = _this$props3.inheritedMargin; if (!draw.isDragging) return; var end = { x: draw.x + draw.dx - left - inheritedMargin.left, y: draw.y + draw.dy - top - inheritedMargin.top }; this.update(function (prevBrush) { var start = prevBrush.start; var extent = _this3.getExtent(start, end); return _extends({}, prevBrush, { end: end, extent: extent }); }); }; _proto.handleDragEnd = function handleDragEnd() { var onBrushEnd = this.props.onBrushEnd; this.update(function (prevBrush) { var extent = prevBrush.extent; var newState = _extends({}, prevBrush, { start: { x: extent.x0, y: extent.y0 }, end: { x: extent.x1, y: extent.y1 }, isBrushing: false }); if (onBrushEnd) { onBrushEnd(newState); } return newState; }); }; _proto.width = function width() { var extent = this.state.extent; var x0 = extent.x0, x1 = extent.x1; return Math.max(Math.max(x0, x1) - Math.min(x0, x1), 0); }; _proto.height = function height() { var extent = this.state.extent; var y1 = extent.y1, y0 = extent.y0; return Math.max(y1 - y0, 0); }; _proto.handles = function handles() { var handleSize = this.props.handleSize; var extent = this.state.extent; var x0 = extent.x0, x1 = extent.x1, y0 = extent.y0, y1 = extent.y1; var offset = handleSize / 2; var width = this.width(); var height = this.height(); return { top: { x: x0 - offset, y: y0 - offset, height: handleSize, width: width + handleSize }, bottom: { x: x0 - offset, y: y1 - offset, height: handleSize, width: width + handleSize }, right: { x: x1 - offset, y: y0 - offset, height: height + handleSize, width: handleSize }, left: { x: x0 - offset, y: y0 - offset, height: height + handleSize, width: handleSize } }; }; _proto.corners = function corners() { var handleSize = this.props.handleSize; var extent = this.state.extent; var x0 = extent.x0, x1 = extent.x1, y0 = extent.y0, y1 = extent.y1; var offset = handleSize / 2; return { topLeft: { x: Math.min(x0, x1) - offset, y: Math.min(y0, y1) - offset }, topRight: { x: Math.max(x0, x1) - offset, y: Math.min(y0, y1) - offset }, bottomLeft: { x: Math.min(x0, x1) - offset, y: Math.max(y0, y1) - offset }, bottomRight: { x: Math.max(x0, x1) - offset, y: Math.max(y0, y1) - offset } }; }; _proto.update = function update(updater) { var _this4 = this; var onChange = this.props.onChange; this.setState(updater, function () { if (onChange) { onChange(_this4.state); } }); }; _proto.reset = function reset() { var _this$props4 = this.props, width = _this$props4.width, height = _this$props4.height; this.update(function () { return { start: undefined, end: undefined, extent: { x0: undefined, x1: undefined, y0: undefined, y1: undefined }, bounds: { x0: 0, x1: width, y0: 0, y1: height }, isBrushing: false, activeHandle: undefined }; }); }; _proto.render = function render() { var _this5 = this; var _this$state = this.state, start = _this$state.start, end = _this$state.end; var _this$props5 = this.props, top = _this$props5.top, left = _this$props5.left, stageWidth = _this$props5.width, stageHeight = _this$props5.height, handleSize = _this$props5.handleSize, _onMouseLeave = _this$props5.onMouseLeave, _onMouseUp = _this$props5.onMouseUp, _onMouseMove = _this$props5.onMouseMove, onBrushEnd = _this$props5.onBrushEnd, _onClick = _this$props5.onClick, resizeTriggerAreas = _this$props5.resizeTriggerAreas, selectedBoxStyle = _this$props5.selectedBoxStyle, disableDraggingSelection = _this$props5.disableDraggingSelection, clickSensitivity = _this$props5.clickSensitivity; var handles = this.handles(); var corners = this.corners(); var width = this.width(); var height = this.height(); var resizeTriggerAreaSet = new Set(resizeTriggerAreas); return _react.default.createElement(_group.Group, { className: "vx-brush", top: top, left: left }, _react.default.createElement(_drag.Drag, { width: stageWidth, height: stageHeight, resetOnStart: true, onDragStart: this.handleDragStart, onDragMove: this.handleDragMove, onDragEnd: this.handleDragEnd }, function (draw) { return _react.default.createElement(_shape.Bar, { className: "vx-brush-overlay", fill: "transparent", x: 0, y: 0, width: stageWidth, height: stageHeight, onDoubleClick: function onDoubleClick() { return function (event) { return _this5.reset(event); }; }, onClick: function onClick() { return function (event) { var duration = _this5.mouseUpTime - _this5.mouseDownTime; if (_onClick && duration < clickSensitivity) _onClick(event); }; }, onMouseDown: function onMouseDown() { return function (event) { _this5.mouseDownTime = new Date(); draw.dragStart(event); }; }, onMouseLeave: function onMouseLeave() { return function (event) { if (_onMouseLeave) _onMouseLeave(event); }; }, onMouseMove: function onMouseMove() { return function (event) { if (!draw.isDragging && _onMouseMove) _onMouseMove(event); if (draw.isDragging) draw.dragMove(event); }; }, onMouseUp: function onMouseUp() { return function (event) { _this5.mouseUpTime = new Date(); if (_onMouseUp) _onMouseUp(event); draw.dragEnd(event); }; }, style: { cursor: 'crosshair' } }); }), start && end && _react.default.createElement(_BrushSelection.default, _extends({ updateBrush: this.update, width: width, height: height, stageWidth: stageWidth, stageHeight: stageHeight, brush: _extends({}, this.state), disableDraggingSelection: disableDraggingSelection, onBrushEnd: onBrushEnd, onMouseLeave: _onMouseLeave, onMouseMove: _onMouseMove, onMouseUp: _onMouseUp, onClick: _onClick }, selectedBoxStyle)), start && end && Object.keys(handles).filter(function (handleKey) { return resizeTriggerAreaSet.has(handleKey); }).map(function (handleKey) { var handle = handles[handleKey]; return _react.default.createElement(_BrushHandle.default, { key: "handle-" + handleKey, type: handleKey, handle: handle, stageWidth: stageWidth, stageHeight: stageHeight, updateBrush: _this5.update, brush: _this5.state, onBrushEnd: onBrushEnd }); }), start && end && Object.keys(corners).filter(function (cornerKey) { return resizeTriggerAreaSet.has(cornerKey); }).map(function (cornerKey) { var corner = corners[cornerKey]; return _react.default.createElement(_BrushCorner.default, { key: "corner-" + cornerKey, type: cornerKey, brush: _this5.state, updateBrush: _this5.update, stageWidth: stageWidth, stageHeight: stageHeight, x: corner.x, y: corner.y, width: handleSize, height: handleSize, onBrushEnd: onBrushEnd, fill: "transparent" }); })); }; return Brush; }(_react.default.Component); exports.default = Brush; Brush.propTypes = propTypes; Brush.defaultProps = defaultProps;