From 1104c1162ede6a77d168da5926a1408a443906d7 Mon Sep 17 00:00:00 2001 From: Nathan Bergey Date: Sun, 20 Jan 2019 22:21:45 -0500 Subject: [PATCH] Solar altitude chart --- package.json | 3 ++- src/index.js | 4 ++-- src/render.js | 50 ++++++++++++++++++++++++++++++++++++++++++++++---- src/style.sass | 8 ++++++++ 4 files changed, 58 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 0d8f2ca..a486d8a 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "license": "MIT", "dependencies": { "d3": "^5.7.0", - "d3-fetch": "^1.1.2" + "d3-fetch": "^1.1.2", + "suncalc": "^1.8.0" }, "devDependencies": { "css-loader": "^2.1.0", diff --git a/src/index.js b/src/index.js index 47bee58..e4f9787 100644 --- a/src/index.js +++ b/src/index.js @@ -8,6 +8,6 @@ let canvas = d3.select('svg') const url = '/forcast.xml' d3.xml(url).then(function(xmldoc) { let data = readxml(xmldoc) - render_astronomy(canvas, 100, 25, data) - render_temperature(canvas, 600, 100, data) + render_astronomy(canvas, 80, 25, data) + render_temperature(canvas, 500, 80, data) }) diff --git a/src/render.js b/src/render.js index 541c99c..ff7bdf2 100644 --- a/src/render.js +++ b/src/render.js @@ -1,4 +1,5 @@ var d3 = require('d3') +var SunCalc = require('suncalc') class Chart { @@ -91,19 +92,22 @@ export function render_astronomy(canvas, height, offset, data) { const fullWidth = canvas.node().getBoundingClientRect().width const margins = { 'left': 75, - 'bottom': 10 + 'bottom': 15 } - const yrange = [0, 75] + const yrange = [0, 75 * (Math.PI/180)] const chart = new Chart(canvas, height, fullWidth, margins, offset, data, yrange) chart.draw_yAxisTitle('Altitude') chart.set_yAxisTic( 0, '0°') - chart.set_yAxisTic(45, '45°') - chart.set_yAxisTic(75, '75°') + chart.set_yAxisTic(45 * (Math.PI/180), '45°') + chart.set_yAxisTic(75 * (Math.PI/180), '75°') const year = chart.beginTime.getFullYear() const month = chart.beginTime.getMonth() + let sunData = [] + const lat = 39.9243509 + const lon = -75.1696126 for (var day = chart.beginTime.getDate(); day <= chart.endTime.getDate(); day++) { const noon = new Date(year, month, day, 12, 0, 0) chart.set_xAxisTic(noon, noon.toLocaleDateString('en-US', {weekday: 'long'})) @@ -114,14 +118,52 @@ export function render_astronomy(canvas, height, offset, data) { const midnight = new Date(year, month, day, 0, 0, 0) chart.draw_yGrid(midnight, 'midnight') } + + // Solar Ephemeris + let todaysSun = [] + const sunEphem = SunCalc.getTimes(new Date(year, month, day, 1, 0, 0), lat, lon) + todaysSun.push({ + 'date': sunEphem.sunrise, + 'alt': 0 + }) + for (var hour = 0; hour < 24; hour++) { + const datetime = new Date(year, month, day, hour, 0, 0) + const sun = SunCalc.getPosition(datetime, lat, lon) + + if (sun.altitude > 0) { + todaysSun.push({ + 'date': datetime, + 'alt': sun.altitude + }) + } + } + todaysSun.push({ + 'date': sunEphem.sunset, + 'alt': 0 + }) + sunData.push(todaysSun) } + const line = d3.line() + .x(function(d) { return chart.xRange(d.date) }) + .y(function(d) { return chart.yRange(d.alt) }) + .curve(d3.curveBasis) + + const sunView = canvas.append('g').attr('id', 'sun') + sunView.selectAll('path').data(sunData).enter() + .append("path") + .attr('class', 'sun') + .attr('d', line) + chart.draw_yAxisLine() chart.draw_xAxisLineTop() chart.draw_xAxisLineBottom() } +/** + * Temperature chart + */ export function render_temperature(canvas, height, offset, data) { const fullWidth = canvas.node().getBoundingClientRect().width const margins = { diff --git a/src/style.sass b/src/style.sass index 397c9fa..2d1cd0b 100644 --- a/src/style.sass +++ b/src/style.sass @@ -48,6 +48,14 @@ path.data stroke: #f00 stroke-width: 2px +path.sun + stroke: #ff0 + stroke-width: 1px + +path.moon + stroke: #999 + stroke-width: 1px + line.now stroke: #f5f stroke-width: 1px