diff --git a/web/static/js/swapp.js b/web/static/js/swapp.js index a003ca2..f074095 100644 --- a/web/static/js/swapp.js +++ b/web/static/js/swapp.js @@ -20,7 +20,7 @@ function SpaceWeather(configuration){ var configs, res$, k, this$ = this; this.configuration = configuration; - console.info("Creating Heliopropa app...", this.configuration); + console.info("Creating HelioPropa app...", this.configuration); this.targets = {}; res$ = []; for (k in this.configuration.targets) { @@ -46,10 +46,10 @@ } active_targets = res$; this.orbits = new Orbits(this.configuration.orbits_container, this.configuration); - started_at = moment().subtract(1, 'years').hours(0).minutes(0).seconds(0); - stopped_at = moment().add(7, 'days').hours(0).minutes(0).seconds(0); - started_at = started_at.format("YYYY-MM-DDTHH:mm:ss"); - stopped_at = stopped_at.format("YYYY-MM-DDTHH:mm:ss"); + this.started_at = moment().subtract(1, 'years').hours(0).minutes(0).seconds(0); + this.stopped_at = moment().add(7, 'days').hours(0).minutes(0).seconds(0); + started_at = this.started_at.format("YYYY-MM-DDTHH:mm:ss"); + stopped_at = this.stopped_at.format("YYYY-MM-DDTHH:mm:ss"); active_targets.forEach(function(target){ return this$.loadData(target.slug, started_at, stopped_at).then(function(data){ console.info("Loaded CSV data for " + target.slug + "."); @@ -209,6 +209,25 @@ }); return this; }; + SpaceWeather.prototype.resizeDomain = function(started_at, stopped_at){ + var tmp; + if (stopped_at < started_at) { + tmp = started_at; + started_at = stopped_at; + stopped_at = started_at; + } + if (started_at === stopped_at) { + console.warn("Please provide different start and stop dates."); + return; + } + if ((this.started_at <= started_at && started_at <= this.stopped_at) && (this.started_at <= stopped_at && stopped_at <= this.stopped_at)) { + console.info("Resizing the temporal domain without fetching new data..."); + timeSeries.forEach(function(ts){ + return ts.resizeDomain(started_at, stopped_at); + }); + this.orbits.resizeDomain(started_at, stopped_at); + } + }; return SpaceWeather; }()); out$.TimeSeries = TimeSeries = (function(){ @@ -227,16 +246,11 @@ this.onMouseOut = bind$(this, 'onMouseOut', prototype); this.onMouseOver = bind$(this, 'onMouseOver', prototype); this.onMouseMove = bind$(this, 'onMouseMove', prototype); - if (this.active) { - console.info("Creating time series '" + this.title + "'..."); - } else { - console.info("Creating inactive time series '" + this.title + "'..."); - } this.init(); } TimeSeries.prototype.init = function(){ var dx, this$ = this; - console.info("Initializing time series '" + this.title + "'...", this.data, this.options); + console.info("Initializing time series " + this.title + " of " + this.target + "..."); this.margin = { top: 30, right: 20, @@ -282,7 +296,7 @@ height = GOLDEN_RATIO * GOLDEN_RATIO * GOLDEN_RATIO * GOLDEN_RATIO * width; this.plotWidth = width; this.plotHeight = height; - console.log("Resizing time series " + this.title + " : " + width + " x " + height); + console.log("Resizing time series " + this.title + " of " + this.target + ": " + width + " x " + height); this.xScale.range([0, width]); this.yScale.range([height, 0]); this.svg.attr('width', width + this.margin.right + this.margin.left).attr('height', height + this.margin.top + this.margin.bottom); @@ -301,6 +315,7 @@ } return this; }; + TimeSeries.prototype.resizeDomain = function(started_at, stopped_at){}; TimeSeries.prototype.onMouseMove = function(){ var x; x = this.xScale.invert(d3.mouse(this.mouseCanvas.node())[0]); @@ -335,7 +350,7 @@ }).left; TimeSeries.prototype.timeFormat = d3.timeFormat("%Y-%m-%d %Hh"); TimeSeries.prototype.moveCursor = function(x0){ - var i, d0, d1, d, xx, yy, transform, mirrored, dx; + var i, d0, d1, d, xx, yy, mirrored, dx, transform; i = this.bisectDate(this.data, x0, 1); d0 = this.data[i - 1]; d1 = this.data[i]; @@ -345,12 +360,12 @@ d = x0 - d0.x > d1.x - x0 ? d1 : d0; xx = this.xScale(d.x); yy = this.yScale(d.y); - transform = "translate(" + xx + ", " + yy + ")"; mirrored = this.plotWidth != null && xx > this.plotWidth / 2 ? true : false; dx = 8; if (mirrored) { dx = -1 * dx; } + transform = "translate(" + xx + ", " + yy + ")"; this.cursorCircle.attr("transform", transform); this.cursorValue.attr("transform", transform).text(d.y).attr('text-anchor', mirrored ? 'end' : 'start').attr("dx", dx); this.cursorValueShadow.attr("transform", transform).text(d.y).attr('text-anchor', mirrored ? 'end' : 'start').attr("dx", dx); @@ -361,6 +376,7 @@ return TimeSeries; }()); out$.Orbits = Orbits = (function(){ + "View of the solar system from above, with orbits segments for selected time\ninterval, from real data."; Orbits.displayName = 'Orbits'; var prototype = Orbits.prototype, constructor = Orbits; function Orbits(container, options){ @@ -403,6 +419,7 @@ 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.svg.node).hide(); return this.resize(); }; Orbits.prototype.orbitersElements = {}; @@ -434,13 +451,13 @@ orbit_line: orbit_line }; this.resize(); + $(this.svg.node).show(); return this; }; Orbits.prototype.resize = function(){ var width, height, slug, ref$, config; width = jQuery(this.container).width() - this.margin.left - this.margin.right; height = 1.0 * width; - console.log("Resize orbits : " + width + " x " + height); this.xScale.range([0, width]); this.yScale.range([height, 0]); this.svg.attr('width', width + this.margin.right + this.margin.left).attr('height', height + this.margin.top + this.margin.bottom); @@ -508,6 +525,7 @@ } return this; }; + Orbits.prototype.resizeDomain = function(started_at, stopped_at){}; return Orbits; }()); function bind$(obj, key, target){ diff --git a/web/static/js/swapp.ls b/web/static/js/swapp.ls index 3b0c0c8..f04e557 100644 --- a/web/static/js/swapp.ls +++ b/web/static/js/swapp.ls @@ -1,5 +1,6 @@ # Livescript transpiles to javascript, and is easier on the eyes and brain. # Get the `lsc` binary from here : http://livescript.net +# It is quite close to Python, syntax-wise, and full of sugar. # To transpile this file to javascript, and generate `swapp.js` : # $ lsc --compile swapp.ls @@ -9,7 +10,7 @@ # All the "javascript" code is in this file, except for inline scripts in # templates, such as `home.html.jinja2`. -# Note: We use Promises and ES6 whenever we can. +# Note: We use Promises and ES6 whenever relevant. ############################################################################### @@ -30,7 +31,7 @@ export class SpaceWeather """ (@configuration) -> - console.info "Creating Heliopropa app...", @configuration + console.info "Creating HelioPropa app...", @configuration @targets = {} configs = [@configuration.targets[k] for k of @configuration.targets] configs.forEach((target_config) ~> @@ -50,10 +51,10 @@ export class SpaceWeather active_targets = [ @targets[k] for k of @targets when @targets[k].config.active ] @orbits = new Orbits(@configuration.orbits_container, @configuration) # Set the h/m/s to zero so that files are cached per whole days - started_at = moment().subtract(1, 'years').hours(0).minutes(0).seconds(0) - stopped_at = moment().add(7, 'days').hours(0).minutes(0).seconds(0) - started_at = started_at.format("YYYY-MM-DDTHH:mm:ss") - stopped_at = stopped_at.format("YYYY-MM-DDTHH:mm:ss") + @started_at = moment().subtract(1, 'years').hours(0).minutes(0).seconds(0) + @stopped_at = moment().add(7, 'days').hours(0).minutes(0).seconds(0) + started_at = @started_at.format("YYYY-MM-DDTHH:mm:ss") + stopped_at = @stopped_at.format("YYYY-MM-DDTHH:mm:ss") active_targets.forEach((target) ~> @loadData(target.slug, started_at, stopped_at).then( (data) ~> @@ -124,7 +125,7 @@ export class SpaceWeather ) promise - timeSeries = [] + timeSeries = [] # Not sure why this ain't an instance prop. Probably should. createTimeSeries: (target, data) -> @configuration['parameters'].forEach((parameter) ~> container = @configuration['time_series_container'] @@ -154,6 +155,26 @@ export class SpaceWeather timeSeries.forEach((ts) -> $(ts.svg.node()).hide() if ts.parameter == parameter_slug) this + resizeDomain: (started_at, stopped_at) -> + if stopped_at < started_at + tmp = started_at + started_at = stopped_at + stopped_at = started_at + + if started_at == stopped_at + console.warn "Please provide different start and stop dates." + return + + if (@started_at <= started_at <= @stopped_at) and (@started_at <= stopped_at <= @stopped_at) + console.info "Resizing the temporal domain without fetching new data..." + timeSeries.forEach((ts) -> ts.resizeDomain started_at, stopped_at) + @orbits.resizeDomain started_at, stopped_at + return + + # todo: fetch new data and remake the plots + + + ############################################################################### ############################################################################### @@ -166,14 +187,12 @@ export class TimeSeries (@parameter, @title, @target, @data, @active, @container, @options = {}) -> # parameter : slug of the parameter to observe, like magn or pdyn # title : string - # target : slug of the TARGET, like jupiter or tchouri + # target : slug of the target, like jupiter or tchouri # data : list of {x: , y: } - if @active then console.info "Creating time series '#{@title}'..." - else console.info "Creating inactive time series '#{@title}'..." @init() init: -> - console.info "Initializing time series '#{@title}'...", @data, @options + console.info "Initializing time series #{@title} of #{@target}..." @margin = { top: 30, @@ -190,7 +209,6 @@ export class TimeSeries @xAxis = d3.axisBottom() .tickFormat(d3.timeFormat("%Y-%m-%d")) .ticks(7) -# .ticks(7, ",f") @yAxis = d3.axisLeft() .ticks(10) @@ -267,7 +285,7 @@ export class TimeSeries @plotWidth = width @plotHeight = height - console.log("Resizing time series #{@title} : #{width} x #{height}") + console.log("Resizing time series #{@title} of #{@target}: #{width} x #{height}") @xScale.range([0, width]); @yScale.range([height, 0]); @@ -304,6 +322,9 @@ export class TimeSeries unless @active then $(@svg.node()).hide() this + resizeDomain: (started_at, stopped_at) -> + # fixme + onMouseMove: ~> x = @xScale.invert(d3.mouse(@mouseCanvas.node())[0]) if @options.onMouseMove? @@ -329,7 +350,7 @@ export class TimeSeries hideCursor: -> @focus.style("display", "none") - bisectDate: d3.bisector((d) -> d.x).left # /!\ complex + bisectDate: d3.bisector((d) -> d.x).left # /!\ complex timeFormat: d3.timeFormat("%Y-%m-%d %Hh") moveCursor: (x0) -> @@ -341,14 +362,12 @@ export class TimeSeries xx = @xScale(d.x) yy = @yScale(d.y) - transform = "translate(#{xx}, #{yy})" - mirrored = if @plotWidth? and xx > @plotWidth / 2 then true else false -# console.log("xx", xx) - dx = 8 + dx = 8 # horizontal delta between the dot and the text dx = -1 * dx if mirrored + transform = "translate(#{xx}, #{yy})" @cursorCircle.attr("transform", transform) @cursorValue.attr("transform", transform).text(d.y) .attr('text-anchor', if mirrored then 'end' else 'start') @@ -370,8 +389,10 @@ export class TimeSeries ############################################################################### export class Orbits - # View of the solar system from above, with orbits segments for selected time - # interval, from real data. + """ + View of the solar system from above, with orbits segments for selected time + interval, from real data. + """ (@container, @options = {}) -> @init() @@ -424,9 +445,7 @@ export class Orbits .attr('width', '32px').attr('height', '32px') @sun.append('svg:title').text("Sol") -# for slug, config of @orbiters -# @initOrbiter(slug, config) - + $(@svg.node).hide(); # we'll show it later when there'll be data @resize() orbitersElements: {} @@ -465,13 +484,15 @@ export class Orbits @resize() + $(@svg.node).show(); + this resize: -> width = jQuery(@container).width() - @margin.left - @margin.right height = 1.0 * width - console.log("Resize orbits : #{width} x #{height}") + #console.log("Resizing orbits : #{width} x #{height}") @xScale.range([0, width]); @yScale.range([height, 0]); @@ -548,7 +569,10 @@ export class Orbits d1 = data[i] continue unless d1 and d0 d = if t - d0.t > d1.t - t then d1 else d0 - @repositionOrbiter(slug, d) # fixme + @repositionOrbiter(slug, d) # fixme <--(why?) this + resizeDomain: (started_at, stopped_at) -> + # fixme + diff --git a/web/view/home.html.jinja2 b/web/view/home.html.jinja2 index ca29b1e..bc13ab9 100755 --- a/web/view/home.html.jinja2 +++ b/web/view/home.html.jinja2 @@ -45,6 +45,7 @@ Parameters