Introducing Word Cloud: A Simple and Extensible React Native Component

Introducing Word Cloud: A Simple and Extensible React Native Component
Photo by Anastasia Judt / Unsplash

I'm excited to introduce a new React Native component that I recently used in the latest release of my Android app: Word Cloud! 🌟

screenshot

What is Word Cloud?

Word Cloud is a lightweight and easy-to-use React Native component for creating beautiful and dynamic word/tag clouds. Inspired by react-tagcloud, this component allows each word to be displayed in different fonts and colors while ensuring they remain clearly visible to users.

Key Features:

  • Simplicity: The implementation is straightforward, comprising only 120 lines of code.
  • Customizability: Easily extend and customize the appearance of the words.
  • Dynamic Styling: Each word is displayed in various fonts and colors for a vibrant visual experience.

Implementation

Here's a sneak peek at the implementation of the Word Cloud component:

import React from 'react';
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';

export interface WordData { word: string, count: number, html: string }
interface WordCloudProps {
    data: WordData[];
    onWordClick?: (worddata: WordData) => void;
}

const WordCloud: React.FC<WordCloudProps> = ({ data, onWordClick }) => {
    const maxFontSize = 30;
    const minFontSize = 24;

    const maxCount = Math.max(...data.map(item => item.count));
    const minCount = Math.min(...data.map(item => item.count));

    const calculateFontSize = (count: number): number => {
        const range = maxCount - minCount;
        if (range <= 0) {
            return minFontSize;
        }
        const fontSizeRange = maxFontSize - minFontSize;
        const adjustedCount = count - minCount;
        return minFontSize + (fontSizeRange * adjustedCount) / range;
    };

    const generateColor = (seed: number): string => {
        const goldenRatioConjugate = 0.618033988749895;
        let hue = (seed * goldenRatioConjugate) % 1; // Generate hue based on the seed

        // Convert hue to RGB
        const rgb = hslToRgb(hue, 0.8, 0.6); // Adjust saturation and lightness for bright colors

        // Convert RGB to hex
        const colorHex = rgbToHex(rgb[0], rgb[1], rgb[2]);

        return colorHex;
    };

    const hslToRgb = (h: number, s: number, l: number): number[] => {
        let r, g, b;

        if (s == 0) {
            r = g = b = l; // Achromatic
        } else {
            const hue2rgb = (p: number, q: number, t: number) => {
                if (t < 0) t += 1;
                if (t > 1) t -= 1;
                if (t < 1 / 6) return p + (q - p) * 6 * t;
                if (t < 1 / 2) return q;
                if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
                return p;
            };

            const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
            const p = 2 * l - q;

            r = hue2rgb(p, q, h + 1 / 3);
            g = hue2rgb(p, q, h);
            b = hue2rgb(p, q, h - 1 / 3);
        }

        return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
    };

    const rgbToHex = (r: number, g: number, b: number): string => {
        return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
    };

    return (
        <View style={styles.container}>
            {data.length > 0 && data.map((item, index) => {
                return <TouchableOpacity key={index} onPress={() => onWordClick && onWordClick(item)}>
                    <Text
                        style={[
                            styles.word,
                            {
                                fontSize: calculateFontSize(item.count),
                                color: generateColor(item.word.length),
                                borderColor: generateColor(item.word.length)
                            }
                        ]}
                    >
                        {item.word}
                    </Text>
                </TouchableOpacity>
            }

            )}
        </View>
    );
};

const styles = StyleSheet.create({
    container: {
        flexDirection: 'row',
        flexWrap: 'wrap',
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#f0f0f0',
    },
    word: {
        margin: 5,
        borderWidth: 1,
        padding: 5,
        borderRadius: 5,
    },

});

export default WordCloud;

Usage

Integrating the Word Cloud component into your project is seamless. Here's how you can use it:

import React from 'react';
import { View } from 'react-native';
import WordCloud from './WordCloud';

const App = () => {
  const words = ['React', 'Native', 'Component', 'Word', 'Cloud', 'Simple', 'Extensible'];

  return (
    <View style={{ padding: 20 }}>
      <WordCloud data={words} />
    </View>
  );
};

export default App;
import React from 'react';

Why Use Word Cloud?

  • Ease of Use: With its minimal codebase, you can quickly integrate Word Cloud into your app.
  • Visual Appeal: The dynamic fonts and colors make your word clouds visually engaging and attractive.
  • Extensibility: Customize the component to fit your specific needs, whether it's for a tag cloud, word frequency visualization, or any other application.

Download the latest version of my app on Google Play to see the Word Cloud component in action!

I'm excited to see how you will use this component in your projects. Happy coding!

Best,
QZL Corp.

Subscribe to Post, Code and Quiet Time.

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe