Public
Edited
Sep 9, 2024
Insert cell
Insert cell
Insert cell
viewof inputs = Inputs.form({
maxWords: Inputs.range([100,1000],{value: 500, step: 1, label: "Words"}),
fontScale: Inputs.range([1,16],{value: 4, step: 0.125, label: "FontScale"}),
powerLaw: Inputs.range([0.0625,2.0],{value: 0.5, step: 0.0625, label: "PowerLaw"}),
height: Inputs.range([240,1024],{value: 480,step: 1,label: "Height"})
})
Insert cell
wordCount=FileAttachment("wordcount@2.csv").csv({array:true,typed:true})
Insert cell
function WordCloud(wordCount, {
size = group => group.length, // Given a grouping of words, returns the size factor for that word
word = d => d, // Given an item of the data array, returns the word
marginTop = 0, // top margin, in pixels
marginRight = 0, // right margin, in pixels
marginBottom = 0, // bottom margin, in pixels
marginLeft = 0, // left margin, in pixels
width = 640, // outer width, in pixels
height = 400, // outer height, in pixels
maxWords = 250, // maximum number of words to extract from the text
fontFamily = "sans-serif", // font family
fontScale = 15, // base font size
powerLaw = 1.0,
fill = null, // text color, can be a constant or a function of the word
background = null,
padding = 0, // amount of padding between the words (in pixels)
rotate = 0, // a constant or function to rotate the words
invalidation // when this promise resolves, stop the simulation
} = {}) {
const data = wordCount
.slice(0,maxWords)
.filter(([w,s])=>!stopwords.has(w.toString().toLowerCase()))
.map(([w,s])=>({text: w.toString(),size: s,font: "sans-serif"}))

console.log(data);
// TGOC background color is

const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height])
.attr("width", width)
.attr("font-family", fontFamily)
.attr("text-anchor", "middle")
.attr("style", "max-width: 100%; height: auto; height: intrinsic;");

svg.append("rect")
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", background);

const g = svg.append("g").attr("transform", `translate(${marginLeft},${marginTop})`);

const areaAvailable = (width - marginLeft - marginRight)*(height - marginTop - marginBottom);

const maxCount = Math.max(... data.map(d=>d.size))

function pixelSize(s) {
return Math.pow(s/maxCount,powerLaw)*fontScale
}

const totalArea = data.map(d=>pixelSize(d.size) + 2*padding).map(x=>x*x).reduce((x,y)=>x+y,0)
const k=Math.sqrt(areaAvailable/totalArea)

const cloud = d3Cloud()
.size([width - marginLeft - marginRight, height - marginTop - marginBottom])
.words(data)
.padding(padding)
.rotate(rotate)
.font(fontFamily)
.fontSize(d => k*pixelSize(d.size))
.on("word", ({size, x, y, rotate, text}) => {
g.append("text")
.datum(text)
.attr("font-size", size)
.attr("fill", fill)
.attr("transform", `translate(${x},${y}) rotate(${rotate})`)
.text(text);
});

cloud.start();
invalidation && invalidation.then(() => cloud.stop());
return svg.node();
}
Insert cell
extrastopwords="get"
Insert cell
stopwords = new Set(("i,me,my,myself,we,us,our,ours,ourselves,you,your,yours,yourself,yourselves,he,him,his,himself,she,her,hers,herself,it,its,itself,they,them,their,theirs,themselves,what,which,who,whom,whose,this,that,these,those,am,is,are,was,were,be,been,being,have,has,had,having,do,does,did,doing,will,would,should,can,could,ought,i'm,you're,he's,she's,it's,we're,they're,i've,you've,we've,they've,i'd,you'd,he'd,she'd,we'd,they'd,i'll,you'll,he'll,she'll,we'll,they'll,isn't,aren't,wasn't,weren't,hasn't,haven't,hadn't,doesn't,don't,didn't,won't,wouldn't,shan't,shouldn't,can't,cannot,couldn't,mustn't,let's,that's,who's,what's,here's,there's,when's,where's,why's,how's,a,an,the,and,but,if,or,because,as,until,while,of,at,by,for,with,about,against,between,into,through,during,before,after,above,below,to,from,up,upon,down,in,out,on,off,over,under,again,further,then,once,here,there,when,where,why,how,all,any,both,each,few,more,most,other,some,such,no,nor,not,only,own,same,so,than,too,very,say,says,said,shall,"+extrastopwords).split(","))
Insert cell
d3Cloud = require("d3-cloud@1")
Insert cell
import {howto} from "@d3/example-components"
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more