feat(stats): improve cache ratio chart
This commit is contained in:
parent
e54f974840
commit
69345a29b0
@ -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;
|
||||
|
||||
@ -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)}%`
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user