comparison 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
comparison
equal deleted inserted replaced
12:9e6289598d8c 13:4eaa9d69c4e2
33 function dewPointC(tempC, rhPct) { 33 function dewPointC(tempC, rhPct) {
34 const gamma = gammaFn(tempC, rhPct); 34 const gamma = gammaFn(tempC, rhPct);
35 return MAGNUS_C * gamma / (MAGNUS_B - gamma); 35 return MAGNUS_C * gamma / (MAGNUS_B - gamma);
36 } 36 }
37 37
38 const HISTORY_SECONDS = 86400;
39
40 /**
41 * Sets up everything.
42 * @param {HTMLElement} tempElement The element where temperature data is.
43 * @param {HTMLElement} dewPointElement The element where the dew point is.
44 */
45 async function setUp(tempElement, dewPointElement) {
46 const nowTS = new Date().getTime() / 1000;
47 const startTS = nowTS - HISTORY_SECONDS;
48 const query = new URL(location.href);
49 query.pathname = query.pathname + '/recent';
50 query.search = '';
51 query.searchParams.set('seconds', String(HISTORY_SECONDS));
52 const results = await fetch(query.href);
53 if (!results.ok) return;
54 const data = await results.json();
55 if (data.length === 0) return;
56
57 const tempsF = data.map(s => [s.sample_time, cToF(s.temp_c)]);
58 const dewPointsF = data.map(
59 s => [s.sample_time, cToF(dewPointC(s.temp_c, s.rh_pct))]);
60 setUpElement(tempElement, [startTS, nowTS], tempsF);
61 setUpElement(dewPointElement, [startTS, nowTS], dewPointsF);
62 }
63
64 /**
65 * Sets up charting for this element.
66 * @param {HTMLElement} element The element to put a graph in.
67 * @param {[number, number]} timeRange The `[start, end]` of the time range.
68 * @param {[number, number][]} data The data to chart.
69 */
70 function setUpElement(element, timeRange, data) {
71 element.insertBefore(document.createElement('canvas'), element.firstChild);
72 element.classList.remove('plain');
73 element.classList.add('fancy');
74 const doDraw = () => redrawCanvas(element, data, timeRange);
75 doDraw();
76 addEventListener('resize', doDraw);
77 }
78
79 /**
80 *
81 * @param {HTMLElement} element The parent element to put the `<canvas>` in.
82 * @param {[number, number][]} data The data to chart.
83 * @param {[number, number]} xRange The `[start, end]` of the X range to plot.
84 */
85 function redrawCanvas(element, data, xRange) {
86 let canvas = element.getElementsByTagName('canvas')[0];
87 if (!canvas) {
88 canvas = document.createElement('canvas');
89 element.insertBefore(canvas, element.firstChild);
90 }
91 const dpr = window.devicePixelRatio || 1;
92 const cssSize = element.getBoundingClientRect();
93 const pxSize = [cssSize.width * dpr, cssSize.height * dpr];
94 canvas.width = pxSize[0];
95 canvas.height = pxSize[1];
96 const ctx = canvas.getContext('2d');
97 ctx.clearRect(0, 0, pxSize[0], pxSize[1]);
98 const computed = getComputedStyle(element);
99 ctx.strokeStyle = computed.color;
100 drawChart(ctx, data, xRange, pxSize);
101 }
102
38 /** The height of the chart in degrees. */ 103 /** The height of the chart in degrees. */
39 const CHART_HEIGHT = 15; 104 const CHART_RANGE_DEGREES = 15;
40 105
41 /** 106 /**
42 * Charts some data. 107 * Charts some data.
43 * 108 *
44 * @param {CanvasRenderingContext2D} ctx The context to draw in. 109 * @param {CanvasRenderingContext2D} ctx The context to draw in.
74 139
75 // We want the last value to be, at most, at the top or bottom 1/4 line 140 // We want the last value to be, at most, at the top or bottom 1/4 line
76 // of the chart. 141 // of the chart.
77 142
78 // If the middle of the range is already close enough, just use that. 143 // If the middle of the range is already close enough, just use that.
79 if (CHART_HEIGHT / 4 <= Math.abs(yMid - lastY)) { 144 if (CHART_RANGE_DEGREES / 4 <= Math.abs(yMid - lastY)) {
80 return [yMid - CHART_HEIGHT / 2, yMid + CHART_HEIGHT / 2]; 145 return [yMid - CHART_RANGE_DEGREES / 2, yMid + CHART_RANGE_DEGREES / 2];
81 } 146 }
82 // Otherwise, clamp the chart range. 147 // Otherwise, clamp the chart range.
83 if (lastY < yMid) { 148 if (lastY < yMid) {
84 return [lastY - CHART_HEIGHT / 4, lastY + 3 * CHART_HEIGHT / 4]; 149 return [lastY - CHART_RANGE_DEGREES / 4, lastY + 3 * CHART_RANGE_DEGREES / 4];
85 } 150 }
86 return [lastY - 3 * CHART_HEIGHT / 4, lastY + CHART_HEIGHT / 4]; 151 return [lastY - 3 * CHART_RANGE_DEGREES / 4, lastY + CHART_RANGE_DEGREES / 4];
87 } 152 }
88 153
89 /** 154 /**
90 * Projects a Cartesian coordinate into Canvas space. 155 * Projects a Cartesian coordinate into Canvas space.
91 * 156 *