victory-core 30.6.1 → 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.
Files changed (71) hide show
  1. package/README.md +13 -12
  2. package/dist/victory-core.js +1083 -842
  3. package/dist/victory-core.min.js +1 -1
  4. package/es/victory-animation/victory-animation.js +26 -21
  5. package/es/victory-label/victory-label.js +8 -2
  6. package/es/victory-primitives/path-helpers.js +1 -1
  7. package/es/victory-transition/victory-transition.js +11 -6
  8. package/es/victory-util/add-events.js +66 -38
  9. package/es/victory-util/axis.js +35 -9
  10. package/es/victory-util/data.js +24 -9
  11. package/es/victory-util/domain.js +15 -7
  12. package/es/victory-util/events.js +1 -1
  13. package/es/victory-util/helpers.js +17 -5
  14. package/es/victory-util/label-helpers.js +3 -5
  15. package/es/victory-util/textsize.js +20 -20
  16. package/es/victory-util/transitions.js +16 -16
  17. package/es/victory-util/wrapper.js +56 -19
  18. package/lib/victory-animation/victory-animation.js +27 -21
  19. package/lib/victory-label/victory-label.js +8 -2
  20. package/lib/victory-primitives/path-helpers.js +1 -1
  21. package/lib/victory-transition/victory-transition.js +12 -6
  22. package/lib/victory-util/add-events.js +66 -38
  23. package/lib/victory-util/axis.js +36 -9
  24. package/lib/victory-util/data.js +25 -9
  25. package/lib/victory-util/domain.js +16 -8
  26. package/lib/victory-util/events.js +1 -1
  27. package/lib/victory-util/helpers.js +17 -5
  28. package/lib/victory-util/label-helpers.js +3 -5
  29. package/lib/victory-util/textsize.js +20 -20
  30. package/lib/victory-util/transitions.js +16 -16
  31. package/lib/victory-util/wrapper.js +56 -19
  32. package/package.json +1 -1
  33. package/src/victory-animation/util.js +47 -45
  34. package/src/victory-animation/victory-animation.js +66 -38
  35. package/src/victory-clip-container/victory-clip-container.js +44 -31
  36. package/src/victory-container/victory-container.js +35 -21
  37. package/src/victory-label/victory-label.js +55 -71
  38. package/src/victory-portal/portal.js +1 -1
  39. package/src/victory-portal/victory-portal.js +10 -7
  40. package/src/victory-primitives/arc.js +15 -4
  41. package/src/victory-primitives/border.js +26 -5
  42. package/src/victory-primitives/circle.js +14 -3
  43. package/src/victory-primitives/clip-path.js +2 -7
  44. package/src/victory-primitives/line-segment.js +28 -5
  45. package/src/victory-primitives/line.js +15 -2
  46. package/src/victory-primitives/path-helpers.js +6 -7
  47. package/src/victory-primitives/point.js +30 -11
  48. package/src/victory-primitives/rect.js +19 -3
  49. package/src/victory-primitives/text.js +21 -11
  50. package/src/victory-primitives/tspan.js +6 -4
  51. package/src/victory-primitives/whisker.js +13 -6
  52. package/src/victory-theme/grayscale.js +153 -128
  53. package/src/victory-theme/material.js +178 -149
  54. package/src/victory-transition/victory-transition.js +31 -25
  55. package/src/victory-util/add-events.js +113 -75
  56. package/src/victory-util/axis.js +89 -35
  57. package/src/victory-util/collection.js +3 -8
  58. package/src/victory-util/common-props.js +42 -36
  59. package/src/victory-util/data.js +78 -43
  60. package/src/victory-util/domain.js +68 -46
  61. package/src/victory-util/events.js +129 -112
  62. package/src/victory-util/helpers.js +36 -16
  63. package/src/victory-util/immutable.js +12 -7
  64. package/src/victory-util/label-helpers.js +34 -18
  65. package/src/victory-util/prop-types.js +11 -23
  66. package/src/victory-util/scale.js +2 -3
  67. package/src/victory-util/selection.js +4 -5
  68. package/src/victory-util/style.js +17 -10
  69. package/src/victory-util/textsize.js +35 -31
  70. package/src/victory-util/transitions.js +53 -35
  71. package/src/victory-util/wrapper.js +112 -56
