Mercurial > personal > weather-server
diff weather_server/static/script.js @ 13:4eaa9d69c4e2
Extremely basic version of the graph drawer.
| author | Paul Fisher <paul@pfish.zone> |
|---|---|
| date | Sun, 06 Oct 2019 17:09:23 -0400 |
| parents | 9e6289598d8c |
| children |
line wrap: on
line diff
--- a/weather_server/static/script.js Sun Oct 06 15:21:03 2019 -0400 +++ b/weather_server/static/script.js Sun Oct 06 17:09:23 2019 -0400 @@ -35,8 +35,73 @@ return MAGNUS_C * gamma / (MAGNUS_B - gamma); } +const HISTORY_SECONDS = 86400; + +/** + * Sets up everything. + * @param {HTMLElement} tempElement The element where temperature data is. + * @param {HTMLElement} dewPointElement The element where the dew point is. + */ +async function setUp(tempElement, dewPointElement) { + const nowTS = new Date().getTime() / 1000; + const startTS = nowTS - HISTORY_SECONDS; + const query = new URL(location.href); + query.pathname = query.pathname + '/recent'; + query.search = ''; + query.searchParams.set('seconds', String(HISTORY_SECONDS)); + const results = await fetch(query.href); + if (!results.ok) return; + const data = await results.json(); + if (data.length === 0) return; + + const tempsF = data.map(s => [s.sample_time, cToF(s.temp_c)]); + const dewPointsF = data.map( + s => [s.sample_time, cToF(dewPointC(s.temp_c, s.rh_pct))]); + setUpElement(tempElement, [startTS, nowTS], tempsF); + setUpElement(dewPointElement, [startTS, nowTS], dewPointsF); +} + +/** + * Sets up charting for this element. + * @param {HTMLElement} element The element to put a graph in. + * @param {[number, number]} timeRange The `[start, end]` of the time range. + * @param {[number, number][]} data The data to chart. + */ +function setUpElement(element, timeRange, data) { + element.insertBefore(document.createElement('canvas'), element.firstChild); + element.classList.remove('plain'); + element.classList.add('fancy'); + const doDraw = () => redrawCanvas(element, data, timeRange); + doDraw(); + addEventListener('resize', doDraw); +} + +/** + * + * @param {HTMLElement} element The parent element to put the `<canvas>` in. + * @param {[number, number][]} data The data to chart. + * @param {[number, number]} xRange The `[start, end]` of the X range to plot. + */ +function redrawCanvas(element, data, xRange) { + let canvas = element.getElementsByTagName('canvas')[0]; + if (!canvas) { + canvas = document.createElement('canvas'); + element.insertBefore(canvas, element.firstChild); + } + const dpr = window.devicePixelRatio || 1; + const cssSize = element.getBoundingClientRect(); + const pxSize = [cssSize.width * dpr, cssSize.height * dpr]; + canvas.width = pxSize[0]; + canvas.height = pxSize[1]; + const ctx = canvas.getContext('2d'); + ctx.clearRect(0, 0, pxSize[0], pxSize[1]); + const computed = getComputedStyle(element); + ctx.strokeStyle = computed.color; + drawChart(ctx, data, xRange, pxSize); +} + /** The height of the chart in degrees. */ -const CHART_HEIGHT = 15; +const CHART_RANGE_DEGREES = 15; /** * Charts some data. @@ -76,14 +141,14 @@ // of the chart. // If the middle of the range is already close enough, just use that. - if (CHART_HEIGHT / 4 <= Math.abs(yMid - lastY)) { - return [yMid - CHART_HEIGHT / 2, yMid + CHART_HEIGHT / 2]; + if (CHART_RANGE_DEGREES / 4 <= Math.abs(yMid - lastY)) { + return [yMid - CHART_RANGE_DEGREES / 2, yMid + CHART_RANGE_DEGREES / 2]; } // Otherwise, clamp the chart range. if (lastY < yMid) { - return [lastY - CHART_HEIGHT / 4, lastY + 3 * CHART_HEIGHT / 4]; + return [lastY - CHART_RANGE_DEGREES / 4, lastY + 3 * CHART_RANGE_DEGREES / 4]; } - return [lastY - 3 * CHART_HEIGHT / 4, lastY + CHART_HEIGHT / 4]; + return [lastY - 3 * CHART_RANGE_DEGREES / 4, lastY + CHART_RANGE_DEGREES / 4]; } /**
