Spaces:
Sleeping
Sleeping
File size: 2,139 Bytes
6242ddb | 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 65 66 67 68 69 70 71 72 73 74 75 76 | import {
BarChart,
Bar,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
ResponsiveContainer,
Cell,
} from 'recharts';
import type { TopicCluster } from '../../types';
interface TopicBarChartProps {
topics: TopicCluster[];
height?: number;
}
const COLORS = [
'#6366f1', '#8b5cf6', '#a855f7', '#d946ef', '#ec4899',
'#f43f5e', '#f97316', '#eab308', '#22c55e', '#14b8a6',
'#06b6d4', '#3b82f6',
];
export function TopicBarChart({ topics, height = 300 }: TopicBarChartProps) {
const data = topics
.filter((t) => t.topic_id !== -1)
.sort((a, b) => b.size - a.size)
.slice(0, 15)
.map((t) => ({
name: t.label.length > 25 ? t.label.slice(0, 25) + '…' : t.label,
size: t.size,
sentiment: t.avg_sentiment,
topic_id: t.topic_id,
}));
if (!data.length) {
return (
<div style={{ height, display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--text-muted)' }}>
No topics found
</div>
);
}
return (
<ResponsiveContainer width="100%" height={height}>
<BarChart data={data} layout="vertical" margin={{ top: 5, right: 20, bottom: 5, left: 120 }}>
<CartesianGrid strokeDasharray="3 3" stroke="var(--border-light)" />
<XAxis type="number" tick={{ fontSize: 11, fill: 'var(--text-muted)' }} />
<YAxis
type="category"
dataKey="name"
tick={{ fontSize: 11, fill: 'var(--text-secondary)' }}
width={110}
/>
<Tooltip
contentStyle={{
background: 'var(--bg-card)',
border: '1px solid var(--border)',
borderRadius: 8,
fontSize: 12,
}}
formatter={(value: number, name: string) => {
if (name === 'size') return [value, 'Entries'];
return [value.toFixed(3), 'Avg Sentiment'];
}}
/>
<Bar dataKey="size" radius={[0, 4, 4, 0]} maxBarSize={24}>
{data.map((_, index) => (
<Cell key={index} fill={COLORS[index % COLORS.length]!} />
))}
</Bar>
</BarChart>
</ResponsiveContainer>
);
}
|