Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save russelllim22/2cfe2520003da7c5a26e40d35f62b6aa to your computer and use it in GitHub Desktop.
Save russelllim22/2cfe2520003da7c5a26e40d35f62b6aa to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<svg id="chartSVG" viewBox="0,0,1600,3200" width="1600"
style=" max-width: 100%;
font-family: Nunito, sans-serif;
border: 1px solid black;
background: radial-gradient(ellipse at bottom right, rgba(137,207,240,1) 20%, rgba(244,194,194,1) 70%);">
<image width="1600px" height="3200px" style="opacity:0.2;" href="babies-pixabay.png">
</image>
</svg>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;700&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Asap+Condensed:wght@400;500&display=swap" rel="stylesheet">
<script src="https://d3js.org/d3.v7.min.js"></script>
<script src="https://rawgit.com/jasondavies/d3-cloud/master/build/d3.layout.cloud.js"></script>
<script src="nameData2020.js"></script>
<script>
const cat10 = ["#1f77b4","#ff7f0e","#2ca02c","#d62728","#9467bd","#8c564b","#e377c2","#7f7f7f","#bcbd22","#17becf"];
const nameData = d3.csvParse("word,gender,count\n" + textFile).map(d => ({
text: d.word,
size: +d.count
})).sort((a,b) => d3.descending(a.size,b.size))
const letters = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
const letterNames = {"other": []};
const letterCounts = [];
letters.forEach((letter)=>{
letterNames[letter] = [];
letterCounts.push({"letter": letter, "count": 0})
})
nameData.forEach((d)=>{
const letter = d.text.slice(0,1);
letterNames[letter].push(d);
letterCounts.find(d => d.letter === letter).count += d.size;
})
letterCounts.sort((a,b)=> d3.ascending(a.count, b.count))
const totalBabies = letterCounts.reduce((a, b) => a + b.count, 0);
const smallCounts = {letter: "other", count: 0, otherLetters: ""}
for(let i = 25; i>=0; i--){
if(letterCounts[i].count < 0.015*totalBabies){
smallCounts.otherLetters += `${letterCounts[i].letter},`;
smallCounts.count += letterCounts[i].count;
letterNames["other"] = letterNames["other"].concat(letterNames[letterCounts[i].letter])
letterCounts.splice(i,1)
}
}
letterCounts.sort((a,b)=> d3.descending(a.count, b.count))
letterCounts.push(smallCounts);
const chartSVG = d3.select("#chartSVG")
const yScale = d3.scaleBand()
.domain(letterCounts.map(d => d.letter))
.range([0, 3200])
.paddingInner(0.1)
.paddingOuter(0.1);
const xScale = d3.scaleLinear([0,450000],[0,1600 - 150])
chartSVG.selectAll(".bar")
.data(letterCounts)
.join("rect")
.classed("bar",true)
.attr("fill", "white")
.attr("stroke","black")
.attr("x", 0)
.attr("y", d => yScale(d.letter))
.attr("height", yScale.bandwidth())
.attr("width", d => xScale(d.count));
chartSVG.selectAll(".label")
.data(letterCounts)
.join("text")
.classed("label",true)
.text(d => `${d.letter}: ${Math.round(100*d.count/totalBabies)}%` + (d.letter === "other" ? ` (${d.otherLetters.slice(0,-1)})`: ""))
.style("font-size",35)
.style("font-weight", 700)
.attr("fill", "black")
.attr("stroke","none")
.attr("x", d => xScale(d.count) + 10)
.attr("y", d => yScale(d.letter) + yScale.bandwidth() / 2 + 5);
function makeCloud(letter, width) {
let words = [...letterNames[letter]].filter(d=>d.size>99);
let height = yScale.bandwidth();
var layout = d3.layout.cloud()
.size([width + 10, height])
.words(words)
.padding(2)
.rotate(d => d.rotate | 0)
.fontSize(d => 0.5*Math.sqrt(d.size))
.on("end", draw);
layout.start();
function draw(words) {
chartSVG.append("g")
.attr("width", width)
.attr("height", height)
.attr("transform", d=> `translate(${width/2},${yScale(letter) + height/2})`)
.style("text-anchor", "middle")
.selectAll("text")
.data(words)
.enter()
.append("text")
.style("font-size", d => `${d.size}px`)
.attr("transform", d => `translate(${[d.x, d.y]})rotate(${d.rotate})`)
.attr("fill", (d,i) => cat10[Math.floor(Math.random()*10)])
.text(d => d.text);
}
}
for(let i=0; i<letterCounts.length; i++){
setTimeout(()=>{
makeCloud(letterCounts[i].letter, xScale(letterCounts[i].count))
},500*i)
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment