Public
Edited
Mar 18, 2024
2 forks
Importers
Insert cell
Insert cell
Insert cell
Insert cell
{
const numbers = [4, 11, 15, 18, 4, 5]
numbers.sort((a, b) => b - a) // Descending order
// numbers.sort((a, b) => a - b) // Ascending order
return numbers
}
Insert cell
Insert cell
{
const numbers = [4, 11, 15, 18, 4, 5]
const sliceNumbers = numbers.slice(0,3)
return sliceNumbers
}
Insert cell
Insert cell
{
const numbers = [4, 11, 15, 18, 4, 5]

let squaredNumbers = [] // Initialize an empty array to store the squared numbers
for (let i = 0; i < numbers.length; i++) {
squaredNumbers.push(numbers[i] * numbers[i]) // Square each number and add it to the squaredNumbers array
}

return squaredNumbers
}
Insert cell
Insert cell
{
function squareNumbers(numbers) {
let squaredNumbers = []
for (let i = 0; i < numbers.length; i++) {
squaredNumbers.push(numbers[i] * numbers[i]); // Square each number and add it to the squaredNumbers array
}

return squaredNumbers
}

const numbers = [4, 11, 15, 18, 4, 5]
const result = squareNumbers(numbers)
return result
}
Insert cell
Insert cell
{
let squareNumbers = function(numbers) {
let squaredNumbers = [] // Initialize an empty array to store the squared numbers
for (let i = 0; i < numbers.length; i++) {
squaredNumbers.push(numbers[i] * numbers[i]) // Square each number and add it to the squaredNumbers array
}
return squaredNumbers // Return the array of squared numbers
}

const numbers = [4, 11, 15, 18, 4, 5]
const result = squareNumbers(numbers)
return result
}
Insert cell
Insert cell
{
const numbers = [4, 11, 15, 18, 4, 5]
const squaredNumbers = numbers.map(number => number * number) // Each item in the array will be passed to the function one by one.
return squaredNumbers
}
Insert cell
Insert cell
{
const numbers = [4, 11, 15, 18, 4, 5]
const firstGreaterThanTen = numbers.find(number => number > 10);
return firstGreaterThanTen
}
Insert cell
Insert cell
{
const numbers = [4, 11, 15, 18, 4, 5]

// Without the spread operator, this wouldn't work directly. Normally, Math.min and Math.max functions don't accept an array as an argument
const minNumber = Math.min(numbers) // This would return NaN
// Using the spread operator
// const minNumber = Math.min(...numbers) // Expands the array into individual numbers
return minNumber
}
Insert cell
Insert cell
{
const age = 20
let isAdult = age >= 18 ? 'is Adult' : 'not Adult'
return isAdult
}
Insert cell
Insert cell
HDR21-22.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
data = hdr2122
Insert cell
Insert cell
Insert cell
world = FileAttachment("countries-110m.json").json()
Insert cell
land = topojson.feature(world, world.objects.land)
Insert cell
Insert cell
//a JSON file containing country codes with their corresponding latitudes and longitudes
countryCodesObject = FileAttachment("country-codes-lat-long-alpha3.json").json()
Insert cell
countryCodes = countryCodesObject.ref_country_codes
Insert cell
dataWithLatLong = data.map(item => {
// Find matching country info from `countryCodes` by ISO3 code
const countryInfo = countryCodes.find(country => country.alpha3 === item.iso3)//countryInfo is an object from countryCodes
// Return new object merging original item with latitude and longitude if found
return {
...item,
latitude: countryInfo ? countryInfo.latitude : null,
longitude: countryInfo ? countryInfo.longitude : null,
}
})
// Filter out items where latitude or longitude is null (i.e., country not found)
.filter(item => item.latitude !== null && item.longitude !== null)

