Fun changes
This commit is contained in:
parent
cd778dd088
commit
349a6c1d53
60 changed files with 1260 additions and 2600 deletions
|
|
@ -1,23 +1,77 @@
|
|||
export default function EnumBarChart({ counts }: { counts: Record<string, number> }) {
|
||||
import { getEnumValueColor } from '../../lib/consts';
|
||||
|
||||
export default function EnumBarChart({
|
||||
counts,
|
||||
globalCounts,
|
||||
featureName,
|
||||
}: {
|
||||
counts: Record<string, number>;
|
||||
globalCounts?: Record<string, number>;
|
||||
featureName?: string;
|
||||
}) {
|
||||
const entries = Object.entries(counts).sort(([, countA], [, countB]) => countB - countA);
|
||||
const localTotal = entries.reduce((sum, [, c]) => sum + c, 0);
|
||||
|
||||
// When global counts are available, normalize both to percentages for comparison
|
||||
const globalTotal = globalCounts
|
||||
? Object.values(globalCounts).reduce((sum, c) => sum + c, 0)
|
||||
: 0;
|
||||
|
||||
const hasGlobal = globalCounts && globalTotal > 0;
|
||||
|
||||
// Compute max percentage across both datasets for consistent bar scaling
|
||||
const maxPct = entries.reduce((max, [label, count]) => {
|
||||
const localPct = localTotal > 0 ? count / localTotal : 0;
|
||||
const globalPct = hasGlobal ? (globalCounts[label] ?? 0) / globalTotal : 0;
|
||||
return Math.max(max, localPct, globalPct);
|
||||
}, 0);
|
||||
|
||||
// Fallback to raw count scaling when no global data
|
||||
const maxCount = Math.max(...entries.map(([, count]) => count), 1);
|
||||
|
||||
return (
|
||||
<div className="space-y-1 mt-1">
|
||||
{entries.map(([label, count]) => (
|
||||
<div key={label} className="flex items-center gap-2 text-xs">
|
||||
<span className="w-16 truncate text-warm-500 dark:text-warm-400 text-right shrink-0">
|
||||
{label}
|
||||
</span>
|
||||
<div className="flex-1 h-3 bg-warm-100 dark:bg-navy-700 rounded overflow-hidden">
|
||||
<div
|
||||
className="h-full bg-teal-500 dark:bg-teal-400 rounded"
|
||||
style={{ width: `${(count / maxCount) * 100}%` }}
|
||||
/>
|
||||
{entries.map(([label, count]) => {
|
||||
const localPct = localTotal > 0 ? count / localTotal : 0;
|
||||
const globalPct = hasGlobal ? (globalCounts[label] ?? 0) / globalTotal : 0;
|
||||
|
||||
const localWidth = hasGlobal
|
||||
? maxPct > 0
|
||||
? (localPct / maxPct) * 100
|
||||
: 0
|
||||
: (count / maxCount) * 100;
|
||||
const globalWidth = hasGlobal && maxPct > 0 ? (globalPct / maxPct) * 100 : 0;
|
||||
|
||||
const overrideColor = featureName ? getEnumValueColor(featureName, label) : null;
|
||||
const barStyle = overrideColor
|
||||
? `rgb(${overrideColor[0]},${overrideColor[1]},${overrideColor[2]})`
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<div key={label} className="flex items-center gap-2 text-xs">
|
||||
<span className="w-16 truncate text-warm-500 dark:text-warm-400 text-right shrink-0">
|
||||
{label}
|
||||
</span>
|
||||
<div className="flex-1 h-3 bg-warm-100 dark:bg-navy-700 rounded overflow-hidden relative">
|
||||
{hasGlobal && (
|
||||
<div
|
||||
className="absolute inset-y-0 left-0 bg-warm-300/60 dark:bg-warm-600/60 rounded"
|
||||
style={{ width: `${globalWidth}%` }}
|
||||
/>
|
||||
)}
|
||||
<div
|
||||
className={
|
||||
barStyle ? 'h-full rounded relative' : 'h-full bg-teal-500 dark:bg-teal-400 rounded relative'
|
||||
}
|
||||
style={{ width: `${localWidth}%`, ...(barStyle ? { backgroundColor: barStyle } : {}) }}
|
||||
/>
|
||||
</div>
|
||||
<span className="w-8 text-warm-500 dark:text-warm-400 text-right shrink-0">
|
||||
{count}
|
||||
</span>
|
||||
</div>
|
||||
<span className="w-8 text-warm-500 dark:text-warm-400 text-right shrink-0">{count}</span>
|
||||
</div>
|
||||
))}
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue