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;