Public
HTTP (deprecated)
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Readme

Big Weather Display

Displays the current day's weather information BIG so you can see it from far away.

Screenshot 2024-06-01 at 13.24.37@2x.png

Currently it's hardcoded for:

  • prospect heights, brooklyn
  • charts of the temp and % change of precipitation

Probably easiest for you to fork it and change it to suit your needs vs making it customizable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/** @jsxImportSource https://esm.sh/react */
import { exponentialBackoffMiddleware } from "https://esm.town/v/stevekrouse/exponentialBackoffMiddleware";
import { fetchJSON } from "https://esm.town/v/stevekrouse/fetchJSON";
import React from "https://esm.sh/react";
import { renderToString } from "https://esm.sh/react-dom/server";
import tailwindURL from "https://esm.town/v/stevekrouse/tailwindURL";
import { weatherGovGrid } from "https://esm.town/v/stevekrouse/weatherGovGrid";
import { DateTime } from "npm:luxon";
// const lat = "40.682632";
// const lon = "-73.974231";
// let { properties: grid } = await weatherGovGrid({
// lat,
// lon,
// });
// const brooklynGridHourly = grid.forecastHourly
const brooklynGridHourly = "https://api.weather.gov/gridpoints/OKX/35,34/forecast/hourly";
async function getHourlyWeather(day: DateTime): Promise<Period[]> {
let { properties: { periods } } = await fetchJSON(brooklynGridHourly);
return periods.filter((x) =>
DateTime.fromISO(x.startTime) >= day.set({ minute: 0, second: 0, millisecond: 0 })
&& DateTime.fromISO(x.startTime) < day.set({ hour: 24, minute: 0, second: 0, millisecond: 0 })
);
}
function formatTime(time: string) {
const hour = parseInt(time.slice(11, 13));
return hour === 12 ? `12pm` : hour < 12 ? `${hour}am` : `${hour - 12}pm`;
}
// returns an svg chart of temperature by hour
function weatherChart(periods) {
const max = periods.reduce((max, period) => Math.max(max, period.temperature), 0);
const maxIndex = periods.findIndex((x) => x.temperature === max);
const min = periods.reduce((min, period) => Math.min(min, period.temperature), max);
const minIndex = periods.findIndex((x) => x.temperature === min);
const range = (max - min) * 2;
const maxPrecipitation = periods.reduce((max, period) => Math.max(max, period.probabilityOfPrecipitation.value), 0);
const maxPrecipitationIndex = periods.findIndex((x) => x.probabilityOfPrecipitation.value === maxPrecipitation);
const heightOffset = 50;
const widthOffset = 20;
const [width, height] = [300 - widthOffset, 200 - heightOffset];
const trueHeight = height + heightOffset;
const trueWidth = width + widthOffset;
return (
<svg viewBox={`${widthOffset / -2} 0 ${trueWidth} ${trueHeight}`} width="100%">
<polyline
fill="none"
stroke="rgba(255, 104, 2, 1)"
strokeWidth="5"
strokeLinejoin="round"
strokeLinecap="round"
points={periods.map((x, i) =>
`${i * (width / (periods.length - 1))},${height - ((x.temperature - min) * (height / range))}`
)
.join("\n")}
/>
<polyline
fill="none"
stroke="rgba(0, 123, 255, 0.85)"
strokeWidth="4"
strokeLinejoin="round"
strokeLinecap="round"
points={periods.map((x, i) =>
`${i * (width / (periods.length - 1))},${height - x.probabilityOfPrecipitation.value}`
)
.join("\n")}
/>
{/* current temp */}
<text
x={0}
y={height - ((periods[0].temperature - min) * (height / range) + 30)}
textAnchor="start"
dominantBaseline="auto"
fill="rgba(255, 104, 2, 1)"
fontSize="30"
>
{periods[0].temperature}°
</text>
{/* max temp */}
{maxIndex > 1 && (
<text
x={maxIndex * (width / (periods.length - 1))}
y={height - ((max - min) * (height / range) + 10)}
textAnchor="middle"
dominantBaseline="auto"
fill="rgba(255, 104, 2, 1)"
fontSize="30"
>
{max}°
</text>
)}
{/* end temp */}
<text
x={width}
y={maxPrecipitationIndex === periods.length - 1
stevekrouse-bigweather.web.val.run
August 31, 2024