sync: update from private repo (6d37c2d)
Some checks failed
CI / build-and-test (push) Has been cancelled
Some checks failed
CI / build-and-test (push) Has been cancelled
This commit is contained in:
parent
641fe0177d
commit
7d5d2d44b1
@ -91,6 +91,7 @@ function rangeFor(preset: Preset, customFrom: string, customTo: string): { from:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CHART_H = 176; // px — stacked-bar plot height (was the h-44 / 11rem class)
|
||||||
const GW = '#6366f1'; // indigo-500 — gateway (source axis)
|
const GW = '#6366f1'; // indigo-500 — gateway (source axis)
|
||||||
const DR = '#22c55e'; // green-500 — direct (source axis)
|
const DR = '#22c55e'; // green-500 — direct (source axis)
|
||||||
const OTHER_COLOR = '#94a3b8'; // slate-400 — folded 'other' bucket
|
const OTHER_COLOR = '#94a3b8'; // slate-400 — folded 'other' bucket
|
||||||
@ -357,21 +358,22 @@ function StackedBars({
|
|||||||
<div className="flex items-center justify-between mb-3">
|
<div className="flex items-center justify-between mb-3">
|
||||||
<span className="text-xs font-medium text-slate-500 uppercase tracking-wide">{t('chart.tokensTitle')}</span>
|
<span className="text-xs font-medium text-slate-500 uppercase tracking-wide">{t('chart.tokensTitle')}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-end gap-1 h-44" role="img" aria-label={ariaLabel}>
|
{/* Bar heights are computed in pixels off CHART_H, not percentages: a
|
||||||
|
percentage-height chain inside this flex column collapses to zero
|
||||||
|
because the column items aren't given a definite height. */}
|
||||||
|
<div className="flex items-end gap-1" style={{ height: CHART_H }} role="img" aria-label={ariaLabel}>
|
||||||
{series.map((b) => {
|
{series.map((b) => {
|
||||||
const sum = bucketTotal(b);
|
const sum = bucketTotal(b);
|
||||||
const hPct = maxBucket > 0 ? (sum / maxBucket) * 100 : 0;
|
const barPx = maxBucket > 0 ? Math.max((sum / maxBucket) * CHART_H, sum > 0 ? 2 : 0) : 0;
|
||||||
return (
|
return (
|
||||||
<div key={b.bucket} className="flex-1 min-w-0 flex flex-col items-center group relative">
|
<div key={b.bucket} className="flex-1 min-w-0 flex flex-col items-center group relative">
|
||||||
<div className="w-full flex flex-col justify-end" style={{ height: '100%' }}>
|
<div className="w-full rounded-t-sm overflow-hidden flex flex-col" style={{ height: barPx }}>
|
||||||
<div className="w-full rounded-t-sm overflow-hidden flex flex-col" style={{ height: `${Math.max(hPct, sum > 0 ? 2 : 0)}%` }}>
|
|
||||||
{keys.map((k, i) => {
|
{keys.map((k, i) => {
|
||||||
const v = total(b.segments[k] ?? zeroCounters());
|
const v = total(b.segments[k] ?? zeroCounters());
|
||||||
const segPct = sum > 0 ? (v / sum) * 100 : 0;
|
const segPx = sum > 0 ? (v / sum) * barPx : 0;
|
||||||
return segPct > 0 ? <div key={k} style={{ height: `${segPct}%`, background: colorFor(k, i, groupBy) }} /> : null;
|
return segPx > 0 ? <div key={k} style={{ height: segPx, background: colorFor(k, i, groupBy) }} /> : null;
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{/* Tooltip (decorative — chart summary is exposed via aria-label) */}
|
{/* Tooltip (decorative — chart summary is exposed via aria-label) */}
|
||||||
<div aria-hidden="true" className="pointer-events-none absolute bottom-full mb-1 hidden group-hover:block z-10 whitespace-nowrap bg-slate-800 text-white text-[10px] rounded px-1.5 py-1 shadow">
|
<div aria-hidden="true" className="pointer-events-none absolute bottom-full mb-1 hidden group-hover:block z-10 whitespace-nowrap bg-slate-800 text-white text-[10px] rounded px-1.5 py-1 shadow">
|
||||||
<div className="font-mono mb-0.5">{b.bucket}</div>
|
<div className="font-mono mb-0.5">{b.bucket}</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user