Insert cell
Plot.plot({
projection: "equirectangular",
marks: [
Plot.geo(land, {
fill: "currentColor", // inherit the color property of its parent element.
fillOpacity: 0.2
}),
Plot.sphere(),
Plot.dot(dataWithLatLong, {
filter: (d) => d.year == yearMap,
x: "longitude",
y: "latitude",
r: "HDI",
fillOpacity: 0.5,
stroke: "region",
title: d => `Country: ${d.country}, HDI: ${d.HDI}` ,//Customize tip
tip:true
})
],
title:`Human Development Index (value) distribution in ${yearMap}`,
r: {
type: "log",
range: [0, 10] // Adjust this range based on your data to make the difference more clearly visible
},
width: 800,
height: 400,
color: {
legend: true
}
});
Insert cell
minYear = Math.min(...data.map(d => d.year));
Insert cell
maxYear = Math.max(...data.map(d => d.year));
Insert cell
viewof yearMap = Inputs.range([minYear, maxYear], {label: "Year", step: 1})
Insert cell
viewof longitude = Inputs.range([0, 180], {value: 5, step: 1, label: "longitude (degree)"})
Insert cell
Plot.plot({
projection: {type: "orthographic", rotate: [-longitude, -30]},
r: {
type: "linear",
range: [0, 7]
},
title:`Human Development Index (value) distribution in ${yearMap}`,
margin: 20,
marks: [
Plot.geo(land, {fill: "currentColor", fillOpacity: 0.2}),
Plot.sphere(),
Plot.dot(dataWithLatLong, {
filter: (d) => d.year == yearMap,
x: "longitude",
y: "latitude",
r: "HDI",
fillOpacity: 0.5,
stroke: "region",
fill: "region",
tip:true
})
]
})
Insert cell
Insert cell
// viewof yearBubble = Inputs.range([1990, 2021], {label: "Year", step: 1})
Insert cell
//Animation: https://observablehq.com/@mbostock/scrubber
import {Scrubber} from "@mbostock/scrubber"
Insert cell
yearsAll = data.map(d => d.year)
Insert cell
uniqueYearSet = new Set(yearsAll)
Insert cell
yearWithoutDuplicate = Array.from(uniqueYearSet)
Insert cell
viewof yearBubble = Scrubber(yearWithoutDuplicate, {loop: false})
// viewof yearBubble = Scrubber(d3.sort(d3.union(data.map((d) => d.year))), {loop: false, delay: 1000 / 24})
Insert cell
viewof bubbleRadius = Inputs.select(["HDI",
"Gender Development Index (value)",
"Gender Inequality Index (value)",
"HDI female",
"HDI male"
], {value: "HDI", label: "Index to explore (bubble size)"})
Insert cell
viewof xAxisBubble = Inputs.select(["Gross National Income Per Capita (2017 PPP$)",
"Gross National Income Per Capita, female (2017 PPP$)",
"Gross National Income Per Capita, male (2017 PPP$)",
], {value: "Gross National Income Per Capita (2017 PPP$)", label: "X-axis"})
Insert cell
viewof yAxisBubble = Inputs.select(["Life Expectancy at Birth (years)",
"Mean Years of Schooling (years)",
"Adolescent Birth Rate (births per 1,000 women ages 15-19)",
], {value: "Life Expectancy at Birth (years)", label: "Y-axis"})
Insert cell
viewof scaleTypeBubble = Inputs.radio(["log", "linear"], {value:"log", label: "Scale Type for Bubble Chart"})
Insert cell
Plot.plot({
marks: [
Plot.dot(data, {
filter: (d) => d.year == yearBubble,
x: xAxisBubble,
y: yAxisBubble,
r: bubbleRadius,
stroke: "region",
tip:true,
}),
Plot.crosshair(data, {x: xAxisBubble, y: yAxisBubble})
],
x: {
type: scaleTypeBubble, // "log"
// domain: [200, 100e3],
label: xAxisBubble}, //"Gross National Income Per Capita (2017 PPP$)"
y: {
// domain: [15, 85],
ticks: 8,
label: yAxisBubble}, // "Life Expectancy at Birth (years)"
color: {
legend: true
},
r: {
range: [0, 10], // Adjust the radius scale so dots are sized between 0 and 50 pixels for visibility
label: bubbleRadius, // "HDI"
},
width: 1152,
height: 600,
grid: true,
});

