Skip to content

Instantly share code, notes, and snippets.

// Adapted from https://observablehq.com/@pixnwave/word-cloud-with-counts
function makeCloud(letter, width) {
const words = [...letterNames[letter]].filter(d=>d.size>99); // only render names with at least 100 babies
const height = yScale.bandwidth();
const cat10 = ["#1f77b4","#ff7f0e","#2ca02c","#d62728","#9467bd","#8c564b","#e377c2","#7f7f7f","#bcbd22","#17becf"];
var layout = d3.layout.cloud()
.size([width + 10, height])
.words(words)
const chartSVG = d3.select("#chartSVG")
const yScale = d3.scaleBand()
.domain(letterCounts.map(d => d.letter))
.range([0, 3200]) // my chart is 3200px high
.paddingInner(0.1)
.paddingOuter(0.1);
const xScale = d3.scaleLinear()
.domain([0,450000]) // the most popular letter (A) has about 450000 babies
const textFile = `Olivia,F,17535
Emma,F,15581
Ava,F,13084
Charlotte,F,13003
Sophia,F,12976
Amelia,F,12704
Isabella,F,12066
Mia,F,11157
...`
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)=>{
<!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>
{#if currentScore === 20}
<svg class="icon-thumbs-up" in:fade="{{delay: 100, duration: 400}}" width="30px" fill="goldenrod" x=-120 y="calc(-50% - 20px)" viewBox="0 0 1000 1000"><use href="#thumbs-up-path"></use></svg>
{#each starArray as star,i}
<g class="star {(i % 3 === 0) ? "twinkle" : "" }" in:fade="{{delay: 100*i, duration: 200}}" style="transform-origin: {-star.x + 80}px {star.y - 30}px;">
<line x1={-star.x +80} y1={star.y - 30 + 2 + (i % 20) /20 *3} x2={-star.x +80} y2={star.y - 30 - 2 - (i % 20) /20 *3} stroke-width=1></line>
<line x1={-star.x + 80 + 2 + (i % 20) /20 *3} y1={star.y - 30} x2={-star.x + 80 - 2 - (i % 20) /20 *3} y2={star.y - 30} stroke-width=1 ></line>
<circle r="{(i % 20) /20 *2 + 1}" cx={-star.x + 80} cy={star.y - 30}></circle>
</g>
{/each}
<script>
import { fade } from 'svelte/transition';
import { tweened } from 'svelte/motion';
import { cubicOut } from 'svelte/easing';
export let currentScore;
const progress = tweened(0, {
duration: 400,
easing: cubicOut
});
<script>
import { fade, fly } from 'svelte/transition';
export let currentQuestion;
</script>
{#if currentQuestion.length > 0}
<p id="question"
in:fly="{{ x: -0.3*window.innerWidth, y: 0.3*window.innerHeight, duration: 500,}}"
out:fly="{{x:0.3*window.innerWidth, y: 0.3*window.innerHeight, duration: 500, delay: 500 }}">
{#if currentQuestion[1].includes("pi") && currentQuestion[2]}
<line id="cosArrow"
x1="110"
y1="115"
x2="{$lengthTween * Math.cos(currentAngle * Math.PI / 180) * 100 + 110}"
y2="115" stroke="goldenrod"
style="opacity: {(showLength === "cos") ? 1 : 0}"
stroke-width="3"
marker-end="{[-270,-90,90,270,450].includes(parseInt(currentAngle)) ? "url(#gold-point)" : "url(#gold-arrow)"}"
/>
<script>
import { tweened } from 'svelte/motion';
import { cubicOut } from 'svelte/easing';
export let currentAngle, showAngle, showLength;
const lengthTween = tweened(0, {
duration: 400,
easing: cubicOut
});