Spaces:
Sleeping
Sleeping
File size: 2,229 Bytes
3786a3f f14eb69 3786a3f f14eb69 3786a3f f14eb69 3786a3f f14eb69 3786a3f f14eb69 3786a3f f14eb69 3786a3f f14eb69 3786a3f f14eb69 3786a3f f14eb69 3786a3f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | 'use client';
import { useMemo, useState } from 'react';
import { useGraphStore } from '@/store/graph';
import { entityColor } from '@/lib/constants';
import { cn } from '@/lib/utils';
export function GraphLegend() {
const data = useGraphStore((s) => s.data);
const visibleTypes = useGraphStore((s) => s.visibleTypes);
const toggleType = useGraphStore((s) => s.toggleType);
const [open, setOpen] = useState(true);
const typeCounts = useMemo(() => {
const counts: Record<string, number> = {};
data.nodes.forEach((n) => (counts[n.type] = (counts[n.type] || 0) + 1));
return counts;
}, [data.nodes]);
const sortedTypes = useMemo(
() => Object.entries(typeCounts).sort((a, b) => b[1] - a[1]),
[typeCounts]
);
return (
<div className="absolute bottom-3 left-3 z-20 max-w-[220px] rounded-md border border-border bg-bg-elevated/95 p-3 shadow-lg backdrop-blur">
<button
onClick={() => setOpen((o) => !o)}
className="mb-2 text-xs font-semibold uppercase tracking-wide text-text-muted"
>
Entity Types {open ? '▾' : '▸'}
</button>
{open && (
<ul className="max-h-[320px] space-y-1 overflow-y-auto scrollbar-thin">
{sortedTypes.map(([type, count]) => {
const hidden = visibleTypes[type] === false;
return (
<li key={type}>
<button
onClick={() => toggleType(type)}
className={cn(
'flex w-full items-center gap-2 text-xs transition-opacity',
hidden && 'opacity-40'
)}
>
<span
className="h-3 w-3 shrink-0 rounded-full"
style={{ backgroundColor: entityColor(type) }}
/>
<span className="flex-1 text-left text-text-secondary truncate">{type}</span>
<span className="shrink-0 text-text-muted">{count}</span>
</button>
</li>
);
})}
{sortedTypes.length === 0 && (
<li className="text-xs text-text-muted">No entities loaded</li>
)}
</ul>
)}
</div>
);
}
|