From 6491a1f1006f76a7f044a2656f2bd426b49edaf2 Mon Sep 17 00:00:00 2001 From: Goutte Date: Mon, 11 Sep 2017 14:02:16 +0200 Subject: [PATCH] Fix up the bugs listed by Vincent. --- CHANGELOG.md | 1 + config.yml | 12 +++++++++++- web/run.py | 26 +++++++++++++------------- web/static/js/swapp.js | 59 ++++++++++++++++++++++++++++++++++++++++++++++------------- web/static/js/swapp.ls | 44 ++++++++++++++++++++++++++++++++------------ web/view/home.html.jinja2 | 8 ++++---- web/view/layout.html.jinja2 | 2 +- 7 files changed, 108 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0544823..2d5fdad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ - [ ] Cache cleanup - [x] API at /cache/clear - [ ] CRON statement to call it +- [ ] Cache warmup - [x] Download raw data (tarball of CSV) for current time interval and targets - [ ] Download raw data as NetCDF for current everything, via SAMP - [x] Add a warning for users with javascript disabled diff --git a/config.yml b/config.yml index e638633..17c7605 100644 --- a/config.yml +++ b/config.yml @@ -5,7 +5,7 @@ # The HTML metadata in the page header. # Don't put double quotes (") in any of these fields. meta: - title: Space Weather + title: Heliopropa ⋅ Solar System Weather keywords: - science - cdpp @@ -15,6 +15,16 @@ meta: # Will be shown by search engines below the title of the page. description: Space weather predictions around solar celestial bodies. +# The top bar +header: + title: CDPP / Heliopropa + links: + - text: Model + href: "https://onlinelibrary.wiley.com/doi/10.1029/2004JA010959/abstract" + - text: Horizon 2020 + href: "https://ec.europa.eu/programmes/horizon2020/" + + # A list of authors that will appear in the HTML metadata and possibly in the # authorship page as well. The order does not matter, it will be shuffled. diff --git a/web/run.py b/web/run.py index 5bdb7d5..eaa7421 100755 --- a/web/run.py +++ b/web/run.py @@ -283,7 +283,7 @@ def retrieve_amda_netcdf(orbiter, what, started_at, stopped_at): # innermost loop of `get_data_for_target`. # The javascript knows the targets' properties under these names. PROPERTIES = ('time', 'vrad', 'vtan', 'vlen', 'magn', 'temp', 'pdyn', 'dens', - 'angl', 'xhci', 'yhci') + 'angl', 'xhee', 'yhee') # The parameters that the users can handle. # The slug must be one of the properties above. @@ -371,12 +371,12 @@ def get_data_for_target(target_config, started_at, stopped_at): (target_config['name'], orbit_file)) cdf_handle = Dataset(orbit_file, "r", format="NETCDF4") times = cdf_handle.variables['Time'] # YYYY DOY HH MM SS .ms - data_hci = cdf_handle.variables['HCI'] - for time, datum_hci in zip(times, data_hci): + data_hee = cdf_handle.variables['HEE'] + for time, datum_hee in zip(times, data_hee): dtime = datetime_from_list(time) if started_at <= dtime <= stopped_at: dkey = dtime.strftime(precision) - orbit_data[dkey] = datum_hci + orbit_data[dkey] = datum_hee cdf_handle.close() all_data = {} # keys are datetime as str, values tuples of data @@ -401,16 +401,16 @@ def get_data_for_target(target_config, started_at, stopped_at): dtime = datetime_from_list(time) if started_at <= dtime <= stopped_at: dkey = dtime.strftime(precision) - x_hci = None - y_hci = None + x_hee = None + y_hee = None if dkey in orbit_data: - x_hci = orbit_data[dkey][0] - y_hci = orbit_data[dkey][1] + x_hee = orbit_data[dkey][0] + y_hee = orbit_data[dkey][1] all_data[dkey] = ( dtime.strftime("%Y-%m-%dT%H:%M:%S+00:00"), vrad, vtan, sqrt(vrad * vrad + vtan * vtan), datum_b, datum_t, datum_n, datum_p, datum_d, - x_hci, y_hci + x_hee, y_hee ) cdf_handle.close() @@ -726,14 +726,14 @@ def download_targets_netcdf(targets, params, started_at, stopped_at): nc_var[:] = values # ORBIT # - nc_x = nc_group.createVariable('xhci', 'f8', (dimension,)) + nc_x = nc_group.createVariable('xhee', 'f8', (dimension,)) nc_x.units = 'Au' - nc_y = nc_group.createVariable('yhci', 'f8', (dimension,)) + nc_y = nc_group.createVariable('yhee', 'f8', (dimension,)) nc_y.units = 'Au' values_x = [] values_y = [] - index_x = available_params.index('xhci') - index_y = available_params.index('yhci') + index_x = available_params.index('xhee') + index_y = available_params.index('yhee') for dkey in dkeys: dval = data[dkey] values_x.append(dval[index_x]) diff --git a/web/static/js/swapp.js b/web/static/js/swapp.js index addca91..2bd8cc2 100644 --- a/web/static/js/swapp.js +++ b/web/static/js/swapp.js @@ -42,7 +42,7 @@ SpaceWeather.prototype.init = function(){ "This is called by the inline bootstrap javascript code.\nThis ain't in the constructor because it might return a Promise later on.\n(for the loader, for example)"; var started_at, stopped_at, this$ = this; - started_at = moment().subtract(1, 'year').hours(0).minutes(0).seconds(0); + started_at = moment().subtract(6, 'month').hours(0).minutes(0).seconds(0); stopped_at = moment().add(1, 'week').hours(0).minutes(0).seconds(0); this.setStartAndStop(started_at, stopped_at); this.loadAndCreatePlots(started_at, stopped_at); @@ -126,7 +126,7 @@ console.debug("Requested CSV for " + target_slug + "...", csv); timeFormat = d3.timeParse('%Y-%m-%dT%H:%M:%S%Z'); data = { - 'hci': [] + 'hee': [] }; configuration['parameters'].forEach(function(parameter){ return data[parameter['id']] = []; @@ -148,11 +148,11 @@ y: parseFloat(d[id]) }); }); - if (d['xhci'] && d['yhci']) { - return data['hci'].push({ + if (d['xhee'] && d['yhee']) { + return data['hee'].push({ t: dtime, - x: parseFloat(d['xhci']), - y: parseFloat(d['yhci']) + x: parseFloat(d['xhee']), + y: parseFloat(d['yhee']) }); } }); @@ -180,12 +180,11 @@ console.info("Loading CSV data of " + target.name + "…"); targetButton = $(".targets-filters .target." + target.slug); targetButton.addClass('loading'); - targetButton.removeClass('failed'); - targetButton.removeClass('empty'); + targetButton.removeClass('failed empty'); return this$.loadData(target.slug, started_at, stopped_at).then(function(data){ console.info("Loaded CSV data of " + target.name + ".", data); this$.createTimeSeries(target, data); - this$.orbits.initOrbiter(target.slug, target.config, data['hci']); + this$.orbits.initOrbiter(target.slug, target.config, data['hee']); targetButton.removeClass('loading'); if (target.active) { return this$.hideLoader(); @@ -392,7 +391,7 @@ }); }; TimeSeries.prototype.init = function(){ - var clipId, dx, this$ = this; + var formatMillisecond, formatSecond, formatMinute, formatHour, formatDay, formatWeek, formatMonth, formatYear, multiFormat, clipId, dx, this$ = this; console.info("Initializing plot of " + this + "…"); this.margin = { top: 30, @@ -402,7 +401,40 @@ }; this.xScale = d3.scaleTime().domain(this.xDataExtent); this.yScale = d3.scaleLinear().domain(this.yDataExtent); - this.xAxis = d3.axisBottom().ticks(7); + formatMillisecond = d3.timeFormat(".%L"); + formatSecond = d3.timeFormat(":%S"); + formatMinute = d3.timeFormat("%I:%M"); + formatHour = d3.timeFormat("%I:%M"); + formatDay = d3.timeFormat("%a %d"); + formatWeek = d3.timeFormat("%b %d"); + formatMonth = d3.timeFormat("%B"); + formatYear = d3.timeFormat("%Y"); + multiFormat = function(date){ + if (date > d3.timeSecond(date)) { + return formatMillisecond(date); + } + if (date > d3.timeMinute(date)) { + return formatSecond(date); + } + if (date > d3.timeHour(date)) { + return formatMinute(date); + } + if (date > d3.timeDay(date)) { + return formatHour(date); + } + if (date > d3.timeMonth(date)) { + if (date > d3.timeWeek(date)) { + return formatDay(date); + } else { + return formatWeek(date); + } + } + if (date > d3.timeYear(date)) { + return formatMonth(date); + } + return formatYear(date); + }; + this.xAxis = d3.axisBottom().tickFormat(multiFormat).ticks(7); this.yAxis = d3.axisLeft().ticks(10); this.line = d3.line().x(function(d){ return this$.xScale(d.x); @@ -563,7 +595,7 @@ TimeSeries.prototype.bisectDate = d3.bisector(function(d){ return d.x; }).left; - TimeSeries.prototype.timeFormat = d3.timeFormat("%Y-%m-%d %Hh"); + TimeSeries.prototype.timeFormat = d3.timeFormat("%Y-%m-%d %H:%M"); TimeSeries.prototype.moveCursor = function(x0){ var i, d0, d1, d, xx, yy, mirrored, dx, transform; i = this.bisectDate(this.data, x0, 1); @@ -634,7 +666,7 @@ this.yAxisTitle.append('tspan').attr('dy', '-3px').text(' (AU)'); this.yAxisTitle.attr('transform', 'rotate(-90)'); this.sun = this.plotWrapper.append("svg:image").attr('xlink:href', this.options.sun.img).attr('width', '32px').attr('height', '32px'); - this.sun.append('svg:title').text("Sol"); + this.sun.append('svg:title').text("Sun"); $(this.svg.node()).hide(); return this.resize(); }; @@ -651,6 +683,7 @@ this.yScale = d3.scaleLinear().domain([-1 * this.extremum, this.extremum]); orbit_ellipse = this.plotWrapper.append("svg:ellipse").classed('orbit orbit_ellipse', true); orbiter = this.plotWrapper.append("svg:image").attr('xlink:href', config['img']).attr('width', '32px').attr('height', '32px'); + orbiter.append('svg:title').text(config.name); orbit_line = d3.line().x(function(d){ return this$.xScale(d.x); }).y(function(d){ diff --git a/web/static/js/swapp.ls b/web/static/js/swapp.ls index 80d8eb5..004bfe5 100644 --- a/web/static/js/swapp.ls +++ b/web/static/js/swapp.ls @@ -74,7 +74,7 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE """ # Default time interval is from two weeks ago to one week ahead. # We set the h/m/s to zero to benefit from a daily cache. - started_at = moment().subtract(1, 'year').hours(0).minutes(0).seconds(0) + started_at = moment().subtract(6, 'month').hours(0).minutes(0).seconds(0) stopped_at = moment().add(1, 'week').hours(0).minutes(0).seconds(0) @setStartAndStop(started_at, stopped_at) @loadAndCreatePlots(started_at, stopped_at) @@ -138,7 +138,7 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE d3.csv(url, (csv) -> console.debug("Requested CSV for #{target_slug}...", csv) timeFormat = d3.timeParse('%Y-%m-%dT%H:%M:%S%Z') - data = { 'hci': [] } + data = { 'hee': [] } configuration['parameters'].forEach((parameter) -> data[parameter['id']] = [] ) @@ -150,9 +150,9 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE id = parameter['id'] data[id].push({x: dtime, y: parseFloat(d[id])}) ) - if d['xhci'] and d['yhci'] - data['hci'].push({ - t: dtime, x: parseFloat(d['xhci']), y: parseFloat(d['yhci']) + if d['xhee'] and d['yhee'] + data['hee'].push({ + t: dtime, x: parseFloat(d['xhee']), y: parseFloat(d['yhee']) }) ) resolve data @@ -175,13 +175,12 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE console.info "Loading CSV data of #{target.name}…" targetButton = $(".targets-filters .target.#{target.slug}") targetButton.addClass('loading') - targetButton.removeClass('failed') - targetButton.removeClass('empty') # fixme + targetButton.removeClass('failed empty') @loadData(target.slug, started_at, stopped_at).then( (data) ~> console.info "Loaded CSV data of #{target.name}.", data @createTimeSeries(target, data) - @orbits.initOrbiter(target.slug, target.config, data['hci']) + @orbits.initOrbiter(target.slug, target.config, data['hee']) targetButton.removeClass('loading') if target.active then @hideLoader() else @disableTarget(target.slug) , @@ -341,8 +340,28 @@ export class TimeSeries @xScale = d3.scaleTime().domain(@xDataExtent) @yScale = d3.scaleLinear().domain(@yDataExtent) + formatMillisecond = d3.timeFormat(".%L") + formatSecond = d3.timeFormat(":%S") + formatMinute = d3.timeFormat("%I:%M") + formatHour = d3.timeFormat("%I:%M") + formatDay = d3.timeFormat("%a %d") + formatWeek = d3.timeFormat("%b %d") + formatMonth = d3.timeFormat("%B") + formatYear = d3.timeFormat("%Y") + + multiFormat = (date) -> + if date > d3.timeSecond(date) then return formatMillisecond(date) + if date > d3.timeMinute(date) then return formatSecond(date) + if date > d3.timeHour(date) then return formatMinute(date) + if date > d3.timeDay(date) then return formatHour(date) + if date > d3.timeMonth(date) + if date > d3.timeWeek(date) then return formatDay(date) + else return formatWeek(date) + if date > d3.timeYear(date) then return formatMonth(date) + return formatYear(date) + @xAxis = d3.axisBottom() -# .tickFormat(d3.timeFormat("%Y-%m-%d")) + .tickFormat(multiFormat) .ticks(7) @yAxis = d3.axisLeft() .ticks(10) @@ -554,7 +573,7 @@ export class TimeSeries @focus.style("display", "none") bisectDate: d3.bisector((d) -> d.x).left # /!\ complex - timeFormat: d3.timeFormat("%Y-%m-%d %Hh") + timeFormat: d3.timeFormat("%Y-%m-%d %H:%M") moveCursor: (x0) -> i = @bisectDate(@data, x0, 1) @@ -610,7 +629,7 @@ export class Orbits left: 60 } - @data = {} # slug => HCI array + @data = {} # slug => HEE array @orbiters = {} # slug => config @orbitersElements = {} @extremum = 1 @@ -647,7 +666,7 @@ export class Orbits @sun = @plotWrapper.append("svg:image") .attr('xlink:href', @options.sun.img) .attr('width', '32px').attr('height', '32px') - @sun.append('svg:title').text("Sol") + @sun.append('svg:title').text("Sun") $(@svg.node()).hide(); # we'll show it later when there'll be data @resize() @@ -668,6 +687,7 @@ export class Orbits orbiter = @plotWrapper.append("svg:image") .attr('xlink:href', config['img']) .attr('width', '32px').attr('height', '32px') + orbiter.append('svg:title').text(config.name) orbit_line = d3.line() .x((d) ~> @xScale(d.x)) diff --git a/web/view/home.html.jinja2 b/web/view/home.html.jinja2 index 643820b..94a3bb7 100755 --- a/web/view/home.html.jinja2 +++ b/web/view/home.html.jinja2 @@ -325,19 +325,19 @@ cursor: not-allowed; } .targets-filters .target.loading { - -webkit-animation-name: spin; + -webkit-animation-name: keyframes_rotate; -webkit-animation-duration: 4000ms; -webkit-animation-iteration-count: infinite; -webkit-animation-timing-function: linear; - -moz-animation-name: spin; + -moz-animation-name: keyframes_rotate; -moz-animation-duration: 4000ms; -moz-animation-iteration-count: infinite; -moz-animation-timing-function: linear; - -ms-animation-name: spin; + -ms-animation-name: keyframes_rotate; -ms-animation-duration: 4000ms; -ms-animation-iteration-count: infinite; -ms-animation-timing-function: linear; - animation-name: spin; + animation-name: keyframes_rotate; animation-duration: 4000ms; animation-iteration-count: infinite; animation-timing-function: linear; diff --git a/web/view/layout.html.jinja2 b/web/view/layout.html.jinja2 index b915244..f6757d9 100755 --- a/web/view/layout.html.jinja2 +++ b/web/view/layout.html.jinja2 @@ -42,7 +42,7 @@ -- libgit2 0.21.2