react-d3-cloud-modern
v1.0.11
Published
A word cloud component using d3-cloud
Downloads
267
Readme
react-d3-cloud-modern
A word cloud react component built with d3-cloud.
A modern fork of react-d3-cloud with updated dependencies to address security vulnerabilities and provide React 19 compatibility.

Features
- 🎨 Interactive word clouds with customizable styling
- ⚡ Optimized with React.memo and deep equality checks
- 🔄 Support for React 16.8+, 17, 18, and 19
- 📦 Dual module support (CommonJS and ESM)
- 🎯 Full TypeScript support with type definitions
- 🖱️ Mouse event handlers (click, mouseover, mouseout)
- 🎲 Customizable word positioning, rotation, and sizing algorithms
- 🛡️ Security-focused with regular dependency updates
Installation
npm install react-d3-cloud-modernUsage
Simple:
import React from 'react';
import { render } from 'react-dom';
import WordCloud from 'react-d3-cloud-modern';
const data = [
{ text: 'Hey', value: 1000 },
{ text: 'lol', value: 200 },
{ text: 'first impression', value: 800 },
{ text: 'very cool', value: 1000000 },
{ text: 'duck', value: 10 },
];
render(<WordCloud data={data} />, document.getElementById('root'));More configuration:
import React from 'react';
import { render } from 'react-dom';
import WordCloud from 'react-d3-cloud-modern';
import { scaleOrdinal } from 'd3-scale';
import { schemeCategory10 } from 'd3-scale-chromatic';
const data = [
{ text: 'Hey', value: 1000 },
{ text: 'lol', value: 200 },
{ text: 'first impression', value: 800 },
{ text: 'very cool', value: 1000000 },
{ text: 'duck', value: 10 },
];
const schemeCategory10ScaleOrdinal = scaleOrdinal(schemeCategory10);
render(
<WordCloud
data={data}
width={500}
height={500}
font="Times"
fontStyle="italic"
fontWeight="bold"
fontSize={(word) => Math.log2(word.value) * 5}
spiral="rectangular"
rotate={(word) => word.value % 360}
padding={5}
random={Math.random}
fill={(d, i) => schemeCategory10ScaleOrdinal(i)}
onWordClick={(event, d) => {
console.log(`onWordClick: ${d.text}`);
}}
onWordMouseOver={(event, d) => {
console.log(`onWordMouseOver: ${d.text}`);
}}
onWordMouseOut={(event, d) => {
console.log(`onWordMouseOut: ${d.text}`);
}}
/>,
document.getElementById('root')
);Please checkout demo
for more detailed props, please refer to below:
Props
| name | description | type | required | default |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------- | -------- | ------------------------------------------- |
| data | The words array | { text: string, value: number }>[] | ✓ |
| width | Width of the layout (px) | number | | 700 |
| height | Height of the layout (px) | number | | 600 |
| font | The font accessor function, which indicates the font face for each word. A constant may be specified instead of a function. | string \| (d) => string | | 'serif' |
| fontStyle | The fontStyle accessor function, which indicates the font style for each word. A constant may be specified instead of a function. | string \| (d) => string | | 'normal' |
| fontWeight | The fontWeight accessor function, which indicates the font weight for each word. A constant may be specified instead of a function. | string \| number \| (d) => string \| number | | 'normal' |
| fontSize | The fontSize accessor function, which indicates the numerical font size for each word. | (d) => number | | (d) => Math.sqrt(d.value) |
| rotate | The rotate accessor function, which indicates the rotation angle (in degrees) for each word. | (d) => number | | () => (~~(Math.random() * 6) - 3) * 30 |
| spiral | The current type of spiral used for positioning words. This can either be one of the two built-in spirals, "archimedean" and "rectangular", or an arbitrary spiral generator can be used | 'archimedean' \| 'rectangular' \| ([width, height]) => t => [x, y] | | 'archimedean' |
| padding | The padding accessor function, which indicates the numerical padding for each word. | number \| (d) => number | | 1 |
| random | The internal random number generator, used for selecting the initial position of each word, and the clockwise/counterclockwise direction of the spiral for each word. This should return a number in the range [0, 1). | (d) => number | | Math.random |
| fill | The fill accessor function, which indicates the color for each word. | (d, i) => string | | (d, i) => schemeCategory10ScaleOrdinal(i) |
| onWordClick | The function will be called when click event is triggered on a word | (event, d) => {} | | null |
| onWordMouseOver | The function will be called when mouseover event is triggered on a word | (event, d) => {} | | null |
| onWordMouseOut | The function will be called when mouseout event is triggered on a word | (event, d) => {} | | null |
FAQ
How to Use with Next.js/SSR
To make <WordCloud /> work with Server-Side Rendering (SSR), you need to avoid rendering it on the server:
{
typeof window !== 'undefined' && <WordCloud data={data} />;
}How to Avoid Unnecessary Re-render
As of version 0.10.1, <WordCloud /> has been wrapped by React.memo() and deep equal comparison under the hood to avoid unnecessary re-render. All you need to do is to make your function props deep equal comparable using useCallback():
import React, { useCallback } from 'react';
import { render } from 'react-dom';
import WordCloud from 'react-d3-cloud-modern';
import { scaleOrdinal } from 'd3-scale';
import { schemeCategory10 } from 'd3-scale-chromatic';
function App() {
const data = [
{ text: 'Hey', value: 1000 },
{ text: 'lol', value: 200 },
{ text: 'first impression', value: 800 },
{ text: 'very cool', value: 1000000 },
{ text: 'duck', value: 10 },
];
const fontSize = useCallback((word) => Math.log2(word.value) * 5, []);
const rotate = useCallback((word) => word.value % 360, []);
const fill = useCallback((d, i) => scaleOrdinal(schemeCategory10)(i), []);
const onWordClick = useCallback((word) => {
console.log(`onWordClick: ${word}`);
}, []);
const onWordMouseOver = useCallback((word) => {
console.log(`onWordMouseOver: ${word}`);
}, []);
const onWordMouseOut = useCallback((word) => {
console.log(`onWordMouseOut: ${word}`);
}, []);
return (
<WordCloud
data={data}
width={500}
height={500}
font="Times"
fontStyle="italic"
fontWeight="bold"
fontSize={fontSize}
spiral="rectangular"
rotate={rotate}
padding={5}
random={Math.random}
fill={fill}
onWordClick={onWordClick}
onWordMouseOver={onWordMouseOver}
onWordMouseOut={onWordMouseOut}
/>
);
);NPM Commands
Install dependencies
npm installBuild
npm run buildThis will build both CommonJS (lib/) and ESM (lib/esm/) versions.
Run Tests
npm testPublish to NPM
npm publish(Note: The prepublishOnly script will automatically run npm run build before publishing.)
Development
Pre-install (for node-canvas support)
Mac OS X
brew install pkg-config cairo pango libpng jpeg giflib librsvgUbuntu and Other Debian Based Systems
sudo apt-get update
sudo apt-get install libcairo2-dev libjpeg8-dev libpango1.0-dev libgif-dev build-essential g++For more details, please check out Installation guides at node-canvas wiki.
License
MIT © Yoctol | carlosalvidrez
Changelog
1.0.8 (Latest)
- Update
@modelcontextprotocol/sdkto1.26.0 - Update
eslintto^9.26.0
1.0.7
- Security: Dependency updates to address vulnerabilities
1.0.6
- Security: Upgrade
canvasto^3.2.1to address security vulnerability
1.0.5
- Update
js-yamlto address security vulnerability
1.0.4
- React 19 compatibility improvements
1.0.3
- Update
@testing-library/reactto v16.3.0 - Update
@types/reactto v19.1.8 - Fix Jest configuration
1.0.2
- Fix TypeScript error in useRef hook
- Improve type safety
1.0.1
- Initial release as fork
- Modernized dependencies
- TypeScript improvements
