From b1177540a1d13701050dc85ed77cd6f1849a4f25 Mon Sep 17 00:00:00 2001 From: Dylan De Faoite Date: Wed, 18 Mar 2026 19:11:18 +0000 Subject: [PATCH] feat(frontend): enhance EmotionalStats component with detailed mood analysis --- frontend/src/components/EmotionalStats.tsx | 110 +++++++++++++++++---- 1 file changed, 89 insertions(+), 21 deletions(-) diff --git a/frontend/src/components/EmotionalStats.tsx b/frontend/src/components/EmotionalStats.tsx index ecc588f..a0a66f3 100644 --- a/frontend/src/components/EmotionalStats.tsx +++ b/frontend/src/components/EmotionalStats.tsx @@ -9,6 +9,9 @@ type EmotionalStatsProps = { 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 @@ -64,39 +67,104 @@ const EmotionalStats = ({contentData}: EmotionalStatsProps) => { return (
-

Average Emotion by Topic

-

Read confidence together with sample size. Topics with fewer than {lowSampleThreshold} events are usually noisy and less reliable.

+

Topic Mood Overview

+

Use the strength score together with post count. Topics with fewer than {lowSampleThreshold} events are often noisy.

Topics: {strongestPerTopic.length} - Median Sample: {medianSampleSize} events - Low Sample (<{lowSampleThreshold}): {lowSampleTopics} - Stable Sample ({stableSampleThreshold}+): {stableSampleTopics} + Median Posts: {medianSampleSize} + Small Topics (<{lowSampleThreshold}): {lowSampleTopics} + Stable Topics ({stableSampleThreshold}+): {stableSampleTopics}

- Confidence reflects how strongly one emotion leads within a topic, not model accuracy. Use larger samples for stronger conclusions. + Strength means how far the top emotion is ahead in that topic. It does not mean model accuracy.

- {strongestPerTopic.map((topic) => ( -
-

{topic.topic}

-
- Top Emotion +
+

Mood Averages

+

Average score for each emotion.

+ {!overallEmotionAverage.length ? ( +
No overall emotion averages available.
+ ) : ( +
+ {[...overallEmotionAverage] + .sort((a, b) => b.score - a.score) + .map((row) => ( +
+
{formatEmotion(row.emotion)}
+
{row.score.toFixed(3)}
+
+ ))}
-
- {formatEmotion(topic.emotion)} + )} +
+ +
+

Mood Split

+

How often each emotion is dominant.

+ {!dominantEmotionDistribution.length ? ( +
No dominant-emotion split available.
+ ) : ( +
+ {[...dominantEmotionDistribution] + .sort((a, b) => b.ratio - a.ratio) + .map((row) => ( +
+
{formatEmotion(row.emotion)}
+
{(row.ratio * 100).toFixed(1)}% • {row.count.toLocaleString()} events
+
+ ))}
-
- Confidence - {topic.value.toFixed(3)} -
-
- Sample Size - {topic.count} events + )} +
+ +
+

Mood by Source

+

Leading emotion in each source.

+ {!emotionBySource.length ? ( +
No source emotion profile available.
+ ) : ( +
+ {[...emotionBySource] + .sort((a, b) => b.event_count - a.event_count) + .map((row) => ( +
+
{row.source}
+
+ {formatEmotion(row.dominant_emotion)} • {row.dominant_score.toFixed(3)} • {row.event_count.toLocaleString()} events +
+
+ ))}
+ )} +
+ +
+

Topic Snapshots

+

Per-topic mood with strength and post count.

+
+ {strongestPerTopic.map((topic) => ( +
+

{topic.topic}

+
+ Likely Mood +
+
+ {formatEmotion(topic.emotion)} +
+
+ Strength + {topic.value.toFixed(3)} +
+
+ Posts in Topic + {topic.count} +
+
+ ))}
- ))} +
);