UNPKG

13.4 kBJavaScriptView Raw
1var _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; }; }();
2
3var _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; };
4
5function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6
7function _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; }
8
9function _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; }
10
11// Copyright (c) 2016 - 2017 Uber Technologies, Inc.
12//
13// Permission is hereby granted, free of charge, to any person obtaining a copy
14// of this software and associated documentation files (the "Software"), to deal
15// in the Software without restriction, including without limitation the rights
16// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17// copies of the Software, and to permit persons to whom the Software is
18// furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included in
21// all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29// THE SOFTWARE.
30
31import PropTypes from 'prop-types';
32import { voronoi } from 'd3-voronoi';
33import { PureComponent } from 'react';
34
35import { AnimationPropType } from '../../animation';
36import { getAttributeFunctor, getAttr0Functor, getAttributeValue, getScaleObjectFromProps, getScalePropTypesByAttribute } from '../../utils/scales-utils';
37
38var propTypes = _extends({}, getScalePropTypesByAttribute('x'), getScalePropTypesByAttribute('y'), getScalePropTypesByAttribute('size'), getScalePropTypesByAttribute('opacity'), getScalePropTypesByAttribute('color'), {
39 width: PropTypes.number,
40 height: PropTypes.number,
41 data: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.object, PropTypes.array])),
42 onValueMouseOver: PropTypes.func,
43 onValueMouseOut: PropTypes.func,
44 onValueClick: PropTypes.func,
45 onValueRightClick: PropTypes.func,
46 onSeriesMouseOver: PropTypes.func,
47 onSeriesMouseOut: PropTypes.func,
48 onSeriesClick: PropTypes.func,
49 onSeriesRightClick: PropTypes.func,
50 onNearestX: PropTypes.func,
51 onNearestXY: PropTypes.func,
52 style: PropTypes.object,
53 animation: AnimationPropType,
54 stack: PropTypes.bool
55});
56
57var defaultProps = {
58 className: '',
59 stack: false,
60 style: {}
61};
62
63var AbstractSeries = function (_PureComponent) {
64 _inherits(AbstractSeries, _PureComponent);
65
66 function AbstractSeries() {
67 var _ref;
68
69 var _temp, _this, _ret;
70
71 _classCallCheck(this, AbstractSeries);
72
73 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
74 args[_key] = arguments[_key];
75 }
76
77 return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = AbstractSeries.__proto__ || Object.getPrototypeOf(AbstractSeries)).call.apply(_ref, [this].concat(args))), _this), _this._seriesClickHandler = function (event) {
78 var onSeriesClick = _this.props.onSeriesClick;
79
80 if (onSeriesClick) {
81 onSeriesClick({ event: event });
82 }
83 }, _this._seriesMouseOutHandler = function (event) {
84 var onSeriesMouseOut = _this.props.onSeriesMouseOut;
85
86 if (onSeriesMouseOut) {
87 onSeriesMouseOut({ event: event });
88 }
89 }, _this._seriesMouseOverHandler = function (event) {
90 var onSeriesMouseOver = _this.props.onSeriesMouseOver;
91
92 if (onSeriesMouseOver) {
93 onSeriesMouseOver({ event: event });
94 }
95 }, _this._seriesRightClickHandler = function (event) {
96 var onSeriesRightClick = _this.props.onSeriesRightClick;
97
98 if (onSeriesRightClick) {
99 onSeriesRightClick({ event: event });
100 }
101 }, _this._valueClickHandler = function (d, event) {
102 var _this$props = _this.props,
103 onValueClick = _this$props.onValueClick,
104 onSeriesClick = _this$props.onSeriesClick;
105
106 if (onValueClick) {
107 onValueClick(d, { event: event });
108 }
109 if (onSeriesClick) {
110 onSeriesClick({ event: event });
111 }
112 }, _this._valueMouseOutHandler = function (d, event) {
113 var _this$props2 = _this.props,
114 onValueMouseOut = _this$props2.onValueMouseOut,
115 onSeriesMouseOut = _this$props2.onSeriesMouseOut;
116
117 if (onValueMouseOut) {
118 onValueMouseOut(d, { event: event });
119 }
120 if (onSeriesMouseOut) {
121 onSeriesMouseOut({ event: event });
122 }
123 }, _this._valueMouseOverHandler = function (d, event) {
124 var _this$props3 = _this.props,
125 onValueMouseOver = _this$props3.onValueMouseOver,
126 onSeriesMouseOver = _this$props3.onSeriesMouseOver;
127
128 if (onValueMouseOver) {
129 onValueMouseOver(d, { event: event });
130 }
131 if (onSeriesMouseOver) {
132 onSeriesMouseOver({ event: event });
133 }
134 }, _this._valueRightClickHandler = function (d, event) {
135 var _this$props4 = _this.props,
136 onValueRightClick = _this$props4.onValueRightClick,
137 onSeriesRightClick = _this$props4.onSeriesRightClick;
138
139 if (onValueRightClick) {
140 onValueRightClick(d, { event: event });
141 }
142 if (onSeriesRightClick) {
143 onSeriesRightClick({ event: event });
144 }
145 }, _temp), _possibleConstructorReturn(_this, _ret);
146 }
147
148 _createClass(AbstractSeries, [{
149 key: 'onParentMouseMove',
150 value: function onParentMouseMove(event) {
151 var _props = this.props,
152 onNearestX = _props.onNearestX,
153 onNearestXY = _props.onNearestXY,
154 data = _props.data;
155
156 if (!onNearestX && !onNearestXY || !data) {
157 return;
158 }
159 if (onNearestXY) {
160 this._handleNearestXY(event);
161 } else {
162 this._handleNearestX(event);
163 }
164 }
165 }, {
166 key: 'onParentTouchMove',
167 value: function onParentTouchMove(e) {
168 e.preventDefault();
169 this.onParentMouseMove(e);
170 }
171 }, {
172 key: 'onParentTouchStart',
173 value: function onParentTouchStart(e) {
174 // prevent mouse event emulation
175 e.preventDefault();
176 }
177
178 /**
179 * Get the attr0 functor.
180 * @param {string} attr Attribute name.
181 * @returns {*} Functor.
182 * @private
183 */
184
185 }, {
186 key: '_getAttr0Functor',
187 value: function _getAttr0Functor(attr) {
188 return getAttr0Functor(this.props, attr);
189 }
190
191 /**
192 * Get attribute functor.
193 * @param {string} attr Attribute name
194 * @returns {*} Functor.
195 * @protected
196 */
197
198 }, {
199 key: '_getAttributeFunctor',
200 value: function _getAttributeFunctor(attr) {
201 return getAttributeFunctor(this.props, attr);
202 }
203
204 /**
205 * Get the attribute value if it is available.
206 * @param {string} attr Attribute name.
207 * @returns {*} Attribute value if available, fallback value or undefined
208 * otherwise.
209 * @protected
210 */
211
212 }, {
213 key: '_getAttributeValue',
214 value: function _getAttributeValue(attr) {
215 return getAttributeValue(this.props, attr);
216 }
217
218 /**
219 * Get the scale object distance by the attribute from the list of properties.
220 * @param {string} attr Attribute name.
221 * @returns {number} Scale distance.
222 * @protected
223 */
224
225 }, {
226 key: '_getScaleDistance',
227 value: function _getScaleDistance(attr) {
228 var scaleObject = getScaleObjectFromProps(this.props, attr);
229 return scaleObject ? scaleObject.distance : 0;
230 }
231 }, {
232 key: '_getXYCoordinateInContainer',
233 value: function _getXYCoordinateInContainer(event) {
234 var _props2 = this.props,
235 _props2$marginTop = _props2.marginTop,
236 marginTop = _props2$marginTop === undefined ? 0 : _props2$marginTop,
237 _props2$marginLeft = _props2.marginLeft,
238 marginLeft = _props2$marginLeft === undefined ? 0 : _props2$marginLeft;
239 var evt = event.nativeEvent,
240 currentTarget = event.currentTarget;
241
242 var rect = currentTarget.getBoundingClientRect();
243 var x = evt.clientX;
244 var y = evt.clientY;
245 if (evt.type === 'touchmove') {
246 x = evt.touches[0].pageX;
247 y = evt.touches[0].pageY;
248 }
249 return {
250 x: x - rect.left - currentTarget.clientLeft - marginLeft,
251 y: y - rect.top - currentTarget.clientTop - marginTop
252 };
253 }
254 }, {
255 key: '_handleNearestX',
256 value: function _handleNearestX(event) {
257 var _props3 = this.props,
258 onNearestX = _props3.onNearestX,
259 data = _props3.data;
260
261 var minDistance = Number.POSITIVE_INFINITY;
262 var value = null;
263 var valueIndex = null;
264
265 var coordinate = this._getXYCoordinateInContainer(event);
266 var xScaleFn = this._getAttributeFunctor('x');
267
268 data.forEach(function (item, i) {
269 var currentCoordinate = xScaleFn(item);
270 var newDistance = Math.abs(coordinate.x - currentCoordinate);
271 if (newDistance < minDistance) {
272 minDistance = newDistance;
273 value = item;
274 valueIndex = i;
275 }
276 });
277 if (!value) {
278 return;
279 }
280 onNearestX(value, {
281 innerX: xScaleFn(value),
282 index: valueIndex,
283 event: event.nativeEvent
284 });
285 }
286 }, {
287 key: '_handleNearestXY',
288 value: function _handleNearestXY(event) {
289 var _props4 = this.props,
290 onNearestXY = _props4.onNearestXY,
291 data = _props4.data;
292
293
294 var coordinate = this._getXYCoordinateInContainer(event);
295 var xScaleFn = this._getAttributeFunctor('x');
296 var yScaleFn = this._getAttributeFunctor('y');
297
298 // Create a voronoi with each node center points
299 var voronoiInstance = voronoi().x(xScaleFn).y(yScaleFn);
300
301 var foundPoint = voronoiInstance(data).find(coordinate.x, coordinate.y);
302 var value = foundPoint.data;
303
304 if (!value) {
305 return;
306 }
307 onNearestXY(value, {
308 innerX: foundPoint[0],
309 innerY: foundPoint[1],
310 index: foundPoint.index,
311 event: event.nativeEvent
312 });
313 }
314
315 /**
316 * Click handler for the entire series.
317 * @param {Object} event Event.
318 * @protected
319 */
320
321
322 /**
323 * Mouse out handler for the entire series.
324 * @param {Object} event Event.
325 * @protected
326 */
327
328
329 /**
330 * Mouse over handler for the entire series.
331 * @param {Object} event Event.
332 * @protected
333 */
334
335
336 /**
337 * Right Click handler for the entire series.
338 * @param {Object} event Event.
339 * @protected
340 */
341
342
343 /**
344 * Click handler for the specific series' value.
345 * @param {Object} d Value object
346 * @param {Object} event Event.
347 * @protected
348 */
349
350
351 /**
352 * Mouse out handler for the specific series' value.
353 * @param {Object} d Value object
354 * @param {Object} event Event.
355 * @protected
356 */
357
358
359 /**
360 * Mouse over handler for the specific series' value.
361 * @param {Object} d Value object
362 * @param {Object} event Event.
363 * @protected
364 */
365
366
367 /**
368 * Right Click handler for the specific series' value.
369 * @param {Object} d Value object
370 * @param {Object} event Event.
371 * @protected
372 */
373
374 }], [{
375 key: 'getParentConfig',
376
377 /**
378 * Get a default config for the parent.
379 * @returns {Object} Empty config.
380 */
381 value: function getParentConfig() {
382 return {};
383 }
384
385 /**
386 * Tells the rest of the world that it requires SVG to work.
387 * @returns {boolean} Result.
388 */
389
390 }, {
391 key: 'requiresSVG',
392 get: function get() {
393 return true;
394 }
395 }]);
396
397 return AbstractSeries;
398}(PureComponent);
399
400AbstractSeries.displayName = 'AbstractSeries';
401AbstractSeries.propTypes = propTypes;
402AbstractSeries.defaultProps = defaultProps;
403
404export default AbstractSeries;
\No newline at end of file