Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 3x 3x 3x 3x 3x 3x 3x 3x 3x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 3x 3x 3x 3x 3x 3x 3x 1x | import { ckmeans } from "simple-statistics"
import { range, quantile } from "d3-array"
import {
excludeUndefined,
uniq,
last,
roundSigFig,
first,
} from "../../clientUtils/Util"
import { BinningStrategy } from "./BinningStrategy"
/** Human-readable labels for the binning strategies */
export const binningStrategyLabels: Record<BinningStrategy, string> = {
equalInterval: "Equal-interval",
quantiles: "Quantiles",
ckmeans: "Ckmeans",
manual: "Manual",
}
function calcEqualIntervalStepSize(
sortedValues: number[],
binCount: number,
minBinValue: number
): number {
if (!sortedValues.length) return 10
const stepSizeInitial = (last(sortedValues)! - minBinValue) / binCount
return roundSigFig(stepSizeInitial, 1)
}
interface GetBinMaximumsWithStrategyArgs {
binningStrategy: BinningStrategy
sortedValues: number[]
binCount: number
/** `minBinValue` is only used in the `equalInterval` binning strategy. */
minBinValue?: number
}
// Some algorithms can create bins that start & end at the same value.
// This also means the first bin can both start and end at the same value – the minimum
// value. This is why we uniq() and why we remove any values <= minimum value.
function normalizeBinValues(
binValues: (number | undefined)[],
minBinValue?: number
): any {
const values = uniq(excludeUndefined(binValues))
return minBinValue !== undefined
? values.filter((v) => v > minBinValue)
: values
}
export function getBinMaximums(args: GetBinMaximumsWithStrategyArgs): number[] {
const { binningStrategy, sortedValues, binCount, minBinValue } = args
const valueCount = sortedValues.length
if (valueCount < 1 || binCount < 1) return []
if (binningStrategy === BinningStrategy.ckmeans) {
const clusters = ckmeans(
sortedValues,
binCount > valueCount ? valueCount : binCount
)
return normalizeBinValues(clusters.map(last), minBinValue)
} else if (binningStrategy === BinningStrategy.quantiles) {
return normalizeBinValues(
range(1, binCount + 1).map((v) =>
quantile(sortedValues, v / binCount)
),
minBinValue
)
} else {
// Equal-interval strategy by default
const minValue = minBinValue ?? first(sortedValues) ?? 0
const binStepSize = calcEqualIntervalStepSize(
sortedValues,
binCount,
minValue
)
return normalizeBinValues(
range(1, binCount + 1).map((n) => minValue + n * binStepSize),
minBinValue
)
}
}
|