@harryjwang/simplewordcloud
Version:
A simple word cloud generator supporting English and Chinese text
138 lines • 5.56 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const browser_tokenizers_1 = require("./browser-tokenizers");
const d3_cloud_1 = __importDefault(require("d3-cloud"));
const d3 = __importStar(require("d3"));
/**
* Default options for the browser word cloud
*/
const DEFAULT_OPTIONS = {
width: 800,
height: 600,
fontFamily: 'Arial, sans-serif',
maxWords: 100,
colors: [...d3.schemeCategory10],
padding: 5,
minFontSize: 10,
maxFontSize: 60,
rotationAngles: [0, 90],
rotationProbability: 0.3
};
/**
* Generate a word cloud in the browser
*/
function generateWordCloud(text, language, container, options = {}) {
// Merge options with defaults
const mergedOptions = Object.assign(Object.assign({}, DEFAULT_OPTIONS), options);
// Get the appropriate tokenizer
const tokenizer = (0, browser_tokenizers_1.getSimplifiedTokenizer)(language);
// Tokenize the text and get word frequencies
const wordCounts = tokenizer.tokenize(text);
// Convert to array and sort by frequency
const words = Array.from(wordCounts.entries())
.sort((a, b) => b[1] - a[1])
.slice(0, mergedOptions.maxWords)
.map(([text, size]) => {
// Scale the font size based on frequency
const counts = Array.from(wordCounts.values());
const minCount = Math.min(...counts);
const maxCount = Math.max(...counts);
// Linear scaling between min and max font size
const scaledSize = minCount === maxCount
? mergedOptions.maxFontSize
: mergedOptions.minFontSize +
(size - minCount) / (maxCount - minCount) *
(mergedOptions.maxFontSize - mergedOptions.minFontSize);
// Determine if word should be rotated
const rotate = Math.random() > mergedOptions.rotationProbability
? 0
: mergedOptions.rotationAngles[Math.floor(Math.random() * mergedOptions.rotationAngles.length)];
return {
text,
size: scaledSize,
rotate
};
});
// Create SVG element
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttribute('width', mergedOptions.width.toString());
svg.setAttribute('height', mergedOptions.height.toString());
svg.setAttribute('class', 'wordcloud');
// Generate the layout using d3-cloud
const layout = (0, d3_cloud_1.default)()
.size([mergedOptions.width, mergedOptions.height])
.words(words)
.padding(mergedOptions.padding)
.rotate((d) => d.rotate)
.font(mergedOptions.fontFamily)
.fontSize((d) => d.size)
.on('end', (words) => {
// Draw the word cloud
const colorScale = d3.scaleOrdinal(mergedOptions.colors);
const g = document.createElementNS('http://www.w3.org/2000/svg', 'g');
g.setAttribute('transform', `translate(${mergedOptions.width / 2},${mergedOptions.height / 2})`);
words.forEach((d, i) => {
const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
text.setAttribute('text-anchor', 'middle');
text.setAttribute('transform', `translate(${d.x},${d.y}) rotate(${d.rotate})`);
text.setAttribute('font-size', `${d.size}px`);
text.setAttribute('font-family', mergedOptions.fontFamily);
text.setAttribute('fill', colorScale(i.toString()));
text.textContent = d.text || '';
g.appendChild(text);
});
svg.appendChild(g);
});
layout.start();
// Clear container and append SVG
container.innerHTML = '';
container.appendChild(svg);
return svg;
}
// Create the SimpleWordCloud object
const SimpleWordCloud = {
generateWordCloud
};
// Export as default for webpack
exports.default = SimpleWordCloud;
// Also attach to window for direct browser usage
if (typeof window !== 'undefined') {
window.SimpleWordCloud = SimpleWordCloud;
}
//# sourceMappingURL=browser.js.map