@@ -2,14 +2,23 @@
2
2
  /* eslint-disable no-use-before-define */
3
3
  import React from "react";
4
4
  import {
5
- assign, uniq, range, last, isFunction, isPlainObject, property, orderBy, isEmpty, includes
5
+ assign,
6
+ uniq,
7
+ range,
8
+ last,
9
+ isFunction,
10
+ isPlainObject,
11
+ property,
12
+ orderBy,
13
+ isEmpty,
14
+ isEqual,
15
+ includes
6
16
  } from "lodash";
7
17
  import Helpers from "./helpers";
8
18
  import Collection from "./collection";
9
19
  import Scale from "./scale";
10
20
  import Immutable from "./immutable";
11
21
 
12
-
13
22
  // Private Functions
14
23
 
15
24
  function parseDatum(datum) {
@@ -85,10 +94,17 @@ function getEventKey(key) {
85
94
 
86
95
  // Returns data with an eventKey prop added to each datum
87
96
  function addEventKeys(props, data) {
97
+ const hasEventKeyAccessor = !!props.eventKey;
88
98
  const eventKeyAccessor = getEventKey(props.eventKey);
89
- return data.map((datum, index) => {
90
- const eventKey = datum.eventKey || eventKeyAccessor(datum) || index;
91
- return assign({ eventKey }, datum);
99
+ return data.map((datum) => {
100
+ if (datum.eventKey !== undefined) {
101
+ return datum;
102
+ } else if (hasEventKeyAccessor) {
103
+ const eventKey = eventKeyAccessor(datum);
104
+ return eventKey !== undefined ? assign({ eventKey }, datum) : datum;
105
+ } else {
106
+ return datum;
107
+ }
92
108
  });
93
109
  }
94
110
 
@@ -107,11 +123,12 @@ function createStringMap(props, axis) {
107
123
  const stringsFromData = getStringsFromData(props, axis);
108
124
 
109
125
  const allStrings = uniq([...stringsFromAxes, ...stringsFromCategories, ...stringsFromData]);
110
- return allStrings.length === 0 ? null :
111
- allStrings.reduce((memo, string, index) => {
112
- memo[string] = index + 1;
113
- return memo;
114
- }, {});
126
+ return allStrings.length === 0
127
+ ? null
128
+ : allStrings.reduce((memo, string, index) => {
129
+ memo[string] = index + 1;
130
+ return memo;
131
+ }, {});
115
132
  }
116
133
 
117
134
  /**
@@ -131,7 +148,7 @@ function downsample(data, maxPoints, startingIndex = 0) {
131
148
  const k = Math.pow(2, Math.ceil(Math.log2(dataLength / maxPoints)));
132
149
  return data.filter(
133
150
  // ensure modulo is always calculated from same reference: i + startingIndex
134
- (d, i) => (((i + startingIndex) % k) === 0)
151
+ (d, i) => (i + startingIndex) % k === 0
135
152
  );
136
153
  }
137
154
  return data;
@@ -150,7 +167,8 @@ function formatData(dataset, props, expectedKeys) {
150
167
  return [];
151
168
  }
152
169
 
153
- expectedKeys = Array.isArray(expectedKeys) ? expectedKeys : ["x", "y", "y0"];
170
+ const defaultKeys = ["x", "y", "y0"];
171
+ expectedKeys = Array.isArray(expectedKeys) ? expectedKeys : defaultKeys;
154
172
 
155
173
  const stringMap = {
156
174
  x: expectedKeys.indexOf("x") !== -1 ? createStringMap(props, "x") : undefined,
@@ -167,31 +185,39 @@ function formatData(dataset, props, expectedKeys) {
167
185
  return memo;
168
186
  }, {});
169
187
 
170
-
171
- const data = dataset.reduce((dataArr, datum, index) => { // eslint-disable-line complexity
172
- datum = parseDatum(datum);
173
- const fallbackValues = { x: index, y: datum };
174
- const processedValues = expectedKeys.reduce((memo, type) => {
175
- const processedValue = accessor[type](datum);
176
- const value = processedValue !== undefined ? processedValue : fallbackValues[type];
177
- if (value !== undefined) {
178
- if (typeof value === "string" && stringMap[type]) {
179
- memo[`${type}Name`] = value;
180
- memo[`_${type}`] = stringMap[type][value];
181
- } else {
182
- memo[`_${type}`] = value;
188
+ const preformattedData =
189
+ isEqual(expectedKeys, defaultKeys) &&
190
+ props.x === "_x" &&
191
+ props.y === "_y" &&
192
+ props.y0 === "_y0";
193
+
194
+ const data = preformattedData
195
+ ? dataset
196
+ : dataset.reduce((dataArr, datum, index) => {
197
+ // eslint-disable-line complexity
198
+ datum = parseDatum(datum);
199
+ const fallbackValues = { x: index, y: datum };
200
+ const processedValues = expectedKeys.reduce((memo, type) => {
201
+ const processedValue = accessor[type](datum);
202
+ const value = processedValue !== undefined ? processedValue : fallbackValues[type];
203
+ if (value !== undefined) {
204
+ if (typeof value === "string" && stringMap[type]) {
205
+ memo[`${type}Name`] = value;
206
+ memo[`_${type}`] = stringMap[type][value];
207
+ } else {
208
+ memo[`_${type}`] = value;
209
+ }
210
+ }
211
+ return memo;
212
+ }, {});
213
+
214
+ const formattedDatum = assign({}, processedValues, datum);
215
+ if (!isEmpty(formattedDatum)) {
216
+ dataArr.push(formattedDatum);
183
217
  }
184
- }
185
- return memo;
186
- }, {});
187
-
188
- const formattedDatum = assign({}, processedValues, datum);
189
- if (!isEmpty(formattedDatum)) {
190
- dataArr.push(formattedDatum);
191
- }
192
218
 
193
- return dataArr;
194
- }, []);
219
+ return dataArr;
220
+ }, []);
195
221
 
196
222
  const sortedData = sortData(data, props.sortKey, props.sortOrder);
197
223
  const cleanedData = cleanData(sortedData, props);
@@ -220,8 +246,9 @@ function generateData(props) {
220
246
  */
221
247
  function getCategories(props, axis) {
222
248
  const currentAxis = Helpers.getCurrentAxis(axis, props.horizontal);
223
- return props.categories && !Array.isArray(props.categories) ?
224
- props.categories[currentAxis] : props.categories;
249
+ return props.categories && !Array.isArray(props.categories)
250
+ ? props.categories[currentAxis]
251
+ : props.categories;
225
252
  }
226
253
 
227
254
  /**
@@ -280,12 +307,20 @@ function getStringsFromData(props, axis) {
280
307
  const key = props[axis] === undefined ? axis : props[axis];
281
308
  const accessor = Helpers.createAccessor(key);
282
309
 
283
- const sortedData = sortData(props.data, props.sortKey, props.sortOrder);
284
- const dataStrings = sortedData.reduce((dataArr, datum) => {
285
- datum = parseDatum(datum);
286
- dataArr.push(accessor(datum));
287
- return dataArr;
288
- }, []).filter((datum) => typeof datum === "string");
310
+ // support immutable data
311
+ const data = props.data.reduce((memo, d) => {
312
+ memo.push(parseDatum(d));
313
+ return memo;
314
+ }, []);
315
+
316
+ const sortedData = sortData(data, props.sortKey, props.sortOrder);
317
+ const dataStrings = sortedData
318
+ .reduce((dataArr, datum) => {
319
+ datum = parseDatum(datum);
320
+ dataArr.push(accessor(datum));
321
+ return dataArr;
322
+ }, [])
323
+ .filter((datum) => typeof datum === "string");
289
324
 
290
325
  // return a unique set of strings
291
326
  return dataStrings.reduce((prev, curr) => {
@@ -17,8 +17,8 @@ function cleanDomain(domain, props, axis) {
17
17
  }
18
18
 
19
19
  const rules = (dom) => {
20
- const almostZero = dom[0] < 0 || dom[1] < 0 ? -1 / Number.MAX_SAFE_INTEGER
21
- : 1 / Number.MAX_SAFE_INTEGER;
20
+ const almostZero =
21
+ dom[0] < 0 || dom[1] < 0 ? -1 / Number.MAX_SAFE_INTEGER : 1 / Number.MAX_SAFE_INTEGER;
22
22
  const domainOne = dom[0] === 0 ? almostZero : dom[0];
23
23
  const domainTwo = dom[1] === 0 ? almostZero : dom[1];
24
24
  return [domainOne, domainTwo];
@@ -29,23 +29,26 @@ function cleanDomain(domain, props, axis) {
29
29
 
30
30
  function getDomainPadding(props, axis) {
31
31
  const formatPadding = (padding) => {
32
- return Array.isArray(padding) ?
33
- { left: padding[0], right: padding[1] } : { left: padding, right: padding };
32
+ return Array.isArray(padding)
33
+ ? { left: padding[0], right: padding[1] }
34
+ : { left: padding, right: padding };
34
35
  };
35
36
 
36
- return isPlainObject(props.domainPadding) ?
37
- formatPadding(props.domainPadding[axis]) : formatPadding(props.domainPadding);
37
+ return isPlainObject(props.domainPadding)
38
+ ? formatPadding(props.domainPadding[axis])
39
+ : formatPadding(props.domainPadding);
38
40
  }
39
41
 
40
42
  function getFlatData(dataset, axis) {
41
43
  return flatten(dataset).map((datum) => {
42
- return datum[`_${axis}`] && datum[`_${axis}`][1] !== undefined ?
43
- datum[`_${axis}`][1] : datum[`_${axis}`];
44
+ return datum[`_${axis}`] && datum[`_${axis}`][1] !== undefined
45
+ ? datum[`_${axis}`][1]
46
+ : datum[`_${axis}`];
44
47
  });
45
48
  }
46
49
 
47
50
  function getExtremeFromData(dataset, axis, type = "min") {
48
- const getExtreme = (arr) => type === "max" ? Math.max(...arr) : Math.min(...arr);
51
+ const getExtreme = (arr) => (type === "max" ? Math.max(...arr) : Math.min(...arr));
49
52
  const initialValue = type === "max" ? -Infinity : Infinity;
50
53
  let containsDate = false;
51
54
  const result = flatten(dataset).reduce((memo, datum) => {
@@ -78,19 +81,20 @@ function padDomain(domain, props, axis) {
78
81
 
79
82
  // Naive initial padding calculation
80
83
  const initialPadding = {
81
- left: Math.abs(max - min) * padding.left / rangeExtent,
82
- right: Math.abs(max - min) * padding.right / rangeExtent
84
+ left: (Math.abs(max - min) * padding.left) / rangeExtent,
85
+ right: (Math.abs(max - min) * padding.right) / rangeExtent
83
86
  };
84
87
 
85
- const singleQuadrantDomainPadding = isPlainObject(props.singleQuadrantDomainPadding) ?
86
- props.singleQuadrantDomainPadding[axis] : props.singleQuadrantDomainPadding;
88
+ const singleQuadrantDomainPadding = isPlainObject(props.singleQuadrantDomainPadding)
89
+ ? props.singleQuadrantDomainPadding[axis]
90
+ : props.singleQuadrantDomainPadding;
87
91
 
88
92
  const adjust = (val, type) => {
89
93
  if (singleQuadrantDomainPadding === false) {
90
94
  return val;
91
95
  }
92
- const coerce = (type === "min" && min >= 0 && val <= 0) ||
93
- (type === "max" && max <= 0 && val >= 0);
96
+ const coerce =
97
+ (type === "min" && min >= 0 && val <= 0) || (type === "max" && max <= 0 && val >= 0);
94
98
  return coerce ? 0 : val;
95
99
  };
96
100
 
@@ -102,8 +106,8 @@ function padDomain(domain, props, axis) {
102
106
 
103
107
  // re-calculate padding, taking the adjusted domain into account
104
108
  const finalPadding = {
105
- left: Math.abs(adjustedDomain.max - adjustedDomain.min) * padding.left / rangeExtent,
106
- right: Math.abs(adjustedDomain.max - adjustedDomain.min) * padding.right / rangeExtent
109
+ left: (Math.abs(adjustedDomain.max - adjustedDomain.min) * padding.left) / rangeExtent,
110
+ right: (Math.abs(adjustedDomain.max - adjustedDomain.min) * padding.right) / rangeExtent
107
111
  };
108
112
 
109
113
  // Adjust the domain by the final padding
@@ -118,9 +122,9 @@ function padDomain(domain, props, axis) {
118
122
  max: maxDomain !== undefined ? maxDomain : paddedDomain.max
119
123
  };
120
124
 
121
- return min instanceof Date || max instanceof Date ?
122
- getDomainFromMinMax(new Date(finalDomain.min), new Date(finalDomain.max)) :
123
- getDomainFromMinMax(finalDomain.min, finalDomain.max);
125
+ return min instanceof Date || max instanceof Date
126
+ ? getDomainFromMinMax(new Date(finalDomain.min), new Date(finalDomain.max))
127
+ : getDomainFromMinMax(finalDomain.min, finalDomain.max);
124
128
  }
125
129
 
126
130
  // Public Methods
@@ -134,18 +138,19 @@ function padDomain(domain, props, axis) {
134
138
  * @returns {Function} a function that takes props and axis and returns a formatted domain
135
139
  */
136
140
  function createDomainFunction(getDomainFromDataFunction, formatDomainFunction) {
137
- getDomainFromDataFunction = isFunction(getDomainFromDataFunction) ?
138
- getDomainFromDataFunction : getDomainFromData;
139
- formatDomainFunction = isFunction(formatDomainFunction) ?
140
- formatDomainFunction : formatDomain;
141
+ getDomainFromDataFunction = isFunction(getDomainFromDataFunction)
142
+ ? getDomainFromDataFunction
143
+ : getDomainFromData;
144
+ formatDomainFunction = isFunction(formatDomainFunction) ? formatDomainFunction : formatDomain;
141
145
  return (props, axis) => {
142
146
  const propsDomain = getDomainFromProps(props, axis);
143
147
  if (propsDomain) {
144
148
  return formatDomainFunction(propsDomain, props, axis);
145
149
  }
146
150
  const categories = Data.getCategories(props, axis);
147
- const domain = categories ?
148
- getDomainFromCategories(props, axis, categories) : getDomainFromDataFunction(props, axis);
151
+ const domain = categories
152
+ ? getDomainFromCategories(props, axis, categories)
153
+ : getDomainFromDataFunction(props, axis);
149
154
  return formatDomainFunction(domain, props, axis);
150
155
  };
151
156
  }
@@ -186,20 +191,23 @@ function getDomainFromCategories(props, axis, categories) {
186
191
  }
187
192
  const minDomain = getMinFromProps(props, axis);
188
193
  const maxDomain = getMaxFromProps(props, axis);
189
- const stringArray = Collection.containsStrings(categories) ?
190
- Data.getStringsFromCategories(props, axis) : [];
191
- const stringMap = stringArray.length === 0 ? null :
192
- stringArray.reduce((memo, string, index) => {
193
- memo[string] = index + 1;
194
- return memo;
195
- }, {});
196
- const categoryValues = stringMap ?
197
- categories.map((value) => stringMap[value]) : categories;
194
+ const stringArray = Collection.containsStrings(categories)
195
+ ? Data.getStringsFromCategories(props, axis)
196
+ : [];
197
+ const stringMap =
198
+ stringArray.length === 0
199
+ ? null
200
+ : stringArray.reduce((memo, string, index) => {
201
+ memo[string] = index + 1;
202
+ return memo;
203
+ }, {});
204
+ const categoryValues = stringMap ? categories.map((value) => stringMap[value]) : categories;
198
205
  const min = minDomain !== undefined ? minDomain : Collection.getMinValue(categoryValues);
199
206
  const max = maxDomain !== undefined ? maxDomain : Collection.getMaxValue(categoryValues);
200
207
  const categoryDomain = getDomainFromMinMax(min, max);
201
- return polar && axis === "x" && Math.abs(startAngle - endAngle) === 360 ?
202
- getSymmetricDomain(categoryDomain, categoryValues) : categoryDomain;
208
+ return polar && axis === "x" && Math.abs(startAngle - endAngle) === 360
209
+ ? getSymmetricDomain(categoryDomain, categoryValues)
210
+ : categoryDomain;
203
211
  }
204
212
 
205
213
  /**
@@ -226,8 +234,9 @@ function getDomainFromData(props, axis, dataset) {
226
234
  const max = maxDomain !== undefined ? maxDomain : getExtremeFromData(dataset, currentAxis, "max");
227
235
  const domain = getDomainFromMinMax(min, max);
228
236
 
229
- return polar && axis === "x" && Math.abs(startAngle - endAngle) === 360 ?
230
- getSymmetricDomain(domain, getFlatData(dataset, currentAxis)) : domain;
237
+ return polar && axis === "x" && Math.abs(startAngle - endAngle) === 360
238
+ ? getSymmetricDomain(domain, getFlatData(dataset, currentAxis))
239
+ : domain;
231
240
  }
232
241
 
233
242
  /**
@@ -280,23 +289,36 @@ function getDomainWithZero(props, axis) {
280
289
  if (propsDomain) {
281
290
  return propsDomain;
282
291
  }
292
+
293
+ const dataset = Data.getData(props);
294
+ const y0Min = dataset.reduce((min, datum) => (datum._y0 < min ? datum._y0 : min), Infinity);
295
+
283
296
  const ensureZero = (domain) => {
284
297
  const currentAxis = Helpers.getCurrentAxis(axis, props.horizontal);
285
- const minDomain = getMinFromProps(props, axis);
286
- const maxDomain = getMaxFromProps(props, axis);
287
298
  if (currentAxis === "x") {
288
299
  return domain;
289
300
  }
290
- const defaultMin = minDomain || 0;
291
- const defaultMax = maxDomain || 0;
292
- const min = minDomain !== undefined ? minDomain : Collection.getMinValue(domain, defaultMin);
293
- const max = maxDomain !== undefined ? maxDomain : Collection.getMaxValue(domain, defaultMax);
301
+
302
+ const defaultMin = y0Min !== Infinity ? y0Min : 0;
303
+ const maxDomainProp = getMaxFromProps(props, axis);
304
+ const minDomainProp = getMinFromProps(props, axis);
305
+ const max =
306
+ maxDomainProp !== undefined ? maxDomainProp : Collection.getMaxValue(domain, defaultMin);
307
+ const min =
308
+ minDomainProp !== undefined ? minDomainProp : Collection.getMinValue(domain, defaultMin);
309
+
294
310
  return getDomainFromMinMax(min, max);
295
311
  };
312
+
313
+ const getDomainFunction = () => {
314
+ return getDomainFromData(props, axis, dataset);
315
+ };
316
+
296
317
  const formatDomainFunction = (domain) => {
297
318
  return formatDomain(ensureZero(domain), props, axis);
298
319
  };
299
- return createDomainFunction(null, formatDomainFunction)(props, axis);
320
+
321
+ return createDomainFunction(getDomainFunction, formatDomainFunction)(props, axis);
300
322
  }
301
323
 
302
324
  /**