{"id":10711,"library":"d3-cloud","title":"D3 Word Cloud Layout","description":"d3-cloud is a JavaScript library for generating Wordle-inspired word clouds, leveraging HTML5 canvas and sprite masks for efficient rendering. It provides a programmatic API to configure cloud properties such as size, word list, font face, font style, font weight, and font size accessor functions. The library integrates well within the D3.js ecosystem, although it can be used standalone to generate word layouts. The current stable version is 1.2.9, indicating a mature and stable codebase rather than one undergoing rapid iterative development. Key differentiators include its canvas-based approach for performance and its comprehensive layout algorithm that handles word placement and collision detection, contrasting with purely SVG-based solutions or those requiring manual positioning. Its primary output is an array of word objects with calculated positions, sizes, and rotations, ready for custom rendering.","status":"maintenance","version":"1.2.9","language":"javascript","source_language":"en","source_url":"https://github.com/jasondavies/d3-cloud","tags":["javascript","word","cloud","tag","visualization","canvas"],"install":[{"cmd":"npm install d3-cloud","lang":"bash","label":"npm"},{"cmd":"yarn add d3-cloud","lang":"bash","label":"yarn"},{"cmd":"pnpm add d3-cloud","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Historically, d3-cloud was designed as a D3 layout plugin (d3.layout.cloud). While it can be used independently for layout generation, D3 is commonly used for rendering the output.","package":"d3","optional":true}],"imports":[{"note":"d3-cloud exports its layout function as the default export for modern ESM usage.","wrong":"import { cloud } from 'd3-cloud';","symbol":"cloud","correct":"import cloud from 'd3-cloud';"},{"note":"For CommonJS environments, the module is imported directly to get the default layout function.","symbol":"cloud","correct":"const cloud = require('d3-cloud');"},{"note":"This is the legacy usage pattern for older D3 versions (v3-v4) where d3-cloud would extend the global d3 object. Requires D3 to be loaded globally before d3-cloud. For modern D3, use the default ESM import.","wrong":"import { cloud } from 'd3-cloud';","symbol":"d3.layout.cloud","correct":"const layout = d3.layout.cloud();"}],"quickstart":{"code":"import cloud from 'd3-cloud';\n\ninterface Word {\n  text: string;\n  value: number;\n  size?: number;\n  x?: number;\n  y?: number;\n  rotate?: number;\n  font?: string;\n  style?: string;\n  weight?: string;\n}\n\nconst wordsData: Word[] = [\n  { text: \"TypeScript\", value: 60 },\n  { text: \"JavaScript\", value: 50 },\n  { text: \"D3\", value: 45 },\n  { text: \"Cloud\", value: 40 },\n  { text: \"Canvas\", value: 35 },\n  { text: \"Layout\", value: 30 },\n  { text: \"Example\", value: 25 },\n  { text: \"Development\", value: 20 },\n  { text: \"Web\", value: 15 },\n  { text: \"Visualization\", value: 55 }\n];\n\nconst width = 960;\nconst height = 500;\n\n// Create a new cloud layout instance\nconst layout = cloud<Word>()\n  .size([width, height])\n  .words(wordsData)\n  .padding(5)\n  .rotate(() => Math.floor(Math.random() * 5) * 30 - 60) // Rotate words by -60, -30, 0, 30, 60 degrees\n  .font(\"Impact\")\n  .fontSize(d => Math.sqrt(d.value) * 8) // Scale font size based on word value\n  .on(\"end\", (words: Word[], bounds: [{ x0: number, y0: number }, { x1: number, y1: number }]) => {\n    console.log(\"Word cloud layout generation complete.\");\n    console.log(\"Successfully placed words:\", words.map(w => ({ text: w.text, size: w.size, x: w.x, y: w.y, rotate: w.rotate })));\n    console.log(\"Overall cloud bounds:\", bounds);\n    // In a real application, you would typically render these 'words' to an HTML5 Canvas or SVG element.\n  });\n\nlayout.start(); // Start the layout algorithm","lang":"typescript","description":"This quickstart demonstrates how to configure and run the d3-cloud layout, setting dimensions, words, font properties, and handling the 'end' event to retrieve the placed words."},"warnings":[{"fix":"To ensure all words are placed, consider increasing the layout size, reducing font sizes, decreasing padding, or implementing a custom collision detection strategy. Monitor the 'end' event output to see which words were successfully placed.","message":"Words that cannot be placed within the specified layout size (due to collisions or insufficient space) are silently omitted from the final output array. Users expecting all input words to always appear might be surprised.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"For modern JavaScript and TypeScript projects, always use `import cloud from 'd3-cloud';` and instantiate the layout directly with `cloud()`. Avoid relying on global `d3` object extension.","message":"d3-cloud was originally designed for older D3 versions (v3-v4) and could extend the global `d3` object (e.g., `d3.layout.cloud()`). Modern D3 (v5+) and module bundlers require importing `d3-cloud` as a standalone module.","severity":"breaking","affected_versions":">=1.0.0 (when migrating to modern D3/ESM)"},{"fix":"Be prepared to implement rendering logic using Canvas API contexts or convert the output data for SVG element creation (e.g., using D3 for SVG rendering).","message":"The library outputs word position data for rendering on an HTML5 Canvas, not directly for SVG. While the data can be adapted for SVG, the intrinsic sprite mask optimization is specific to canvas.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Utilize the `.timeInterval(milliseconds)` method to yield control back to the browser periodically, allowing the UI to remain responsive. Adjust the `milliseconds` value based on performance needs.","message":"For very large word lists or complex layouts, the layout algorithm can be computationally intensive and might block the browser's event loop, leading to UI freezes. The `timeInterval` method can help mitigate this.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"For modern usage, ensure you are using `import cloud from 'd3-cloud';` and then `cloud()`. For legacy D3 integration, ensure the `d3` library is loaded globally before `d3-cloud`'s script.","cause":"The d3-cloud library was not imported or initialized correctly, or the global 'd3' object (for legacy usage) was not available when d3-cloud was loaded.","error":"TypeError: Cannot read properties of undefined (reading 'cloud')"},{"fix":"Ensure you create an instance of the layout: `const layout = cloud();` (for modern ESM) or `const layout = d3.layout.cloud();` (for legacy global D3).","cause":"The `cloud()` function was not invoked to create a layout instance before attempting to call its methods, or the import was incorrect.","error":"TypeError: layout.start is not a function"},{"fix":"Increase the `size` of the layout, decrease `padding`, adjust the `fontSize` accessor to make words smaller (e.g., `d => Math.sqrt(d.value) * 5` instead of `* 10`), or reduce the total number of words in the input array. Check the output of the 'end' event to identify which words were dropped.","cause":"The d3-cloud algorithm attempts to place words along a spiral. If a word cannot find an uncollided position within its search, it is discarded.","error":"Some words are not appearing in the final word cloud, even if space seems available."}],"ecosystem":"npm"}