victory-box-plot 36.9.1 → 36.9.2-next.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 +13 -0
- package/dist/victory-box-plot.js +3955 -5337
- package/dist/victory-box-plot.min.js +1 -1
- package/es/helper-methods.d.ts +3 -3
- package/es/helper-methods.js +268 -322
- package/es/index.d.ts +1 -1
- package/es/victory-box-plot.d.ts +139 -139
- package/es/victory-box-plot.js +87 -156
- package/lib/helper-methods.d.ts +3 -3
- package/lib/helper-methods.js +268 -339
- package/lib/index.d.ts +1 -1
- package/lib/index.js +0 -2
- package/lib/victory-box-plot.d.ts +139 -139
- package/lib/victory-box-plot.js +87 -161
- package/package.json +9 -13
- package/src/helper-methods.tsx +3 -3
- package/src/victory-box-plot.tsx +8 -8
package/es/helper-methods.js
CHANGED
|
@@ -1,51 +1,34 @@
|
|
|
1
|
-
import _isNil from "lodash/isNil";
|
|
2
|
-
import _isNaN from "lodash/isNaN";
|
|
3
1
|
import _keys from "lodash/keys";
|
|
4
2
|
import _groupBy from "lodash/groupBy";
|
|
5
3
|
import _uniq from "lodash/uniq";
|
|
6
4
|
import _defaults from "lodash/defaults";
|
|
7
5
|
import _orderBy from "lodash/orderBy";
|
|
8
|
-
|
|
9
|
-
function _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; }
|
|
10
|
-
|
|
11
6
|
import { Helpers, Scale, Domain, Data, Collection } from "victory-core";
|
|
12
7
|
import { min as d3Min, max as d3Max, quantile as d3Quantile } from "victory-vendor/d3-array";
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
var checkProcessedData = function (data) {
|
|
8
|
+
const TYPES = ["max", "min", "median", "q1", "q3"];
|
|
9
|
+
const checkProcessedData = data => {
|
|
16
10
|
/* check if the data is pre-processed. start by checking that it has
|
|
17
11
|
all required quartile attributes. */
|
|
18
|
-
|
|
19
|
-
return TYPES.every(
|
|
20
|
-
return typeof datum["_".concat(val)] !== "undefined";
|
|
21
|
-
});
|
|
12
|
+
const hasQuartileAttributes = data.every(datum => {
|
|
13
|
+
return TYPES.every(val => typeof datum[`_${val}`] !== "undefined");
|
|
22
14
|
});
|
|
23
|
-
|
|
24
15
|
if (hasQuartileAttributes) {
|
|
25
16
|
// check that the independent variable is distinct
|
|
26
|
-
|
|
27
|
-
return d._x;
|
|
28
|
-
});
|
|
29
|
-
|
|
17
|
+
const values = data.map(d => d._x);
|
|
30
18
|
if (!_uniq(values).length === values.length) {
|
|
31
|
-
throw new Error(
|
|
19
|
+
throw new Error(`
|
|
20
|
+
data prop may only take an array of objects with a unique
|
|
21
|
+
independent variable. Make sure your x values are distinct.
|
|
22
|
+
`);
|
|
32
23
|
}
|
|
33
|
-
|
|
34
24
|
return true;
|
|
35
25
|
}
|
|
36
|
-
|
|
37
26
|
return false;
|
|
38
27
|
};
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
var getSummaryStatistics = function (data) {
|
|
45
|
-
var dependentVars = data.map(function (datum) {
|
|
46
|
-
return datum._y;
|
|
47
|
-
});
|
|
48
|
-
var quartiles = {
|
|
28
|
+
const nanToNull = val => Number.isNaN(val) ? null : val;
|
|
29
|
+
const getSummaryStatistics = data => {
|
|
30
|
+
const dependentVars = data.map(datum => datum._y);
|
|
31
|
+
const quartiles = {
|
|
49
32
|
_q1: nanToNull(d3Quantile(dependentVars, 0.25)),
|
|
50
33
|
// eslint-disable-line no-magic-numbers
|
|
51
34
|
_q3: nanToNull(d3Quantile(dependentVars, 0.75)),
|
|
@@ -58,46 +41,36 @@ var getSummaryStatistics = function (data) {
|
|
|
58
41
|
_y: data[0]._y
|
|
59
42
|
});
|
|
60
43
|
};
|
|
61
|
-
|
|
62
|
-
var processData = function (data) {
|
|
44
|
+
const processData = data => {
|
|
63
45
|
/* check if the data is coming in a pre-processed form,
|
|
64
46
|
i.e. { x || y, min, max, q1, q3, median }. if not, process it. */
|
|
65
|
-
|
|
66
|
-
|
|
47
|
+
const isProcessed = checkProcessedData(data);
|
|
67
48
|
if (!isProcessed) {
|
|
68
49
|
// check if the data is coming with x or y values as an array
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
return Array.isArray(datum._y);
|
|
74
|
-
});
|
|
75
|
-
var sortKey = "_y";
|
|
76
|
-
var groupKey = "_x";
|
|
77
|
-
|
|
50
|
+
const arrayX = data.every(datum => Array.isArray(datum._x));
|
|
51
|
+
const arrayY = data.every(datum => Array.isArray(datum._y));
|
|
52
|
+
const sortKey = "_y";
|
|
53
|
+
const groupKey = "_x";
|
|
78
54
|
if (arrayX) {
|
|
79
|
-
throw new Error(
|
|
55
|
+
throw new Error(`
|
|
56
|
+
data should not be given as in array for x
|
|
57
|
+
`);
|
|
80
58
|
} else if (arrayY) {
|
|
81
59
|
/* generate summary statistics for each datum. to do this, flatten
|
|
82
60
|
the depedentVarArray and process each datum separately */
|
|
83
|
-
return data.map(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
var sortedData = _orderBy(dataArray, sortKey);
|
|
89
|
-
|
|
61
|
+
return data.map(datum => {
|
|
62
|
+
const dataArray = datum[sortKey].map(d => Object.assign({}, datum, {
|
|
63
|
+
[sortKey]: d
|
|
64
|
+
}));
|
|
65
|
+
const sortedData = _orderBy(dataArray, sortKey);
|
|
90
66
|
return getSummaryStatistics(sortedData);
|
|
91
67
|
});
|
|
92
68
|
} else {
|
|
93
69
|
/* Group data by independent variable and generate summary statistics for each group */
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
var sortedData = _orderBy(datum, sortKey);
|
|
100
|
-
|
|
70
|
+
const groupedData = _groupBy(data, groupKey);
|
|
71
|
+
return _keys(groupedData).map(key => {
|
|
72
|
+
const datum = groupedData[key];
|
|
73
|
+
const sortedData = _orderBy(datum, sortKey);
|
|
101
74
|
return getSummaryStatistics(sortedData);
|
|
102
75
|
});
|
|
103
76
|
}
|
|
@@ -105,84 +78,69 @@ var processData = function (data) {
|
|
|
105
78
|
return data;
|
|
106
79
|
}
|
|
107
80
|
};
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
var formattedData = Data.formatData(props.data, props, accessorTypes);
|
|
81
|
+
export const getData = props => {
|
|
82
|
+
const accessorTypes = TYPES.concat("x", "y");
|
|
83
|
+
const formattedData = Data.formatData(props.data, props, accessorTypes);
|
|
112
84
|
return formattedData.length ? processData(formattedData) : [];
|
|
113
85
|
};
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
return memo < datum["_".concat(axis)] ? memo : datum["_".concat(axis)];
|
|
86
|
+
const reduceDataset = (dataset, props, axis) => {
|
|
87
|
+
const minDomain = Domain.getMinFromProps(props, axis);
|
|
88
|
+
const maxDomain = Domain.getMaxFromProps(props, axis);
|
|
89
|
+
const minData = minDomain !== undefined ? minDomain : dataset.reduce((memo, datum) => {
|
|
90
|
+
return memo < datum[`_${axis}`] ? memo : datum[`_${axis}`];
|
|
120
91
|
}, Infinity);
|
|
121
|
-
|
|
122
|
-
return memo > datum[
|
|
92
|
+
const maxData = maxDomain !== undefined ? maxDomain : dataset.reduce((memo, datum) => {
|
|
93
|
+
return memo > datum[`_${axis}`] ? memo : datum[`_${axis}`];
|
|
123
94
|
}, -Infinity);
|
|
124
95
|
return Domain.getDomainFromMinMax(minData, maxData);
|
|
125
96
|
};
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
var minData = minDomain !== undefined ? minDomain : dataset.reduce(function (memo, datum) {
|
|
97
|
+
const getDomainFromMinMaxValues = (dataset, props, axis) => {
|
|
98
|
+
const minDomain = Domain.getMinFromProps(props, axis);
|
|
99
|
+
const maxDomain = Domain.getMaxFromProps(props, axis);
|
|
100
|
+
const minData = minDomain !== undefined ? minDomain : dataset.reduce((memo, datum) => {
|
|
131
101
|
return memo < datum._min ? memo : datum._min;
|
|
132
102
|
}, Infinity);
|
|
133
|
-
|
|
103
|
+
const maxData = maxDomain !== undefined ? maxDomain : dataset.reduce((memo, datum) => {
|
|
134
104
|
return memo > datum._max ? memo : datum._max;
|
|
135
105
|
}, -Infinity);
|
|
136
106
|
return Domain.getDomainFromMinMax(minData, maxData);
|
|
137
107
|
};
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
var dataset = getData(props);
|
|
143
|
-
|
|
108
|
+
const getDomainFromData = (props, axis) => {
|
|
109
|
+
const minDomain = Domain.getMinFromProps(props, axis);
|
|
110
|
+
const maxDomain = Domain.getMaxFromProps(props, axis);
|
|
111
|
+
const dataset = getData(props);
|
|
144
112
|
if (dataset.length < 1) {
|
|
145
113
|
return minDomain !== undefined && maxDomain !== undefined ? Domain.getDomainFromMinMax(minDomain, maxDomain) : undefined;
|
|
146
114
|
}
|
|
147
|
-
|
|
148
115
|
return axis === "y" ? getDomainFromMinMaxValues(dataset, props, axis) : reduceDataset(dataset, props, axis);
|
|
149
116
|
};
|
|
150
|
-
|
|
151
|
-
export var getDomain = function (props, axis) {
|
|
117
|
+
export const getDomain = (props, axis) => {
|
|
152
118
|
return Domain.createDomainFunction(getDomainFromData)(props, axis);
|
|
153
119
|
};
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
var baseStyle = styleObject["".concat(namespace, "Labels")] || styleObject.labels;
|
|
158
|
-
|
|
120
|
+
const getLabelStyle = (props, styleObject, namespace) => {
|
|
121
|
+
const component = props[`${namespace}LabelComponent`] || props.labelComponent;
|
|
122
|
+
const baseStyle = styleObject[`${namespace}Labels`] || styleObject.labels;
|
|
159
123
|
if (!Helpers.isTooltip(component)) {
|
|
160
124
|
return baseStyle;
|
|
161
125
|
}
|
|
162
|
-
|
|
163
|
-
var tooltipTheme = props.theme && props.theme.tooltip || {};
|
|
126
|
+
const tooltipTheme = props.theme && props.theme.tooltip || {};
|
|
164
127
|
return _defaults({}, tooltipTheme.style, baseStyle);
|
|
165
128
|
};
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
129
|
+
const getStyles = function (props, styleObject) {
|
|
130
|
+
if (styleObject === void 0) {
|
|
131
|
+
styleObject = {};
|
|
132
|
+
}
|
|
170
133
|
if (props.disableInlineStyles) {
|
|
171
134
|
return {};
|
|
172
135
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
var parentStyles = {
|
|
136
|
+
const style = props.style || {};
|
|
137
|
+
const parentStyles = {
|
|
176
138
|
height: "100%",
|
|
177
139
|
width: "100%"
|
|
178
140
|
};
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
var boxStyles = _defaults({}, style.boxes, styleObject.boxes);
|
|
183
|
-
|
|
184
|
-
var whiskerStyles = _defaults({}, style.whiskers, styleObject.whiskers);
|
|
185
|
-
|
|
141
|
+
const labelStyles = _defaults({}, style.labels, getLabelStyle(props, styleObject));
|
|
142
|
+
const boxStyles = _defaults({}, style.boxes, styleObject.boxes);
|
|
143
|
+
const whiskerStyles = _defaults({}, style.whiskers, styleObject.whiskers);
|
|
186
144
|
return {
|
|
187
145
|
boxes: boxStyles,
|
|
188
146
|
labels: labelStyles,
|
|
@@ -200,63 +158,67 @@ var getStyles = function (props) {
|
|
|
200
158
|
whiskers: whiskerStyles
|
|
201
159
|
};
|
|
202
160
|
};
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
161
|
+
const getCalculatedValues = props => {
|
|
162
|
+
const {
|
|
163
|
+
theme,
|
|
164
|
+
horizontal
|
|
165
|
+
} = props;
|
|
166
|
+
const data = getData(props);
|
|
167
|
+
const range = {
|
|
209
168
|
x: Helpers.getRange(props, "x"),
|
|
210
169
|
y: Helpers.getRange(props, "y")
|
|
211
170
|
};
|
|
212
|
-
|
|
171
|
+
const domain = {
|
|
213
172
|
x: getDomain(props, "x"),
|
|
214
173
|
y: getDomain(props, "y")
|
|
215
174
|
};
|
|
216
|
-
|
|
175
|
+
const scale = {
|
|
217
176
|
x: Scale.getBaseScale(props, "x").domain(domain.x).range(props.horizontal ? range.y : range.x),
|
|
218
177
|
y: Scale.getBaseScale(props, "y").domain(domain.y).range(props.horizontal ? range.x : range.y)
|
|
219
178
|
};
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
179
|
+
const defaultStyles = theme && theme.boxplot && theme.boxplot.style ? theme.boxplot.style : {};
|
|
180
|
+
const style = getStyles(props, defaultStyles);
|
|
181
|
+
const defaultOrientation = props.horizontal ? "top" : "right";
|
|
182
|
+
const labelOrientation = props.labelOrientation || defaultOrientation;
|
|
183
|
+
const boxWidth = props.boxWidth || 1;
|
|
225
184
|
return {
|
|
226
|
-
data
|
|
227
|
-
horizontal
|
|
228
|
-
domain
|
|
229
|
-
scale
|
|
230
|
-
style
|
|
231
|
-
labelOrientation
|
|
232
|
-
boxWidth
|
|
185
|
+
data,
|
|
186
|
+
horizontal,
|
|
187
|
+
domain,
|
|
188
|
+
scale,
|
|
189
|
+
style,
|
|
190
|
+
labelOrientation,
|
|
191
|
+
boxWidth
|
|
233
192
|
};
|
|
234
|
-
};
|
|
235
|
-
|
|
193
|
+
};
|
|
236
194
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
195
|
+
// eslint-disable-next-line complexity
|
|
196
|
+
const getWhiskerProps = (props, type) => {
|
|
197
|
+
const {
|
|
198
|
+
horizontal,
|
|
199
|
+
style,
|
|
200
|
+
boxWidth,
|
|
201
|
+
whiskerWidth,
|
|
202
|
+
datum,
|
|
203
|
+
scale,
|
|
204
|
+
index,
|
|
205
|
+
disableInlineStyles
|
|
206
|
+
} = props;
|
|
207
|
+
const {
|
|
208
|
+
min,
|
|
209
|
+
max,
|
|
210
|
+
q1,
|
|
211
|
+
q3,
|
|
212
|
+
x,
|
|
213
|
+
y
|
|
214
|
+
} = props.positions;
|
|
215
|
+
const boxValue = type === "min" ? q1 : q3;
|
|
216
|
+
const whiskerValue = type === "min" ? min : max;
|
|
217
|
+
const width = typeof whiskerWidth === "number" ? whiskerWidth : boxWidth;
|
|
256
218
|
return {
|
|
257
|
-
datum
|
|
258
|
-
index
|
|
259
|
-
scale
|
|
219
|
+
datum,
|
|
220
|
+
index,
|
|
221
|
+
scale,
|
|
260
222
|
majorWhisker: {
|
|
261
223
|
x1: horizontal ? boxValue : x,
|
|
262
224
|
y1: horizontal ? y : boxValue,
|
|
@@ -270,128 +232,127 @@ var getWhiskerProps = function (props, type) {
|
|
|
270
232
|
y2: horizontal ? y + width / 2 : whiskerValue
|
|
271
233
|
},
|
|
272
234
|
style: disableInlineStyles ? {} : style[type] || style.whisker,
|
|
273
|
-
disableInlineStyles
|
|
235
|
+
disableInlineStyles
|
|
274
236
|
};
|
|
275
237
|
};
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
238
|
+
const getBoxProps = (props, type) => {
|
|
239
|
+
const {
|
|
240
|
+
horizontal,
|
|
241
|
+
boxWidth,
|
|
242
|
+
style,
|
|
243
|
+
scale,
|
|
244
|
+
datum,
|
|
245
|
+
index,
|
|
246
|
+
disableInlineStyles
|
|
247
|
+
} = props;
|
|
248
|
+
const {
|
|
249
|
+
median,
|
|
250
|
+
q1,
|
|
251
|
+
q3,
|
|
252
|
+
x,
|
|
253
|
+
y
|
|
254
|
+
} = props.positions;
|
|
255
|
+
const defaultX = type === "q1" ? q1 : median;
|
|
256
|
+
const defaultY = type === "q1" ? median : q3;
|
|
257
|
+
const defaultWidth = type === "q1" ? median - q1 : q3 - median;
|
|
258
|
+
const defaultHeight = type === "q1" ? q1 - median : median - q3;
|
|
295
259
|
return {
|
|
296
|
-
datum
|
|
297
|
-
scale
|
|
298
|
-
index
|
|
260
|
+
datum,
|
|
261
|
+
scale,
|
|
262
|
+
index,
|
|
299
263
|
x: horizontal ? defaultX : x - boxWidth / 2,
|
|
300
264
|
y: horizontal ? y - boxWidth / 2 : defaultY,
|
|
301
265
|
width: horizontal ? defaultWidth : boxWidth,
|
|
302
266
|
height: horizontal ? boxWidth : defaultHeight,
|
|
303
267
|
style: disableInlineStyles ? {} : style[type] || style.boxes,
|
|
304
|
-
disableInlineStyles
|
|
268
|
+
disableInlineStyles
|
|
305
269
|
};
|
|
306
270
|
};
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
271
|
+
const getMedianProps = props => {
|
|
272
|
+
const {
|
|
273
|
+
boxWidth,
|
|
274
|
+
horizontal,
|
|
275
|
+
style,
|
|
276
|
+
datum,
|
|
277
|
+
scale,
|
|
278
|
+
index,
|
|
279
|
+
disableInlineStyles
|
|
280
|
+
} = props;
|
|
281
|
+
const {
|
|
282
|
+
median,
|
|
283
|
+
x,
|
|
284
|
+
y
|
|
285
|
+
} = props.positions;
|
|
320
286
|
return {
|
|
321
|
-
datum
|
|
322
|
-
scale
|
|
323
|
-
index
|
|
287
|
+
datum,
|
|
288
|
+
scale,
|
|
289
|
+
index,
|
|
324
290
|
x1: horizontal ? median : x - boxWidth / 2,
|
|
325
291
|
y1: horizontal ? y - boxWidth / 2 : median,
|
|
326
292
|
x2: horizontal ? median : x + boxWidth / 2,
|
|
327
293
|
y2: horizontal ? y + boxWidth / 2 : median,
|
|
328
294
|
style: disableInlineStyles ? {} : style.median,
|
|
329
|
-
disableInlineStyles
|
|
295
|
+
disableInlineStyles
|
|
330
296
|
};
|
|
331
297
|
};
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
298
|
+
const getText = (props, type) => {
|
|
299
|
+
const {
|
|
300
|
+
datum,
|
|
301
|
+
index,
|
|
302
|
+
labels
|
|
303
|
+
} = props;
|
|
304
|
+
const propName = `${type}Labels`;
|
|
305
|
+
const labelProp = props[propName];
|
|
340
306
|
if (!labelProp && !labels) {
|
|
341
307
|
return null;
|
|
342
308
|
} else if (labelProp === true || labels === true) {
|
|
343
|
-
|
|
344
|
-
return
|
|
309
|
+
const dataName = `_${type}`;
|
|
310
|
+
return `${datum[dataName]}`;
|
|
345
311
|
}
|
|
346
|
-
|
|
347
312
|
return Array.isArray(labelProp) ? labelProp[index] : labelProp;
|
|
348
313
|
};
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
var labelStyle = style[namespace] || style.labels;
|
|
367
|
-
var defaultVerticalAnchors = {
|
|
314
|
+
const getOrientation = (labelOrientation, type) => typeof labelOrientation === "object" && labelOrientation[type] || labelOrientation;
|
|
315
|
+
const getLabelProps = (props, text, type) => {
|
|
316
|
+
const {
|
|
317
|
+
datum,
|
|
318
|
+
positions,
|
|
319
|
+
index,
|
|
320
|
+
boxWidth,
|
|
321
|
+
horizontal,
|
|
322
|
+
labelOrientation,
|
|
323
|
+
style,
|
|
324
|
+
theme,
|
|
325
|
+
disableInlineStyles
|
|
326
|
+
} = props;
|
|
327
|
+
const orientation = getOrientation(labelOrientation, type);
|
|
328
|
+
const namespace = `${type}Labels`;
|
|
329
|
+
const labelStyle = style[namespace] || style.labels;
|
|
330
|
+
const defaultVerticalAnchors = {
|
|
368
331
|
top: "end",
|
|
369
332
|
bottom: "start",
|
|
370
333
|
left: "middle",
|
|
371
334
|
right: "middle"
|
|
372
335
|
};
|
|
373
|
-
|
|
336
|
+
const defaultTextAnchors = {
|
|
374
337
|
left: "end",
|
|
375
338
|
right: "start",
|
|
376
339
|
top: "middle",
|
|
377
340
|
bottom: "middle"
|
|
378
341
|
};
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
var sign = {
|
|
342
|
+
const whiskerWidth = typeof props.whiskerWidth === "number" ? props.whiskerWidth : boxWidth;
|
|
343
|
+
const width = type === "min" || type === "max" ? whiskerWidth : boxWidth;
|
|
344
|
+
const getOffset = coord => {
|
|
345
|
+
const sign = {
|
|
384
346
|
x: orientation === "left" ? -1 : 1,
|
|
385
347
|
y: orientation === "top" ? -1 : 1
|
|
386
348
|
};
|
|
387
349
|
return sign[coord] * width / 2 + sign[coord] * (labelStyle.padding || 0);
|
|
388
350
|
};
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
orientation: orientation,
|
|
351
|
+
const labelProps = {
|
|
352
|
+
text,
|
|
353
|
+
datum,
|
|
354
|
+
index,
|
|
355
|
+
orientation,
|
|
395
356
|
style: disableInlineStyles ? {} : labelStyle,
|
|
396
357
|
y: horizontal ? positions.y : positions[type],
|
|
397
358
|
x: horizontal ? positions[type] : positions.x,
|
|
@@ -400,106 +361,92 @@ var getLabelProps = function (props, text, type) {
|
|
|
400
361
|
textAnchor: labelStyle.textAnchor || defaultTextAnchors[orientation],
|
|
401
362
|
verticalAnchor: labelStyle.verticalAnchor || defaultVerticalAnchors[orientation],
|
|
402
363
|
angle: labelStyle.angle,
|
|
403
|
-
horizontal
|
|
404
|
-
disableInlineStyles
|
|
364
|
+
horizontal,
|
|
365
|
+
disableInlineStyles
|
|
405
366
|
};
|
|
406
|
-
|
|
407
|
-
|
|
367
|
+
const component = props[`${type}LabelComponent`];
|
|
408
368
|
if (!Helpers.isTooltip(component)) {
|
|
409
369
|
return labelProps;
|
|
410
370
|
}
|
|
411
|
-
|
|
412
|
-
var tooltipTheme = theme && theme.tooltip || {};
|
|
371
|
+
const tooltipTheme = theme && theme.tooltip || {};
|
|
413
372
|
return _defaults({}, labelProps, Helpers.omit(tooltipTheme, ["style"]));
|
|
414
373
|
};
|
|
415
|
-
|
|
416
|
-
var getDataProps = function (props, type) {
|
|
374
|
+
const getDataProps = (props, type) => {
|
|
417
375
|
if (type === "median") {
|
|
418
376
|
return getMedianProps(props);
|
|
419
377
|
} else if (type === "min" || type === "max") {
|
|
420
378
|
return getWhiskerProps(props, type);
|
|
421
379
|
}
|
|
422
|
-
|
|
423
380
|
return getBoxProps(props, type);
|
|
424
|
-
};
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
var isDatumOutOfBounds = function (datum, domain) {
|
|
428
|
-
var exists = function (val) {
|
|
429
|
-
return val !== undefined;
|
|
430
|
-
};
|
|
431
|
-
|
|
432
|
-
var _x = datum._x,
|
|
433
|
-
_min = datum._min,
|
|
434
|
-
_max = datum._max;
|
|
435
|
-
var minDomainX = Collection.getMinValue(domain.x);
|
|
436
|
-
var maxDomainX = Collection.getMaxValue(domain.x);
|
|
437
|
-
var minDomainY = Collection.getMinValue(domain.y);
|
|
438
|
-
var maxDomainY = Collection.getMaxValue(domain.y);
|
|
439
|
-
|
|
440
|
-
var underMin = function (min) {
|
|
441
|
-
return function (val) {
|
|
442
|
-
return exists(val) && val < min;
|
|
443
|
-
};
|
|
444
|
-
};
|
|
445
|
-
|
|
446
|
-
var overMax = function (max) {
|
|
447
|
-
return function (val) {
|
|
448
|
-
return exists(val) && val > max;
|
|
449
|
-
};
|
|
450
|
-
};
|
|
451
|
-
|
|
452
|
-
var isUnderMinX = underMin(minDomainX);
|
|
453
|
-
var isUnderMinY = underMin(minDomainY);
|
|
454
|
-
var isOverMaxX = overMax(maxDomainX);
|
|
455
|
-
var isOverMaxY = overMax(maxDomainY);
|
|
456
|
-
var yOutOfBounds;
|
|
457
|
-
var xOutOfBounds; // if x is out of the bounds of the domain
|
|
458
|
-
|
|
459
|
-
if (isUnderMinX(_x) || isOverMaxX(_x)) xOutOfBounds = true; // if min/max are out of the bounds of the domain
|
|
381
|
+
};
|
|
460
382
|
|
|
383
|
+
// if all data points on an axis are out of bound of the domain, filter out this datum
|
|
384
|
+
const isDatumOutOfBounds = (datum, domain) => {
|
|
385
|
+
const exists = val => val !== undefined;
|
|
386
|
+
const {
|
|
387
|
+
_x,
|
|
388
|
+
_min,
|
|
389
|
+
_max
|
|
390
|
+
} = datum;
|
|
391
|
+
const minDomainX = Collection.getMinValue(domain.x);
|
|
392
|
+
const maxDomainX = Collection.getMaxValue(domain.x);
|
|
393
|
+
const minDomainY = Collection.getMinValue(domain.y);
|
|
394
|
+
const maxDomainY = Collection.getMaxValue(domain.y);
|
|
395
|
+
const underMin = min => val => exists(val) && val < min;
|
|
396
|
+
const overMax = max => val => exists(val) && val > max;
|
|
397
|
+
const isUnderMinX = underMin(minDomainX);
|
|
398
|
+
const isUnderMinY = underMin(minDomainY);
|
|
399
|
+
const isOverMaxX = overMax(maxDomainX);
|
|
400
|
+
const isOverMaxY = overMax(maxDomainY);
|
|
401
|
+
let yOutOfBounds;
|
|
402
|
+
let xOutOfBounds;
|
|
403
|
+
|
|
404
|
+
// if x is out of the bounds of the domain
|
|
405
|
+
if (isUnderMinX(_x) || isOverMaxX(_x)) xOutOfBounds = true;
|
|
406
|
+
// if min/max are out of the bounds of the domain
|
|
461
407
|
if (isUnderMinY(_min) && isUnderMinY(_max) || isOverMaxY(_min) && isOverMaxY(_max)) yOutOfBounds = true;
|
|
462
408
|
return yOutOfBounds || xOutOfBounds;
|
|
463
409
|
};
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
410
|
+
export const getBaseProps = (initialProps, fallbackProps) => {
|
|
411
|
+
const modifiedProps = Helpers.modifyProps(initialProps, fallbackProps, "boxplot");
|
|
412
|
+
const props = Object.assign({}, modifiedProps, getCalculatedValues(modifiedProps));
|
|
413
|
+
const {
|
|
414
|
+
groupComponent,
|
|
415
|
+
width,
|
|
416
|
+
height,
|
|
417
|
+
padding,
|
|
418
|
+
standalone,
|
|
419
|
+
theme,
|
|
420
|
+
events,
|
|
421
|
+
sharedEvents,
|
|
422
|
+
scale,
|
|
423
|
+
horizontal,
|
|
424
|
+
data,
|
|
425
|
+
style,
|
|
426
|
+
domain,
|
|
427
|
+
name
|
|
428
|
+
} = props;
|
|
429
|
+
const initialChildProps = {
|
|
483
430
|
parent: {
|
|
484
|
-
domain
|
|
485
|
-
scale
|
|
486
|
-
width
|
|
487
|
-
height
|
|
488
|
-
data
|
|
489
|
-
standalone
|
|
490
|
-
name
|
|
491
|
-
theme
|
|
431
|
+
domain,
|
|
432
|
+
scale,
|
|
433
|
+
width,
|
|
434
|
+
height,
|
|
435
|
+
data,
|
|
436
|
+
standalone,
|
|
437
|
+
name,
|
|
438
|
+
theme,
|
|
492
439
|
style: style.parent || {},
|
|
493
|
-
padding
|
|
494
|
-
groupComponent
|
|
495
|
-
horizontal
|
|
440
|
+
padding,
|
|
441
|
+
groupComponent,
|
|
442
|
+
horizontal
|
|
496
443
|
}
|
|
497
444
|
};
|
|
498
|
-
|
|
499
|
-
return data.reduce(
|
|
500
|
-
|
|
445
|
+
const boxScale = scale.y;
|
|
446
|
+
return data.reduce((acc, datum, index) => {
|
|
447
|
+
const eventKey = !Helpers.isNil(datum.eventKey) ? datum.eventKey : index;
|
|
501
448
|
if (isDatumOutOfBounds(datum, domain)) return acc;
|
|
502
|
-
|
|
449
|
+
const positions = {
|
|
503
450
|
x: horizontal ? scale.y(datum._y) : scale.x(datum._x),
|
|
504
451
|
y: horizontal ? scale.x(datum._x) : scale.y(datum._y),
|
|
505
452
|
min: boxScale(datum._min),
|
|
@@ -508,22 +455,21 @@ export var getBaseProps = function (initialProps, fallbackProps) {
|
|
|
508
455
|
q1: boxScale(datum._q1),
|
|
509
456
|
q3: boxScale(datum._q3)
|
|
510
457
|
};
|
|
511
|
-
|
|
512
|
-
index
|
|
513
|
-
datum
|
|
514
|
-
positions
|
|
458
|
+
const dataProps = Object.assign({
|
|
459
|
+
index,
|
|
460
|
+
datum,
|
|
461
|
+
positions
|
|
515
462
|
}, props);
|
|
516
|
-
|
|
463
|
+
const dataObj = TYPES.reduce((memo, type) => {
|
|
517
464
|
memo[type] = getDataProps(dataProps, type);
|
|
518
465
|
return memo;
|
|
519
466
|
}, {});
|
|
520
467
|
acc[eventKey] = dataObj;
|
|
521
|
-
TYPES.forEach(
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
468
|
+
TYPES.forEach(type => {
|
|
469
|
+
const labelText = getText(dataProps, type);
|
|
470
|
+
const labelProp = props.labels || props[`${type}Labels`];
|
|
525
471
|
if (labelText !== null && labelText !== undefined || labelProp && (events || sharedEvents)) {
|
|
526
|
-
|
|
472
|
+
const target = `${type}Labels`;
|
|
527
473
|
acc[eventKey][target] = getLabelProps(Object.assign({}, props, dataProps), labelText, type);
|
|
528
474
|
}
|
|
529
475
|
});
|