fix(stats): stack largest segments at bottom

This commit is contained in:
Adam
2026-05-29 09:30:32 -05:00
parent 0a60dbdcee
commit 16cae9a323
+25 -12
View File
@@ -648,7 +648,7 @@ function TopModelsChart(props: { data: UsagePoint[]; range: UsageRange }) {
}} }}
> >
<div data-slot="top-models-stack" style={{ "grid-template-rows": getTopModelsSegmentRows(day) }}> <div data-slot="top-models-stack" style={{ "grid-template-rows": getTopModelsSegmentRows(day) }}>
<For each={visibleTopModelsSegments(day)}> <For each={stackedTopModelsSegments(day)}>
{(item) => ( {(item) => (
<i <i
data-series={item.index} data-series={item.index}
@@ -729,7 +729,7 @@ function getTopModelsMaxTotal(data: UsagePoint[]) {
function getTopModelsSegmentRows(point: UsagePoint) { function getTopModelsSegmentRows(point: UsagePoint) {
const total = usageTotal(point) const total = usageTotal(point)
if (total <= 0) return "" if (total <= 0) return ""
return visibleTopModelsSegments(point) return stackedTopModelsSegments(point)
.map((item) => `${(item.segment.value / total) * 100}%`) .map((item) => `${(item.segment.value / total) * 100}%`)
.join(" ") .join(" ")
} }
@@ -738,6 +738,12 @@ function visibleTopModelsSegments(point: UsagePoint) {
return point.segments.map((segment, index) => ({ segment, index })).filter((item) => item.segment.value > 0) return point.segments.map((segment, index) => ({ segment, index })).filter((item) => item.segment.value > 0)
} }
function stackedTopModelsSegments(point: UsagePoint) {
return visibleTopModelsSegments(point)
.slice()
.sort((a, b) => a.segment.value - b.segment.value || a.index - b.index)
}
function getTopModelsSegmentColor(index: number, muted: boolean, activeSegment: number | undefined) { function getTopModelsSegmentColor(index: number, muted: boolean, activeSegment: number | undefined) {
if (activeSegment !== undefined) if (activeSegment !== undefined)
return activeSegment === index ? (usageColors[index] ?? "var(--stats-text)") : "var(--stats-layer-2)" return activeSegment === index ? (usageColors[index] ?? "var(--stats-text)") : "var(--stats-layer-2)"
@@ -982,35 +988,35 @@ function MarketShare(props: {
onClick={() => props.onActiveIndexChange(index())} onClick={() => props.onActiveIndexChange(index())}
onPointerEnter={() => props.onActiveIndexChange(index())} onPointerEnter={() => props.onActiveIndexChange(index())}
> >
<For each={day.authors}> <For each={stackedMarketAuthors(day)}>
{(author, authorIndex) => ( {(item) => (
<span <span
data-active={props.activeAuthor === author.author ? "true" : undefined} data-active={props.activeAuthor === item.author.author ? "true" : undefined}
data-muted={ data-muted={
props.activeAuthor !== undefined && props.activeAuthor !== author.author ? "true" : undefined props.activeAuthor !== undefined && props.activeAuthor !== item.author.author ? "true" : undefined
} }
style={{ style={{
"background-color": getMarketSegmentColor( "background-color": getMarketSegmentColor(
author.author, item.author.author,
marketColors[authorIndex()] ?? "var(--stats-text)", marketColors[item.index] ?? "var(--stats-text)",
props.activeAuthor, props.activeAuthor,
), ),
"flex-grow": author.share, "flex-grow": item.author.share,
}} }}
onPointerEnter={(event) => { onPointerEnter={(event) => {
event.stopPropagation() event.stopPropagation()
props.onActiveIndexChange(index()) props.onActiveIndexChange(index())
props.onActiveAuthorChange(author.author) props.onActiveAuthorChange(item.author.author)
}} }}
onPointerDown={(event) => { onPointerDown={(event) => {
event.stopPropagation() event.stopPropagation()
props.onActiveIndexChange(index()) props.onActiveIndexChange(index())
props.onActiveAuthorChange(author.author) props.onActiveAuthorChange(item.author.author)
}} }}
onClick={(event) => { onClick={(event) => {
event.stopPropagation() event.stopPropagation()
props.onActiveIndexChange(index()) props.onActiveIndexChange(index())
props.onActiveAuthorChange(author.author) props.onActiveAuthorChange(item.author.author)
}} }}
/> />
)} )}
@@ -1063,6 +1069,13 @@ function getMarketSegmentColor(author: string, color: string, activeAuthor: stri
return "var(--stats-bar-idle)" return "var(--stats-bar-idle)"
} }
function stackedMarketAuthors(day: MarketDay) {
return day.authors
.map((author, index) => ({ author, index }))
.slice()
.sort((a, b) => a.author.share - b.author.share || a.index - b.index)
}
function isMarketMobileLabelHidden(index: number, count: number) { function isMarketMobileLabelHidden(index: number, count: number) {
return count > 7 && index % 2 === 1 return count > 7 && index % 2 === 1
} }