Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 

409 wiersze
14 KiB

  1. var _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; };
  2. var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  3. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  5. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  6. import React from 'react';
  7. import AbstractSeries from './series/abstract-series';
  8. import { getAttributeScale } from '../utils/scales-utils';
  9. import PropTypes from 'prop-types';
  10. function getLocs(evt) {
  11. var xLoc = evt.type === 'touchstart' ? evt.pageX : evt.offsetX;
  12. var yLoc = evt.type === 'touchstart' ? evt.pageY : evt.offsetY;
  13. return { xLoc: xLoc, yLoc: yLoc };
  14. }
  15. var Highlight = function (_AbstractSeries) {
  16. _inherits(Highlight, _AbstractSeries);
  17. function Highlight() {
  18. var _ref;
  19. var _temp, _this, _ret;
  20. _classCallCheck(this, Highlight);
  21. for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
  22. args[_key] = arguments[_key];
  23. }
  24. return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = Highlight.__proto__ || Object.getPrototypeOf(Highlight)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
  25. dragging: false,
  26. brushArea: { top: 0, right: 0, bottom: 0, left: 0 },
  27. brushing: false,
  28. startLocX: 0,
  29. startLocY: 0,
  30. dragArea: null
  31. }, _temp), _possibleConstructorReturn(_this, _ret);
  32. }
  33. _createClass(Highlight, [{
  34. key: '_getDrawArea',
  35. value: function _getDrawArea(xLoc, yLoc) {
  36. var _state = this.state,
  37. startLocX = _state.startLocX,
  38. startLocY = _state.startLocY;
  39. var _props = this.props,
  40. enableX = _props.enableX,
  41. enableY = _props.enableY,
  42. highlightWidth = _props.highlightWidth,
  43. highlightHeight = _props.highlightHeight,
  44. innerWidth = _props.innerWidth,
  45. innerHeight = _props.innerHeight,
  46. marginLeft = _props.marginLeft,
  47. marginRight = _props.marginRight,
  48. marginBottom = _props.marginBottom,
  49. marginTop = _props.marginTop;
  50. var plotHeight = innerHeight + marginTop + marginBottom;
  51. var plotWidth = innerWidth + marginLeft + marginRight;
  52. var touchWidth = highlightWidth || plotWidth;
  53. var touchHeight = highlightHeight || plotHeight;
  54. return {
  55. bottom: enableY ? Math.max(startLocY, yLoc) : touchHeight,
  56. right: enableX ? Math.max(startLocX, xLoc) : touchWidth,
  57. left: enableX ? Math.min(xLoc, startLocX) : 0,
  58. top: enableY ? Math.min(yLoc, startLocY) : 0
  59. };
  60. }
  61. }, {
  62. key: '_getDragArea',
  63. value: function _getDragArea(xLoc, yLoc) {
  64. var _props2 = this.props,
  65. enableX = _props2.enableX,
  66. enableY = _props2.enableY;
  67. var _state2 = this.state,
  68. startLocX = _state2.startLocX,
  69. startLocY = _state2.startLocY,
  70. dragArea = _state2.dragArea;
  71. return {
  72. bottom: dragArea.bottom + (enableY ? yLoc - startLocY : 0),
  73. left: dragArea.left + (enableX ? xLoc - startLocX : 0),
  74. right: dragArea.right + (enableX ? xLoc - startLocX : 0),
  75. top: dragArea.top + (enableY ? yLoc - startLocY : 0)
  76. };
  77. }
  78. }, {
  79. key: '_clickedOutsideDrag',
  80. value: function _clickedOutsideDrag(xLoc, yLoc) {
  81. var _props3 = this.props,
  82. enableX = _props3.enableX,
  83. enableY = _props3.enableY;
  84. var _state3 = this.state,
  85. dragArea = _state3.dragArea,
  86. _state3$brushArea = _state3.brushArea,
  87. left = _state3$brushArea.left,
  88. right = _state3$brushArea.right,
  89. top = _state3$brushArea.top,
  90. bottom = _state3$brushArea.bottom;
  91. var clickedOutsideDragX = dragArea && (xLoc < left || xLoc > right);
  92. var clickedOutsideDragY = dragArea && (yLoc < top || yLoc > bottom);
  93. if (enableX && enableY) {
  94. return clickedOutsideDragX || clickedOutsideDragY;
  95. }
  96. if (enableX) {
  97. return clickedOutsideDragX;
  98. }
  99. if (enableY) {
  100. return clickedOutsideDragY;
  101. }
  102. return true;
  103. }
  104. }, {
  105. key: '_convertAreaToCoordinates',
  106. value: function _convertAreaToCoordinates(brushArea) {
  107. // NOTE only continuous scales are supported for brushing/getting coordinates back
  108. var _props4 = this.props,
  109. enableX = _props4.enableX,
  110. enableY = _props4.enableY,
  111. marginLeft = _props4.marginLeft,
  112. marginTop = _props4.marginTop;
  113. var xScale = getAttributeScale(this.props, 'x');
  114. var yScale = getAttributeScale(this.props, 'y');
  115. // Ensure that users wishes are being respected about which scales are evaluated
  116. // this is specifically enabled to ensure brushing on mixed categorical and linear
  117. // charts will run as expected
  118. if (enableX && enableY) {
  119. return {
  120. bottom: yScale.invert(brushArea.bottom),
  121. left: xScale.invert(brushArea.left - marginLeft),
  122. right: xScale.invert(brushArea.right - marginLeft),
  123. top: yScale.invert(brushArea.top)
  124. };
  125. }
  126. if (enableY) {
  127. return {
  128. bottom: yScale.invert(brushArea.bottom - marginTop),
  129. top: yScale.invert(brushArea.top - marginTop)
  130. };
  131. }
  132. if (enableX) {
  133. return {
  134. left: xScale.invert(brushArea.left - marginLeft),
  135. right: xScale.invert(brushArea.right - marginLeft)
  136. };
  137. }
  138. return {};
  139. }
  140. }, {
  141. key: 'startBrushing',
  142. value: function startBrushing(e) {
  143. var _this2 = this;
  144. var _props5 = this.props,
  145. onBrushStart = _props5.onBrushStart,
  146. onDragStart = _props5.onDragStart,
  147. drag = _props5.drag;
  148. var dragArea = this.state.dragArea;
  149. var _getLocs = getLocs(e.nativeEvent),
  150. xLoc = _getLocs.xLoc,
  151. yLoc = _getLocs.yLoc;
  152. var startArea = function startArea(dragging, resetDrag) {
  153. var emptyBrush = {
  154. bottom: yLoc,
  155. left: xLoc,
  156. right: xLoc,
  157. top: yLoc
  158. };
  159. _this2.setState({
  160. dragging: dragging,
  161. brushArea: dragArea && !resetDrag ? dragArea : emptyBrush,
  162. brushing: !dragging,
  163. startLocX: xLoc,
  164. startLocY: yLoc
  165. });
  166. };
  167. var clickedOutsideDrag = this._clickedOutsideDrag(xLoc, yLoc);
  168. if (drag && !dragArea || !drag || clickedOutsideDrag) {
  169. startArea(false, clickedOutsideDrag);
  170. if (onBrushStart) {
  171. onBrushStart(e);
  172. }
  173. return;
  174. }
  175. if (drag && dragArea) {
  176. startArea(true, clickedOutsideDrag);
  177. if (onDragStart) {
  178. onDragStart(e);
  179. }
  180. }
  181. }
  182. }, {
  183. key: 'stopBrushing',
  184. value: function stopBrushing(e) {
  185. var _state4 = this.state,
  186. brushing = _state4.brushing,
  187. dragging = _state4.dragging,
  188. brushArea = _state4.brushArea;
  189. // Quickly short-circuit if the user isn't brushing in our component
  190. if (!brushing && !dragging) {
  191. return;
  192. }
  193. var _props6 = this.props,
  194. onBrushEnd = _props6.onBrushEnd,
  195. onDragEnd = _props6.onDragEnd,
  196. drag = _props6.drag;
  197. var noHorizontal = Math.abs(brushArea.right - brushArea.left) < 5;
  198. var noVertical = Math.abs(brushArea.top - brushArea.bottom) < 5;
  199. // Invoke the callback with null if the selected area was < 5px
  200. var isNulled = noVertical || noHorizontal;
  201. // Clear the draw area
  202. this.setState({
  203. brushing: false,
  204. dragging: false,
  205. brushArea: drag ? brushArea : { top: 0, right: 0, bottom: 0, left: 0 },
  206. startLocX: 0,
  207. startLocY: 0,
  208. dragArea: drag && !isNulled && brushArea
  209. });
  210. if (brushing && onBrushEnd) {
  211. onBrushEnd(!isNulled ? this._convertAreaToCoordinates(brushArea) : null);
  212. }
  213. if (drag && onDragEnd) {
  214. onDragEnd(!isNulled ? this._convertAreaToCoordinates(brushArea) : null);
  215. }
  216. }
  217. }, {
  218. key: 'onBrush',
  219. value: function onBrush(e) {
  220. var _props7 = this.props,
  221. onBrush = _props7.onBrush,
  222. onDrag = _props7.onDrag,
  223. drag = _props7.drag;
  224. var _state5 = this.state,
  225. brushing = _state5.brushing,
  226. dragging = _state5.dragging;
  227. var _getLocs2 = getLocs(e.nativeEvent),
  228. xLoc = _getLocs2.xLoc,
  229. yLoc = _getLocs2.yLoc;
  230. if (brushing) {
  231. var brushArea = this._getDrawArea(xLoc, yLoc);
  232. this.setState({ brushArea: brushArea });
  233. if (onBrush) {
  234. onBrush(this._convertAreaToCoordinates(brushArea));
  235. }
  236. }
  237. if (drag && dragging) {
  238. var _brushArea = this._getDragArea(xLoc, yLoc);
  239. this.setState({ brushArea: _brushArea });
  240. if (onDrag) {
  241. onDrag(this._convertAreaToCoordinates(_brushArea));
  242. }
  243. }
  244. }
  245. }, {
  246. key: 'render',
  247. value: function render() {
  248. var _this3 = this;
  249. var _props8 = this.props,
  250. color = _props8.color,
  251. className = _props8.className,
  252. highlightHeight = _props8.highlightHeight,
  253. highlightWidth = _props8.highlightWidth,
  254. highlightX = _props8.highlightX,
  255. highlightY = _props8.highlightY,
  256. innerWidth = _props8.innerWidth,
  257. innerHeight = _props8.innerHeight,
  258. marginLeft = _props8.marginLeft,
  259. marginRight = _props8.marginRight,
  260. marginTop = _props8.marginTop,
  261. marginBottom = _props8.marginBottom,
  262. opacity = _props8.opacity;
  263. var _state$brushArea = this.state.brushArea,
  264. left = _state$brushArea.left,
  265. right = _state$brushArea.right,
  266. top = _state$brushArea.top,
  267. bottom = _state$brushArea.bottom;
  268. var leftPos = 0;
  269. if (highlightX) {
  270. var xScale = getAttributeScale(this.props, 'x');
  271. leftPos = xScale(highlightX);
  272. }
  273. var topPos = 0;
  274. if (highlightY) {
  275. var yScale = getAttributeScale(this.props, 'y');
  276. topPos = yScale(highlightY);
  277. }
  278. var plotWidth = marginLeft + marginRight + innerWidth;
  279. var plotHeight = marginTop + marginBottom + innerHeight;
  280. var touchWidth = highlightWidth || plotWidth;
  281. var touchHeight = highlightHeight || plotHeight;
  282. return React.createElement(
  283. 'g',
  284. {
  285. transform: 'translate(' + leftPos + ', ' + topPos + ')',
  286. className: className + ' rv-highlight-container'
  287. },
  288. React.createElement('rect', {
  289. className: 'rv-mouse-target',
  290. fill: 'black',
  291. opacity: '0',
  292. x: '0',
  293. y: '0',
  294. width: Math.max(touchWidth, 0),
  295. height: Math.max(touchHeight, 0),
  296. onMouseDown: function onMouseDown(e) {
  297. return _this3.startBrushing(e);
  298. },
  299. onMouseMove: function onMouseMove(e) {
  300. return _this3.onBrush(e);
  301. },
  302. onMouseUp: function onMouseUp(e) {
  303. return _this3.stopBrushing(e);
  304. },
  305. onMouseLeave: function onMouseLeave(e) {
  306. return _this3.stopBrushing(e);
  307. }
  308. // preventDefault() so that mouse event emulation does not happen
  309. , onTouchEnd: function onTouchEnd(e) {
  310. e.preventDefault();
  311. _this3.stopBrushing(e);
  312. },
  313. onTouchCancel: function onTouchCancel(e) {
  314. e.preventDefault();
  315. _this3.stopBrushing(e);
  316. },
  317. onContextMenu: function onContextMenu(e) {
  318. return e.preventDefault();
  319. },
  320. onContextMenuCapture: function onContextMenuCapture(e) {
  321. return e.preventDefault();
  322. }
  323. }),
  324. React.createElement('rect', {
  325. className: 'rv-highlight',
  326. pointerEvents: 'none',
  327. opacity: opacity,
  328. fill: color,
  329. x: left,
  330. y: top,
  331. width: Math.min(Math.max(0, right - left), touchWidth),
  332. height: Math.min(Math.max(0, bottom - top), touchHeight)
  333. })
  334. );
  335. }
  336. }]);
  337. return Highlight;
  338. }(AbstractSeries);
  339. Highlight.displayName = 'HighlightOverlay';
  340. Highlight.defaultProps = {
  341. color: 'rgb(77, 182, 172)',
  342. className: '',
  343. enableX: true,
  344. enableY: true,
  345. opacity: 0.3
  346. };
  347. Highlight.propTypes = _extends({}, AbstractSeries.propTypes, {
  348. enableX: PropTypes.bool,
  349. enableY: PropTypes.bool,
  350. highlightHeight: PropTypes.number,
  351. highlightWidth: PropTypes.number,
  352. highlightX: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  353. highlightY: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  354. onBrushStart: PropTypes.func,
  355. onDragStart: PropTypes.func,
  356. onBrush: PropTypes.func,
  357. onDrag: PropTypes.func,
  358. onBrushEnd: PropTypes.func,
  359. onDragEnd: PropTypes.func
  360. });
  361. export default Highlight;