import type { ContentAnalysisResponse } from "../types/ApiTypes" import StatsStyling from "../styles/stats_styling"; const styles = StatsStyling; type EmotionalStatsProps = { contentData: ContentAnalysisResponse; } const EmotionalStats = ({contentData}: EmotionalStatsProps) => { const rows = contentData.average_emotion_by_topic ?? []; const overallEmotionAverage = contentData.overall_emotion_average ?? []; const dominantEmotionDistribution = contentData.dominant_emotion_distribution ?? []; const emotionBySource = contentData.emotion_by_source ?? []; const lowSampleThreshold = 20; const stableSampleThreshold = 50; const emotionKeys = rows.length ? Object.keys(rows[0]).filter((key) => key.startsWith("emotion_")) : []; const strongestPerTopic = rows.map((row) => { let maxKey = ""; let maxValue = Number.NEGATIVE_INFINITY; emotionKeys.forEach((key) => { const value = Number(row[key] ?? 0); if (value > maxValue) { maxValue = value; maxKey = key; } }); return { topic: String(row.topic), count: Number(row.n ?? 0), emotion: maxKey.replace("emotion_", "") || "unknown", value: maxValue > Number.NEGATIVE_INFINITY ? maxValue : 0 }; }); const formatEmotion = (value: string) => { if (!value) return "Unknown"; return value.charAt(0).toUpperCase() + value.slice(1); }; const sampleSizes = strongestPerTopic .map((topic) => topic.count) .filter((count) => Number.isFinite(count) && count > 0) .sort((a, b) => a - b); const lowSampleTopics = strongestPerTopic.filter((topic) => topic.count < lowSampleThreshold).length; const stableSampleTopics = strongestPerTopic.filter((topic) => topic.count >= stableSampleThreshold).length; const medianSampleSize = sampleSizes.length ? sampleSizes[Math.floor(sampleSizes.length / 2)] : 0; if (!rows.length) { return (
No topic emotion data available.
Use the strength score together with post count. Topics with fewer than {lowSampleThreshold} events are often noisy.
Strength means how far the top emotion is ahead in that topic. It does not mean model accuracy.
Average score for each emotion.
{!overallEmotionAverage.length ? (How often each emotion is dominant.
{!dominantEmotionDistribution.length ? (Leading emotion in each source.
{!emotionBySource.length ? (Per-topic mood with strength and post count.