import { memo, useMemo } from "react"; import { LineChart, Line, XAxis, YAxis, Tooltip, CartesianGrid, ResponsiveContainer, } from "recharts"; import ActivityHeatmap from "../stats/ActivityHeatmap"; import { ReactWordcloud } from "@cp949/react-wordcloud"; import StatsStyling from "../styles/stats_styling"; import Card from "../components/Card"; import { type SummaryResponse, type FrequencyWord, type UserEndpointResponse, type TimeAnalysisResponse, type LinguisticAnalysisResponse, } from "../types/ApiTypes"; import { buildAllRecordsSpec, buildDateBucketSpec, buildOneTimeUsersSpec, buildUserSpec, type CorpusExplorerSpec, } from "../utils/corpusExplorer"; const styles = StatsStyling; const MAX_WORDCLOUD_WORDS = 250; const exploreButtonStyle = { padding: "4px 8px", fontSize: 12 }; const WORDCLOUD_OPTIONS = { rotations: 2, rotationAngles: [0, 90] as [number, number], fontSizes: [14, 60] as [number, number], enableTooltip: true, }; type SummaryStatsProps = { userData: UserEndpointResponse | null; timeData: TimeAnalysisResponse | null; linguisticData: LinguisticAnalysisResponse | null; summary: SummaryResponse | null; onExplore: (spec: CorpusExplorerSpec) => void; }; type WordCloudPanelProps = { words: { text: string; value: number }[]; }; const WordCloudPanel = memo(({ words }: WordCloudPanelProps) => ( )); function formatDateRange(startUnix: number, endUnix: number) { const start = new Date(startUnix * 1000); const end = new Date(endUnix * 1000); const fmt = (d: Date) => d.toLocaleDateString(undefined, { year: "numeric", month: "short", day: "2-digit", }); return `${fmt(start)} -> ${fmt(end)}`; } function convertFrequencyData(data: FrequencyWord[]) { return data.map((d: FrequencyWord) => ({ text: d.word, value: d.count, })); } const renderExploreButton = (onClick: () => void) => ( ); const SummaryStats = ({ userData, timeData, linguisticData, summary, onExplore, }: SummaryStatsProps) => { const wordCloudWords = useMemo( () => convertFrequencyData( (linguisticData?.word_frequencies ?? []).slice(0, MAX_WORDCLOUD_WORDS), ), [linguisticData?.word_frequencies], ); const topUsersPreview = useMemo( () => (userData?.top_users ?? []).slice(0, 100), [userData?.top_users], ); return (
onExplore(buildAllRecordsSpec()))} style={{ gridColumn: "span 4" }} /> onExplore(buildAllRecordsSpec()))} style={{ gridColumn: "span 4" }} /> onExplore(buildAllRecordsSpec()))} style={{ gridColumn: "span 4" }} /> onExplore(buildAllRecordsSpec()))} style={{ gridColumn: "span 4" }} /> onExplore(buildOneTimeUsersSpec()))} style={{ gridColumn: "span 4" }} /> 3 ? "..." : "") : "-" } rightSlot={renderExploreButton(() => onExplore(buildAllRecordsSpec()))} style={{ gridColumn: "span 4" }} />

Activity Over Time

How much posting happened each day.

{ const payload = (state as { activePayload?: Array<{ payload?: { date?: string } }> }) ?.activePayload?.[0]?.payload as | { date?: string } | undefined; if (payload?.date) { onExplore(buildDateBucketSpec(String(payload.date))); } }} >

Common Words

Frequently used words across the dataset.

Most Active Users

Who posted the most events.

{topUsersPreview.map((item) => (
onExplore(buildUserSpec(item.author))} >
{item.author}
{item.source} • {item.count} events
))}

Weekly Activity Pattern

When activity tends to happen by weekday and hour.

); }; export default SummaryStats;