victory-core 31.1.0 → 31.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24,6 +24,7 @@ import PropTypes from "prop-types";
24
24
  import * as d3Ease from "d3-ease";
25
25
  import { victoryInterpolator } from "./util";
26
26
  import Timer from "../victory-util/timer";
27
+ import isEqual from "react-fast-compare";
27
28
 
28
29
  var VictoryAnimation =
29
30
  /*#__PURE__*/
@@ -68,31 +69,35 @@ function (_React$Component) {
68
69
  this.traverseQueue();
69
70
  }
70
71
  }
71
- /* lifecycle */
72
-
73
72
  }, {
74
- key: "componentWillReceiveProps",
75
- value: function componentWillReceiveProps(nextProps) {
76
- /* cancel existing loop if it exists */
77
- this.getTimer().unsubscribe(this.loopID);
78
- /* If an object was supplied */
79
-
80
- if (!Array.isArray(nextProps.data)) {
81
- // Replace the tween queue. Could set `this.queue = [nextProps.data]`,
82
- // but let's reuse the same array.
83
- this.queue.length = 0;
84
- this.queue.push(nextProps.data);
85
- /* If an array was supplied */
86
- } else {
87
- var _queue;
73
+ key: "shouldComponentUpdate",
74
+ value: function shouldComponentUpdate(nextProps, nextState) {
75
+ var equalProps = isEqual(this.props, nextProps);
88
76
 
89
- /* Extend the tween queue */
90
- (_queue = this.queue).push.apply(_queue, _toConsumableArray(nextProps.data));
91
- }
92
- /* Start traversing the tween queue */
77
+ if (!equalProps) {
78
+ /* cancel existing loop if it exists */
79
+ this.getTimer().unsubscribe(this.loopID);
80
+ /* If an object was supplied */
81
+
82
+ if (!Array.isArray(nextProps.data)) {
83
+ // Replace the tween queue. Could set `this.queue = [nextProps.data]`,
84
+ // but let's reuse the same array.
85
+ this.queue.length = 0;
86
+ this.queue.push(nextProps.data);
87
+ /* If an array was supplied */
88
+ } else {
89
+ var _queue;
93
90
 
91
+ /* Extend the tween queue */
92
+ (_queue = this.queue).push.apply(_queue, _toConsumableArray(nextProps.data));
93
+ }
94
+ /* Start traversing the tween queue */
95
+
96
+
97
+ this.traverseQueue();
98
+ }
94
99
 
95
- this.traverseQueue();
100
+ return nextState.animationInfo.animating || !equalProps;
96
101
  }
97
102
  }, {
98
103
  key: "componentWillUnmount",
@@ -24,6 +24,7 @@ import Collection from "../victory-util/collection";
24
24
  import Helpers from "../victory-util/helpers";
25
25
  import Timer from "../victory-util/timer";
26
26
  import Transitions from "../victory-util/transitions";
27
+ import isEqual from "react-fast-compare";
27
28
 
28
29
  var VictoryTransition =
29
30
  /*#__PURE__*/
@@ -56,14 +57,18 @@ function (_React$Component) {
56
57
  }); //eslint-disable-line react/no-did-mount-set-state
57
58
  }
