diff --git a/src/app/page.tsx b/src/app/page.tsx index d3ee09a..cd6f3a3 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -6,6 +6,7 @@ import { Checkbox } from "@/components/ui/checkbox"; import { Stats } from "@/components/Stats"; import LetterDensity from "@/components/LetterDensity"; import { Input } from "@/components/ui/input"; +import WordDensity from "@/components/WordDensity"; const config = { includeSpaces: true, @@ -58,6 +59,24 @@ export default function Home() { result.letterDensity[char] = +(result.letterDensity[char] / totalLetters).toFixed(3); } + const words = inputText.toLowerCase().match(/[a-zäöüß]+/gi) || []; + const totalWords = words.length; + result.wordDensity = {}; + + for (let word of words) { + result.wordDensity[word] = (result.wordDensity[word] || 0) + 1; + } + + for (let word in result.wordDensity) { + result.wordDensity[word] = +(result.wordDensity[word] / totalWords).toFixed(3); + } + result.lineCount = (inputText.match(/\n/g) || []).length + 1; + result.spaceCount = (inputText.match(/ /g) || []).length; + const sortedWords = Object.entries(result.wordDensity).sort((a, b) => b[1] - a[1]); + result.topWord = sortedWords[0]?.[0] ?? null; + result.topWordFrequency = sortedWords[0] ? +(sortedWords[0][1] * 100).toFixed(1) : null; + + setAnalysis(result); }, [text, includeSpaces, useCustomLimit, charLimit]); @@ -116,8 +135,15 @@ export default function Home() { charCount={analysis.charCount} wordCount={analysis.wordCount} sentenceCount={analysis.sentenceCount} + lineCount={analysis.lineCount} + spaceCount={analysis.spaceCount} + topWord={analysis.topWord} + topWordFrequency={analysis.topWordFrequency} /> + + + )} diff --git a/src/components/Stats.tsx b/src/components/Stats.tsx index 513e7bf..8af4e59 100644 --- a/src/components/Stats.tsx +++ b/src/components/Stats.tsx @@ -4,29 +4,56 @@ interface StatsProps { charCount: number; wordCount: number; sentenceCount: number; + lineCount: number; + spaceCount: number; + topWord: string | null; + topWordFrequency: number | null; } -export function Stats({ charCount, wordCount, sentenceCount }: StatsProps) { +export function Stats({ charCount, wordCount, sentenceCount, lineCount, spaceCount, topWord, topWordFrequency }: StatsProps) { return ( -
+
- + {charCount} Total Characters - - + + {wordCount} Word Count - - + + {sentenceCount} Sentence Count + + + {lineCount} + Line Count + + + + + {spaceCount} + Spaces + + + + + + {topWord ?? "—"} + + + Top word{topWordFrequency !== null ? ` (${topWordFrequency}%)` : ""} + + + +
); } diff --git a/src/components/WordDensity.tsx b/src/components/WordDensity.tsx new file mode 100644 index 0000000..17864f8 --- /dev/null +++ b/src/components/WordDensity.tsx @@ -0,0 +1,46 @@ +"use client"; +import { Progress } from "@/components/ui/progress"; +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion"; + +type WordDensityProps = { + density: Record; +}; + +export default function WordDensity({ density }: WordDensityProps) { + const sorted = Object.entries(density).sort((a, b) => b[1] - a[1]); + const firstFive = sorted.slice(0, 5); + const rest = sorted.slice(5); + + return ( +
+

Word Density

+
+ {firstFive.map(([word, value]) => ( +
+

{word}

+ +

{(value * 100).toFixed(2)}%

+
+ ))} +
+ {rest.length > 0 && ( + + + See more + +
+ {rest.map(([word, value]) => ( +
+

{word}

+ +

{(value * 100).toFixed(2)}%

+
+ ))} +
+
+
+
+ )} +
+ ); +}