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

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more