This code generates an SVG image of a word cloud by using D3.js and the d3-cloud
library to layout and style words based on their frequency. It takes an array of word objects as input and returns an SVG string representing the word cloud.
npm run import -- "Create a word-cloud"
var D3Node = require('d3-node');
var cloud = require('d3-cloud');
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
function drawD3Cloud(wordCount) {
var d3n = new D3Node(); // initializes D3 with container element
var d3 = d3n.d3;
var fill = d3.scaleOrdinal(d3.schemeCategory20);
d3n.createSVG(
width + margin.left + margin.right,
height + margin.top + margin.bottom)
.append('g')
.attr(
'transform',
'translate(' + (margin.left + width / 2) + ',' + (margin.top + height / 2) + ')')
.selectAll('text')
.data(wordCount)
.enter().append('text')
.style('font-size', function (d) {
return d.size + 'px';
})
.style('font-family', 'Impact')
.style('fill', function (d, i) {
return fill(i);
})
.attr('text-anchor', 'middle')
.attr('transform', function (d) {
return 'translate(' + [d.x, d.y] + ')rotate(' + d.rotate + ')';
})
.text(function (d) {
return d.text;
});
return d3n.svgString();
};
function d3CloudToSVG(wordCount) {
console.log('git');
var Canvas = require('canvas');
return new Promise(resolve => {
cloud()
.canvas(function () {
return new Canvas(1, 1);
})
.size([width, height])
.words(wordCount)
.padding(0)
.rotate(function () {
return ~~(Math.random() * 120) - 60;
})
.font('Impact')
.fontSize(function (d) {
return d.size;
})
.on('end', function (wordCount) {
resolve(drawD3Cloud(wordCount));
})
.start();
});
};
module.exports = d3CloudToSVG;
const { createCanvas } = require('canvas');
const cloud = require('d3-cloud');
const { D3Node } = require('d3-node');
/**
* Configuration for the D3 chart.
* @type {Object}
*/
const config = {
margin: {
top: 20,
right: 20,
bottom: 30,
left: 50,
},
width: 960,
height: 500,
};
/**
* Function to draw the D3 cloud chart.
* @param {Object[]} wordCount - Array of objects containing word information.
* @returns {Promise<string>} SVG string of the D3 chart.
*/
async function drawD3Cloud(wordCount) {
// Create a new D3Node instance
const d3n = new D3Node();
const d3 = d3n.d3;
// Create a scale for fill colors
const fill = d3.scaleOrdinal(d3.schemeCategory20);
// Create a new SVG element
const svg = d3n.createSVG(config.width + config.margin.left + config.margin.right, config.height + config.margin.top + config.margin.bottom)
.append('g')
.attr('transform', `translate(${config.margin.left + config.width / 2}, ${config.margin.top + config.height / 2})`);
// Select all text elements and bind data
svg.selectAll('text')
.data(wordCount)
.enter()
.append('text')
.style('font-size', (d) => `${d.size}px`)
.style('font-family', 'Impact')
.style('fill', (d, i) => fill(i))
.attr('text-anchor','middle')
.attr('transform', (d) => `translate(${d.x}, ${d.y}) rotate(${d.rotate})`)
.text((d) => d.text);
// Return the SVG string
return d3n.svgString();
}
/**
* Function to generate the D3 cloud chart.
* @param {Object[]} wordCount - Array of objects containing word information.
* @returns {Promise<string>} SVG string of the D3 chart.
*/
async function d3CloudToSVG(wordCount) {
// Create a new canvas element
const canvas = createCanvas(1, 1);
const context = canvas.getContext('2d');
// Create a new cloud instance
const cloudInstance = cloud()
.canvas(() => canvas)
.size([config.width, config.height])
.words(wordCount)
.padding(0)
.rotate(() => ~~(Math.random() * 120) - 60)
.font('Impact')
.fontSize((d) => d.size)
.on('end', (wordCount) => {
// Draw the D3 cloud chart
const svgString = drawD3Cloud(wordCount);
context.font = '16px Arial';
context.fillStyle = 'white';
context.textAlign = 'center';
context.textBaseline ='middle';
context.fillText(svgString, canvas.width / 2, canvas.height / 2);
// Return the SVG string
return canvas.toDataURL();
})
.start();
// Wait for the cloud instance to finish
return new Promise((resolve) => {
cloudInstance.on('end', (svgString) => resolve(svgString));
});
}
module.exports = d3CloudToSVG;
This code generates an SVG image of a word cloud using D3.js and the d3-cloud
library.
Here's a breakdown:
Setup:
d3-node
for using D3.js in a Node.js environment and d3-cloud
for word cloud generation.drawD3Cloud
Function:
wordCount
) as input.D3Node
.d3CloudToSVG
Function:
d3-cloud
to generate the word cloud layout.drawD3Cloud
with the generated word cloud data to create the SVG representation.Export:
d3CloudToSVG
function, making it available for use in other modules.In essence, this code takes an array of words with their frequencies and generates a visually appealing word cloud as an SVG image.