Public
Edited
Feb 18
Insert cell
Insert cell
import {vl} from "@vega/vega-lite-api-v5"
Insert cell
import {printTable} from "@uwdata/data-utilities"
Insert cell
jobsData = await FileAttachment("jobs.json").json()
Insert cell
viz1 = {
const chart = vl.markBar()
.width(600)
.height(400)
.data(jobsData)
.transform([{
aggregate: [{
op: "distinct",
field: "job",
as: "unique_jobs"
}],
groupby: ["year"]
}])
.encode(
vl.x().fieldO("year").axis({
title: "Year",
labelAngle: -45
}).sort("ascending"),
vl.y().fieldQ("unique_jobs").axis({
title: "Number of Unique Job Categories",
grid: true
}),
vl.tooltip([
{field: "year", type: "ordinal", title: "Year"},
{field: "unique_jobs", type: "quantitative", title: "Unique Jobs"}
])
)
.title("Evolution of Job Categories in Data (1850-2000)");
return chart.render();
}
Insert cell
viz2 = {
const chart = vl.markBar()
.width(600)
.height(300)
.data(jobsData)
.transform([
{
aggregate: [{
op: "sum",
field: "count",
as: "total_count"
}],
groupby: ["year", "sex"]
}
])
.encode(
vl.x().fieldN("year").axis({
title: "Census Year",
labelAngle: -45
}).sort("ascending"),
vl.y().fieldQ("total_count").stack(true).axis({
title: "Number of Workers",
format: "~s"
}),
vl.color().fieldN("sex").scale({
domain: ["women", "men"],
range: ["#ff7f0e", "#1f77b4"]
})
)
.title("Gender Distribution in Workforce (1850-2000)");

return chart.render();
}
Insert cell
viz3 = {
const chart = vl.markBar()
.width(600)
.height(300)
.data(jobsData)
.transform([
{
filter: "datum.job === 'Apprentice'"
},
{
aggregate: [{
op: "sum",
field: "count",
as: "total"
}],
groupby: ["year", "sex"]
}
])
.encode(
vl.x().fieldN("year").axis({
title: "Census Year",
labelAngle: -45
}).sort("ascending"),
vl.y().fieldQ("total").stack(true).axis({
title: "Number of Apprentices",
format: "~s"
}),
vl.color().fieldN("sex").scale({
domain: ["women", "men"],
range: ["#ff7f0e", "#1f77b4"]
})
)
.title("Apprenticeship Trends by Gender (1850-2000)");

return chart.render();
}
Insert cell
viz4 = {
const totalsByJob = d3.rollup(jobsData,
v => d3.sum(v, d => d.count),
d => d.job
);
const top5Jobs = Array.from(totalsByJob, ([job, total]) => ({job, total}))
.sort((a, b) => b.total - a.total)
.slice(0, 5)
.map(d => d.job);
const chart = vl.markLine()
.width(600)
.height(300)
.data(jobsData)
.transform([
{
filter: `datum.job == '${top5Jobs[0]}' || datum.job == '${top5Jobs[1]}' || datum.job == '${top5Jobs[2]}' || datum.job == '${top5Jobs[3]}' || datum.job == '${top5Jobs[4]}'`
},
{
aggregate: [{
op: "sum",
field: "count",
as: "total"
}],
groupby: ["year", "job"]
}
])
.encode(
vl.x().fieldN("year").axis({
title: "Census Year",
labelAngle: -45
}).sort("ascending"),
vl.y().fieldQ("total").axis({
title: "Number of Workers",
format: "~s"
}),
vl.color().fieldN("job")
)
.title("Trends in Top 5 Most Common Jobs (1850-2000)");

return chart.render();
}
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