feat: add ChartTooltip component for ThemedChart
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
.tooltip {
|
||||
background: var(--bg-surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
box-shadow: var(--shadow-md);
|
||||
padding: 6px 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.time {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 10px;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 4px;
|
||||
padding-bottom: 3px;
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.row:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.label {
|
||||
color: var(--text-muted);
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-family: var(--font-mono);
|
||||
font-weight: 600;
|
||||
font-size: 11px;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
41
src/design-system/composites/ThemedChart/ChartTooltip.tsx
Normal file
41
src/design-system/composites/ThemedChart/ChartTooltip.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
import type { TooltipProps } from 'recharts'
|
||||
import styles from './ChartTooltip.module.css'
|
||||
|
||||
function formatValue(val: number): string {
|
||||
if (val >= 1_000_000) return `${(val / 1_000_000).toFixed(1)}M`
|
||||
if (val >= 1000) return `${(val / 1000).toFixed(1)}k`
|
||||
if (Number.isInteger(val)) return String(val)
|
||||
return val.toFixed(1)
|
||||
}
|
||||
|
||||
function formatTimestamp(val: unknown): string | null {
|
||||
if (val == null) return null
|
||||
const str = String(val)
|
||||
const ms = typeof val === 'number' && val > 1e12 ? val
|
||||
: typeof val === 'number' && val > 1e9 ? val * 1000
|
||||
: Date.parse(str)
|
||||
if (isNaN(ms)) return str
|
||||
return new Date(ms).toLocaleString([], {
|
||||
month: 'short', day: 'numeric',
|
||||
hour: '2-digit', minute: '2-digit', second: '2-digit',
|
||||
})
|
||||
}
|
||||
|
||||
export function ChartTooltip({ active, payload, label }: TooltipProps<number, string>) {
|
||||
if (!active || !payload?.length) return null
|
||||
|
||||
const timeLabel = formatTimestamp(label)
|
||||
|
||||
return (
|
||||
<div className={styles.tooltip}>
|
||||
{timeLabel && <div className={styles.time}>{timeLabel}</div>}
|
||||
{payload.map((entry) => (
|
||||
<div key={entry.dataKey as string} className={styles.row}>
|
||||
<span className={styles.dot} style={{ background: entry.color }} />
|
||||
<span className={styles.label}>{entry.name}:</span>
|
||||
<span className={styles.value}>{formatValue(entry.value as number)}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user