feat(stats): improve cache ratio chart

This commit is contained in:
Adam 2026-06-02 13:31:40 -05:00
parent e54f974840
commit 69345a29b0
No known key found for this signature in database
GPG Key ID: 9CB48779AF150E75
2 changed files with 164 additions and 18 deletions

View File

@ -2264,6 +2264,116 @@
color: var(--stats-muted);
}
[data-page="stats"] [data-slot="cache-ratio-heading"] {
display: grid;
grid-template-columns: 56px minmax(96px, 180px) minmax(160px, 1fr);
align-items: center;
gap: 12px;
height: 18px;
padding: 0 12px;
color: var(--stats-faint);
font-size: 9px;
font-weight: 600;
line-height: 1;
text-transform: uppercase;
}
[data-page="stats"] [data-slot="cache-ratio-heading"] b {
justify-self: end;
font-weight: 600;
}
[data-page="stats"] [data-slot="cache-ratio-rows"] {
display: grid;
gap: 8px;
}
[data-page="stats"] button[data-component="cache-ratio-row"] {
display: grid;
grid-template-columns: 56px minmax(96px, 180px) minmax(160px, 1fr);
align-items: center;
gap: 12px;
width: 100%;
height: 28px;
padding: 0 12px;
border: 0;
border-radius: 0;
background: transparent;
color: var(--stats-text);
font-size: 10px;
line-height: 14px;
text-align: left;
}
[data-page="stats"] button[data-component="cache-ratio-row"][data-active="true"] {
background: #0000000a;
}
[data-page="stats"] [data-component="cache-ratio-row"] strong {
color: var(--stats-text);
font-weight: 500;
white-space: nowrap;
}
[data-page="stats"] [data-component="cache-ratio-row"][data-active="true"] strong {
color: var(--stats-accent-text);
}
[data-page="stats"] [data-component="cache-ratio-row"] > span {
overflow: hidden;
color: var(--stats-muted);
font-weight: 400;
text-overflow: ellipsis;
white-space: nowrap;
}
[data-page="stats"] [data-component="cache-ratio-marker"] {
position: relative;
display: block;
min-width: 0;
height: 7px;
overflow: visible;
background:
linear-gradient(
90deg,
transparent calc(20% - 0.5px),
var(--stats-line) calc(20% - 0.5px) calc(20% + 0.5px),
transparent calc(20% + 0.5px) calc(40% - 0.5px),
var(--stats-line) calc(40% - 0.5px) calc(40% + 0.5px),
transparent calc(40% + 0.5px) calc(60% - 0.5px),
var(--stats-line) calc(60% - 0.5px) calc(60% + 0.5px),
transparent calc(60% + 0.5px) calc(80% - 0.5px),
var(--stats-line) calc(80% - 0.5px) calc(80% + 0.5px),
transparent calc(80% + 0.5px)
),
linear-gradient(90deg, var(--stats-line) 0 1px, transparent 1px calc(100% - 1px), var(--stats-line) calc(100% - 1px)),
var(--stats-layer-2);
font-style: normal;
}
[data-page="stats"] [data-component="cache-ratio-marker"] em {
position: absolute;
top: 50%;
left: var(--cache-ratio-fill);
display: block;
width: 7px;
height: 13px;
transform: translate(-50%, -50%);
background: var(--stats-text);
}
[data-page="stats"] [data-component="cache-ratio-row"][data-active="true"] [data-component="cache-ratio-marker"] {
background: var(--stats-line-strong);
}
[data-page="stats"] [data-component="cache-ratio-row"][data-active="true"] [data-component="cache-ratio-marker"] em {
background: var(--stats-accent);
}
[data-page="stats"] [data-component="token-tooltip"][data-variant="cache-ratio"] {
left: 30%;
}
[data-page="stats"] [data-slot="token-footer"] {
display: flex;
align-items: center;
@ -2407,6 +2517,13 @@
opacity: 0.78;
}
[data-page="stats"][data-theme="dark"] button[data-component="cache-ratio-row"][data-active="true"],
:root[data-stats-theme="dark"]
[data-page="stats"]:not([data-theme="light"])
button[data-component="cache-ratio-row"][data-active="true"] {
background: #ffffff0d;
}
[data-page="stats"][data-theme="dark"] [data-slot="header-button"][data-variant="neutral"],
[data-page="stats"][data-theme="dark"] [data-slot="menu-button"],
:root[data-stats-theme="dark"]
@ -2756,6 +2873,12 @@
font-size: 16px;
}
[data-page="stats"] [data-slot="cache-ratio-heading"],
[data-page="stats"] button[data-component="cache-ratio-row"] {
grid-template-columns: 44px minmax(72px, 1fr) minmax(86px, 1.2fr);
gap: 8px;
}
[data-page="stats"] [data-slot="top-models-mobile-controls"] {
display: flex;
gap: 8px;

View File

@ -1391,29 +1391,39 @@ function CacheRatioChart(props: {
activeIndex: number
onActiveIndexChange: (index: number) => void
}) {
const max = createMemo(() => Math.max(0, ...props.data.map((item) => item.ratio)) || 100)
const active = createMemo(() => props.data[props.activeIndex] ?? props.data[0])
return (
<div data-component="cache-ratio">
<For each={props.data}>
{(item, index) => (
<button
type="button"
data-component="token-row"
data-active={props.activeIndex === index() ? "true" : undefined}
onClick={() => props.onActiveIndexChange(index())}
onPointerEnter={() => props.onActiveIndexChange(index())}
>
<strong>{formatRatio(item.ratio)}</strong>
<span>{item.model}</span>
<MetricBar value={item.ratio} max={max()} active={props.activeIndex === index()} />
</button>
)}
</For>
<div data-component="cache-ratio" data-variant="marker">
<div data-slot="cache-ratio-heading" aria-hidden="true">
<strong>Ratio</strong>
<span>Model</span>
<b>0-100%</b>
</div>
<div data-slot="cache-ratio-rows">
<For each={props.data}>
{(item, index) => (
<button
type="button"
data-component="cache-ratio-row"
data-active={props.activeIndex === index() ? "true" : undefined}
onClick={() => props.onActiveIndexChange(index())}
onPointerEnter={() => props.onActiveIndexChange(index())}
>
<strong>{formatRatio(item.ratio)}</strong>
<span>{item.model}</span>
<CacheRatioMarker ratio={item.ratio} active={props.activeIndex === index()} />
</button>
)}
</For>
</div>
<Show when={active()}>
{(item) => (
<div data-component="token-tooltip" style={{ top: `${props.activeIndex * 36 + 2}px` }}>
<div
data-component="token-tooltip"
data-variant="cache-ratio"
style={{ top: `${props.activeIndex * 36 + 28}px` }}
>
<p>
<span>Cache Ratio</span>
<strong>{formatRatio(item().ratio)}</strong>
@ -1433,6 +1443,19 @@ function CacheRatioChart(props: {
)
}
function CacheRatioMarker(props: { ratio: number; active: boolean }) {
const fill = createMemo(() => Math.min(100, Math.max(0, props.ratio)))
return (
<i
data-component="cache-ratio-marker"
data-active={props.active ? "true" : undefined}
style={{ "--cache-ratio-fill": `${fill()}%` } as JSX.CSSProperties}
>
<em />
</i>
)
}
function formatRatio(value: number) {
return `${value.toFixed(value > 0 && value < 10 ? 1 : 0)}%`
}