Analytics: General Statistics
Relevant source files
The following files were used as context for generating this wiki page:The General Statistics feature provides a comprehensive quantitative summary of chat messages. It processes the entire message list for a selected chat to calculate various metrics, including message type distribution, activity timelines, and specific data points like audio duration and communication streaks. These statistics are then presented to the user in a dedicated display component.
This system is orchestrated by the MessageDataProcessor, which uses a specialized StatisticsProcessor to perform the calculations. The final data is rendered by the StatisticsDisplay React component on the results page.
Architecture and Data Flow
The generation and display of statistics follow a clear, multi-layered process. It begins at the UI level, passes through a central data processor, is handled by a dedicated statistics calculator, and is finally rendered by a display component.
The following diagram illustrates the high-level data flow for statistics generation.
ResultsStep.jsx: The UI component that initiates the process. It creates an instance ofMessageDataProcessor.MessageDataProcessor.js: This class acts as a facade for all analytics processing. It receives the raw message list and, when requested, lazy-loads the statistics by instantiating and running theStatisticsProcessor.StatisticsProcessor.js: This class contains the core logic for iterating through messages and calculating all statistical metrics.StatisticsDisplay.jsx: A React component that receives the final, processed statistics object and renders it for the user.
Statistics Calculation (StatisticsProcessor)
The StatisticsProcessor class is the engine of the statistics feature. It is responsible for all calculations based on the provided message list, daily message counts, and chat names.
Sources: web/src/analytics/processors/statisticsProcessor.js
Class Structure
The StatisticsProcessor is designed to encapsulate all logic related to statistical analysis.
Processing Logic
The main method, processStatistics, follows a sequential workflow to generate the complete statistics object.
Statistics Data Structure
A standardized data structure is initialized for each chat to accumulate the metrics.
| Field | Type | Description |
|---|---|---|
total | Number | Total number of messages. |
firstMessageTime | String | Timestamp of the first message. |
lastMessageTime | String | Timestamp of the last message. |
longestAudio | Number | Duration of the longest audio message in seconds. |
totalAudioDuration | Number | Sum of all audio message durations in seconds. |
avgAudioDuration | Number | Average audio message duration in seconds. |
longestDaysStreak | Number | The longest consecutive number of days with at least one message. |
dayWithMessages | Number | The total count of unique days that have at least one message. |
text, link, image, etc. | Number | A counter for each message type defined in MESSAGE_STATS_TYPES. |
Sources: web/src/analytics/processors/statisticsProcessor.js:42-59, web/src/analytics/constants.js:6-19
Core Metrics Calculation
The processMessage method iterates through each message and updates the statistics object for the corresponding chat.
- It increments the
totalmessage count. - It increments the counter for the specific message
type(e.g.,stats.text++). - It also handles special cases like
editandstarproperties. - For audio messages, it updates
longestAudioandtotalAudioDuration. - It tracks the
firstMessageTimeandlastMessageTime.
Sources: web/src/analytics/processors/statisticsProcessor.js:65-92
Streak Calculation
The calculateStreaks method determines the longest consecutive day streak of messaging. It iterates through the messagesPerDay data structure.
- If a chat has messages on a given day, its
possibleNewStreakis incremented. - If a chat has no messages on a given day, the current streak is broken. The
possibleNewStreakis compared to thecurrentLongestStreakand reset to 0. - The final
longestDaysStreakis the maximum of the last recorded streak and any ongoing streak at the end of the period.
Sources: web/src/analytics/processors/statisticsProcessor.js:97-124
Display Component (StatisticsDisplay)
The StatisticsDisplay.jsx component is a presentational component responsible for rendering the calculated statistics in a user-friendly format. It receives the stats object for a single chat as a prop.
Sources: web/src/analytics/components/StatisticsDisplay.jsx
Key Display Sections
The component is divided into two main visual sections:
-
Message Type Breakdown: A series of progress bars, one for each message type defined in
MESSAGE_STATS_TYPES. Each bar visually represents the percentage of that message type relative to the total, along with the absolute count. The colors are sourced fromCHART_COLORS.
Sources: web/src/analytics/components/StatisticsDisplay.jsx:16-43, web/src/analytics/constants.js:6-25 -
Main Statistics List: A grid that displays key metrics in a label-value format.
| Label | Value Source / Formatting |
|---|---|
| First message sent on: | stats.firstMessageTime |
| Last message sent on: | stats.lastMessageTime |
| Longest audio lasts: | formatDuration(stats.longestAudio) |
| Total audio duration: | formatDuration(stats.totalAudioDuration) |
| Average audio duration: | formatDuration(stats.avgAudioDuration) |
| Longest days streak: | stats.longestDaysStreak (appends 'd') |
| Days with at least one message: | stats.dayWithMessages (appends 'd') |
Sources: web/src/analytics/components/StatisticsDisplay.jsx:81-105
The formatDuration helper uses the pretty-ms library to convert seconds into a human-readable string (e.g., 1m 30s).
Sources: web/src/analytics/components/StatisticsDisplay.jsx:48-52, web/package.json:7
Helper Functions (statsHelpers.js)
A small set of utility functions supports the statistics processing and display logic.
| Function | Description |
|---|---|
formatPercent(count, total) | Calculates a percentage and formats it to one decimal place if under 10, otherwise rounds to the nearest integer. |
calculateAverage(total, count) | Calculates the rounded average of a total and a count, returning 0 if the count is zero. |
findMaxValue(obj) | Finds the maximum numerical value from an object's values. |
Sources: web/src/analytics/utils/statsHelpers.js
System Integration
The following sequence diagram shows how the components interact to deliver the statistics to the user interface.