perfect-postcode/frontend/src/lib/format.ts
2026-02-04 22:27:56 +00:00

48 lines
1.7 KiB
TypeScript

export function formatValue(value: number): string {
if (Math.abs(value) >= 1_000_000) return `${(value / 1_000_000).toFixed(1)}M`;
if (Math.abs(value) >= 1_000) return `${(value / 1_000).toFixed(1)}k`;
if (Number.isInteger(value)) return value.toLocaleString();
return value.toFixed(1);
}
export function formatFilterValue(value: number): string {
if (Math.abs(value) >= 1_000_000) return `${(value / 1_000_000).toFixed(1)}M`;
if (Math.abs(value) >= 1_000) return `${(value / 1_000).toFixed(1)}k`;
if (Number.isInteger(value)) return value.toString();
return value.toFixed(2);
}
export function formatDuration(d: string): string {
if (d === 'F') return 'Freehold';
if (d === 'L') return 'Leasehold';
return d;
}
export function formatAge(value: number, approximate = true): string {
if (value >= 1000) return approximate ? `~${Math.round(value)}` : `${Math.round(value)}`;
return Math.round(value).toString();
}
// Format number with optional decimals, used in PropertyCard
export function formatNumber(value: number | undefined, decimals = 0): string {
if (value === undefined) return '';
return decimals > 0 ? value.toFixed(decimals) : Math.round(value).toLocaleString();
}
// Calculate weighted mean from histogram
export function calculateHistogramMean(histogram: {
min: number;
bin_width: number;
counts: number[];
}): number | undefined {
if (!histogram.counts.length) return undefined;
const totalCount = histogram.counts.reduce((a, b) => a + b, 0);
if (totalCount === 0) return undefined;
let weightedSum = 0;
for (let i = 0; i < histogram.counts.length; i++) {
const binCenter = histogram.min + (i + 0.5) * histogram.bin_width;
weightedSum += binCenter * histogram.counts[i];
}
return weightedSum / totalCount;
}