48 lines
1.7 KiB
TypeScript
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;
|
|
}
|