UNPKG

18.6 kBJavaScriptView Raw
1function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
2
3import _isEqual from "lodash/isEqual";
4import _isFunction from "lodash/isFunction";
5import _isNil from "lodash/isNil";
6
7function _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); }
8
9function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
10
11function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
12
13function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
14
15function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
16
17function _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); } }
18
19function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
20
21function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
22
23function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
24
25function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
26
27function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
28
29function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
30
31function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
32
33function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
34
35/**
36 * @fileOverview Render a group of scatters
37 */
38import React, { PureComponent } from 'react';
39import Animate from 'react-smooth';
40import classNames from 'classnames';
41import { Layer } from '../container/Layer';
42import { LabelList } from '../component/LabelList';
43import { findAllByType } from '../util/ReactUtils';
44import { Global } from '../util/Global';
45import { ZAxis } from './ZAxis';
46import { Curve } from '../shape/Curve';
47import { Symbols } from '../shape/Symbols';
48import { ErrorBar } from './ErrorBar';
49import { Cell } from '../component/Cell';
50import { uniqueId, interpolateNumber, getLinearRegression } from '../util/DataUtils';
51import { getValueByDataKey, getCateCoordinateOfLine } from '../util/ChartUtils';
52import { filterProps, adaptEventsOfChild } from '../util/types';
53export var Scatter = /*#__PURE__*/function (_PureComponent) {
54 _inherits(Scatter, _PureComponent);
55
56 var _super = _createSuper(Scatter);
57
58 function Scatter() {
59 var _this;
60
61 _classCallCheck(this, Scatter);
62
63 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
64 args[_key] = arguments[_key];
65 }
66
67 _this = _super.call.apply(_super, [this].concat(args));
68 _this.state = {
69 isAnimationFinished: false
70 };
71
72 _this.handleAnimationEnd = function () {
73 _this.setState({
74 isAnimationFinished: true
75 });
76 };
77
78 _this.handleAnimationStart = function () {
79 _this.setState({
80 isAnimationFinished: false
81 });
82 };
83
84 _this.id = uniqueId('recharts-scatter-');
85 return _this;
86 }
87
88 _createClass(Scatter, [{
89 key: "renderSymbolsStatically",
90 value: function renderSymbolsStatically(points) {
91 var _this2 = this;
92
93 var _this$props = this.props,
94 shape = _this$props.shape,
95 activeShape = _this$props.activeShape,
96 activeIndex = _this$props.activeIndex;
97 var baseProps = filterProps(this.props);
98 return points.map(function (entry, i) {
99 var props = _objectSpread(_objectSpread({
100 key: "symbol-".concat(i)
101 }, baseProps), entry);
102
103 return /*#__PURE__*/React.createElement(Layer, _extends({
104 className: "recharts-scatter-symbol"
105 }, adaptEventsOfChild(_this2.props, entry, i), {
106 key: "symbol-".concat(i) // eslint-disable-line react/no-array-index-key
107
108 }), Scatter.renderSymbolItem(activeIndex === i ? activeShape : shape, props));
109 });
110 }
111 }, {
112 key: "renderSymbolsWithAnimation",
113 value: function renderSymbolsWithAnimation() {
114 var _this3 = this;
115
116 var _this$props2 = this.props,
117 points = _this$props2.points,
118 isAnimationActive = _this$props2.isAnimationActive,
119 animationBegin = _this$props2.animationBegin,
120 animationDuration = _this$props2.animationDuration,
121 animationEasing = _this$props2.animationEasing,
122 animationId = _this$props2.animationId;
123 var prevPoints = this.state.prevPoints;
124 return /*#__PURE__*/React.createElement(Animate, {
125 begin: animationBegin,
126 duration: animationDuration,
127 isActive: isAnimationActive,
128 easing: animationEasing,
129 from: {
130 t: 0
131 },
132 to: {
133 t: 1
134 },
135 key: "pie-".concat(animationId),
136 onAnimationEnd: this.handleAnimationEnd,
137 onAnimationStart: this.handleAnimationStart
138 }, function (_ref) {
139 var t = _ref.t;
140 var stepData = points.map(function (entry, index) {
141 var prev = prevPoints && prevPoints[index];
142
143 if (prev) {
144 var interpolatorCx = interpolateNumber(prev.cx, entry.cx);
145 var interpolatorCy = interpolateNumber(prev.cy, entry.cy);
146 var interpolatorSize = interpolateNumber(prev.size, entry.size);
147 return _objectSpread(_objectSpread({}, entry), {}, {
148 cx: interpolatorCx(t),
149 cy: interpolatorCy(t),
150 size: interpolatorSize(t)
151 });
152 }
153
154 var interpolator = interpolateNumber(0, entry.size);
155 return _objectSpread(_objectSpread({}, entry), {}, {
156 size: interpolator(t)
157 });
158 });
159 return /*#__PURE__*/React.createElement(Layer, null, _this3.renderSymbolsStatically(stepData));
160 });
161 }
162 }, {
163 key: "renderSymbols",
164 value: function renderSymbols() {
165 var _this$props3 = this.props,
166 points = _this$props3.points,
167 isAnimationActive = _this$props3.isAnimationActive;
168 var prevPoints = this.state.prevPoints;
169
170 if (isAnimationActive && points && points.length && (!prevPoints || !_isEqual(prevPoints, points))) {
171 return this.renderSymbolsWithAnimation();
172 }
173
174 return this.renderSymbolsStatically(points);
175 }
176 }, {
177 key: "renderErrorBar",
178 value: function renderErrorBar() {
179 var isAnimationActive = this.props.isAnimationActive;
180
181 if (isAnimationActive && !this.state.isAnimationFinished) {
182 return null;
183 }
184
185 var _this$props4 = this.props,
186 points = _this$props4.points,
187 xAxis = _this$props4.xAxis,
188 yAxis = _this$props4.yAxis,
189 children = _this$props4.children;
190 var errorBarItems = findAllByType(children, ErrorBar.displayName);
191
192 if (!errorBarItems) {
193 return null;
194 }
195
196 function dataPointFormatterY(dataPoint, dataKey) {
197 return {
198 x: dataPoint.cx,
199 y: dataPoint.cy,
200 value: +dataPoint.node.y,
201 errorVal: getValueByDataKey(dataPoint, dataKey)
202 };
203 }
204
205 function dataPointFormatterX(dataPoint, dataKey) {
206 return {
207 x: dataPoint.cx,
208 y: dataPoint.cy,
209 value: +dataPoint.node.x,
210 errorVal: getValueByDataKey(dataPoint, dataKey)
211 };
212 }
213
214 return errorBarItems.map(function (item, i) {
215 var direction = item.props.direction;
216 return /*#__PURE__*/React.cloneElement(item, {
217 key: i,
218 // eslint-disable-line react/no-array-index-key
219 data: points,
220 xAxis: xAxis,
221 yAxis: yAxis,
222 layout: direction === 'x' ? 'vertical' : 'horizontal',
223 dataPointFormatter: direction === 'x' ? dataPointFormatterX : dataPointFormatterY
224 });
225 });
226 }
227 }, {
228 key: "renderLine",
229 value: function renderLine() {
230 var _this$props5 = this.props,
231 points = _this$props5.points,
232 line = _this$props5.line,
233 lineType = _this$props5.lineType,
234 lineJointType = _this$props5.lineJointType;
235 var scatterProps = filterProps(this.props);
236 var customLineProps = filterProps(line);
237 var linePoints, lineItem;
238
239 if (lineType === 'joint') {
240 linePoints = points.map(function (entry) {
241 return {
242 x: entry.cx,
243 y: entry.cy
244 };
245 });
246 } else if (lineType === 'fitting') {
247 var _getLinearRegression = getLinearRegression(points),
248 xmin = _getLinearRegression.xmin,
249 xmax = _getLinearRegression.xmax,
250 a = _getLinearRegression.a,
251 b = _getLinearRegression.b;
252
253 var linearExp = function linearExp(x) {
254 return a * x + b;
255 };
256
257 linePoints = [{
258 x: xmin,
259 y: linearExp(xmin)
260 }, {
261 x: xmax,
262 y: linearExp(xmax)
263 }];
264 }
265
266 var lineProps = _objectSpread(_objectSpread(_objectSpread({}, scatterProps), {}, {
267 fill: 'none',
268 stroke: scatterProps && scatterProps.fill
269 }, customLineProps), {}, {
270 points: linePoints
271 });
272
273 if ( /*#__PURE__*/React.isValidElement(line)) {
274 lineItem = /*#__PURE__*/React.cloneElement(line, lineProps);
275 } else if (_isFunction(line)) {
276 lineItem = line(lineProps);
277 } else {
278 lineItem = /*#__PURE__*/React.createElement(Curve, _extends({}, lineProps, {
279 type: lineJointType
280 }));
281 }
282
283 return /*#__PURE__*/React.createElement(Layer, {
284 className: "recharts-scatter-line",
285 key: "recharts-scatter-line"
286 }, lineItem);
287 }
288 }, {
289 key: "render",
290 value: function render() {
291 var _this$props6 = this.props,
292 hide = _this$props6.hide,
293 points = _this$props6.points,
294 line = _this$props6.line,
295 className = _this$props6.className,
296 xAxis = _this$props6.xAxis,
297 yAxis = _this$props6.yAxis,
298 left = _this$props6.left,
299 top = _this$props6.top,
300 width = _this$props6.width,
301 height = _this$props6.height,
302 id = _this$props6.id,
303 isAnimationActive = _this$props6.isAnimationActive;
304
305 if (hide || !points || !points.length) {
306 return null;
307 }
308
309 var isAnimationFinished = this.state.isAnimationFinished;
310 var layerClass = classNames('recharts-scatter', className);
311 var needClip = xAxis && xAxis.allowDataOverflow || yAxis && yAxis.allowDataOverflow;
312 var clipPathId = _isNil(id) ? this.id : id;
313 return /*#__PURE__*/React.createElement(Layer, {
314 className: layerClass,
315 clipPath: needClip ? "url(#clipPath-".concat(clipPathId, ")") : null
316 }, needClip ? /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement("clipPath", {
317 id: "clipPath-".concat(clipPathId)
318 }, /*#__PURE__*/React.createElement("rect", {
319 x: left,
320 y: top,
321 width: width,
322 height: height
323 }))) : null, line && this.renderLine(), this.renderErrorBar(), /*#__PURE__*/React.createElement(Layer, {
324 key: "recharts-scatter-symbols"
325 }, this.renderSymbols()), (!isAnimationActive || isAnimationFinished) && LabelList.renderCallByParent(this.props, points));
326 }
327 }], [{
328 key: "getDerivedStateFromProps",
329 value: function getDerivedStateFromProps(nextProps, prevState) {
330 if (nextProps.animationId !== prevState.prevAnimationId) {
331 return {
332 prevAnimationId: nextProps.animationId,
333 curPoints: nextProps.points,
334 prevPoints: prevState.curPoints
335 };
336 }
337
338 if (nextProps.points !== prevState.curPoints) {
339 return {
340 curPoints: nextProps.points
341 };
342 }
343
344 return null;
345 }
346 }, {
347 key: "renderSymbolItem",
348 value: function renderSymbolItem(option, props) {
349 var symbol;
350
351 if ( /*#__PURE__*/React.isValidElement(option)) {
352 symbol = /*#__PURE__*/React.cloneElement(option, props);
353 } else if (_isFunction(option)) {
354 symbol = option(props);
355 } else if (typeof option === 'string') {
356 symbol = /*#__PURE__*/React.createElement(Symbols, _extends({}, props, {
357 type: option
358 }));
359 }
360
361 return symbol;
362 }
363 }]);
364
365 return Scatter;
366}(PureComponent);
367Scatter.displayName = 'Scatter';
368Scatter.defaultProps = {
369 xAxisId: 0,
370 yAxisId: 0,
371 zAxisId: 0,
372 legendType: 'circle',
373 lineType: 'joint',
374 lineJointType: 'linear',
375 data: [],
376 shape: 'circle',
377 hide: false,
378 isAnimationActive: !Global.isSsr,
379 animationBegin: 0,
380 animationDuration: 400,
381 animationEasing: 'linear'
382};
383
384Scatter.getComposedData = function (_ref2) {
385 var xAxis = _ref2.xAxis,
386 yAxis = _ref2.yAxis,
387 zAxis = _ref2.zAxis,
388 item = _ref2.item,
389 displayedData = _ref2.displayedData,
390 xAxisTicks = _ref2.xAxisTicks,
391 yAxisTicks = _ref2.yAxisTicks,
392 offset = _ref2.offset;
393 var tooltipType = item.props.tooltipType;
394 var cells = findAllByType(item.props.children, Cell.displayName);
395 var xAxisDataKey = _isNil(xAxis.dataKey) ? item.props.dataKey : xAxis.dataKey;
396 var yAxisDataKey = _isNil(yAxis.dataKey) ? item.props.dataKey : yAxis.dataKey;
397 var zAxisDataKey = zAxis && zAxis.dataKey;
398 var defaultRangeZ = zAxis ? zAxis.range : ZAxis.defaultProps.range;
399 var defaultZ = defaultRangeZ && defaultRangeZ[0];
400 var xBandSize = xAxis.scale.bandwidth ? xAxis.scale.bandwidth() : 0;
401 var yBandSize = yAxis.scale.bandwidth ? yAxis.scale.bandwidth() : 0;
402 var points = displayedData.map(function (entry, index) {
403 var x = getValueByDataKey(entry, xAxisDataKey);
404 var y = getValueByDataKey(entry, yAxisDataKey);
405 var z = !_isNil(zAxisDataKey) && getValueByDataKey(entry, zAxisDataKey) || '-';
406 var tooltipPayload = [{
407 name: _isNil(xAxis.dataKey) ? item.props.name : xAxis.name || xAxis.dataKey,
408 unit: xAxis.unit || '',
409 value: x,
410 payload: entry,
411 dataKey: xAxisDataKey,
412 type: tooltipType
413 }, {
414 name: _isNil(yAxis.dataKey) ? item.props.name : yAxis.name || yAxis.dataKey,
415 unit: yAxis.unit || '',
416 value: y,
417 payload: entry,
418 dataKey: yAxisDataKey,
419 type: tooltipType
420 }];
421
422 if (z !== '-') {
423 tooltipPayload.push({
424 name: zAxis.name || zAxis.dataKey,
425 unit: zAxis.unit || '',
426 value: z,
427 payload: entry,
428 dataKey: zAxisDataKey,
429 type: tooltipType
430 });
431 }
432
433 var cx = getCateCoordinateOfLine({
434 axis: xAxis,
435 ticks: xAxisTicks,
436 bandSize: xBandSize,
437 entry: entry,
438 index: index,
439 dataKey: xAxisDataKey
440 });
441 var cy = getCateCoordinateOfLine({
442 axis: yAxis,
443 ticks: yAxisTicks,
444 bandSize: yBandSize,
445 entry: entry,
446 index: index,
447 dataKey: yAxisDataKey
448 });
449 var size = z !== '-' ? zAxis.scale(z) : defaultZ;
450 var radius = Math.sqrt(Math.max(size, 0) / Math.PI);
451 return _objectSpread(_objectSpread({}, entry), {}, {
452 cx: cx,
453 cy: cy,
454 x: cx - radius,
455 y: cy - radius,
456 xAxis: xAxis,
457 yAxis: yAxis,
458 zAxis: zAxis,
459 width: 2 * radius,
460 height: 2 * radius,
461 size: size,
462 node: {
463 x: x,
464 y: y,
465 z: z
466 },
467 tooltipPayload: tooltipPayload,
468 tooltipPosition: {
469 x: cx,
470 y: cy
471 },
472 payload: entry
473 }, cells && cells[index] && cells[index].props);
474 });
475 return _objectSpread({
476 points: points
477 }, offset);
478};
\No newline at end of file