(g)
| 63 | |
| 64 | // For each small multiple… |
| 65 | function box (g) { |
| 66 | g.each(function (data, index) { |
| 67 | data = data.map(value).sort(ascending); |
| 68 | const _g = select(this); |
| 69 | const n = data.length; |
| 70 | let min; |
| 71 | let max; |
| 72 | |
| 73 | // Leave if there are no items. |
| 74 | if (n === 0) {return;} |
| 75 | |
| 76 | // Compute quartiles. Must return exactly 3 elements. |
| 77 | const quartileData = data.quartiles = quartiles(data); |
| 78 | |
| 79 | // Compute whiskers. Must return exactly 2 elements, or null. |
| 80 | const whiskerIndices = whiskers && whiskers.call(this, data, index), |
| 81 | whiskerData = whiskerIndices && whiskerIndices.map(_i => data[_i]); |
| 82 | |
| 83 | // Compute outliers. If no whiskers are specified, all data are 'outliers'. |
| 84 | // We compute the outliers as indices, so that we can join across transitions! |
| 85 | const outlierIndices = whiskerIndices ? |
| 86 | range(0, whiskerIndices[0]).concat(range(whiskerIndices[1] + 1, n)) : range(n); |
| 87 | |
| 88 | // Determine the maximum value based on if outliers are shown |
| 89 | if (showOutliers) { |
| 90 | min = data[0]; |
| 91 | max = data[n - 1]; |
| 92 | } else { |
| 93 | min = data[whiskerIndices[0]]; |
| 94 | max = data[whiskerIndices[1]]; |
| 95 | } |
| 96 | const pointIndices = range(whiskerIndices[0], whiskerIndices[1] + 1); |
| 97 | |
| 98 | // Compute the new x-scale. |
| 99 | const x1 = scaleLinear() |
| 100 | .domain(domain && domain.call(this, data, index) || [min, max]) |
| 101 | .range([height, 0]); |
| 102 | |
| 103 | // Retrieve the old x-scale, if this is an update. |
| 104 | const x0 = this.__chart__ || scaleLinear() |
| 105 | .domain([0, Infinity]) |
| 106 | .range(x1.range()); |
| 107 | |
| 108 | // Stash the new scale. |
| 109 | this.__chart__ = x1; |
| 110 | |
| 111 | // Note: the box, median, and box tick elements are fixed in number, |
| 112 | // so we only have to handle enter and update. In contrast, the outliers |
| 113 | // and other elements are variable, so we need to exit them! Variable |
| 114 | // elements also fade in and out. |
| 115 | |
| 116 | // Update center line: the vertical line spanning the whiskers. |
| 117 | const center = _g.selectAll('line.center') |
| 118 | .data(whiskerData ? [whiskerData] : []); |
| 119 | |
| 120 | center.enter().insert('line', 'rect') |
| 121 | .attr('class', 'center') |
| 122 | .attr('x1', width / 2) |
nothing calls this directly
no test coverage detected