-
Notifications
You must be signed in to change notification settings - Fork 186
/
Copy pathbox.js
86 lines (79 loc) · 2.53 KB
/
box.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import {max, min, quantile} from "d3";
import {marks} from "../mark.js";
import {identity} from "../options.js";
import {groupX, groupY, groupZ} from "../transforms/group.js";
import {map} from "../transforms/map.js";
import {barX, barY} from "./bar.js";
import {dot} from "./dot.js";
import {ruleX, ruleY} from "./rule.js";
import {tickX, tickY} from "./tick.js";
// Returns a composite mark for producing a horizontal box plot, applying the
// necessary statistical transforms. The boxes are grouped by y, if present.
export function boxX(
data,
{
x = identity,
y = null,
r,
fill = "#ccc",
fillOpacity,
stroke = "currentColor",
strokeOpacity,
strokeWidth = 2,
sort,
...options
} = {}
) {
const group = y != null ? groupY : groupZ;
return marks(
ruleY(data, group({x1: loqr1, x2: hiqr2}, {x, y, stroke, strokeOpacity, ...options})),
barX(data, group({x1: "p25", x2: "p75"}, {x, y, fill, fillOpacity, ...options})),
tickX(data, group({x: "p50"}, {x, y, stroke, strokeOpacity, strokeWidth, sort, ...options})),
dot(data, map({x: oqr}, {x, y, z: y, r, stroke, strokeOpacity, ...options}))
);
}
// Returns a composite mark for producing a vertical box plot, applying the
// necessary statistical transforms. The boxes are grouped by x, if present.
export function boxY(
data,
{
y = identity,
x = null,
r,
fill = "#ccc",
fillOpacity,
stroke = "currentColor",
strokeOpacity,
strokeWidth = 2,
sort,
...options
} = {}
) {
const group = x != null ? groupX : groupZ;
return marks(
ruleX(data, group({y1: loqr1, y2: hiqr2}, {x, y, stroke, strokeOpacity, ...options})),
barY(data, group({y1: "p25", y2: "p75"}, {x, y, fill, fillOpacity, ...options})),
tickY(data, group({y: "p50"}, {x, y, stroke, strokeOpacity, strokeWidth, sort, ...options})),
dot(data, map({y: oqr}, {x, y, z: x, r, stroke, strokeOpacity, ...options}))
);
}
// A map function that returns only outliers, returning NaN for non-outliers
function oqr(values) {
const r1 = loqr1(values);
const r2 = hiqr2(values);
return values.map((v) => (v < r1 || v > r2 ? v : NaN));
}
function loqr1(values) {
const lo = quartile1(values) * 2.5 - quartile3(values) * 1.5;
return min(values, (d) => (d >= lo ? d : NaN));
}
function hiqr2(values) {
const hi = quartile3(values) * 2.5 - quartile1(values) * 1.5;
return max(values, (d) => (d <= hi ? d : NaN));
}
function quartile1(values) {
return quantile(values, 0.25);
}
function quartile3(values) {
return quantile(values, 0.75);
}