58
59
  }, {
59
- key: "componentWillReceiveProps",
60
- value: function componentWillReceiveProps(nextProps) {
60
+ key: "shouldComponentUpdate",
61
+ value: function shouldComponentUpdate(nextProps) {
61
62
  var _this2 = this;
62
63
 
63
- this.getTimer().bypassAnimation();
64
- this.setState(this.getTransitionState(this.props, nextProps), function () {
65
- return _this2.getTimer().resumeAnimation();
66
- });
64
+ if (!isEqual(this.props, nextProps)) {
65
+ this.getTimer().bypassAnimation();
66
+ this.setState(this.getTransitionState(this.props, nextProps), function () {
67
+ return _this2.getTimer().resumeAnimation();
68
+ });
69
+ }
70
+
71
+ return true;
67
72
  }
68
73
  }, {
69
74
  key: "componentWillUnmount",
@@ -34,9 +34,18 @@ import VictoryTransition from "../victory-transition/victory-transition";
34
34
 
35
35
  var datumHasXandY = function (datum) {
36
36
  return !_isNil(datum._x) && !_isNil(datum._y);
37
- };
38
-
39
- export default (function (WrappedComponent) {
37
+ }; // used for checking state changes. Expected components can be passed in via options
38
+
39
+
40
+ var defaultComponents = [{
41
+ name: "parent",
42
+ index: "parent"
43
+ }, {
44
+ name: "data"
45
+ }, {
46
+ name: "labels"
47
+ }];
48
+ export default (function (WrappedComponent, options) {
40
49
  return (
41
50
  /*#__PURE__*/
42
51
  function (_WrappedComponent) {
@@ -63,23 +72,73 @@ export default (function (WrappedComponent) {
63
72
  _this.cacheValues(calculatedValues);
64
73
 
65
74
  _this.externalMutations = _this.getExternalMutations(props);
75
+ _this.calculatedState = _this.getStateChanges(props, calculatedValues);
66
76
  return _this;
67
77
  }
68
78
 
69
79
  _createClass(addEvents, [{
70
- key: "componentDidUpdate",
71
- value: function componentDidUpdate() {
72
- var externalMutations = this.getExternalMutations(this.props);
73
-
74
- if (!isEqual(this.externalMutations, externalMutations)) {
80
+ key: "shouldComponentUpdate",
81
+ value: function shouldComponentUpdate(nextProps) {
82
+ var calculatedValues = this.getCalculatedValues(nextProps);
83
+ var externalMutations = this.getExternalMutations(nextProps);
84
+ var animating = this.props.animating || this.props.animate;
85
+ var newMutation = !isEqual(externalMutations, this.externalMutations);
86
+
87
+ if (animating || newMutation) {
88
+ this.cacheValues(calculatedValues);
75
89
  this.externalMutations = externalMutations;
76
- this.applyExternalMutations(this.props, externalMutations);
90
+ this.applyExternalMutations(nextProps, externalMutations);
91
+ return true;
77
92
  }
78
- }
93
+
94
+ var calculatedState = this.getStateChanges(nextProps, calculatedValues);
95
+
96
+ if (!isEqual(this.calculatedState, calculatedState)) {
97
+ this.calculatedState = calculatedState;
98
+ this.cacheValues(calculatedValues);
99
+ return true;
100
+ }
101
+
102
+ if (!isEqual(this.props, nextProps)) {
103
+ this.cacheValues(calculatedValues);
104
+ return true;
105
+ }
106
+
107
+ return false;
108
+ } // compile all state changes from own and parent state. Order doesn't matter, as any state
109
+ // state change should trigger a re-render
110
+
79
111
  }, {
80
- key: "componentWillReceiveProps",
81
- value: function componentWillReceiveProps(nextProps) {
82
- this.cacheValues(this.getCalculatedValues(nextProps));
112
+ key: "getStateChanges",
113
+ value: function getStateChanges(props, calculatedValues) {
114
+ var _this2 = this;
115
+
116
+ var hasEvents = calculatedValues.hasEvents,
117
+ getSharedEventState = calculatedValues.getSharedEventState;
118
+
119
+ if (!hasEvents) {
120
+ return {};
121
+ }
122
+
123
+ var getState = function (key, type) {
124
+ var result = _defaults({}, _this2.getEventState(key, type), getSharedEventState(key, type));
125
+
126
+ return _isEmpty(result) ? undefined : result;
127
+ };
128
+
129
+ options = options || {};
130
+ var components = options.components || defaultComponents;
131
+ var stateChanges = components.map(function (component) {
132
+ if (!props.standalone && component.name === "parent") {
133
+ // don't check for changes on parent props for non-standalone components
134
+ return undefined;
135
+ } else {
136
+ return component.index !== undefined ? getState(component.index, component.name) : calculatedValues.dataKeys.map(function (key) {
137
+ return getState(key, component.name);
138
+ }).filter(Boolean);
139
+ }
140
+ }).filter(Boolean);
141
+ return stateChanges;
83
142
  }
84
143
  }, {
85
144
  key: "applyExternalMutations",
@@ -133,10 +192,10 @@ export default (function (WrappedComponent) {
133
192
  }, {
134
193
  key: "cacheValues",
135
194
  value: function cacheValues(obj) {
136
- var _this2 = this;
195
+ var _this3 = this;
137
196
 
138
197
  _keys(obj).forEach(function (key) {
139
- _this2[key] = obj[key];
198
+ _this3[key] = obj[key];
140
199
  });
141
200
  }
142
201
  }, {
@@ -222,7 +281,7 @@ export default (function (WrappedComponent) {
222
281
  }, {
223
282
  key: "renderContinuousData",
224
283
  value: function renderContinuousData(props) {
225
- var _this3 = this;
284
+ var _this4 = this;
226
285
 
227
286
  var dataComponent = props.dataComponent,
228
287
  labelComponent = props.labelComponent,
@@ -231,7 +290,7 @@ export default (function (WrappedComponent) {
231
290
  var dataKeys = _without(this.dataKeys, "all");
232
291
 
233
292
  var labelComponents = dataKeys.reduce(function (memo, key) {
234
- var labelProps = _this3.getComponentProps(labelComponent, "labels", key);
293
+ var labelProps = _this4.getComponentProps(labelComponent, "labels", key);
235
294
 
236
295
  if (labelProps && labelProps.text !== undefined && labelProps.text !== null) {
237
296
  memo = memo.concat(React.cloneElement(labelComponent, labelProps));
@@ -246,14 +305,14 @@ export default (function (WrappedComponent) {
246
305
  }, {
247
306
  key: "renderData",
248
307
  value: function renderData(props) {
249
- var _this4 = this;
308
+ var _this5 = this;
250
309
 
251
310
  var shouldRenderDatum = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : datumHasXandY;
252
311
  var dataComponent = props.dataComponent,
253
312
  labelComponent = props.labelComponent,
254
313
  groupComponent = props.groupComponent;
255
314
  var dataComponents = this.dataKeys.reduce(function (validDataComponents, _dataKey, index) {
256
- var dataProps = _this4.getComponentProps(dataComponent, "data", index);
315
+ var dataProps = _this5.getComponentProps(dataComponent, "data", index);
257
316
 
258
317
  if (shouldRenderDatum(dataProps.datum)) {
259
318
  validDataComponents.push(React.cloneElement(dataComponent, dataProps));
@@ -262,7 +321,7 @@ export default (function (WrappedComponent) {
262
321
  return validDataComponents;
263
322
  }, []);
264
323
  var labelComponents = this.dataKeys.map(function (_dataKey, index) {
265
- var labelProps = _this4.getComponentProps(labelComponent, "labels", index);
324
+ var labelProps = _this5.getComponentProps(labelComponent, "labels", index);
266
325
 
267
326
  if (labelProps.text !== undefined && labelProps.text !== null) {
268
327
  return React.cloneElement(labelComponent, labelProps);
@@ -5,6 +5,7 @@ import _orderBy from "lodash/orderBy";
5
5
  import _range from "lodash/range";
6
6
  import _uniq from "lodash/uniq";
7
7
  import _invert from "lodash/invert";
8
+ import _isObject from "lodash/isObject";
8
9
  import _isFunction from "lodash/isFunction";
9
10
  import _identity from "lodash/identity";
10
11
 
@@ -211,8 +212,10 @@ function stringTicks(props) {
211
212
  }
212
213
 
213
214
  function getDefaultTickFormat(props) {
214
- var tickValues = props.tickValues,
215
- stringMap = props.stringMap;
215
+ var tickValues = props.tickValues;
216
+ var axis = getAxis(props);
217
+ var currentAxis = getCurrentAxis(axis, props.horizontal);
218
+ var stringMap = props.stringMap && props.stringMap[currentAxis];
216
219
  var fallbackFormat = tickValues && !Collection.containsDates(tickValues) ? function (x) {
217
220
  return x;
218
221
  } : undefined;
@@ -240,8 +243,10 @@ function getDefaultTickFormat(props) {
240
243
  }
241
244
 
242
245
  function getTickFormat(props, scale) {
243
- var tickFormat = props.tickFormat,
244
- stringMap = props.stringMap;
246
+ var tickFormat = props.tickFormat;
247
+ var axis = getAxis(props);
248
+ var currentAxis = getCurrentAxis(axis, props.horizontal);
249
+ var stringMap = props.stringMap && props.stringMap[currentAxis];
245
250
 
246
251
  if (!tickFormat) {
247
252
  var defaultTickFormat = getDefaultTickFormat(props);
@@ -272,8 +277,9 @@ function getTickFormat(props, scale) {
272
277
  }
273
278
 
274
279
  function getStringTicks(props) {
275
- var stringMap = props.stringMap;
276
280
  var axis = getAxis(props);
281
+ var currentAxis = getCurrentAxis(axis, props.horizontal);
282
+ var stringMap = props.stringMap && props.stringMap[currentAxis];
277
283
  var categories = Array.isArray(props.categories) ? props.categories : props.categories && props.categories[axis];
278
284
  var ticksFromCategories = categories && Collection.containsOnlyStrings(categories) ? categories.map(function (tick) {
279
285
  return stringMap[tick];
@@ -286,8 +292,10 @@ function getStringTicks(props) {
286
292
 
287
293
  function getTickArray(props) {
288
294
  var tickValues = props.tickValues,
289
- tickFormat = props.tickFormat,
290
- stringMap = props.stringMap;
295
+ tickFormat = props.tickFormat;
296
+ var axis = getAxis(props);
297
+ var currentAxis = getCurrentAxis(axis, props.horizontal);
298
+ var stringMap = props.stringMap && props.stringMap[currentAxis];
291
299
 
292
300
  var getTicksFromFormat = function () {
293
301
  if (!tickFormat || !Array.isArray(tickFormat)) {
@@ -314,7 +322,6 @@ function getTickArray(props) {
314
322
  var tickArray = ticks ? _uniq(ticks) : getTicksFromFormat(props);
315
323
 
316
324
  var filterArray = function (arr) {
317
- var axis = getAxis(props);
318
325
  var domain = props.domain && props.domain[axis] || props.domain;
319
326
  return Array.isArray(domain) ? arr.filter(function (t) {
320
327
  return t >= Math.min.apply(Math, _toConsumableArray(domain)) && t <= Math.max.apply(Math, _toConsumableArray(domain));
@@ -410,6 +417,24 @@ function getDomain(props, axis) {
410
417
  return Domain.createDomainFunction(getDomainFromData)(props, inherentAxis);
411
418
  }
412
419
 
420
+ function getAxisValue(props, axis) {
421
+ if (!props.axisValue) {
422
+ return undefined;
423
+ }
424
+
425
+ var scaleAxis = axis === "x" ? "y" : "x";
426
+ var scale = _isObject(props.scale) && _isFunction(props.scale[scaleAxis]) ? props.scale[scaleAxis] : undefined;
427
+
428
+ if (!scale) {
429
+ return undefined;
430
+ }
431
+
432
+ var stringMapAxis = getCurrentAxis(axis, props.horizontal) === "x" ? "y" : "x";
433
+ var stringMap = _isObject(props.stringMap) && props.stringMap[stringMapAxis];
434
+ var axisValue = stringMap && typeof props.axisValue === "string" ? stringMap[props.axisValue] : props.axisValue;
435
+ return scale(axisValue);
436
+ }
437
+
413
438
  export default {
414
439
  getTicks: getTicks,
415
440
  getTickFormat: getTickFormat,
@@ -423,5 +448,6 @@ export default {
423
448
  getOriginSign: getOriginSign,
424
449
  getDomain: getDomain,
425
450
  isVertical: isVertical,
426
- stringTicks: stringTicks
451
+ stringTicks: stringTicks,
452
+ getAxisValue: getAxisValue
427
453
  };
@@ -338,8 +338,13 @@ function getStringsFromData(props, axis) {
338
338
  }
339
339
 
340
340
  var key = props[axis] === undefined ? axis : props[axis];
341
- var accessor = Helpers.createAccessor(key);
342
- var sortedData = sortData(props.data, props.sortKey, props.sortOrder);
341
+ var accessor = Helpers.createAccessor(key); // support immutable data
342
+
343
+ var data = props.data.reduce(function (memo, d) {
344
+ memo.push(parseDatum(d));
345
+ return memo;
346
+ }, []);
347
+ var sortedData = sortData(data, props.sortKey, props.sortOrder);
343
348
  var dataStrings = sortedData.reduce(function (dataArr, datum) {
344
349
  datum = parseDatum(datum);
345
350
  dataArr.push(accessor(datum));
@@ -289,9 +289,7 @@ function reduceChildren(children, iteratee) {
289
289
  } else {
290
290
  var result = iteratee(child, childName, parent);
291
291
 
292
- if (Array.isArray(result)) {
293
- memo = result.reduce(combine, memo);
294
- } else if (result) {
292
+ if (result) {
295
293
  memo = combine(memo, result);
296
294
  }
297
295
  }
@@ -128,14 +128,15 @@ export default {
128
128
  getAllEvents: function (props) {
129
129
  var components = ["groupComponent", "containerComponent", "labelComponent"];
130
130
  this.componentEvents = Events.getComponentEvents(props, components);
131
+ var events = props.events;
131
132
 
132
133
  if (Array.isArray(this.componentEvents)) {
133
134
  var _componentEvents;
134
135
 
135
- return Array.isArray(props.events) ? (_componentEvents = this.componentEvents).concat.apply(_componentEvents, _toConsumableArray(props.events)) : this.componentEvents;
136
+ events = Array.isArray(props.events) ? (_componentEvents = this.componentEvents).concat.apply(_componentEvents, _toConsumableArray(props.events)) : this.componentEvents;
136
137
  }
137
138
 
138
- return props.events;
139
+ return events || [];
139
140
  },
140
141
  getAnimationProps: function (props, child, index) {
141
142
  var _this = this;
@@ -373,9 +374,15 @@ export default {
373
374
  };
374
375
 
375
376
  var combine = function (memo, datum) {
377
+ var x = Array.isArray(datum) ? datum.map(function (d) {
378
+ return d.x;
379
+ }).filter(Boolean) : datum.x;
380
+ var y = Array.isArray(datum) ? datum.map(function (d) {
381
+ return d.y;
382
+ }).filter(Boolean) : datum.y;
376
383
  return {
377
- x: datum.x !== undefined ? memo.x.concat(datum.x) : memo.x,
378
- y: datum.y !== undefined ? memo.y.concat(datum.y) : memo.y
384
+ x: x !== undefined ? memo.x.concat(x) : memo.x,
385
+ y: y !== undefined ? memo.y.concat(y) : memo.y
379
386
  };
380
387
  };
381
388
 
@@ -15,6 +15,8 @@ var _util = require("./util");
15
15
 
16
16
  var _timer = _interopRequireDefault(require("../victory-util/timer"));
17
17
 
18
+ var _reactFastCompare = _interopRequireDefault(require("react-fast-compare"));
19
+
18
20
  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
19
21
 
20
22
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -82,31 +84,35 @@ function (_React$Component) {
82
84
  this.traverseQueue();
83
85
  }
84
86
  }
85
- /* lifecycle */
86
-
87
87
  }, {
88
- key: "componentWillReceiveProps",
89
- value: function componentWillReceiveProps(nextProps) {
90
- /* cancel existing loop if it exists */
91
- this.getTimer().unsubscribe(this.loopID);
92
- /* If an object was supplied */
93
-
94
- if (!Array.isArray(nextProps.data)) {
95
- // Replace the tween queue. Could set `this.queue = [nextProps.data]`,
96
- // but let's reuse the same array.
97
- this.queue.length = 0;
98
- this.queue.push(nextProps.data);
99
- /* If an array was supplied */
100
- } else {
101
- var _queue;
88
+ key: "shouldComponentUpdate",
89
+ value: function shouldComponentUpdate(nextProps, nextState) {
90
+ var equalProps = (0, _reactFastCompare.default)(this.props, nextProps);
102
91
 
103
- /* Extend the tween queue */
104
- (_queue = this.queue).push.apply(_queue, _toConsumableArray(nextProps.data));
105
- }
106
- /* Start traversing the tween queue */
92
+ if (!equalProps) {
93
+ /* cancel existing loop if it exists */
94
+ this.getTimer().unsubscribe(this.loopID);
95
+ /* If an object was supplied */
96
+
97
+ if (!Array.isArray(nextProps.data)) {
98
+ // Replace the tween queue. Could set `this.queue = [nextProps.data]`,
99
+ // but let's reuse the same array.
100
+ this.queue.length = 0;
101
+ this.queue.push(nextProps.data);
102
+ /* If an array was supplied */
103
+ } else {
104
+ var _queue;
107
105
 
106
+ /* Extend the tween queue */
107
+ (_queue = this.queue).push.apply(_queue, _toConsumableArray(nextProps.data));
108
+ }
109
+ /* Start traversing the tween queue */
110
+
111
+
112
+ this.traverseQueue();
113
+ }
108
114
 
109
- this.traverseQueue();
115
+ return nextState.animationInfo.animating || !equalProps;
110
116
  }
111
117
  }, {
112
118
  key: "componentWillUnmount",
@@ -27,6 +27,8 @@ var _timer = _interopRequireDefault(require("../victory-util/timer"));
27
27
 
28
28
  var _transitions = _interopRequireDefault(require("../victory-util/transitions"));
29
29
 
30
+ var _reactFastCompare = _interopRequireDefault(require("react-fast-compare"));
31
+
30
32
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
31
33
 
32
34
  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); }
@@ -74,14 +76,18 @@ function (_React$Component) {
74
76
  }); //eslint-disable-line react/no-did-mount-set-state
75
77
  }
76
78
  }, {
77
- key: "componentWillReceiveProps",
78
- value: function componentWillReceiveProps(nextProps) {
79
+ key: "shouldComponentUpdate",
80
+ value: function shouldComponentUpdate(nextProps) {
79
81
  var _this2 = this;
80
82
 
81
- this.getTimer().bypassAnimation();
82
- this.setState(this.getTransitionState(this.props, nextProps), function () {
83
- return _this2.getTimer().resumeAnimation();
84
- });
83
+ if (!(0, _reactFastCompare.default)(this.props, nextProps)) {
84
+ this.getTimer().bypassAnimation();
85
+ this.setState(this.getTransitionState(this.props, nextProps), function () {
86
+ return _this2.getTimer().resumeAnimation();
87
+ });
88
+ }
89
+
90
+ return true;
85
91
  }
86
92
  }, {
87
93
  key: "componentWillUnmount",