Public
Edited
Feb 4, 2023
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
x = 100
Insert cell
// print the variable you created in the previoxus cell by typing its name here and running the cell
x
Insert cell
Insert cell
{
// declare and initialize one or more variables here (e.g. let y = 10, const str = "Hello, World!")
let y = 100
}
Insert cell
// what happens if you try to print a variable you created in the block above?
y
Insert cell
Insert cell
{
// create an array that contains more than one string (e.g. let strArr = ["Jan", "Feb", "Mar", "Apr", "May"])
// print the element in the middle of the array (e.g. return strArr[2])
let strArr = ["Jan", "Feb", "Mar", "Apr", "May"]
return strArr[2]
}
Insert cell
Insert cell
// your code here
pet = ({
name: "Sawyer",
age: 10,
type: "Dog",
breed: "Golden Retriever"
})
Insert cell
Insert cell
function generateRandomNumber(){
return Math.floor(Math.random() * 100); // Math.random() returns a float between 0 and 1
}
Insert cell
Insert cell
function generateNameNumberPairs (names) {
// add code here: initialize an empty array
let data = [];
names.forEach(function (name) {
// add code here: get a random number, store the name and the number in an object,
// and push object into array
data.push({name:name, number: generateRandomNumber()});
});
/****
"Array.forEach" is an iterative method for iterating through the elements of an array
Alternatively, you can use a for loop to iterate through the array
for (let i = 0; i < names.length; i++) {
data.push({name: names[i], number: generateRandomNumber()});
}
****/
return data;
}
Insert cell
// call the above function with a list of names
generateNameNumberPairs(["Kelly", "Jim", "John", "Sam", "Mike"]);
Insert cell
Insert cell
Insert cell
Insert cell
<svg width="70" height="70" style="border: 1px solid black">
<rect x="10" y="10" width="50" height="50" fill="green" />
</svg>
Insert cell
Insert cell
<svg width="70" height="70" style="border: 1px solid black">
<circle cx="35" cy="35" r="25" fill="green" stroke="blue"/>
</svg>
Insert cell
Insert cell
<svg width="70" height="70" style="border: 1px solid black">
<line x1="0" y1="0" x2="70" y2="70" stroke="black" stroke-width="2"/>
</svg>
Insert cell
Insert cell
<svg width="160" height="28" style="border: 1px solid black">
<text x="80" y="20" text-anchor="middle" fill="red">Hello, World!</text>
</svg>
Insert cell
Insert cell
<svg width="160" height="160" style="border: 1px solid black">
<g style="transform: translate(30px, 30px);">
<rect x="0" y="0" width="100" height="100" fill="orange" />
<circle cx="25" cy="25" r="20" fill="crimson" />
<circle cx="75" cy="25" r="20" fill="crimson" />
<circle cx="25" cy="75" r="20" fill="crimson" />
<circle cx="75" cy="75" r="20" fill="crimson" />
</g>
</svg>
Insert cell
Insert cell
// import D3, version 7
d3 = require('d3@7')
Insert cell
Insert cell
<div id="rainbowCirclesContainer">
<div id="rainbowCirclesText" style="font-family: Lato, sans-serif">Here's a line of circles</div>
<svg id="rainbowCirclesSvg" width="230" height="30" style="border: 1px solid black">
<circle id="red" class="rainbowCircles" cx="25" cy="15" r="10" fill="red" />
<circle id="orange" class="rainbowCircles" cx="50" cy="15" r="10" fill="orange" />
<circle id="yellow" class="rainbowCircles" cx="75" cy="15" r="10" fill="gold" />
<circle id="green" class="rainbowCircles" cx="100" cy="15" r="10" fill="green" />
<circle id="blue" class="rainbowCircles" cx="125" cy="15" r="10" fill="blue" />
<circle id="indigo" class="rainbowCircles" cx="150" cy="15" r="10" fill="indigo" />
<circle id="violet" class="rainbowCircles" cx="175" cy="15" r="10" fill="violet" />
</svg>
</div>
Insert cell
Insert cell
{
let violetCircle = d3.select("#violet");
violetCircle.attr("fill", "purple");
let circles = d3.selectAll(".rainbowCircles"); // what happens if we instead selected using "circle"?
circles.attr("r", 5);
let svg = d3.select("#rainbowCirclesSvg");
svg.style("border", "none");

let str = d3.select("#rainbowCirclesText"); // try printing the text first by returning it in the block
str.text(str.text()+ " in rainbow colors");
}
Insert cell
Insert cell
d3.select("#rainbowCirclesSvg")
.append("circle")
.attr("cx",200)
.attr("cy",15)
.attr("class","rainbowCircles")
.attr("fill","black")
.attr("r",5)
Insert cell
Insert cell
dataset = d3.json("https://raw.githubusercontent.com/vega/vega-datasets/next/data/gapminder.json");
Insert cell
Insert cell
Insert cell
Insert cell
list = {
const ol = d3.create('ol');
ol.selectAll('li') // selects all 'li' elements (which may or may not exist!)
.data(topTenList) // provides the backing data
.join('li') // joins data with the selection, creating 'li' elements as needed
.text(d => `${d.country}: ${d.pop}`) // add formatted text to 'li' elements
return ol.node(); // return the DOM element node of the 'ol' elemenet
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
totalPopData = d3.rollups(dataset, groupedEntries => d3.sum(groupedEntries, d => d.pop), d => d.year);
/* Arrow functions are used here to make the code more concise
The arrow function {d => d.year} is equivalent to writing the following
function (d) {
return d.year;
}
*/
Insert cell
// this step is not necessary, but makes the data more readable
totalPopDataEntries = totalPopData.map(([year, pop]) => {
return {year: year, pop: pop}
});
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
margin = ({top: 40, right: 20, bottom: 40, left: 100}) // save room for axis labels
Insert cell
svgWidth = 400
Insert cell
svgHeight = 300
Insert cell
width = svgWidth - margin.left - margin.right
Insert cell
height = svgHeight - margin.top - margin.bottom
Insert cell
Insert cell
xScale = d3.scaleBand()
.domain(totalPopDataEntries.map(d => d.year))
.range([0, width])
.padding(0.1); // 0.1 means 10% of the entire band width
Insert cell
Insert cell
xScale(1965) // change this to a different value
Insert cell
Insert cell
yScale = d3.scaleLinear()
.domain([0, d3.max(totalPopDataEntries, d => d.pop)]) // d3.max returns the maximum population value here
.range([height, 0]); // why do we have 0 mapped to height and max population mapped to 0?
Insert cell
Insert cell
yScale(78)
Insert cell
Insert cell
Insert cell
{
// give this svg an id so we can select it outside this cell
const barChart = d3.select(html`<svg id="total-population-bar-chart"></svg>`);
barChart.attr("width", svgWidth);
barChart.attr("height", svgHeight);

// add x-axis
barChart.append("g")
.attr('transform', `translate(${margin.left}, ${height + margin.top})`)
.call(d3.axisBottom(xScale));
// add add y-axis
barChart.append("g")
.attr('transform', `translate(${margin.left}, ${margin.top})`)
.call(d3.axisLeft(yScale));

// add chart title
barChart.append("text")
.attr("x", svgWidth / 2)
.attr("y", 20)
.attr("text-anchor", "middle")
.text("Total Population from 1955-2005");
// add x-axis title
barChart.append("text")
.attr("x", (width / 2)+margin.left)
.attr("y", svgHeight - 5)
.attr("text-anchor", "middle")
.attr("font-size", "14px")
.text("Year");
// add y-axis title, remember that all transformations are around the (0, 0) origin
barChart.append("text")
.attr("x", -(margin.top + height / 2))
.attr("y", 15)
.attr("transform", "rotate(-90)") // rotate it by -90 degrees
.attr("text-anchor", "middle")
.attr("font-size", "14px")
.text("Population");
return barChart.node();
}
Insert cell
Insert cell
{
const barChart = d3.select("#total-population-bar-chart");
// you can ignore the following, it's only done to allow redrawing elements in the Observable notebook
if (!barChart.select(".barGroup").empty()) {
barChart.select(".barGroup").remove()
}
const barGroup = barChart.append("g") // create a group to keep the bars
.attr("class", "barGroup")
.attr("transform", `translate(${margin.left}, ${margin.top})`); // shift all bars by the margin offset

// Add rectangles here by binding the totalPopDataEntries array with rect elements
barGroup.selectAll("rect")
.data(totalPopDataEntries)
.join("rect")
.attr("x", d => xScale(d.year))
.attr("y", d => yScale(d.pop))
.attr("width", xScale.bandwidth())
.attr("height", d => height - yScale(d.pop))
.attr("fill","steelblue");
}
Insert cell
Insert cell
Insert cell
function drawBarChart (inputArray, chartTitle) {
const barChart = d3.create("svg");
barChart.attr("width", svgWidth);
barChart.attr("height", svgHeight);
// add the x and y axes and their titles here

// add chart title here using the chartTitle parameter

// draw the rectangles here

barChart.append("g")
.attr('transform', `translate(${margin.left}, ${height + margin.top})`)
.call(d3.axisBottom(xScale));
// add add y-axis
barChart.append("g")
.attr('transform', `translate(${margin.left}, ${margin.top})`)
.call(d3.axisLeft(yScale));

// add chart title
barChart.append("text")
.attr("x", svgWidth / 2)
.attr("y", 20)
.attr("text-anchor", "middle")
.text(chartTitle);
// add x-axis title
barChart.append("text")
.attr("x", (width / 2)+margin.left)
.attr("y", svgHeight - 5)
.attr("text-anchor", "middle")
.attr("font-size", "14px")
.text("Year");
// add y-axis title, remember that all transformations are around the (0, 0) origin
barChart.append("text")
.attr("x", -(margin.top + height / 2))
.attr("y", 15)
.attr("transform", "rotate(-90)") // rotate it by -90 degrees
.attr("text-anchor", "middle")
.attr("font-size", "14px")
.text("Population");

const barGroup = barChart.append("g") // create a group to keep the bars
.attr("class", "barGroup")
.attr("transform", `translate(${margin.left}, ${margin.top})`); // shift all bars by the margin offset

barGroup.selectAll("rect")
.data(inputArray)
.join("rect")
.attr("x", d => xScale(d.year))
.attr("y", d => yScale(d.pop))
.attr("width", xScale.bandwidth())
.attr("height", d => height - yScale(d.pop))
.attr("fill","steelblue");
return barChart.node();
}
Insert cell
Insert cell
drawBarChart(dataset.filter(d => d.country == "United States"), "United States");
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
yScaleAmerica = d3.scaleLinear()
.domain([0, d3.max(americaData, v => d3.max(v.values, d => d.pop))])
.range([height, 0]);
Insert cell
Insert cell
Insert cell
Insert cell
{
const smallMultiple = d3.select(html`<div id="america-small-multiple"></svg>`);

americaData.forEach(countryEntry => {
drawBarChartAmerica(smallMultiple, /* add code here */, /* add code here */);
})
return smallMultiple.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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