UNPKG

21.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 _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
8
9function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
10
11function _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); }
12
13function 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; }
14
15function _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; }
16
17function _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; }
18
19function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
20
21function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
22
23function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
24
25function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
26
27function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
28
29function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
30
31function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
32
33function _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); } }
34
35function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
36
37function _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); }
38
39function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
40
41function _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); }; }
42
43function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
44
45function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
46
47function _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; } }
48
49function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
50
51/**
52 * @fileOverview Line
53 */
54import React, { PureComponent } from 'react';
55import Animate from 'react-smooth';
56import classNames from 'classnames';
57import { Curve } from '../shape/Curve';
58import { Dot } from '../shape/Dot';
59import { Layer } from '../container/Layer';
60import { LabelList } from '../component/LabelList';
61import { ErrorBar } from './ErrorBar';
62import { uniqueId, interpolateNumber } from '../util/DataUtils';
63import { findAllByType } from '../util/ReactUtils';
64import { Global } from '../util/Global';
65import { getCateCoordinateOfLine, getValueByDataKey } from '../util/ChartUtils';
66import { filterProps } from '../util/types';
67export var Line = /*#__PURE__*/function (_PureComponent) {
68 _inherits(Line, _PureComponent);
69
70 var _super = _createSuper(Line);
71
72 function Line() {
73 var _this;
74
75 _classCallCheck(this, Line);
76
77 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
78 args[_key] = arguments[_key];
79 }
80
81 _this = _super.call.apply(_super, [this].concat(args));
82 _this.mainCurve = void 0;
83 _this.state = {
84 isAnimationFinished: true,
85 totalLength: 0
86 };
87
88 _this.getStrokeDasharray = function (length, totalLength, lines) {
89 var lineLength = lines.reduce(function (pre, next) {
90 return pre + next;
91 });
92 var count = Math.floor(length / lineLength);
93 var remainLength = length % lineLength;
94 var restLength = totalLength - length;
95 var remainLines = [];
96
97 for (var i = 0, sum = 0;; sum += lines[i], ++i) {
98 if (sum + lines[i] > remainLength) {
99 remainLines = [].concat(_toConsumableArray(lines.slice(0, i)), [remainLength - sum]);
100 break;
101 }
102 }
103
104 var emptyLines = remainLines.length % 2 === 0 ? [0, restLength] : [restLength];
105 return [].concat(_toConsumableArray(Line.repeat(lines, count)), _toConsumableArray(remainLines), emptyLines).map(function (line) {
106 return "".concat(line, "px");
107 }).join(', ');
108 };
109
110 _this.id = uniqueId('recharts-line-');
111
112 _this.pathRef = function (node) {
113 _this.mainCurve = node;
114 };
115
116 _this.handleAnimationEnd = function () {
117 _this.setState({
118 isAnimationFinished: true
119 });
120
121 if (_this.props.onAnimationEnd) {
122 _this.props.onAnimationEnd();
123 }
124 };
125
126 _this.handleAnimationStart = function () {
127 _this.setState({
128 isAnimationFinished: false
129 });
130
131 if (_this.props.onAnimationStart) {
132 _this.props.onAnimationStart();
133 }
134 };
135
136 return _this;
137 }
138
139 _createClass(Line, [{
140 key: "componentDidMount",
141 value:
142 /* eslint-disable react/no-did-mount-set-state */
143 function componentDidMount() {
144 if (!this.props.isAnimationActive) {
145 return;
146 }
147
148 var totalLength = this.getTotalLength();
149 this.setState({
150 totalLength: totalLength
151 });
152 }
153 }, {
154 key: "getTotalLength",
155 value: function getTotalLength() {
156 var curveDom = this.mainCurve;
157
158 try {
159 return curveDom && curveDom.getTotalLength && curveDom.getTotalLength() || 0;
160 } catch (err) {
161 return 0;
162 }
163 }
164 }, {
165 key: "renderErrorBar",
166 value: function renderErrorBar() {
167 if (this.props.isAnimationActive && !this.state.isAnimationFinished) {
168 return null;
169 }
170
171 var _this$props = this.props,
172 points = _this$props.points,
173 xAxis = _this$props.xAxis,
174 yAxis = _this$props.yAxis,
175 layout = _this$props.layout,
176 children = _this$props.children;
177 var errorBarItems = findAllByType(children, ErrorBar.displayName);
178
179 if (!errorBarItems) {
180 return null;
181 }
182
183 function dataPointFormatter(dataPoint, dataKey) {
184 return {
185 x: dataPoint.x,
186 y: dataPoint.y,
187 value: dataPoint.value,
188 errorVal: getValueByDataKey(dataPoint.payload, dataKey)
189 };
190 }
191
192 return errorBarItems.map(function (item, i) {
193 return /*#__PURE__*/React.cloneElement(item, {
194 // eslint-disable-next-line react/no-array-index-key
195 key: "bar-".concat(i),
196 data: points,
197 xAxis: xAxis,
198 yAxis: yAxis,
199 layout: layout,
200 dataPointFormatter: dataPointFormatter
201 });
202 });
203 }
204 }, {
205 key: "renderDots",
206 value: function renderDots(needClip, clipPathId) {
207 var isAnimationActive = this.props.isAnimationActive;
208
209 if (isAnimationActive && !this.state.isAnimationFinished) {
210 return null;
211 }
212
213 var _this$props2 = this.props,
214 dot = _this$props2.dot,
215 points = _this$props2.points,
216 dataKey = _this$props2.dataKey;
217 var lineProps = filterProps(this.props);
218 var customDotProps = filterProps(dot, true);
219 var dots = points.map(function (entry, i) {
220 var dotProps = _objectSpread(_objectSpread(_objectSpread({
221 key: "dot-".concat(i),
222 r: 3
223 }, lineProps), customDotProps), {}, {
224 value: entry.value,
225 dataKey: dataKey,
226 cx: entry.x,
227 cy: entry.y,
228 index: i,
229 payload: entry.payload
230 });
231
232 return Line.renderDotItem(dot, dotProps);
233 });
234 var dotsProps = {
235 clipPath: needClip ? "url(#clipPath-".concat(clipPathId, ")") : null
236 };
237 return /*#__PURE__*/React.createElement(Layer, _extends({
238 className: "recharts-line-dots",
239 key: "dots"
240 }, dotsProps), dots);
241 }
242 }, {
243 key: "renderCurveStatically",
244 value: function renderCurveStatically(points, needClip, clipPathId, props) {
245 // eslint-disable-next-line @typescript-eslint/no-unused-vars
246 var _this$props3 = this.props,
247 type = _this$props3.type,
248 layout = _this$props3.layout,
249 connectNulls = _this$props3.connectNulls,
250 ref = _this$props3.ref,
251 others = _objectWithoutProperties(_this$props3, ["type", "layout", "connectNulls", "ref"]);
252
253 var curveProps = _objectSpread(_objectSpread(_objectSpread({}, filterProps(others, true)), {}, {
254 fill: 'none',
255 className: 'recharts-line-curve',
256 clipPath: needClip ? "url(#clipPath-".concat(clipPathId, ")") : null,
257 points: points
258 }, props), {}, {
259 type: type,
260 layout: layout,
261 connectNulls: connectNulls
262 });
263
264 return /*#__PURE__*/React.createElement(Curve, _extends({}, curveProps, {
265 pathRef: this.pathRef
266 }));
267 }
268 }, {
269 key: "renderCurveWithAnimation",
270 value: function renderCurveWithAnimation(needClip, clipPathId) {
271 var _this2 = this;
272
273 var _this$props4 = this.props,
274 points = _this$props4.points,
275 strokeDasharray = _this$props4.strokeDasharray,
276 isAnimationActive = _this$props4.isAnimationActive,
277 animationBegin = _this$props4.animationBegin,
278 animationDuration = _this$props4.animationDuration,
279 animationEasing = _this$props4.animationEasing,
280 animationId = _this$props4.animationId,
281 animateNewValues = _this$props4.animateNewValues,
282 width = _this$props4.width,
283 height = _this$props4.height;
284 var _this$state = this.state,
285 prevPoints = _this$state.prevPoints,
286 totalLength = _this$state.totalLength;
287 return /*#__PURE__*/React.createElement(Animate, {
288 begin: animationBegin,
289 duration: animationDuration,
290 isActive: isAnimationActive,
291 easing: animationEasing,
292 from: {
293 t: 0
294 },
295 to: {
296 t: 1
297 },
298 key: "line-".concat(animationId),
299 onAnimationEnd: this.handleAnimationEnd,
300 onAnimationStart: this.handleAnimationStart
301 }, function (_ref) {
302 var t = _ref.t;
303
304 if (prevPoints) {
305 var prevPointsDiffFactor = prevPoints.length / points.length;
306 var stepData = points.map(function (entry, index) {
307 var prevPointIndex = Math.floor(index * prevPointsDiffFactor);
308
309 if (prevPoints[prevPointIndex]) {
310 var prev = prevPoints[prevPointIndex];
311 var interpolatorX = interpolateNumber(prev.x, entry.x);
312 var interpolatorY = interpolateNumber(prev.y, entry.y);
313 return _objectSpread(_objectSpread({}, entry), {}, {
314 x: interpolatorX(t),
315 y: interpolatorY(t)
316 });
317 } // magic number of faking previous x and y location
318
319
320 if (animateNewValues) {
321 var _interpolatorX = interpolateNumber(width * 2, entry.x);
322
323 var _interpolatorY = interpolateNumber(height / 2, entry.y);
324
325 return _objectSpread(_objectSpread({}, entry), {}, {
326 x: _interpolatorX(t),
327 y: _interpolatorY(t)
328 });
329 }
330
331 return _objectSpread(_objectSpread({}, entry), {}, {
332 x: entry.x,
333 y: entry.y
334 });
335 });
336 return _this2.renderCurveStatically(stepData, needClip, clipPathId);
337 }
338
339 var interpolator = interpolateNumber(0, totalLength);
340 var curLength = interpolator(t);
341 var currentStrokeDasharray;
342
343 if (strokeDasharray) {
344 var lines = "".concat(strokeDasharray).split(/[,\s]+/gim).map(function (num) {
345 return parseFloat(num);
346 });
347 currentStrokeDasharray = _this2.getStrokeDasharray(curLength, totalLength, lines);
348 } else {
349 currentStrokeDasharray = "".concat(curLength, "px ").concat(totalLength - curLength, "px");
350 }
351
352 return _this2.renderCurveStatically(points, needClip, clipPathId, {
353 strokeDasharray: currentStrokeDasharray
354 });
355 });
356 }
357 }, {
358 key: "renderCurve",
359 value: function renderCurve(needClip, clipPathId) {
360 var _this$props5 = this.props,
361 points = _this$props5.points,
362 isAnimationActive = _this$props5.isAnimationActive;
363 var _this$state2 = this.state,
364 prevPoints = _this$state2.prevPoints,
365 totalLength = _this$state2.totalLength;
366
367 if (isAnimationActive && points && points.length && (!prevPoints && totalLength > 0 || !_isEqual(prevPoints, points))) {
368 return this.renderCurveWithAnimation(needClip, clipPathId);
369 }
370
371 return this.renderCurveStatically(points, needClip, clipPathId);
372 }
373 }, {
374 key: "render",
375 value: function render() {
376 var _this$props6 = this.props,
377 hide = _this$props6.hide,
378 dot = _this$props6.dot,
379 points = _this$props6.points,
380 className = _this$props6.className,
381 xAxis = _this$props6.xAxis,
382 yAxis = _this$props6.yAxis,
383 top = _this$props6.top,
384 left = _this$props6.left,
385 width = _this$props6.width,
386 height = _this$props6.height,
387 isAnimationActive = _this$props6.isAnimationActive,
388 id = _this$props6.id;
389
390 if (hide || !points || !points.length) {
391 return null;
392 }
393
394 var isAnimationFinished = this.state.isAnimationFinished;
395 var hasSinglePoint = points.length === 1;
396 var layerClass = classNames('recharts-line', className);
397 var needClip = xAxis && xAxis.allowDataOverflow || yAxis && yAxis.allowDataOverflow;
398 var clipPathId = _isNil(id) ? this.id : id;
399 return /*#__PURE__*/React.createElement(Layer, {
400 className: layerClass
401 }, needClip ? /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement("clipPath", {
402 id: "clipPath-".concat(clipPathId)
403 }, /*#__PURE__*/React.createElement("rect", {
404 x: left,
405 y: top,
406 width: width,
407 height: height
408 }))) : null, !hasSinglePoint && this.renderCurve(needClip, clipPathId), this.renderErrorBar(), (hasSinglePoint || dot) && this.renderDots(needClip, clipPathId), (!isAnimationActive || isAnimationFinished) && LabelList.renderCallByParent(this.props, points));
409 }
410 }], [{
411 key: "getDerivedStateFromProps",
412 value: function getDerivedStateFromProps(nextProps, prevState) {
413 if (nextProps.animationId !== prevState.prevAnimationId) {
414 return {
415 prevAnimationId: nextProps.animationId,
416 curPoints: nextProps.points,
417 prevPoints: prevState.curPoints
418 };
419 }
420
421 if (nextProps.points !== prevState.curPoints) {
422 return {
423 curPoints: nextProps.points
424 };
425 }
426
427 return null;
428 }
429 }, {
430 key: "repeat",
431 value: function repeat(lines, count) {
432 var linesUnit = lines.length % 2 !== 0 ? [].concat(_toConsumableArray(lines), [0]) : lines;
433 var result = [];
434
435 for (var i = 0; i < count; ++i) {
436 result = [].concat(_toConsumableArray(result), _toConsumableArray(linesUnit));
437 }
438
439 return result;
440 }
441 }, {
442 key: "renderDotItem",
443 value: function renderDotItem(option, props) {
444 var dotItem;
445
446 if ( /*#__PURE__*/React.isValidElement(option)) {
447 dotItem = /*#__PURE__*/React.cloneElement(option, props);
448 } else if (_isFunction(option)) {
449 dotItem = option(props);
450 } else {
451 var className = classNames('recharts-line-dot', option ? option.className : '');
452 dotItem = /*#__PURE__*/React.createElement(Dot, _extends({}, props, {
453 className: className
454 }));
455 }
456
457 return dotItem;
458 }
459 }]);
460
461 return Line;
462}(PureComponent);
463Line.displayName = 'Line';
464Line.defaultProps = {
465 xAxisId: 0,
466 yAxisId: 0,
467 connectNulls: false,
468 activeDot: true,
469 dot: true,
470 legendType: 'line',
471 stroke: '#3182bd',
472 strokeWidth: 1,
473 fill: '#fff',
474 points: [],
475 isAnimationActive: !Global.isSsr,
476 animateNewValues: true,
477 animationBegin: 0,
478 animationDuration: 1500,
479 animationEasing: 'ease',
480 hide: false
481};
482
483Line.getComposedData = function (_ref2) {
484 var props = _ref2.props,
485 xAxis = _ref2.xAxis,
486 yAxis = _ref2.yAxis,
487 xAxisTicks = _ref2.xAxisTicks,
488 yAxisTicks = _ref2.yAxisTicks,
489 dataKey = _ref2.dataKey,
490 bandSize = _ref2.bandSize,
491 displayedData = _ref2.displayedData,
492 offset = _ref2.offset;
493 var layout = props.layout;
494 var points = displayedData.map(function (entry, index) {
495 var value = getValueByDataKey(entry, dataKey);
496
497 if (layout === 'horizontal') {
498 return {
499 x: getCateCoordinateOfLine({
500 axis: xAxis,
501 ticks: xAxisTicks,
502 bandSize: bandSize,
503 entry: entry,
504 index: index
505 }),
506 y: _isNil(value) ? null : yAxis.scale(value),
507 value: value,
508 payload: entry
509 };
510 }
511
512 return {
513 x: _isNil(value) ? null : xAxis.scale(value),
514 y: getCateCoordinateOfLine({
515 axis: yAxis,
516 ticks: yAxisTicks,
517 bandSize: bandSize,
518 entry: entry,
519 index: index
520 }),
521 value: value,
522 payload: entry
523 };
524 });
525 return _objectSpread({
526 points: points,
527 layout: layout
528 }, offset);
529};
\No newline at end of file