Public
Edited
Dec 5, 2022
4 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
hemisphere = ({ year, month }, config = {}) => {
const { width = 600, height = Math.min(width, 600) } = config;
// const height = Math.min(width, 600);
const context = DOM.context2d(width, height);
const projection = d3.geoOrthographic().fitExtent(
[
[10, 10],
[width - 10, height * 2 - 20]
],
sphere
);
const path = d3.geoPath(projection, context);

function render(country, arc) {
context.clearRect(0, 0, width, height);

context.beginPath(),
context.rect(0, 0, width, height),
(context.fillStyle = "hsl(200, 50%, 44%)"),
context.fill();

context.beginPath(),
path(sphere),
// (context.fillStyle = "#fff"),
(context.fillStyle = "hsl(200, 6%, 96%)"),
context.fill();

context.beginPath(),
path(land),
(context.fillStyle = "#ccc"),
context.fill();
// context.beginPath(),
// path(country),
// (context.fillStyle = "#f00"),
// context.fill();
// context.beginPath(),
// path(borders),
// (context.strokeStyle = "#fff"),
// (context.lineWidth = 0.5),
// context.stroke();

context.beginPath(),
// path(typhoonPath),
// path(typhoonPathOfMonth(month)),
path(getTyphoonsPath(typhoonsOfDate({ year, month }))),
// (context.strokeStyle = "rgba(255,100,100,0.5)"),
(context.strokeStyle = "hsla(0, 100%, 80%, 0.5)"),
(context.lineWidth = 0.75),
context.stroke();

context.beginPath(),
path(sphere),
(context.strokeStyle = "#002"),
(context.lineWidth = 1),
context.stroke();
context.beginPath(), path(arc), context.stroke();

if (year) {
(context.font = `bold ${height * 0.25}px Arial`),
(context.fillStyle = "hsla(200, 50%, 0%, 0.5)"),
(context.textAlign = "left"),
context.fillText(year, 30, height * 0.28);
}
if (month) {
(context.font = `bold ${height * 0.25}px Arial`),
(context.fillStyle = "hsla(200, 50%, 0%, 0.5)"),
(context.textAlign = "right"),
context.fillText(monthLabels.at(month - 1), width - 30, height * 0.28);
}

return context.canvas;
}

projection.rotate([230, 0, 0]);
return render(japan);
}
Insert cell
sphere = ({ type: "Sphere" })
Insert cell
japan = countries.find((d) => d.properties.name === "Japan")
Insert cell
countries = topojson.feature(world, world.objects.countries).features
Insert cell
borders = topojson.mesh(world, world.objects.countries, (a, b) => a !== b)
Insert cell
land = topojson.feature(world, world.objects.land)
Insert cell
world = d3.json("https://cdn.jsdelivr.net/npm/world-atlas@2/countries-50m.json")
Insert cell
Inputs.table(data)
Insert cell
typhoonsOfDate({ year: 2022 })
Insert cell
getTyphoonsPath = (typhoons) => ({
type: "MultiLineString",
coordinates: typhoons.map((d) => d.map((e) => [e.longitude, e.latitude]))
})
Insert cell
typhoonsOfDate = ({ year, month }) => {
return [...typhoons.values()].filter((d) =>
year
? d.at(0).date.getFullYear() === year
: d.at(0).date.getMonth() + 1 === month
);
}
Insert cell
typhoonsOfMonth = (month) => {
return [...typhoons.values()].filter(
(d) => d.at(0).date.getMonth() + 1 === month
);
}
Insert cell
typhoonsOfMonth(9)
Insert cell
typhoonPathOfMonth = (month) => ({
type: "MultiLineString",
coordinates: typhoonsOfMonth(month).map((d) =>
d.map((e) => [e.longitude, e.latitude])
)
})
Insert cell
typhoonPath = ({
type: "MultiLineString",
coordinates: [...typhoons.values()].map((d) =>
d.map((e) => [e.longitude, e.latitude])
)
})
Insert cell
[...typhoons.values()].map((d) => d.map((e) => 0))
Insert cell
Insert cell
Insert cell
typhoonsRollup = d3
.rollups(
[...typhoons],
(v) => v.length,
([number, d]) => d.at(0).date.getMonth() + 1,
([number, d]) => d.at(0).date.getFullYear()
)
.map(([month, d]) => d.map(([year, count]) => ({ year, month, count })))
.flat()
Insert cell
typhoonsByMonth = d3.group(
[...typhoons],
([number, d]) => d.at(0).date.getMonth() + 1,
([number, d]) => d.at(0).date.getFullYear()
)
Insert cell
_data = getData(uris.at(0))
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
years = d3.range(2022, 2000, -1)
Insert cell
d3.csv(proxy + uris.at(-1))
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