Commit fe3132dd4aa9260bee2dcae60e29e224a51a99a2

Authored by Goutte
1 parent 4816cef4

Refactor even more.

CHANGELOG.md
1 1 ## TO DO
2 2  
3 3 - Add source name on time series
  4 +- Support multiple sources
4 5 - Start/Stop datetime fields
5 6 - Play button to start time dimension
6   -- Download raw data (as CSV) for time interval
  7 +- Download raw data (as CSV) for current time interval
7 8 - Same via SAMP
8 9  
9 10 ## 0.0.0
... ...
web/static/js/swapp.js
... ... @@ -6,9 +6,18 @@
6 6 SpaceWeather.displayName = 'SpaceWeather';
7 7 var prototype = SpaceWeather.prototype, constructor = SpaceWeather;
8 8 function SpaceWeather(configuration){
  9 + var configs, res$, k, this$ = this;
9 10 this.configuration = configuration;
10   - console.info("Creating Space Weather app...", configuration);
  11 + console.info("Creating Space Weather app...", this.configuration);
11 12 this.sources = {};
  13 + res$ = [];
  14 + for (k in this.configuration.sources) {
  15 + res$.push(this.configuration.sources[k]);
  16 + }
  17 + configs = res$;
  18 + configs.forEach(function(source_config){
  19 + return this$.sources[source_config.slug] = new Source(source_config.slug, source_config.name, source_config);
  20 + });
12 21 }
13 22 SpaceWeather.prototype.buildDataUrlForSource = function(source_slug){
14 23 var url;
... ... @@ -36,6 +45,30 @@
36 45 source.hide();
37 46 return this;
38 47 };
  48 + SpaceWeather.prototype.resize = function(){
  49 + timeSeries.forEach(function(ts){
  50 + return ts.resize();
  51 + });
  52 + return typeof orbits != 'undefined' && orbits !== null ? orbits.resize() : void 8;
  53 + };
  54 + SpaceWeather.prototype.init = function(){
  55 + var active_sources, res$, k, this$ = this;
  56 + res$ = [];
  57 + for (k in this.sources) {
  58 + if (this.sources[k].config.active) {
  59 + res$.push(this.sources[k]);
  60 + }
  61 + }
  62 + active_sources = res$;
  63 + return active_sources.forEach(function(source){
  64 + return this$.loadData(source.slug, '2016-01-01T00:00:00', '2023-01-01T00:00:00').then(function(data){
  65 + this$.createTimeSeries(source, data);
  66 + return this$.orbits = new Orbits(configuration.sources, data['hci'], configuration.orbits_container);
  67 + }, function(data){
  68 + return console.error('Failed to load SW data.', data);
  69 + });
  70 + });
  71 + };
