Published
Edited
Jan 6, 2022
14 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
zip = FileAttachment("GHS_STAT_UCDB2015MT_GLOBE_R2019A_V1_2.csv.zip").zip() // unzip
Insert cell
csv = zip.file("GHS_STAT_UCDB2015MT_GLOBE_R2019A_V1_2.csv").csv({ typed: true })
Insert cell
db = {
const table = "stat";
const db = await SQLiteDatabaseClient.open(null);
const columns = csv.columns || Object.keys(csv[0]);

// create a table
await db.query(`CREATE TABLE ${table}(${columns})`);

// fill it with our data; thanks, Annie Zhang!
for (const d of csv)
await db.query(
`INSERT INTO ${table} VALUES (${Array.from(
Object.values(d),
JSON.stringify
)});`
);

return db;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Plot.carto({
marks: [
Plot.feature({ type: "Sphere" }),
Plot.points(await db.query("SELECT * FROM stat LIMIT 2000"), {
lonLat: (d) => [d.GCPNT_LON, d.GCPNT_LAT],
fill: (d) => d.E_EC2O_R15 / d.P15
})
],
width,
color: { type: "sqrt", scheme: "reds" },
height: width * 0.5
})
Insert cell
Insert cell
climate = Plot.carto({
rotate: [-10, 0],
marks: [
Plot.feature({ type: "Sphere" }),
Plot.feature(land, { strokeWidth: 0.25 }),
Plot.points(
await db.query(
"SELECT * FROM stat WHERE E_KG_NM_LST<>'NAN' ORDER BY P15 DESC LIMIT 8000"
),
{
lonLat: (d) => [d.GCPNT_LON, d.GCPNT_LAT],
fill: (d) =>
d["E_KG_NM_LST"]
.replace(/Snow.*/, "Snow")
.replace(/,/g, "")
.split(/ /g)
.slice(0, 2)
.join(" "),
stroke: "white",
strokeWidth: 0.4,
title: "UC_NM_MN", // city name
r: "P15"
}
)
],
width,
height: width * 0.5,
color: { scheme: "category10", legend: true },
r: { type: "pow", exponent: 0.333, range: [0, 10] }
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Plot.carto({
projection: "bertin1953",
marks: [
Plot.feature({ type: "Sphere" }),
Plot.feature(land, { strokeWidth: 0.25 }),
Plot.points([].concat(increase, decrease), {
lonLat: (d) => [d.GCPNT_LON, d.GCPNT_LAT],
fill: (d) => d.rate > 1,
stroke: "white",
strokeWidth: 0.4,
title: "UC_NM_MN", // city name
r: "P15",
fillOpacity: 0.5,
sort: "P15"
})
],
color: { scheme: "rdbu" },
width,
height: width * 0.65
})
Insert cell
Insert cell
Insert cell
Insert cell
// Plot.carto is an experimental plugin for Observable Plot
import { Plot, land } from "@fil/plot-carto-0-4"
Insert cell
query = (value) => qq(db, { value, width })
Insert cell
// qq = quick query
qq = (db, { describe = false, prompt = "db>", ...options } = {}) => {
const t = Inputs.text({ label: prompt, ...options });
d3.select(t).style("margin-bottom", "7px");
const d = d3.create("div");
const desc = d3.create("div");
const err = d3
.create("div")
.style("font-family", "sans-serif")
.style("font-size", "10px")
.style("color", "brown");
if (describe)
db.describe()
.then((description) => {
err.html("");
desc.html("").append(() => description);
})
.catch((e) => err.html(e));

if (options.value != null) run_query(options.value);

t.addEventListener("input", async () => {
if (t.value === "") err.html("");
else run_query(t.value);
});
const a = html`<div>${t}${d.node()}${err.node()}${desc.node()}</div>`;
return a;

function run_query(q) {
db.query(q)
.then((data) => {
err.html("");
d.html("").append(() => Inputs.table(data));
a.value = data;
a.dispatchEvent(new CustomEvent("input"));
})
.catch((e) => err.html(e));
}
}
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