victory-core 36.9.2 → 37.0.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.
- package/CHANGELOG.md +6 -0
- package/dist/victory-core.js +4371 -5749
- package/dist/victory-core.min.js +1 -1
- package/es/victory-accessible-group/victory-accessible-group.js +9 -15
- package/es/victory-animation/util.js +28 -47
- package/es/victory-animation/victory-animation.js +51 -67
- package/es/victory-clip-container/victory-clip-container.js +153 -229
- package/es/victory-container/victory-container.js +157 -216
- package/es/victory-label/victory-label.js +246 -323
- package/es/victory-portal/portal-context.js +1 -2
- package/es/victory-portal/portal.js +30 -76
- package/es/victory-portal/victory-portal.js +47 -104
- package/es/victory-primitives/arc.js +44 -47
- package/es/victory-primitives/background.js +14 -17
- package/es/victory-primitives/border.js +20 -24
- package/es/victory-primitives/circle.js +13 -27
- package/es/victory-primitives/clip-path.js +3 -7
- package/es/victory-primitives/line-segment.js +20 -24
- package/es/victory-primitives/line.js +13 -27
- package/es/victory-primitives/path.js +13 -27
- package/es/victory-primitives/point.js +36 -40
- package/es/victory-primitives/rect.js +13 -27
- package/es/victory-primitives/text.js +15 -28
- package/es/victory-primitives/tspan.js +13 -26
- package/es/victory-primitives/whisker.js +43 -47
- package/es/victory-theme/grayscale.js +22 -22
- package/es/victory-theme/material.js +46 -46
- package/es/victory-theme/victory-theme.js +3 -3
- package/es/victory-transition/victory-transition.js +126 -206
- package/es/victory-util/add-events.js +263 -374
- package/es/victory-util/axis.js +126 -222
- package/es/victory-util/collection.js +13 -41
- package/es/victory-util/data.js +159 -214
- package/es/victory-util/default-transitions.js +33 -51
- package/es/victory-util/domain.js +122 -171
- package/es/victory-util/events.js +168 -258
- package/es/victory-util/helpers.js +153 -178
- package/es/victory-util/hooks/use-animation-state.js +61 -99
- package/es/victory-util/hooks/use-previous-props.js +2 -2
- package/es/victory-util/immutable.js +6 -8
- package/es/victory-util/label-helpers.js +128 -130
- package/es/victory-util/line-helpers.js +29 -41
- package/es/victory-util/log.js +1 -1
- package/es/victory-util/point-path-helpers.js +89 -49
- package/es/victory-util/scale.js +24 -42
- package/es/victory-util/selection.js +39 -40
- package/es/victory-util/style.js +8 -13
- package/es/victory-util/textsize.js +80 -154
- package/es/victory-util/timer-context.js +2 -2
- package/es/victory-util/timer.js +40 -76
- package/es/victory-util/transitions.js +110 -150
- package/es/victory-util/type-helpers.js +2 -3
- package/es/victory-util/user-props.js +24 -49
- package/es/victory-util/wrapper.js +184 -247
- package/lib/index.js +0 -30
- package/lib/victory-accessible-group/victory-accessible-group.js +9 -19
- package/lib/victory-animation/util.js +28 -63
- package/lib/victory-animation/victory-animation.js +54 -83
- package/lib/victory-clip-container/victory-clip-container.js +156 -243
- package/lib/victory-container/victory-container.js +160 -232
- package/lib/victory-label/victory-label.js +248 -344
- package/lib/victory-portal/portal-context.js +1 -6
- package/lib/victory-portal/portal.js +31 -81
- package/lib/victory-portal/victory-portal.js +50 -116
- package/lib/victory-primitives/arc.js +48 -57
- package/lib/victory-primitives/background.js +16 -28
- package/lib/victory-primitives/border.js +22 -34
- package/lib/victory-primitives/circle.js +16 -36
- package/lib/victory-primitives/clip-path.js +3 -11
- package/lib/victory-primitives/index.js +0 -28
- package/lib/victory-primitives/line-segment.js +22 -34
- package/lib/victory-primitives/line.js +16 -36
- package/lib/victory-primitives/path.js +16 -36
- package/lib/victory-primitives/point.js +38 -52
- package/lib/victory-primitives/rect.js +16 -36
- package/lib/victory-primitives/text.js +15 -33
- package/lib/victory-primitives/tspan.js +13 -31
- package/lib/victory-primitives/whisker.js +45 -57
- package/lib/victory-theme/grayscale.js +23 -24
- package/lib/victory-theme/material.js +47 -48
- package/lib/victory-theme/victory-theme.js +2 -7
- package/lib/victory-transition/victory-transition.js +129 -224
- package/lib/victory-util/add-events.js +263 -380
- package/lib/victory-util/axis.js +128 -241
- package/lib/victory-util/collection.js +13 -50
- package/lib/victory-util/data.js +160 -239
- package/lib/victory-util/default-transitions.js +33 -54
- package/lib/victory-util/domain.js +123 -193
- package/lib/victory-util/events.js +167 -274
- package/lib/victory-util/helpers.js +156 -207
- package/lib/victory-util/hooks/index.js +0 -2
- package/lib/victory-util/hooks/use-animation-state.js +63 -113
- package/lib/victory-util/hooks/use-previous-props.js +2 -7
- package/lib/victory-util/immutable.js +6 -18
- package/lib/victory-util/index.js +2 -51
- package/lib/victory-util/label-helpers.js +130 -141
- package/lib/victory-util/line-helpers.js +31 -49
- package/lib/victory-util/log.js +1 -2
- package/lib/victory-util/point-path-helpers.js +91 -63
- package/lib/victory-util/scale.js +26 -57
- package/lib/victory-util/selection.js +41 -49
- package/lib/victory-util/style.js +8 -16
- package/lib/victory-util/textsize.js +80 -157
- package/lib/victory-util/timer-context.js +2 -8
- package/lib/victory-util/timer.js +40 -76
- package/lib/victory-util/transitions.js +110 -152
- package/lib/victory-util/type-helpers.js +2 -9
- package/lib/victory-util/user-props.js +25 -59
- package/lib/victory-util/wrapper.js +186 -281
- package/package.json +2 -2
package/es/victory-util/data.js
CHANGED
|
@@ -6,216 +6,184 @@ import _orderBy from "lodash/orderBy";
|
|
|
6
6
|
import _property from "lodash/property";
|
|
7
7
|
import _isPlainObject from "lodash/isPlainObject";
|
|
8
8
|
import _uniq from "lodash/uniq";
|
|
9
|
-
|
|
10
|
-
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
11
|
-
|
|
12
|
-
function _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."); }
|
|
13
|
-
|
|
14
|
-
function _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); }
|
|
15
|
-
|
|
16
|
-
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
17
|
-
|
|
18
|
-
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
19
|
-
|
|
20
|
-
function _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; }
|
|
21
|
-
|
|
22
9
|
/* eslint-disable no-use-before-define */
|
|
23
10
|
import React from "react";
|
|
24
11
|
import * as Helpers from "./helpers";
|
|
25
12
|
import * as Collection from "./collection";
|
|
26
13
|
import * as Scale from "./scale";
|
|
27
|
-
import * as Immutable from "./immutable";
|
|
14
|
+
import * as Immutable from "./immutable";
|
|
15
|
+
|
|
16
|
+
// Private Functions
|
|
28
17
|
|
|
29
18
|
function parseDatum(datum) {
|
|
30
|
-
|
|
19
|
+
const immutableDatumWhitelist = {
|
|
31
20
|
errorX: true,
|
|
32
21
|
errorY: true
|
|
33
22
|
};
|
|
34
23
|
return Immutable.isImmutable(datum) ? Immutable.shallowToJS(datum, immutableDatumWhitelist) : datum;
|
|
35
24
|
}
|
|
36
|
-
|
|
37
25
|
function getLength(data) {
|
|
38
26
|
return Immutable.isIterable(data) ? data.size : data.length;
|
|
39
|
-
}
|
|
40
|
-
|
|
27
|
+
}
|
|
41
28
|
|
|
29
|
+
// Returns generated data for a given axis based on domain and sample from props
|
|
42
30
|
function generateDataArray(props, axis) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
31
|
+
const propsDomain = _isPlainObject(props.domain) ? props.domain[axis] : props.domain;
|
|
32
|
+
const domain = propsDomain || Scale.getBaseScale(props, axis).domain();
|
|
33
|
+
const samples = props.samples || 1;
|
|
34
|
+
const domainMax = Math.max(...domain);
|
|
35
|
+
const domainMin = Math.min(...domain);
|
|
36
|
+
const step = (domainMax - domainMin) / samples;
|
|
37
|
+
const values = Helpers.range(domainMin, domainMax, step);
|
|
50
38
|
return values[values.length - 1] === domainMax ? values : values.concat(domainMax);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
function sortData(dataset, sortKey) {
|
|
55
|
-
var sortOrder = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "ascending";
|
|
39
|
+
}
|
|
56
40
|
|
|
41
|
+
// Returns sorted data. If no sort keys are provided, data is returned unaltered.
|
|
42
|
+
function sortData(dataset, sortKey, sortOrder) {
|
|
43
|
+
if (sortOrder === void 0) {
|
|
44
|
+
sortOrder = "ascending";
|
|
45
|
+
}
|
|
57
46
|
if (!sortKey) {
|
|
58
47
|
return dataset;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
var formattedSortKey = sortKey;
|
|
48
|
+
}
|
|
63
49
|
|
|
50
|
+
// Ensures previous VictoryLine api for sortKey prop stays consistent
|
|
51
|
+
let formattedSortKey = sortKey;
|
|
64
52
|
if (sortKey === "x" || sortKey === "y") {
|
|
65
|
-
formattedSortKey =
|
|
53
|
+
formattedSortKey = `_${sortKey}`;
|
|
66
54
|
}
|
|
67
|
-
|
|
68
|
-
var order = sortOrder === "ascending" ? "asc" : "desc";
|
|
55
|
+
const order = sortOrder === "ascending" ? "asc" : "desc";
|
|
69
56
|
return _orderBy(dataset, formattedSortKey, order);
|
|
70
|
-
}
|
|
71
|
-
|
|
57
|
+
}
|
|
72
58
|
|
|
59
|
+
// This method will remove data points that break certain scales. (log scale only)
|
|
73
60
|
function cleanData(dataset, props) {
|
|
74
|
-
|
|
75
|
-
|
|
61
|
+
const smallNumber = 1 / Number.MAX_SAFE_INTEGER;
|
|
62
|
+
const scaleType = {
|
|
76
63
|
x: Scale.getScaleType(props, "x"),
|
|
77
64
|
y: Scale.getScaleType(props, "y")
|
|
78
65
|
};
|
|
79
|
-
|
|
80
66
|
if (scaleType.x !== "log" && scaleType.y !== "log") {
|
|
81
67
|
return dataset;
|
|
82
68
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
return scaleType[axis] === "log" ? datum["_".concat(axis)] !== 0 : true;
|
|
69
|
+
const rules = (datum, axis) => {
|
|
70
|
+
return scaleType[axis] === "log" ? datum[`_${axis}`] !== 0 : true;
|
|
86
71
|
};
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
var _y = rules(datum, "y") ? datum._y : smallNumber;
|
|
92
|
-
|
|
93
|
-
var _y0 = rules(datum, "y0") ? datum._y0 : smallNumber;
|
|
94
|
-
|
|
72
|
+
const sanitize = datum => {
|
|
73
|
+
const _x = rules(datum, "x") ? datum._x : smallNumber;
|
|
74
|
+
const _y = rules(datum, "y") ? datum._y : smallNumber;
|
|
75
|
+
const _y0 = rules(datum, "y0") ? datum._y0 : smallNumber;
|
|
95
76
|
return Object.assign({}, datum, {
|
|
96
|
-
_x
|
|
97
|
-
_y
|
|
98
|
-
_y0
|
|
77
|
+
_x,
|
|
78
|
+
_y,
|
|
79
|
+
_y0
|
|
99
80
|
});
|
|
100
81
|
};
|
|
101
|
-
|
|
102
|
-
return dataset.map(function (datum) {
|
|
82
|
+
return dataset.map(datum => {
|
|
103
83
|
if (rules(datum, "x") && rules(datum, "y") && rules(datum, "y0")) {
|
|
104
84
|
return datum;
|
|
105
85
|
}
|
|
106
|
-
|
|
107
86
|
return sanitize(datum);
|
|
108
87
|
});
|
|
109
|
-
}
|
|
110
|
-
|
|
88
|
+
}
|
|
111
89
|
|
|
90
|
+
// Returns a data accessor given an eventKey prop
|
|
112
91
|
function getEventKey(key) {
|
|
113
92
|
// creates a data accessor function
|
|
114
93
|
// given a property key, path, array index, or null for identity.
|
|
115
94
|
if (Helpers.isFunction(key)) {
|
|
116
95
|
return key;
|
|
117
96
|
} else if (key === null || key === undefined) {
|
|
118
|
-
return
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
} // otherwise, assume it is an array index, property key or path (_.property handles all three)
|
|
122
|
-
|
|
123
|
-
|
|
97
|
+
return () => undefined;
|
|
98
|
+
}
|
|
99
|
+
// otherwise, assume it is an array index, property key or path (_.property handles all three)
|
|
124
100
|
return _property(key);
|
|
125
|
-
}
|
|
126
|
-
|
|
101
|
+
}
|
|
127
102
|
|
|
103
|
+
// Returns data with an eventKey prop added to each datum
|
|
128
104
|
function addEventKeys(props, data) {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
return data.map(
|
|
105
|
+
const hasEventKeyAccessor = !!props.eventKey;
|
|
106
|
+
const eventKeyAccessor = getEventKey(props.eventKey);
|
|
107
|
+
return data.map((datum, index) => {
|
|
132
108
|
if (datum.eventKey !== undefined) {
|
|
133
109
|
return datum;
|
|
134
110
|
} else if (hasEventKeyAccessor) {
|
|
135
|
-
|
|
111
|
+
const eventKey = eventKeyAccessor(datum, index);
|
|
136
112
|
return eventKey !== undefined ? Object.assign({
|
|
137
|
-
eventKey
|
|
113
|
+
eventKey
|
|
138
114
|
}, datum) : datum;
|
|
139
115
|
}
|
|
140
|
-
|
|
141
116
|
return datum;
|
|
142
117
|
});
|
|
143
|
-
}
|
|
144
|
-
// This method will remove data points that fall outside of the desired domain (non-continuous charts only)
|
|
118
|
+
}
|
|
145
119
|
|
|
120
|
+
// Exported Functions
|
|
146
121
|
|
|
122
|
+
// This method will remove data points that fall outside of the desired domain (non-continuous charts only)
|
|
147
123
|
export function formatDataFromDomain(dataset, domain, defaultBaseline) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
var isUnderMinY = underMin(minDomainY);
|
|
171
|
-
var isOverMaxX = overMax(maxDomainX);
|
|
172
|
-
var isOverMaxY = overMax(maxDomainY); // eslint-disable-next-line complexity
|
|
173
|
-
|
|
174
|
-
return dataset.map(function (datum) {
|
|
175
|
-
var _x = datum._x,
|
|
176
|
-
_y = datum._y,
|
|
177
|
-
_y0 = datum._y0,
|
|
178
|
-
_y1 = datum._y1; // single x point less than min domain
|
|
179
|
-
|
|
124
|
+
const exists = val => val !== undefined;
|
|
125
|
+
const minDomainX = Collection.getMinValue(domain.x);
|
|
126
|
+
const maxDomainX = Collection.getMaxValue(domain.x);
|
|
127
|
+
const minDomainY = Collection.getMinValue(domain.y);
|
|
128
|
+
const maxDomainY = Collection.getMaxValue(domain.y);
|
|
129
|
+
const underMin = min => val => exists(val) && val < min;
|
|
130
|
+
const overMax = max => val => exists(val) && val > max;
|
|
131
|
+
const isUnderMinX = underMin(minDomainX);
|
|
132
|
+
const isUnderMinY = underMin(minDomainY);
|
|
133
|
+
const isOverMaxX = overMax(maxDomainX);
|
|
134
|
+
const isOverMaxY = overMax(maxDomainY);
|
|
135
|
+
|
|
136
|
+
// eslint-disable-next-line complexity
|
|
137
|
+
return dataset.map(datum => {
|
|
138
|
+
let {
|
|
139
|
+
_x,
|
|
140
|
+
_y,
|
|
141
|
+
_y0,
|
|
142
|
+
_y1
|
|
143
|
+
} = datum;
|
|
144
|
+
|
|
145
|
+
// single x point less than min domain
|
|
180
146
|
if (isUnderMinX(_x) || isOverMaxX(_x)) _x = null;
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
if (!exists(value)) return datum;
|
|
184
|
-
|
|
185
|
-
if (!exists(baseline) && (isUnderMinY(value) || isOverMaxY(value))) _y = null; // baseline and value are both less than min domain or both greater than max domain
|
|
147
|
+
const baseline = exists(_y0) ? _y0 : defaultBaseline;
|
|
148
|
+
const value = exists(_y1) ? _y1 : _y;
|
|
149
|
+
if (!exists(value)) return datum;
|
|
186
150
|
|
|
187
|
-
|
|
151
|
+
// value only and less than min domain or greater than max domain
|
|
152
|
+
if (!exists(baseline) && (isUnderMinY(value) || isOverMaxY(value))) _y = null;
|
|
188
153
|
|
|
189
|
-
|
|
154
|
+
// baseline and value are both less than min domain or both greater than max domain
|
|
155
|
+
if (isUnderMinY(baseline) && isUnderMinY(value) || isOverMaxY(baseline) && isOverMaxY(value)) _y = _y0 = _y1 = null;
|
|
190
156
|
|
|
157
|
+
// baseline and value with only baseline below min, set baseline to minDomainY
|
|
158
|
+
if (isUnderMinY(baseline) && !isUnderMinY(value)) _y0 = minDomainY;
|
|
159
|
+
// baseline and value with only baseline above max, set baseline to maxDomainY
|
|
191
160
|
if (isOverMaxY(baseline) && !isOverMaxY(value)) _y0 = maxDomainY;
|
|
192
161
|
return Object.assign({}, datum, _omitBy({
|
|
193
|
-
_x
|
|
194
|
-
_y
|
|
195
|
-
_y0
|
|
196
|
-
_y1
|
|
162
|
+
_x,
|
|
163
|
+
_y,
|
|
164
|
+
_y0,
|
|
165
|
+
_y1
|
|
197
166
|
}, _isUndefined));
|
|
198
167
|
});
|
|
199
168
|
}
|
|
169
|
+
|
|
200
170
|
/**
|
|
201
171
|
* Returns an object mapping string data to numeric data
|
|
202
172
|
* @param {Object} props: the props object
|
|
203
173
|
* @param {String} axis: the current axis
|
|
204
174
|
* @returns {Object} an object mapping string data to numeric data
|
|
205
175
|
*/
|
|
206
|
-
|
|
207
176
|
export function createStringMap(props, axis) {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
return allStrings.length === 0 ? null : allStrings.reduce(function (memo, string, index) {
|
|
177
|
+
const stringsFromAxes = getStringsFromAxes(props, axis);
|
|
178
|
+
const stringsFromCategories = getStringsFromCategories(props, axis);
|
|
179
|
+
const stringsFromData = getStringsFromData(props, axis);
|
|
180
|
+
const allStrings = _uniq([...stringsFromAxes, ...stringsFromCategories, ...stringsFromData]);
|
|
181
|
+
return allStrings.length === 0 ? null : allStrings.reduce((memo, string, index) => {
|
|
215
182
|
memo[string] = index + 1;
|
|
216
183
|
return memo;
|
|
217
184
|
}, {});
|
|
218
185
|
}
|
|
186
|
+
|
|
219
187
|
/**
|
|
220
188
|
* Reduces the size of a data array, such that it is <= maxPoints.
|
|
221
189
|
* @param {Array} data: an array of data; must be sorted
|
|
@@ -224,24 +192,23 @@ export function createStringMap(props, axis) {
|
|
|
224
192
|
assumes `data` param is a subset of larger dataset that has been zoommed
|
|
225
193
|
* @returns {Array} an array of data, a subset of data param
|
|
226
194
|
*/
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
195
|
+
export function downsample(data, maxPoints, startingIndex) {
|
|
196
|
+
if (startingIndex === void 0) {
|
|
197
|
+
startingIndex = 0;
|
|
198
|
+
}
|
|
230
199
|
// ensures that the downampling of data while zooming looks good.
|
|
231
|
-
|
|
232
|
-
|
|
200
|
+
const dataLength = getLength(data);
|
|
233
201
|
if (dataLength > maxPoints) {
|
|
234
202
|
// limit k to powers of 2, e.g. 64, 128, 256
|
|
235
203
|
// so that the same points will be chosen reliably, reducing flicker on zoom
|
|
236
|
-
|
|
237
|
-
return data.filter(
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
});
|
|
204
|
+
const k = Math.pow(2, Math.ceil(Math.log2(dataLength / maxPoints)));
|
|
205
|
+
return data.filter(
|
|
206
|
+
// ensure modulo is always calculated from same reference: i + startingIndex
|
|
207
|
+
(d, i) => (i + startingIndex) % k === 0);
|
|
241
208
|
}
|
|
242
|
-
|
|
243
209
|
return data;
|
|
244
210
|
}
|
|
211
|
+
|
|
245
212
|
/**
|
|
246
213
|
* Returns formatted data. Data accessors are applied, and string values are replaced.
|
|
247
214
|
* @param {Array} dataset: the original domain
|
|
@@ -249,31 +216,25 @@ export function downsample(data, maxPoints) {
|
|
|
249
216
|
* @param {Array} expectedKeys: an array of expected data keys
|
|
250
217
|
* @returns {Array} the formatted data
|
|
251
218
|
*/
|
|
252
|
-
|
|
253
219
|
export function formatData(dataset, props, expectedKeys) {
|
|
254
|
-
|
|
255
|
-
|
|
220
|
+
const isArrayOrIterable = Array.isArray(dataset) || Immutable.isIterable(dataset);
|
|
256
221
|
if (!isArrayOrIterable || getLength(dataset) < 1) {
|
|
257
222
|
return [];
|
|
258
223
|
}
|
|
259
|
-
|
|
260
|
-
|
|
224
|
+
const defaultKeys = ["x", "y", "y0"];
|
|
225
|
+
// TODO: We shouldn’t mutate the expectedKeys param here,
|
|
261
226
|
// but we need to figure out why changing it causes regressions in tests.
|
|
262
227
|
// eslint-disable-next-line no-param-reassign
|
|
263
|
-
|
|
264
228
|
expectedKeys = Array.isArray(expectedKeys) ? expectedKeys : defaultKeys;
|
|
265
|
-
|
|
266
|
-
var createAccessor = function (name) {
|
|
229
|
+
const createAccessor = name => {
|
|
267
230
|
return Helpers.createAccessor(props[name] !== undefined ? props[name] : name);
|
|
268
231
|
};
|
|
269
|
-
|
|
270
|
-
var accessor = expectedKeys.reduce(function (memo, type) {
|
|
232
|
+
const accessor = expectedKeys.reduce((memo, type) => {
|
|
271
233
|
memo[type] = createAccessor(type);
|
|
272
234
|
return memo;
|
|
273
235
|
}, {});
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
236
|
+
const preformattedData = _isEqual(expectedKeys, defaultKeys) && props.x === "_x" && props.y === "_y" && props.y0 === "_y0";
|
|
237
|
+
let stringMap;
|
|
277
238
|
if (preformattedData === false) {
|
|
278
239
|
// stringMap is not required if the data is preformatted
|
|
279
240
|
stringMap = {
|
|
@@ -282,173 +243,157 @@ export function formatData(dataset, props, expectedKeys) {
|
|
|
282
243
|
y0: expectedKeys.indexOf("y0") !== -1 ? createStringMap(props, "y") : undefined
|
|
283
244
|
};
|
|
284
245
|
}
|
|
285
|
-
|
|
286
|
-
var data = preformattedData ? dataset : dataset.reduce(function (dataArr, datum, index) {
|
|
246
|
+
const data = preformattedData ? dataset : dataset.reduce((dataArr, datum, index) => {
|
|
287
247
|
// eslint-disable-line complexity
|
|
288
|
-
|
|
289
|
-
|
|
248
|
+
const parsedDatum = parseDatum(datum);
|
|
249
|
+
const fallbackValues = {
|
|
290
250
|
x: index,
|
|
291
251
|
y: parsedDatum
|
|
292
252
|
};
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
253
|
+
const processedValues = expectedKeys.reduce((memo, type) => {
|
|
254
|
+
const processedValue = accessor[type](parsedDatum);
|
|
255
|
+
const value = processedValue !== undefined ? processedValue : fallbackValues[type];
|
|
297
256
|
if (value !== undefined) {
|
|
298
257
|
if (typeof value === "string" && stringMap[type]) {
|
|
299
|
-
memo[
|
|
300
|
-
memo[
|
|
258
|
+
memo[`${type}Name`] = value;
|
|
259
|
+
memo[`_${type}`] = stringMap[type][value];
|
|
301
260
|
} else {
|
|
302
|
-
memo[
|
|
261
|
+
memo[`_${type}`] = value;
|
|
303
262
|
}
|
|
304
263
|
}
|
|
305
|
-
|
|
306
264
|
return memo;
|
|
307
265
|
}, {});
|
|
308
|
-
|
|
309
|
-
|
|
266
|
+
const formattedDatum = Object.assign({}, processedValues, parsedDatum);
|
|
310
267
|
if (!_isEmpty(formattedDatum)) {
|
|
311
268
|
dataArr.push(formattedDatum);
|
|
312
269
|
}
|
|
313
|
-
|
|
314
270
|
return dataArr;
|
|
315
271
|
}, []);
|
|
316
|
-
|
|
317
|
-
|
|
272
|
+
const sortedData = sortData(data, props.sortKey, props.sortOrder);
|
|
273
|
+
const cleanedData = cleanData(sortedData, props);
|
|
318
274
|
return addEventKeys(props, cleanedData);
|
|
319
275
|
}
|
|
276
|
+
|
|
320
277
|
/**
|
|
321
278
|
* Returns generated x and y data based on domain and sample from props
|
|
322
279
|
* @param {Object} props: the props object
|
|
323
280
|
* @returns {Array} an array of data
|
|
324
281
|
*/
|
|
325
|
-
|
|
326
282
|
export function generateData(props) {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
283
|
+
const xValues = generateDataArray(props, "x");
|
|
284
|
+
const yValues = generateDataArray(props, "y");
|
|
285
|
+
const values = xValues.map((x, i) => {
|
|
330
286
|
return {
|
|
331
|
-
x
|
|
287
|
+
x,
|
|
332
288
|
y: yValues[i]
|
|
333
289
|
};
|
|
334
290
|
});
|
|
335
291
|
return values;
|
|
336
292
|
}
|
|
293
|
+
|
|
337
294
|
/**
|
|
338
295
|
* Returns an array of categories for a given axis
|
|
339
296
|
* @param {Object} props: the props object
|
|
340
297
|
* @param {String} axis: the current axis
|
|
341
298
|
* @returns {Array} an array of categories
|
|
342
299
|
*/
|
|
343
|
-
|
|
344
300
|
export function getCategories(props, axis) {
|
|
345
301
|
return props.categories && !Array.isArray(props.categories) ? props.categories[axis] : props.categories;
|
|
346
302
|
}
|
|
303
|
+
|
|
347
304
|
/**
|
|
348
305
|
* Returns an array of formatted data
|
|
349
306
|
* @param {Object} props: the props object
|
|
350
307
|
* @returns {Array} an array of data
|
|
351
308
|
*/
|
|
352
|
-
|
|
353
309
|
export function getData(props) {
|
|
354
310
|
return props.data ? formatData(props.data, props) : formatData(generateData(props), props);
|
|
355
311
|
}
|
|
312
|
+
|
|
356
313
|
/**
|
|
357
314
|
* Returns an array of strings from axis tickValues for a given axis
|
|
358
315
|
* @param {Object} props: the props object
|
|
359
316
|
* @param {String} axis: the current axis
|
|
360
317
|
* @returns {Array} an array of strings
|
|
361
318
|
*/
|
|
362
|
-
|
|
363
319
|
export function getStringsFromAxes(props, axis) {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
320
|
+
const {
|
|
321
|
+
tickValues,
|
|
322
|
+
tickFormat
|
|
323
|
+
} = props;
|
|
324
|
+
let tickValueArray;
|
|
368
325
|
if (!tickValues || !Array.isArray(tickValues) && !tickValues[axis]) {
|
|
369
326
|
tickValueArray = tickFormat && Array.isArray(tickFormat) ? tickFormat : [];
|
|
370
327
|
} else {
|
|
371
328
|
tickValueArray = tickValues[axis] || tickValues;
|
|
372
329
|
}
|
|
373
|
-
|
|
374
|
-
return tickValueArray.filter(function (val) {
|
|
375
|
-
return typeof val === "string";
|
|
376
|
-
});
|
|
330
|
+
return tickValueArray.filter(val => typeof val === "string");
|
|
377
331
|
}
|
|
332
|
+
|
|
378
333
|
/**
|
|
379
334
|
* Returns an array of strings from categories for a given axis
|
|
380
335
|
* @param {Object} props: the props object
|
|
381
336
|
* @param {String} axis: the current axis
|
|
382
337
|
* @returns {Array} an array of strings
|
|
383
338
|
*/
|
|
384
|
-
|
|
385
339
|
export function getStringsFromCategories(props, axis) {
|
|
386
340
|
if (!props.categories) {
|
|
387
341
|
return [];
|
|
388
342
|
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
var categoryStrings = categories && categories.filter(function (val) {
|
|
392
|
-
return typeof val === "string";
|
|
393
|
-
});
|
|
343
|
+
const categories = getCategories(props, axis);
|
|
344
|
+
const categoryStrings = categories && categories.filter(val => typeof val === "string");
|
|
394
345
|
return categoryStrings ? Collection.removeUndefined(categoryStrings) : [];
|
|
395
346
|
}
|
|
347
|
+
|
|
396
348
|
/**
|
|
397
349
|
* Returns an array of strings from data
|
|
398
350
|
* @param {Object} props: the props object
|
|
399
351
|
* @param {String} axis: the current axis
|
|
400
352
|
* @returns {Array} an array of strings
|
|
401
353
|
*/
|
|
402
|
-
|
|
403
354
|
export function getStringsFromData(props, axis) {
|
|
404
|
-
|
|
405
|
-
|
|
355
|
+
const isArrayOrIterable = Array.isArray(props.data) || Immutable.isIterable(props.data);
|
|
406
356
|
if (!isArrayOrIterable) {
|
|
407
357
|
return [];
|
|
408
358
|
}
|
|
359
|
+
const key = props[axis] === undefined ? axis : props[axis];
|
|
360
|
+
const accessor = Helpers.createAccessor(key);
|
|
409
361
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
var data = props.data.reduce(function (memo, d) {
|
|
362
|
+
// support immutable data
|
|
363
|
+
const data = props.data.reduce((memo, d) => {
|
|
414
364
|
memo.push(parseDatum(d));
|
|
415
365
|
return memo;
|
|
416
366
|
}, []);
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
367
|
+
const sortedData = sortData(data, props.sortKey, props.sortOrder);
|
|
368
|
+
const dataStrings = sortedData.reduce((dataArr, datum) => {
|
|
369
|
+
const parsedDatum = parseDatum(datum);
|
|
420
370
|
dataArr.push(accessor(parsedDatum));
|
|
421
371
|
return dataArr;
|
|
422
|
-
}, []).filter(
|
|
423
|
-
return typeof datum === "string";
|
|
424
|
-
}); // return a unique set of strings
|
|
372
|
+
}, []).filter(datum => typeof datum === "string");
|
|
425
373
|
|
|
426
|
-
return
|
|
374
|
+
// return a unique set of strings
|
|
375
|
+
return dataStrings.reduce((prev, curr) => {
|
|
427
376
|
if (curr !== undefined && curr !== null && prev.indexOf(curr) === -1) {
|
|
428
377
|
prev.push(curr);
|
|
429
378
|
}
|
|
430
|
-
|
|
431
379
|
return prev;
|
|
432
380
|
}, []);
|
|
433
381
|
}
|
|
382
|
+
|
|
434
383
|
/**
|
|
435
384
|
* Checks whether a given component can be used to calculate data
|
|
436
385
|
* @param {Component} component: a React component instance
|
|
437
386
|
* @returns {Boolean} Returns true if the given component has a role included in the whitelist
|
|
438
387
|
*/
|
|
439
|
-
|
|
440
388
|
export function isDataComponent(component) {
|
|
441
|
-
|
|
389
|
+
const getRole = child => {
|
|
442
390
|
return child && child.type ? child.type.role : "";
|
|
443
391
|
};
|
|
444
|
-
|
|
445
|
-
var role = getRole(component);
|
|
446
|
-
|
|
392
|
+
let role = getRole(component);
|
|
447
393
|
if (role === "portal") {
|
|
448
|
-
|
|
394
|
+
const children = React.Children.toArray(component.props.children);
|
|
449
395
|
role = children.length ? getRole(children[0]) : "";
|
|
450
396
|
}
|
|
451
|
-
|
|
452
|
-
var whitelist = ["area", "bar", "boxplot", "candlestick", "errorbar", "group", "histogram", "line", "pie", "scatter", "stack", "voronoi"];
|
|
397
|
+
const whitelist = ["area", "bar", "boxplot", "candlestick", "errorbar", "group", "histogram", "line", "pie", "scatter", "stack", "voronoi"];
|
|
453
398
|
return whitelist.includes(role);
|
|
454
399
|
}
|