File size: 3,597 Bytes
75137c7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/**
 * Utility functions for analyzing analysis results and calculating statistics
 */

import type { AnalysisResult } from '../types/analysis.types.ts';

/**
 * Statistics about stance distribution
 */
export type StanceStats = {
  total: number;
  pro: number;
  con: number;
  proPercentage: number;
  conPercentage: number;
};

/**
 * Topic frequency data
 */
export type TopicFrequency = {
  topic: string;
  count: number;
  proCount: number;
  conCount: number;
};

/**
 * Time-based statistics
 */
export type TimeStats = {
  date: string;
  count: number;
};

/**
 * Calculate stance distribution statistics
 */
export function calculateStanceStats(results: AnalysisResult[]): StanceStats {
  const total = results.length;
  const pro = results.filter((r) => r.predicted_stance === 'PRO').length;
  const con = results.filter((r) => r.predicted_stance === 'CON').length;

  return {
    total,
    pro,
    con,
    proPercentage: total > 0 ? (pro / total) * 100 : 0,
    conPercentage: total > 0 ? (con / total) * 100 : 0,
  };
}

/**
 * Calculate topic frequency statistics
 */
export function calculateTopicFrequency(
  results: AnalysisResult[],
  limit: number = 10
): TopicFrequency[] {
  const topicMap = new Map<string, { count: number; proCount: number; conCount: number }>();

  results.forEach((result) => {
    const topic = result.topic.trim();
    if (!topic) return;

    const existing = topicMap.get(topic) || { count: 0, proCount: 0, conCount: 0 };
    existing.count += 1;
    if (result.predicted_stance === 'PRO') {
      existing.proCount += 1;
    } else {
      existing.conCount += 1;
    }
    topicMap.set(topic, existing);
  });

  return Array.from(topicMap.entries())
    .map(([topic, stats]) => ({
      topic,
      count: stats.count,
      proCount: stats.proCount,
      conCount: stats.conCount,
    }))
    .sort((a, b) => b.count - a.count)
    .slice(0, limit);
}

/**
 * Calculate time-based statistics (grouped by date)
 */
export function calculateTimeStats(results: AnalysisResult[]): TimeStats[] {
  const dateMap = new Map<string, number>();

  results.forEach((result) => {
    const date = new Date(result.created_at).toISOString().split('T')[0];
    dateMap.set(date, (dateMap.get(date) || 0) + 1);
  });

  return Array.from(dateMap.entries())
    .map(([date, count]) => ({ date, count }))
    .sort((a, b) => a.date.localeCompare(b.date));
}

/**
 * Get unique topics count
 */
export function getUniqueTopicsCount(results: AnalysisResult[]): number {
  const uniqueTopics = new Set(results.map((r) => r.topic.trim()).filter((t) => t));
  return uniqueTopics.size;
}

/**
 * Get average argument length (in characters)
 */
export function getAverageArgumentLength(results: AnalysisResult[]): number {
  if (results.length === 0) return 0;
  const totalLength = results.reduce((sum, r) => sum + r.argument.length, 0);
  return Math.round(totalLength / results.length);
}

/**
 * Get most recent analysis date
 */
export function getMostRecentAnalysisDate(results: AnalysisResult[]): string | null {
  if (results.length === 0) return null;
  const dates = results.map((r) => new Date(r.created_at).getTime());
  const mostRecent = new Date(Math.max(...dates));
  return mostRecent.toISOString().split('T')[0];
}

/**
 * Get oldest analysis date
 */
export function getOldestAnalysisDate(results: AnalysisResult[]): string | null {
  if (results.length === 0) return null;
  const dates = results.map((r) => new Date(r.created_at).getTime());
  const oldest = new Date(Math.min(...dates));
  return oldest.toISOString().split('T')[0];
}