84 lines
2.7 KiB
TypeScript
84 lines
2.7 KiB
TypeScript
import type { ColumnFormatType } from "@internal/clickhouse";
|
|
import { formatDurationMilliseconds } from "@trigger.dev/core/v3";
|
|
import { formatCurrencyAccurate } from "~/utils/numberFormatter";
|
|
|
|
/**
|
|
* Format a number as binary bytes (KiB, MiB, GiB, TiB)
|
|
*/
|
|
export function formatBytes(bytes: number): string {
|
|
if (bytes === 0) return "0 B";
|
|
const units = ["B", "KiB", "MiB", "GiB", "TiB"];
|
|
const i = Math.min(
|
|
Math.max(0, Math.floor(Math.log(Math.abs(bytes)) / Math.log(1024))),
|
|
units.length - 1
|
|
);
|
|
return `${(bytes / Math.pow(1024, i)).toFixed(i === 0 ? 0 : 2)} ${units[i]}`;
|
|
}
|
|
|
|
/**
|
|
* Format a number as decimal bytes (KB, MB, GB, TB)
|
|
*/
|
|
export function formatDecimalBytes(bytes: number): string {
|
|
if (bytes === 0) return "0 B";
|
|
const units = ["B", "KB", "MB", "GB", "TB"];
|
|
const i = Math.min(
|
|
Math.max(0, Math.floor(Math.log(Math.abs(bytes)) / Math.log(1000))),
|
|
units.length - 1
|
|
);
|
|
return `${(bytes / Math.pow(1000, i)).toFixed(i === 0 ? 0 : 2)} ${units[i]}`;
|
|
}
|
|
|
|
/**
|
|
* Format a large number with human-readable suffix (K, M, B)
|
|
*/
|
|
export function formatQuantity(value: number): string {
|
|
const abs = Math.abs(value);
|
|
if (abs >= 1_000_000_000) return `${(value / 1_000_000_000).toFixed(2)}B`;
|
|
if (abs >= 1_000_000) return `${(value / 1_000_000).toFixed(2)}M`;
|
|
if (abs >= 1_000) return `${(value / 1_000).toFixed(2)}K`;
|
|
return value.toLocaleString();
|
|
}
|
|
|
|
/**
|
|
* Format a dollar amount with adaptive precision — avoids trailing zeros.
|
|
*/
|
|
function formatCostAdaptive(dollars: number): string {
|
|
if (dollars === 0) return "$0";
|
|
const abs = Math.abs(dollars);
|
|
if (abs >= 1000) return `$${dollars.toFixed(2)}`;
|
|
if (abs >= 1) return `$${dollars.toFixed(2)}`;
|
|
if (abs >= 0.01) return `$${dollars.toFixed(4)}`;
|
|
if (abs >= 0.0001) return `$${dollars.toFixed(6)}`;
|
|
return formatCurrencyAccurate(dollars);
|
|
}
|
|
|
|
/**
|
|
* Creates a value formatter function for a given column format type.
|
|
* Used by chart tooltips, legend values, and big number cards.
|
|
*/
|
|
export function createValueFormatter(
|
|
format?: ColumnFormatType
|
|
): ((value: number) => string) | undefined {
|
|
if (!format) return undefined;
|
|
switch (format) {
|
|
case "bytes":
|
|
return (v) => formatBytes(v);
|
|
case "decimalBytes":
|
|
return (v) => formatDecimalBytes(v);
|
|
case "percent":
|
|
return (v) => `${v.toFixed(2)}%`;
|
|
case "quantity":
|
|
return (v) => formatQuantity(v);
|
|
case "duration":
|
|
return (v) => formatDurationMilliseconds(v, { style: "short" });
|
|
case "durationSeconds":
|
|
return (v) => formatDurationMilliseconds(v * 1000, { style: "short" });
|
|
case "costInDollars":
|
|
return (v) => formatCostAdaptive(v);
|
|
case "cost":
|
|
return (v) => formatCostAdaptive(v / 100);
|
|
default:
|
|
return undefined;
|
|
}
|
|
}
|