Commit 243cd8a4c2a49b4281de7979ef908cd2cd3cff5c
1 parent
4900d232
Exists in
master
and in
2 other branches
Timestamp party commit 😁
WOOOOOOOOOOO 1500000000
Showing
3 changed files
with
101 additions
and
55 deletions
Show diff stats
web/static/js/swapp.js
... | ... | @@ -16,8 +16,9 @@ |
16 | 16 | out$.SpaceWeather = SpaceWeather = (function(){ |
17 | 17 | "The main app, instanciated from an inline script.\nIt defaults to an interval starting a year ago, and ending in seven days.\n(both at midnight)"; |
18 | 18 | SpaceWeather.displayName = 'SpaceWeather'; |
19 | - var API_TIME_FORMAT, timeSeries, prototype = SpaceWeather.prototype, constructor = SpaceWeather; | |
19 | + var API_TIME_FORMAT, INPUT_TIME_FORMAT, prototype = SpaceWeather.prototype, constructor = SpaceWeather; | |
20 | 20 | API_TIME_FORMAT = "YYYY-MM-DDTHH:mm:ss"; |
21 | + INPUT_TIME_FORMAT = "YYYY-MM-DD"; | |
21 | 22 | function SpaceWeather(configuration){ |
22 | 23 | var configs, res$, k, this$ = this; |
23 | 24 | this.configuration = configuration; |
... | ... | @@ -35,6 +36,7 @@ |
35 | 36 | this.configuration['parameters'].forEach(function(p){ |
36 | 37 | return this$.parameters[p['id']] = p; |
37 | 38 | }); |
39 | + this.timeSeries = []; | |
38 | 40 | } |
39 | 41 | SpaceWeather.prototype.init = function(){ |
40 | 42 | "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)"; |
... | ... | @@ -45,6 +47,7 @@ |
45 | 47 | started_at = this.started_at.format(API_TIME_FORMAT); |
46 | 48 | stopped_at = this.stopped_at.format(API_TIME_FORMAT); |
47 | 49 | console.info("Setting time interval from " + started_at + " to " + stopped_at + "…"); |
50 | + this.setStartAndStop(this.started_at, this.stopped_at); | |
48 | 51 | this.loadAndCreatePlots(started_at, stopped_at); |
49 | 52 | return window.addEventListener('resize', function(){ |
50 | 53 | return this$.resize(); |
... | ... | @@ -64,7 +67,7 @@ |
64 | 67 | }; |
65 | 68 | SpaceWeather.prototype.enableTarget = function(target_slug){ |
66 | 69 | var this$ = this; |
67 | - timeSeries.forEach(function(ts){ | |
70 | + this.timeSeries.forEach(function(ts){ | |
68 | 71 | if (ts.target.slug === target_slug && this$.parameters[ts.parameter].active) { |
69 | 72 | return ts.show(); |
70 | 73 | } |
... | ... | @@ -73,7 +76,7 @@ |
73 | 76 | return this; |
74 | 77 | }; |
75 | 78 | SpaceWeather.prototype.disableTarget = function(target_slug){ |
76 | - timeSeries.forEach(function(ts){ | |
79 | + this.timeSeries.forEach(function(ts){ | |
77 | 80 | if (ts.target.slug === target_slug) { |
78 | 81 | return ts.hide(); |
79 | 82 | } |
... | ... | @@ -86,7 +89,7 @@ |
86 | 89 | if ((ref$ = this.orbits) != null) { |
87 | 90 | ref$.resize(); |
88 | 91 | } |
89 | - return timeSeries.forEach(function(ts){ | |
92 | + return this.timeSeries.forEach(function(ts){ | |
90 | 93 | return ts.resize(); |
91 | 94 | }); |
92 | 95 | }; |
... | ... | @@ -136,8 +139,11 @@ |
136 | 139 | }); |
137 | 140 | }; |
138 | 141 | SpaceWeather.prototype.loadAndCreatePlots = function(started_at, stopped_at){ |
142 | + "started_at: moment(.js) object\nstopped_at: moment(.js) object"; | |
139 | 143 | var active_targets, res$, k, this$ = this; |
140 | 144 | this.showLoader(); |
145 | + started_at = started_at.format(API_TIME_FORMAT); | |
146 | + stopped_at = stopped_at.format(API_TIME_FORMAT); | |
141 | 147 | res$ = []; |
142 | 148 | for (k in this.targets) { |
143 | 149 | if (this.targets[k].active) { |
... | ... | @@ -162,16 +168,14 @@ |
162 | 168 | }); |
163 | 169 | }; |
164 | 170 | SpaceWeather.prototype.clearPlots = function(){ |
165 | - var timeSeries; | |
166 | 171 | this.orbits.clear(); |
167 | - timeSeries.forEach(function(ts){ | |
172 | + this.timeSeries.forEach(function(ts){ | |
168 | 173 | return ts.clear(); |
169 | 174 | }); |
170 | 175 | this.orbits = null; |
171 | - timeSeries = []; | |
176 | + this.timeSeries = []; | |
172 | 177 | return this; |
173 | 178 | }; |
174 | - timeSeries = []; | |
175 | 179 | SpaceWeather.prototype.createTimeSeries = function(target, data){ |
176 | 180 | var this$ = this; |
177 | 181 | this.configuration['parameters'].forEach(function(parameter){ |
... | ... | @@ -182,24 +186,24 @@ |
182 | 186 | if (!(id in data)) { |
183 | 187 | console.error("No data for id '" + id + "'.", data); |
184 | 188 | } |
185 | - return timeSeries.push(new TimeSeries(id, title, target, data[id], this$.parameters[id].active, container)); | |
189 | + return this$.timeSeries.push(new TimeSeries(id, title, target, data[id], this$.parameters[id].active, container)); | |
186 | 190 | }); |
187 | - return timeSeries.forEach(function(ts){ | |
191 | + this.timeSeries.forEach(function(ts){ | |
188 | 192 | ts.options['onMouseOver'] = function(){ |
189 | - timeSeries.forEach(function(ts2){ | |
193 | + this$.timeSeries.forEach(function(ts2){ | |
190 | 194 | return ts2.showCursor(); |
191 | 195 | }); |
192 | 196 | return true; |
193 | 197 | }; |
194 | 198 | ts.options['onMouseOut'] = function(){ |
195 | - timeSeries.forEach(function(ts2){ | |
199 | + this$.timeSeries.forEach(function(ts2){ | |
196 | 200 | return ts2.hideCursor(); |
197 | 201 | }); |
198 | 202 | return true; |
199 | 203 | }; |
200 | 204 | ts.options['onMouseMove'] = function(t){ |
201 | 205 | var ref$; |
202 | - timeSeries.forEach(function(ts2){ | |
206 | + this$.timeSeries.forEach(function(ts2){ | |
203 | 207 | return ts2.moveCursor(t); |
204 | 208 | }); |
205 | 209 | if ((ref$ = this$.orbits) != null) { |
... | ... | @@ -208,7 +212,7 @@ |
208 | 212 | return true; |
209 | 213 | }; |
210 | 214 | ts.options['onBrushEnd'] = function(sta, sto){ |
211 | - this$.resizeDomain(sta, sto); | |
215 | + this$.resizeDomain(moment(sta), moment(sto)); | |
212 | 216 | return true; |
213 | 217 | }; |
214 | 218 | return ts.options['onDblClick'] = function(){ |
... | ... | @@ -220,6 +224,7 @@ |
220 | 224 | return true; |
221 | 225 | }; |
222 | 226 | }); |
227 | + return this.timeSeries; | |
223 | 228 | }; |
224 | 229 | SpaceWeather.prototype.enableParameter = function(parameter_slug){ |
225 | 230 | var this$ = this; |
... | ... | @@ -227,7 +232,7 @@ |
227 | 232 | console.error("Unknown parameter " + parameter_slug + "."); |
228 | 233 | } |
229 | 234 | this.parameters[parameter_slug].active = true; |
230 | - timeSeries.forEach(function(ts){ | |
235 | + this.timeSeries.forEach(function(ts){ | |
231 | 236 | if (ts.parameter === parameter_slug && this$.targets[ts.target.slug].active) { |
232 | 237 | return ts.show(); |
233 | 238 | } |
... | ... | @@ -239,7 +244,7 @@ |
239 | 244 | console.error("Unknown parameter " + parameter_slug + "."); |
240 | 245 | } |
241 | 246 | this.parameters[parameter_slug].active = false; |
242 | - timeSeries.forEach(function(ts){ | |
247 | + this.timeSeries.forEach(function(ts){ | |
243 | 248 | if (ts.parameter === parameter_slug) { |
244 | 249 | return ts.hide(); |
245 | 250 | } |
... | ... | @@ -253,7 +258,7 @@ |
253 | 258 | return [this.started_at, this.stopped_at]; |
254 | 259 | }; |
255 | 260 | SpaceWeather.prototype.resizeDomain = function(started_at, stopped_at){ |
256 | - var tmp; | |
261 | + var tmp, formatted_started_at, formatted_stopped_at; | |
257 | 262 | if (stopped_at < started_at) { |
258 | 263 | tmp = started_at; |
259 | 264 | started_at = stopped_at; |
... | ... | @@ -263,31 +268,44 @@ |
263 | 268 | console.warn("Please provide distinct start and stop dates."); |
264 | 269 | return; |
265 | 270 | } |
266 | - this.current_started_at = started_at; | |
267 | - this.current_stopped_at = stopped_at; | |
271 | + this.setStartAndStop(started_at, stopped_at); | |
272 | + formatted_started_at = started_at.format(); | |
273 | + formatted_stopped_at = stopped_at.format(); | |
268 | 274 | if ((this.started_at <= started_at && started_at <= this.stopped_at) && (this.started_at <= stopped_at && stopped_at <= this.stopped_at)) { |
269 | - console.info("Resizing the temporal domain from " + started_at + " to " + stopped_at + " without fetching new data…"); | |
270 | - timeSeries.forEach(function(ts){ | |
275 | + console.info("Resizing the temporal domain from " + formatted_started_at + " to " + formatted_stopped_at + " without fetching new data…"); | |
276 | + this.timeSeries.forEach(function(ts){ | |
271 | 277 | if (!ts.visible) { |
272 | 278 | return ts.zoomIn(started_at, stopped_at); |
273 | 279 | } |
274 | 280 | }); |
275 | - timeSeries.forEach(function(ts){ | |
281 | + this.timeSeries.forEach(function(ts){ | |
276 | 282 | if (ts.visible) { |
277 | 283 | return ts.zoomIn(started_at, stopped_at); |
278 | 284 | } |
279 | 285 | }); |
280 | 286 | this.orbits.resizeDomain(started_at, stopped_at); |
281 | - return; | |
287 | + } else { | |
288 | + console.info("Resizing the temporal domain from " + formatted_started_at + " to " + formatted_stopped_at + " and fetching new data…"); | |
289 | + console.warn("This might take a while… Why not see what else we're up to on http://cdpp.eu while you're waiting?"); | |
290 | + this.clearPlots(); | |
291 | + this.loadAndCreatePlots(started_at, stopped_at); | |
282 | 292 | } |
283 | - this.clearPlots(); | |
284 | - return this.loadAndCreatePlots(started_at, stopped_at); | |
293 | + return this; | |
285 | 294 | }; |
286 | 295 | SpaceWeather.prototype.resetZoom = function(){ |
287 | - timeSeries.forEach(function(ts){ | |
296 | + this.timeSeries.forEach(function(ts){ | |
288 | 297 | return ts.resetZoom(); |
289 | 298 | }); |
290 | - return this.orbits.resetZoom(); | |
299 | + this.orbits.resetZoom(); | |
300 | + this.setStartAndStop(this.started_at, this.stopped_at); | |
301 | + return this; | |
302 | + }; | |
303 | + SpaceWeather.prototype.setStartAndStop = function(started_at, stopped_at){ | |
304 | + this.current_started_at = started_at; | |
305 | + this.current_stopped_at = stopped_at; | |
306 | + $("#started_at").val(started_at.format(INPUT_TIME_FORMAT)); | |
307 | + $("#stopped_at").val(stopped_at.format(INPUT_TIME_FORMAT)); | |
308 | + return this; | |
291 | 309 | }; |
292 | 310 | return SpaceWeather; |
293 | 311 | }()); | ... | ... |
web/static/js/swapp.ls
... | ... | @@ -36,6 +36,7 @@ export class SpaceWeather |
36 | 36 | """ |
37 | 37 | |
38 | 38 | API_TIME_FORMAT = "YYYY-MM-DDTHH:mm:ss" |
39 | + INPUT_TIME_FORMAT = "YYYY-MM-DD" | |
39 | 40 | |
40 | 41 | (@configuration) -> |
41 | 42 | console.info """ |
... | ... | @@ -62,6 +63,7 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE |
62 | 63 | @configuration['parameters'].forEach((p) ~> |
63 | 64 | @parameters[p['id']] = p |
64 | 65 | ) |
66 | + @timeSeries = [] | |
65 | 67 | |
66 | 68 | init: -> |
67 | 69 | """ |
... | ... | @@ -77,7 +79,9 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE |
77 | 79 | started_at = @started_at.format(API_TIME_FORMAT) |
78 | 80 | stopped_at = @stopped_at.format(API_TIME_FORMAT) |
79 | 81 | console.info "Setting time interval from #{started_at} to #{stopped_at}…" |
82 | + @setStartAndStop(@started_at, @stopped_at) | |
80 | 83 | @loadAndCreatePlots(started_at, stopped_at) |
84 | + | |
81 | 85 | window.addEventListener 'resize', ~> @resize() |
82 | 86 | |
83 | 87 | buildDataUrlForTarget: (target_slug, started_at, stopped_at) -> |
... | ... | @@ -97,18 +101,18 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE |
97 | 101 | # this |
98 | 102 | |
99 | 103 | enableTarget: (target_slug) -> |
100 | - timeSeries.forEach((ts) ~> ts.show() if ts.target.slug == target_slug && @parameters[ts.parameter].active) | |
104 | + @timeSeries.forEach((ts) ~> ts.show() if ts.target.slug == target_slug && @parameters[ts.parameter].active) | |
101 | 105 | @targets[target_slug].active = true |
102 | 106 | this |
103 | 107 | |
104 | 108 | disableTarget: (target_slug) -> |
105 | - timeSeries.forEach((ts) -> ts.hide() if ts.target.slug == target_slug) | |
109 | + @timeSeries.forEach((ts) -> ts.hide() if ts.target.slug == target_slug) | |
106 | 110 | @targets[target_slug].active = false |
107 | 111 | this |
108 | 112 | |
109 | 113 | resize: -> |
110 | 114 | @orbits?.resize(); |
111 | - timeSeries.forEach((ts) -> ts.resize()) | |
115 | + @timeSeries.forEach((ts) -> ts.resize()) | |
112 | 116 | |
113 | 117 | showLoader: -> |
114 | 118 | $("\#plots_loader").show(); |
... | ... | @@ -121,6 +125,7 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE |
121 | 125 | Load the data as CSV for the specified target and interval, |
122 | 126 | and return it in a Promise. |
123 | 127 | """ |
128 | + | |
124 | 129 | sw = this |
125 | 130 | new Promise((resolve, reject) -> |
126 | 131 | url = sw.buildDataUrlForTarget(target_slug, started_at, stopped_at) |
... | ... | @@ -144,7 +149,13 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE |
144 | 149 | ) |
145 | 150 | |
146 | 151 | loadAndCreatePlots: (started_at, stopped_at) -> |
152 | + """ | |
153 | + started_at: moment(.js) object | |
154 | + stopped_at: moment(.js) object | |
155 | + """ | |
147 | 156 | @showLoader() |
157 | + started_at = started_at.format(API_TIME_FORMAT) | |
158 | + stopped_at = stopped_at.format(API_TIME_FORMAT) | |
148 | 159 | active_targets = [@targets[k] for k of @targets when @targets[k].active] |
149 | 160 | active_targets.forEach((target) ~> |
150 | 161 | console.info "Loading CSV data of #{target.name}…" |
... | ... | @@ -164,45 +175,45 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE |
164 | 175 | |
165 | 176 | clearPlots: -> |
166 | 177 | @orbits.clear() |
167 | - timeSeries.forEach((ts) -> ts.clear()) | |
178 | + @timeSeries.forEach((ts) -> ts.clear()) | |
168 | 179 | @orbits = null |
169 | - timeSeries = [] # do we de-reference all existing TimeSeries ? #memleak? | |
180 | + @timeSeries = [] # do we de-reference everything ? listeners ? #memleak? | |
170 | 181 | this |
171 | 182 | |
172 | - timeSeries = [] # deprecated (was for scoping) ; use @property with ~> | |
173 | 183 | createTimeSeries: (target, data) -> |
174 | 184 | @configuration['parameters'].forEach((parameter) ~> |
175 | 185 | container = @configuration['time_series_container'] |
176 | 186 | id = parameter['id'] ; title = parameter['title'] |
177 | 187 | if id not of data then console.error("No data for id '#{id}'.", data) |
178 | - timeSeries.push(new TimeSeries( | |
188 | + @timeSeries.push(new TimeSeries( | |
179 | 189 | id, title, target, data[id], @parameters[id].active, container |
180 | 190 | )) |
181 | 191 | ) |
182 | - timeSeries.forEach((ts) ~> # returning true may be faster | |
183 | - ts.options['onMouseOver'] = -> | |
184 | - timeSeries.forEach((ts2) -> ts2.showCursor()) ; true | |
185 | - ts.options['onMouseOut'] = -> | |
186 | - timeSeries.forEach((ts2) -> ts2.hideCursor()) ; true | |
192 | + @timeSeries.forEach((ts) ~> # returning true may be faster | |
193 | + ts.options['onMouseOver'] = ~> | |
194 | + @timeSeries.forEach((ts2) -> ts2.showCursor()) ; true | |
195 | + ts.options['onMouseOut'] = ~> | |
196 | + @timeSeries.forEach((ts2) -> ts2.hideCursor()) ; true | |
187 | 197 | ts.options['onMouseMove'] = (t) ~> |
188 | - timeSeries.forEach((ts2) -> ts2.moveCursor(t)) | |
198 | + @timeSeries.forEach((ts2) -> ts2.moveCursor(t)) | |
189 | 199 | @orbits?.moveToDate(t) ; true |
190 | 200 | ts.options['onBrushEnd'] = (sta, sto) ~> |
191 | - @resizeDomain(sta, sto) ; true | |
201 | + @resizeDomain(moment(sta), moment(sto)) ; true | |
192 | 202 | ts.options['onDblClick'] = ~> |
193 | 203 | @resetZoom() ; $("\#zoom_controls_help")?.remove() ; true |
194 | 204 | ) |
205 | + @timeSeries | |
195 | 206 | |
196 | 207 | enableParameter: (parameter_slug) -> |
197 | 208 | if parameter_slug not of @parameters then console.error("Unknown parameter #{parameter_slug}.") |
198 | 209 | @parameters[parameter_slug].active = true |
199 | - timeSeries.forEach((ts) ~> ts.show() if ts.parameter == parameter_slug && @targets[ts.target.slug].active) | |
210 | + @timeSeries.forEach((ts) ~> ts.show() if ts.parameter == parameter_slug && @targets[ts.target.slug].active) | |
200 | 211 | this |
201 | 212 | |
202 | 213 | disableParameter: (parameter_slug) -> |
203 | 214 | if parameter_slug not of @parameters then console.error("Unknown parameter #{parameter_slug}.") |
204 | 215 | @parameters[parameter_slug].active = false |
205 | - timeSeries.forEach((ts) -> ts.hide() if ts.parameter == parameter_slug) | |
216 | + @timeSeries.forEach((ts) -> ts.hide() if ts.parameter == parameter_slug) | |
206 | 217 | this |
207 | 218 | |
208 | 219 | getDomain: -> |
... | ... | @@ -220,27 +231,39 @@ https://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE |
220 | 231 | console.warn "Please provide distinct start and stop dates." |
221 | 232 | return |
222 | 233 | |
223 | - @current_started_at = started_at | |
224 | - @current_stopped_at = stopped_at | |
234 | + @setStartAndStop(started_at, stopped_at) | |
235 | + formatted_started_at = started_at.format() | |
236 | + formatted_stopped_at = stopped_at.format() | |
225 | 237 | |
226 | 238 | if (@started_at <= started_at <= @stopped_at) and |
227 | 239 | (@started_at <= stopped_at <= @stopped_at) then |
228 | - console.info "Resizing the temporal domain from #{started_at} to #{stopped_at} without fetching new data…" | |
240 | + console.info "Resizing the temporal domain from #{formatted_started_at} to #{formatted_stopped_at} without fetching new data…" | |
229 | 241 | # We first resize the hidden time series and only afterwards we resize |
230 | 242 | # the visible ones, for a smoother transition. |
231 | - timeSeries.forEach((ts) -> if not ts.visible then ts.zoomIn(started_at, stopped_at)) | |
232 | - timeSeries.forEach((ts) -> if ts.visible then ts.zoomIn(started_at, stopped_at)) | |
243 | + @timeSeries.forEach((ts) -> if not ts.visible then ts.zoomIn(started_at, stopped_at)) | |
244 | + @timeSeries.forEach((ts) -> if ts.visible then ts.zoomIn(started_at, stopped_at)) | |
233 | 245 | @orbits.resizeDomain started_at, stopped_at |
234 | - return | |
235 | - | |
236 | - # fetch new data and remake the plots | |
237 | - @clearPlots() | |
238 | - @loadAndCreatePlots(started_at, stopped_at) | |
246 | + else | |
247 | + console.info "Resizing the temporal domain from #{formatted_started_at} to #{formatted_stopped_at} and fetching new data…" | |
248 | + console.warn "This might take a while… Why not see what else we're up to on http://cdpp.eu while you're waiting?" | |
249 | + # fetch new data and remake the plots | |
250 | + @clearPlots() | |
251 | + @loadAndCreatePlots(started_at, stopped_at) | |
239 | 252 | |
253 | + this | |
240 | 254 | |
241 | 255 | resetZoom: -> |
242 | - timeSeries.forEach((ts) -> ts.resetZoom()) | |
256 | + @timeSeries.forEach((ts) -> ts.resetZoom()) | |
243 | 257 | @orbits.resetZoom() |
258 | + @setStartAndStop(@started_at, @stopped_at) | |
259 | + this | |
260 | + | |
261 | + setStartAndStop: (started_at, stopped_at) -> | |
262 | + @current_started_at = started_at | |
263 | + @current_stopped_at = stopped_at | |
264 | + $("\#started_at").val(started_at.format(INPUT_TIME_FORMAT)) | |
265 | + $("\#stopped_at").val(stopped_at.format(INPUT_TIME_FORMAT)) | |
266 | + this | |
244 | 267 | |
245 | 268 | |
246 | 269 | ... | ... |
web/view/home.html.jinja2
... | ... | @@ -425,7 +425,12 @@ jQuery().ready(function($){ |
425 | 425 | } |
426 | 426 | return false; |
427 | 427 | }); |
428 | - | |
428 | + $('#apply_new_interval').on("click", function(e){ | |
429 | + var started_at = moment($("#started_at").val()); | |
430 | + var stopped_at = moment($("#stopped_at").val()); | |
431 | + sw.resizeDomain(started_at, stopped_at); | |
432 | + return false; | |
433 | + }) | |
429 | 434 | |
430 | 435 | }); |
431 | 436 | </script> | ... | ... |