35 lines
1.5 KiB
TypeScript
35 lines
1.5 KiB
TypeScript
/** Time ranges offered above CloudWatch charts. */
|
|
export const RANGES = [{label: '1 hour', minutes: 60}, {label: '3 hours', minutes: 180}, {label: '24 hours', minutes: 1440}, {label: '7 days', minutes: 10080}]
|
|
|
|
/** About five round ticks covering [min, max], always including zero when the range does. */
|
|
export function niceTicks(min: number, max: number, count = 5): number[] {
|
|
const span = max - min
|
|
const raw = span / (count - 1)
|
|
const magnitude = 10 ** Math.floor(Math.log10(raw))
|
|
const step = [1, 2, 2.5, 5, 10].map((factor) => factor * magnitude).find((candidate) => candidate >= raw) ?? 10 * magnitude
|
|
const start = Math.floor(min / step) * step
|
|
const end = Math.ceil(max / step) * step
|
|
const ticks: number[] = []
|
|
for (let value = start; value <= end + step / 2; value += step) ticks.push(Number(value.toPrecision(12)))
|
|
return ticks
|
|
}
|
|
|
|
export function timeTicks(start: number, end: number, count: number): number[] {
|
|
if (end <= start) return [start]
|
|
const step = (end - start) / count
|
|
return Array.from({length: count + 1}, (_, index) => start + index * step)
|
|
}
|
|
|
|
export function formatValue(value: number): string {
|
|
const abs = Math.abs(value)
|
|
if (abs >= 1e9) return `${trim(value / 1e9)}B`
|
|
if (abs >= 1e6) return `${trim(value / 1e6)}M`
|
|
if (abs >= 1e3) return `${trim(value / 1e3)}K`
|
|
return trim(value)
|
|
}
|
|
|
|
function trim(value: number): string {
|
|
return Number.isInteger(value) ? String(value) : value.toFixed(Math.abs(value) < 10 ? 2 : 1).replace(/\.?0+$/, '')
|
|
}
|
|
|