39 72 SpaceWeather.prototype.loadData = function(source_slug, started_at, stopped_at){
40 73 var sw, promise;
41 74 sw = this;
... ... @@ -75,8 +108,8 @@
75 108 });
76 109 return promise;
77 110 };
78   - SpaceWeather.prototype.createTimeSeries = function(data){
79   - var timeSeries;
  111 + SpaceWeather.prototype.createTimeSeries = function(source, data){
  112 + var timeSeries, this$ = this;
80 113 timeSeries = [];
81 114 this.configuration['parameters'].forEach(function(parameter){
82 115 var container, id, title;
... ... @@ -86,7 +119,7 @@
86 119 if (!(id in data)) {
87 120 console.error("No data for id '" + id + "'.", data);
88 121 }
89   - return timeSeries.push(new TimeSeries(id, title, data[id], container));
  122 + return timeSeries.push(new TimeSeries(id, title, source, data[id], container));
90 123 });
91 124 return timeSeries.forEach(function(ts){
92 125 ts.options['onMouseOver'] = function(){
... ... @@ -100,10 +133,11 @@
100 133 });
101 134 };
102 135 return ts.options['onMouseMove'] = function(t){
  136 + var ref$;
103 137 timeSeries.forEach(function(ts2){
104 138 return ts2.moveCursor(t);
105 139 });
106   - return typeof orbits != 'undefined' && orbits !== null ? orbits.moveToDate(t) : void 8;
  140 + return (ref$ = this$.orbits) != null ? ref$.moveToDate(t) : void 8;
107 141 };
108 142 });
109 143 };
... ... @@ -112,8 +146,9 @@
112 146 Source = (function(){
113 147 Source.displayName = 'Source';
114 148 var prototype = Source.prototype, constructor = Source;
115   - function Source(slug, config){
  149 + function Source(slug, name, config){
116 150 this.slug = slug;
  151 + this.name = name;
117 152 this.config = config;
118 153 this.time_series = {};
119 154 }
... ... @@ -141,9 +176,10 @@
141 176 out$.TimeSeries = TimeSeries = (function(){
142 177 TimeSeries.displayName = 'TimeSeries';
143 178 var prototype = TimeSeries.prototype, constructor = TimeSeries;
144   - function TimeSeries(slug, title, data, container, options){
  179 + function TimeSeries(slug, title, source, data, container, options){
145 180 this.slug = slug;
146 181 this.title = title;
  182 + this.source = source;
147 183 this.data = data;
148 184 this.container = container;
149 185 this.options = options != null
... ... @@ -162,7 +198,7 @@
162 198 top: 30,
163 199 right: 20,
164 200 bottom: 30,
165   - left: 60
  201 + left: 80
166 202 };
167 203 this.xScale = d3.scaleTime().domain(d3.extent(this.data, function(d){
168 204 return d.x;
... ... @@ -187,6 +223,7 @@
187 223 this.plotWrapper.append('g').classed('x axis', true);
188 224 this.plotWrapper.append('g').classed('y axis', true);
189 225 this.yAxisText = this.plotWrapper.append("text").attr("transform", "rotate(-90)").attr("dy", "1em").style("text-anchor", "middle").text(this.title);
  226 + this.yAxisTextSource = this.plotWrapper.append("text").attr("transform", "rotate(-90)").attr("dy", "1em").style("text-anchor", "middle").style("font-style", "oblique").text(this.source.name);
190 227 this.focus = this.plotWrapper.append('g').style("display", "none");
191 228 this.cursorCircle = this.focus.append("circle").attr("class", "cursor-circle").attr("r", 3);
192 229 dx = 8;
... ... @@ -213,7 +250,8 @@
213 250 this.yAxis.ticks(Math.floor(height / 18));
214 251 this.svg.select('.x.axis').attr('transform', 'translate(0,' + height + ')').call(this.xAxis);
215 252 this.svg.select('.y.axis').call(this.yAxis);
216   - this.yAxisText.attr("y", 0 - this.margin.left).attr("x", 0 - height / 2);
  253 + this.yAxisText.attr("y", 20 - this.margin.left).attr("x", 0 - height / 2);
  254 + this.yAxisTextSource.attr("y", 0 - this.margin.left).attr("x", 0 - height / 2);
217 255 this.mouseCanvas.attr("width", width).attr("height", height);
218 256 return this;
219 257 };
... ...
web/static/js/swapp.ls
... ... @@ -8,8 +8,12 @@ const GOLDEN_RATIO = 2 / (1 + Math.sqrt(5))
8 8 export class SpaceWeather
9 9  
10 10 (@configuration) ->
11   - console.info "Creating Space Weather app...", configuration
  11 + console.info "Creating Space Weather app...", @configuration
12 12 @sources = {}
  13 + configs = [@configuration.sources[k] for k of @configuration.sources]
  14 + configs.forEach((source_config) ~>
  15 + @sources[source_config.slug] = new Source(source_config.slug, source_config.name, source_config)
  16 + )
13 17  
14 18 buildDataUrlForSource: (source_slug) ->
15 19 url = @configuration['api']['data_for_interval']
... ... @@ -33,6 +37,23 @@ export class SpaceWeather
33 37 source.hide()
34 38 this
35 39  
  40 + resize: ->
  41 + timeSeries.forEach((ts) -> ts.resize())
  42 + orbits?.resize();
  43 +
  44 + init: ->
  45 + active_sources = [ @sources[k] for k of @sources when @sources[k].config.active ]
  46 + active_sources.forEach((source) ~>
  47 + @loadData(source.slug, '2016-01-01T00:00:00', '2023-01-01T00:00:00').then(
  48 + (data) ~>
  49 + @createTimeSeries(source, data)
  50 + # fixme: don't create a new Orbits instance every time
  51 + @orbits = new Orbits(configuration.sources, data['hci'], configuration.orbits_container)
  52 + ,
  53 + (data) ~> console.error('Failed to load SW data.', data)
  54 + )
  55 + )
  56 +
36 57 loadData: (source_slug, started_at, stopped_at) ->
37 58 sw = this
38 59 promise = new Promise((resolve, reject) ->
... ... @@ -57,29 +78,29 @@ export class SpaceWeather
57 78 )
58 79 promise
59 80  
60   - createTimeSeries: (data) ->
  81 + createTimeSeries: (source, data) ->
61 82 timeSeries = []
62 83 @configuration['parameters'].forEach((parameter) ->
63 84 container = @configuration['time_series_container']
64 85 id = parameter['id'] ; title = parameter['title']
65 86 if id not of data then console.error("No data for id '#{id}'.", data)
66   - timeSeries.push(new TimeSeries(id, title, data[id], container))
  87 + timeSeries.push(new TimeSeries(id, title, source, data[id], container))
67 88 )
68   - timeSeries.forEach((ts) ->
  89 + timeSeries.forEach((ts) ~>
69 90 ts.options['onMouseOver'] = ->
70 91 timeSeries.forEach((ts2) -> ts2.showCursor())
71 92 ts.options['onMouseOut'] = ->
72 93 timeSeries.forEach((ts2) -> ts2.hideCursor())
73   - ts.options['onMouseMove'] = (t) ->
  94 + ts.options['onMouseMove'] = (t) ~>
74 95 timeSeries.forEach((ts2) -> ts2.moveCursor(t))
75   - orbits?.moveToDate(t)
  96 + @orbits?.moveToDate(t)
76 97 )
77 98  
78 99  
79 100  
80 101  
81 102 class Source
82   - (@slug, @config) ->
  103 + (@slug, @name, @config) ->
83 104 @time_series = {}
84 105  
85 106 addTimeSeries: (ts) ->
... ... @@ -102,7 +123,7 @@ export class TimeSeries
102 123 # Time in x-axis
103 124 # Data in y-axis
104 125  
105   - (@slug, @title, @data, @container, @options = {}) ->
  126 + (@slug, @title, @source, @data, @container, @options = {}) ->
106 127 # title : string
107 128 # data : list of {x: <datetime>, y: <float>}
108 129 console.info "Creating time series '#{@title}'..."
... ... @@ -115,7 +136,7 @@ export class TimeSeries
115 136 top: 30,
116 137 right: 20,
117 138 bottom: 30,
118   - left: 60
  139 + left: 80
119 140 }
120 141  
121 142 @xScale = d3.scaleTime().domain(d3.extent(@data, (d) -> d.x))
... ... @@ -159,6 +180,12 @@ export class TimeSeries
159 180 .attr("dy", "1em")
160 181 .style("text-anchor", "middle")
161 182 .text(@title)
  183 + @yAxisTextSource = @plotWrapper.append("text")
  184 + .attr("transform", "rotate(-90)")
  185 + .attr("dy", "1em")
  186 + .style("text-anchor", "middle")
  187 + .style("font-style", "oblique")
  188 + .text(@source.name)
162 189  
163 190 @focus = @plotWrapper.append('g').style("display", "none")
164 191  
... ... @@ -221,9 +248,12 @@ export class TimeSeries
221 248 @svg.select('.y.axis')
222 249 .call(@yAxis)
223 250  
224   - @yAxisText.attr("y", 0 - @margin.left)
  251 + @yAxisText.attr("y", 20 - @margin.left)
225 252 .attr("x", 0 - (height / 2))
226 253  
  254 + @yAxisTextSource.attr("y", 0 - @margin.left)
  255 + .attr("x", 0 - (height / 2))
  256 +
227 257 @mouseCanvas.attr("width", width)
228 258 .attr("height", height)
229 259  
... ...
web/view/home.html.jinja2
... ... @@ -208,18 +208,8 @@ var configuration = {
208 208 };
209 209  
210 210 jQuery().ready(function($){
211   - var timeSeries = [];
212   - var orbits;
213   -
214 211 var sw = new SpaceWeather(configuration);
215   - sw.loadData('jupiter', '2016-01-01T00:00:00', '2023-01-01T00:00:00').then(
216   - function (data) {
217   - console.log('OK', data);
218   - sw.createTimeSeries(data);
219   - orbits = new Orbits(configuration.sources, data['hci'], configuration.orbits_container);
220   - },
221   - function (data) { console.error('Failed to load SW data.', data); }
222   - );
  212 + sw.init();
223 213  
224 214 var toggleTimeSeries = function(slug) {
225 215 $('#time_series .'+slug).toggleClass('hidden');
... ... @@ -232,8 +222,7 @@ jQuery().ready(function($){
232 222 });
233 223  
234 224 window.addEventListener('resize', function() {
235   - timeSeries.forEach(function(ts){ ts.resize(); });
236   - if (orbits) orbits.resize();
  225 + sw.resize();
237 226 });
238 227  
239 228 });
... ...