Insert cell
Insert cell
topTen2021 = data
.filter(d => d.year === 2021)
.sort((a, b) => b.HDI - a.HDI)
.slice(0, 10)
.map(d => d.country)
Insert cell
topTenBump = data.filter(d => topTen2021.includes(d.country)) //.includes(d.country) checks whether d.country (the country property of the current element d) is present in the topTen2021 array.
Insert cell
viewof yearRangeStart = Inputs.range([1990, 2010], {value: 1990, step: 1, label: "yearRangeStart"})
Insert cell
viewof yearRangeEnd = Inputs.range([yearRangeStart, 2021], {value: yearRangeStart + 10, step: 1, label: "yearRangeEnd "});
Insert cell
yearRange = [yearRangeStart, yearRangeEnd]
Insert cell
topTenBumpInRange = topTenBump.filter(d => d.year >= yearRange[0] && d.year <= yearRange[1])
Insert cell
// topTenBumpInRange
Insert cell
Plot.plot({
width:1200,
marginTop: 20,
marginBottom: 35,
marginLeft: 175,
marginRight: 175,
x: {
domain: yearRange,
label: null,
tickFormat: d => d.toString(),
},
y: {
axis: null,
},
marks: [
// Adding dots to highlight specific data points.
Plot.dot(topTenBumpInRange, Plot.stackY2({
x: "year",
z: "country",
order: "HDI",
reverse: true,
fill: "country",
r: 3 // Radius of dots.
})),
// Plotting HDI trends per country with a line mark.
Plot.line(topTenBumpInRange, Plot.stackY2({
x: "year",
z: "country",
order: "HDI",
reverse: true,
stroke: "country",
curve: "bump-x",
fill: null
})),
// Displaying HDI values at data points.
Plot.text(topTenBumpInRange, Plot.stackY2({
x: "year",
z: "country",
order: "HDI",
reverse: true,
fill: "country",
dy: -9, // Adjust vertical position of text.
text: "HDI"
})),
// Labeling the first data point with the country name for each line.
Plot.text(topTenBumpInRange, Plot.selectFirst(Plot.stackY2({
x: "year",
z: "country",
order: "HDI",
reverse: true,
text: "country",
dx: -8, // Adjust horizontal position of text.
textAnchor: "end",
fill: "currentColor"
}))),
// Labeling the last data point with the country name for each line.
Plot.text(topTenBumpInRange, Plot.selectLast(Plot.stackY2({
x: "year",
z: "country",
order: "HDI",
reverse: true,
text: "country",
dx: 18, // Adjust horizontal position of text.
textAnchor: "start",
fill: "currentColor"
})))
]
});


Insert cell
// import {Scrubber} from "@mbostock/scrubber"
Insert cell
// countryNames = ["Afghanistan", "Benin", "Cyprus", "Mali", "Pakistan", "Yemen"]
Insert cell
// filteredCountryData = data.filter(d => countryNames.includes(d.country));
// filteredCountryData = data
Insert cell
// columnNames = ["HDI", "HDI female", "HDI male", "Gender Inequality Index (value)", "Gender Development Index (value)"];
Insert cell
// {
// // Assuming filteredData is already defined and filtered for the year 2022 or whichever year you're interested in
// const columnMarks = [];

// // Generate dot and text marks for each column
// columnNames.forEach((columnName) => {
// // Dot marks for bubbles
// columnMarks.push(Plot.dot(filteredCountryData, {
// filter: (d) => d.year == 2018,
// x: d => columnName, // Assigning each dot to its column based on the columnName
// y: "country",
// r: d => d[columnName] * 15, // Adjust the multiplier as needed to suit your data scale
// fill: d => d[columnName], // This can be adjusted or removed based on your color needs
// title: d => `${d.country}: ${d[columnName]}`, // Optional: adds a tooltip showing the value,
// }));
// // Text marks for labels - adjust or remove this part if not needed
// columnMarks.push(Plot.text(filteredCountryData, {
// x: d => columnName,
// y: "country",
// text: null,
// dy: -20, // Adjust text position
// fill: "black"
// }));
// });

// const plot = Plot.plot({
// marginTop: 80,
// marginLeft: 120,
// color: {
// scheme: "RdYlGn",
// domain: [0, 1] // Assuming your data values range from 0 to 1, adjust as needed
// },
// x: {
// domain: columnNames,
// axis: "top",
// label: null,
// tickSize: 0,
// tickRotate: -35
// },
// y: {
// label: null,
// tickSize: 0
// },
// marks: [
// ...columnMarks // Spread the previously prepared marks here
// ],
// width: 700,
// height: 3500
// });

// return plot
// }
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