위젯 기능 추가

This commit is contained in:
Macbook
2026-06-14 01:03:51 +09:00
parent 95595f7e9e
commit 6936792ad4
57 changed files with 6728 additions and 540 deletions
+55
View File
@@ -0,0 +1,55 @@
import type { TickerData } from '../hooks/useMarketTicker';
import { getKoreanName } from '../utils/marketNameCache';
import { safePercentFromRate } from '../utils/safeFormat';
export type MoverSortKey = 'gainers' | 'losers' | 'volume';
export function tickerListFromMap(tickers: Map<string, TickerData>): TickerData[] {
return [...tickers.values()].filter(t => t.market.startsWith('KRW-') && t.tradePrice != null);
}
export function sortTickers(items: TickerData[], key: MoverSortKey, limit = 15): TickerData[] {
const copy = [...items];
if (key === 'gainers') {
return copy
.filter(t => (t.changeRate ?? 0) > 0)
.sort((a, b) => (b.changeRate ?? 0) - (a.changeRate ?? 0))
.slice(0, limit);
}
if (key === 'losers') {
return copy
.filter(t => (t.changeRate ?? 0) < 0)
.sort((a, b) => (a.changeRate ?? 0) - (b.changeRate ?? 0))
.slice(0, limit);
}
return copy
.sort((a, b) => (b.accTradePrice24 ?? 0) - (a.accTradePrice24 ?? 0))
.slice(0, limit);
}
export function changeColorClass(rate: number | null | undefined): string {
if (rate == null || rate === 0) return 'wd-muted';
return rate > 0 ? 'wd-up' : 'wd-down';
}
export function fmtPct(rate: number | null | undefined): string {
return safePercentFromRate(rate, 2).replace('—', '-');
}
export function fmtKrwShort(n: number | null | undefined): string {
if (n == null || !Number.isFinite(n)) return '-';
if (n >= 1_0000_0000) return `${(n / 1_0000_0000).toFixed(1)}`;
if (n >= 1_0000) return `${Math.round(n / 1_0000).toLocaleString('ko-KR')}`;
return n.toLocaleString('ko-KR', { maximumFractionDigits: 0 });
}
export function resolveName(market: string, ticker?: TickerData): string {
return ticker?.koreanName || getKoreanName(market) || market.replace('KRW-', '');
}
export function heatmapColor(rate: number | null | undefined): string {
if (rate == null || rate === 0) return 'rgba(120, 130, 150, 0.35)';
const intensity = Math.min(1, Math.abs(rate) * 8);
if (rate > 0) return `rgba(231, 76, 60, ${0.25 + intensity * 0.55})`;
return `rgba(52, 152, 219, ${0.25 + intensity * 0.55})`;
}