|
1 |
| -import {group as grouper, sort, sum, deviation, min, max, mean, median, mode, variance, InternSet, minIndex, maxIndex} from "d3"; |
| 1 | +import {group as grouper, sort, sum, deviation, min, max, mean, median, mode, variance, InternSet, minIndex, maxIndex, rollup} from "d3"; |
2 | 2 | import {ascendingDefined, firstof} from "../defined.js";
|
3 |
| -import {valueof, maybeColorChannel, maybeInput, maybeTuple, maybeLazyChannel, lazyChannel, first, identity, take, labelof, range} from "../options.js"; |
| 3 | +import {valueof, maybeColorChannel, maybeInput, maybeTuple, maybeLazyChannel, lazyChannel, first, identity, take, labelof, range, second} from "../options.js"; |
4 | 4 | import {basic} from "./basic.js";
|
5 | 5 |
|
6 | 6 | // Group on {z, fill, stroke}.
|
@@ -135,7 +135,11 @@ export function hasOutput(outputs, ...names) {
|
135 | 135 | }
|
136 | 136 |
|
137 | 137 | export function maybeOutputs(outputs, inputs) {
|
138 |
| - return Object.entries(outputs).map(([name, reduce]) => { |
| 138 | + const entries = Object.entries(outputs); |
| 139 | + // Propagate standard mark channels by default. |
| 140 | + if (inputs.title != null && outputs.title === undefined) entries.push(["title", reduceTitle]); |
| 141 | + if (inputs.href != null && outputs.href === undefined) entries.push(["href", reduceFirst]); |
| 142 | + return entries.map(([name, reduce]) => { |
139 | 143 | return reduce == null
|
140 | 144 | ? {name, initialize() {}, scope() {}, reduce() {}}
|
141 | 145 | : maybeOutput(name, reduce, inputs);
|
@@ -266,6 +270,19 @@ const reduceFirst = {
|
266 | 270 | }
|
267 | 271 | };
|
268 | 272 |
|
| 273 | +const reduceTitle = { |
| 274 | + reduce(I, X) { |
| 275 | + const n = 5; |
| 276 | + const groups = sort(rollup(I, V => V.length, i => X[i]), second); |
| 277 | + const top = groups.slice(-n).reverse(); |
| 278 | + if (top.length < groups.length) { |
| 279 | + const bottom = groups.slice(0, 1 - n); |
| 280 | + top[n - 1] = [`… ${bottom.length.toLocaleString("en-US")} more`, sum(bottom, second)]; |
| 281 | + } |
| 282 | + return top.map(([key, value]) => `${key} (${value.toLocaleString("en-US")})`).join("\n"); |
| 283 | + } |
| 284 | +}; |
| 285 | + |
269 | 286 | const reduceLast = {
|
270 | 287 | reduce(I, X) {
|
271 | 288 | return X[I[I.length - 1]];
|
|
0 commit comments