Commit a21f81d9ba6c72b12ffeb0e2b4dd8e1286b9b1f4
1 parent
7d6dee0f
Exists in
master
and in
3 other branches
Enable Venus and Mars.
Showing
6 changed files
with
119 additions
and
77 deletions
Show diff stats
config.yml
@@ -66,7 +66,8 @@ targets: | @@ -66,7 +66,8 @@ targets: | ||
66 | slug: 'mercury' | 66 | slug: 'mercury' |
67 | name: 'Mercury' | 67 | name: 'Mercury' |
68 | title: 'Mercury (coming soon)' | 68 | title: 'Mercury (coming soon)' |
69 | - orbit: 'mercury_orb_all' | 69 | + orbit: |
70 | + model: 'mercury_orb_all' | ||
70 | models: | 71 | models: |
71 | - slug: 'tao_mercury_sw' | 72 | - slug: 'tao_mercury_sw' |
72 | started_at: "1990-01-01T01:30:00" | 73 | started_at: "1990-01-01T01:30:00" |
@@ -76,62 +77,76 @@ targets: | @@ -76,62 +77,76 @@ targets: | ||
76 | - type: 'planet' | 77 | - type: 'planet' |
77 | slug: 'venus' | 78 | slug: 'venus' |
78 | name: 'Venus' | 79 | name: 'Venus' |
79 | - title: 'Venus (coming soon)' | ||
80 | - orbit: 'venus_orb_all' | 80 | + title: 'Venus' |
81 | + orbit: | ||
82 | + model: 'venus_orb_all' | ||
83 | + semimajor: 0.72333199 | ||
84 | + semiminor: 0.7233154 | ||
81 | models: | 85 | models: |
82 | - slug: 'tao_venus_sw' | 86 | - slug: 'tao_venus_sw' |
83 | started_at: "1990-01-01T01:30:00" | 87 | started_at: "1990-01-01T01:30:00" |
84 | stopped_at: "2017-02-19T00:00:00" | 88 | stopped_at: "2017-02-19T00:00:00" |
85 | - locked: true | 89 | + locked: false |
86 | default: true | 90 | default: true |
87 | - type: 'planet' | 91 | - type: 'planet' |
88 | slug: 'earth' | 92 | slug: 'earth' |
89 | name: 'Earth' | 93 | name: 'Earth' |
90 | title: 'Earth (coming soon)' | 94 | title: 'Earth (coming soon)' |
91 | - orbit: 'earth_orb_all' | 95 | + orbit: |
96 | + model: 'earth_orb_all' | ||
92 | #model: 'tao_earth_sw' | 97 | #model: 'tao_earth_sw' |
93 | locked: true | 98 | locked: true |
94 | default: true | 99 | default: true |
95 | - type: 'planet' | 100 | - type: 'planet' |
96 | slug: 'mars' | 101 | slug: 'mars' |
97 | name: 'Mars' | 102 | name: 'Mars' |
98 | - title: 'Mars (coming soon)' | ||
99 | - orbit: 'mars_orb_all' | 103 | + title: 'Mars' |
100 | models: | 104 | models: |
101 | - slug: 'tao_mars_sw' | 105 | - slug: 'tao_mars_sw' |
102 | started_at: "1990-01-01T01:30:00" | 106 | started_at: "1990-01-01T01:30:00" |
103 | stopped_at: "2017-02-19T00:00:00" | 107 | stopped_at: "2017-02-19T00:00:00" |
108 | + orbit: | ||
109 | + model: 'mars_orb_all' | ||
110 | + semimajor: 1.52366231 | ||
111 | + semiminor: 1.51700011 | ||
104 | locked: false | 112 | locked: false |
105 | default: true | 113 | default: true |
106 | - type: 'planet' | 114 | - type: 'planet' |
107 | slug: 'jupiter' | 115 | slug: 'jupiter' |
108 | name: 'Jupiter' | 116 | name: 'Jupiter' |
109 | title: 'Jupiter' | 117 | title: 'Jupiter' |
110 | - orbit: 'jupiter_orb_all' | ||
111 | models: | 118 | models: |
112 | - slug: 'tao_jup_sw' | 119 | - slug: 'tao_jup_sw' |
113 | started_at: "1990-01-01T01:30:00" | 120 | started_at: "1990-01-01T01:30:00" |
114 | stopped_at: "2017-02-19T00:00:00" | 121 | stopped_at: "2017-02-19T00:00:00" |
115 | - started_at: "1990-01-01T01:30:00" | ||
116 | - stopped_at: "2017-02-19T00:00:00" | 122 | +# started_at: "1990-01-01T01:30:00" |
123 | +# stopped_at: "2017-02-19T00:00:00" | ||
124 | + orbit: | ||
125 | + model: 'jupiter_orb_all' | ||
126 | + semimajor: 5.45516759 | ||
127 | + semiminor: 4.95155843 | ||
117 | locked: false | 128 | locked: false |
118 | default: true | 129 | default: true |
119 | - type: 'planet' | 130 | - type: 'planet' |
120 | slug: 'saturn' | 131 | slug: 'saturn' |
121 | name: 'Saturn' | 132 | name: 'Saturn' |
122 | - title: 'Saturn (coming soon)' | ||
123 | - orbit: 'saturn_orb_all' | 133 | + title: 'Saturn' |
134 | + orbit: | ||
135 | + model: 'saturn_orb_all' | ||
136 | + semimajor: 9.53707032 | ||
137 | + semiminor: 9.5230773 | ||
124 | models: | 138 | models: |
125 | - slug: 'tao_sat_sw' | 139 | - slug: 'tao_sat_sw' |
126 | started_at: "1990-01-01T01:30:00" | 140 | started_at: "1990-01-01T01:30:00" |
127 | stopped_at: "2017-02-19T00:00:00" | 141 | stopped_at: "2017-02-19T00:00:00" |
128 | - locked: true | 142 | + locked: false |
129 | default: true | 143 | default: true |
130 | - type: 'probe' | 144 | - type: 'probe' |
131 | slug: 'rosetta' | 145 | slug: 'rosetta' |
132 | name: 'Rosetta' | 146 | name: 'Rosetta' |
133 | title: 'Rosetta (coming soon)' | 147 | title: 'Rosetta (coming soon)' |
134 | - orbit: 'ros_orb_cruise' | 148 | + orbit: |
149 | + model: 'ros_orb_cruise' | ||
135 | models: | 150 | models: |
136 | - slug: 'tao_ros_sw' | 151 | - slug: 'tao_ros_sw' |
137 | started_at: "1990-01-01T01:30:00" | 152 | started_at: "1990-01-01T01:30:00" |
@@ -142,7 +157,8 @@ targets: | @@ -142,7 +157,8 @@ targets: | ||
142 | slug: 'juno' | 157 | slug: 'juno' |
143 | name: 'Juno' | 158 | name: 'Juno' |
144 | title: 'Juno (coming soon)' | 159 | title: 'Juno (coming soon)' |
145 | - orbit: 'juno_cruise_all' | 160 | + orbit: |
161 | + model: 'juno_cruise_all' | ||
146 | models: | 162 | models: |
147 | - slug: 'tao_juno_sw' | 163 | - slug: 'tao_juno_sw' |
148 | started_at: "1990-01-01T01:30:00" | 164 | started_at: "1990-01-01T01:30:00" |
@@ -153,7 +169,8 @@ targets: | @@ -153,7 +169,8 @@ targets: | ||
153 | slug: 'tchouri' | 169 | slug: 'tchouri' |
154 | name: 'Tchouri' | 170 | name: 'Tchouri' |
155 | title: 'Tchouri (coming soon)' | 171 | title: 'Tchouri (coming soon)' |
156 | - orbit: 'p67_orb_all' | 172 | + orbit: |
173 | + model: 'p67_orb_all' | ||
157 | locked: true | 174 | locked: true |
158 | default: false | 175 | default: false |
159 | 176 |
web/run.py
@@ -281,7 +281,7 @@ def get_orbiter_csv(source): | @@ -281,7 +281,7 @@ def get_orbiter_csv(source): | ||
281 | # http://cdpp.irap.omp.eu/BASE/DDService/getDataUrl.php?dataSet=jupiter_orb_all&StartTime=2014-02-23T10:00:10&StopTime=2017-02-24T23:59:00 | 281 | # http://cdpp.irap.omp.eu/BASE/DDService/getDataUrl.php?dataSet=jupiter_orb_all&StartTime=2014-02-23T10:00:10&StopTime=2017-02-24T23:59:00 |
282 | # http://cdpp.irap.omp.eu/BASE/DATA/TAO/JUPITER/SW/sw_2014.nc.gz | 282 | # http://cdpp.irap.omp.eu/BASE/DATA/TAO/JUPITER/SW/sw_2014.nc.gz |
283 | model_files = retrieve_data(source, model_slug, started_at, stopped_at) | 283 | model_files = retrieve_data(source, model_slug, started_at, stopped_at) |
284 | - orbits_files = retrieve_data(source, source_config['orbit'], started_at, stopped_at) | 284 | + orbits_files = retrieve_data(source, source_config['orbit']['model'], started_at, stopped_at) |
285 | 285 | ||
286 | si = StringIO.StringIO() | 286 | si = StringIO.StringIO() |
287 | cw = csv_writer(si) | 287 | cw = csv_writer(si) |
web/static/js/swapp.js
@@ -46,10 +46,11 @@ | @@ -46,10 +46,11 @@ | ||
46 | return this; | 46 | return this; |
47 | }; | 47 | }; |
48 | SpaceWeather.prototype.resize = function(){ | 48 | SpaceWeather.prototype.resize = function(){ |
49 | + var ref$; | ||
49 | timeSeries.forEach(function(ts){ | 50 | timeSeries.forEach(function(ts){ |
50 | return ts.resize(); | 51 | return ts.resize(); |
51 | }); | 52 | }); |
52 | - return typeof orbits != 'undefined' && orbits !== null ? orbits.resize() : void 8; | 53 | + return (ref$ = this.orbits) != null ? ref$.resize() : void 8; |
53 | }; | 54 | }; |
54 | SpaceWeather.prototype.init = function(){ | 55 | SpaceWeather.prototype.init = function(){ |
55 | var active_sources, res$, k, this$ = this; | 56 | var active_sources, res$, k, this$ = this; |
@@ -60,10 +61,13 @@ | @@ -60,10 +61,13 @@ | ||
60 | } | 61 | } |
61 | } | 62 | } |
62 | active_sources = res$; | 63 | active_sources = res$; |
64 | + this.orbits = new Orbits(this.configuration.orbits_container, this.configuration); | ||
63 | return active_sources.forEach(function(source){ | 65 | 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){ | 66 | return this$.loadData(source.slug, '2016-01-01T00:00:00', '2023-01-01T00:00:00').then(function(data){ |
67 | + console.info("Loaded CSV data for " + source.slug + "."); | ||
65 | this$.createTimeSeries(source, data); | 68 | this$.createTimeSeries(source, data); |
66 | - return this$.orbits = new Orbits(this$.configuration.sources, data['hci'], this$.configuration.orbits_container, this$.configuration); | 69 | + console.log("HOOOOOO"); |
70 | + return this$.orbits.initOrbiter(source.slug, source.config, data['hci']); | ||
67 | }, function(data){ | 71 | }, function(data){ |
68 | return console.error('Failed to load SW data.', data); | 72 | return console.error('Failed to load SW data.', data); |
69 | }); | 73 | }); |
@@ -317,28 +321,24 @@ | @@ -317,28 +321,24 @@ | ||
317 | out$.Orbits = Orbits = (function(){ | 321 | out$.Orbits = Orbits = (function(){ |
318 | Orbits.displayName = 'Orbits'; | 322 | Orbits.displayName = 'Orbits'; |
319 | var prototype = Orbits.prototype, constructor = Orbits; | 323 | var prototype = Orbits.prototype, constructor = Orbits; |
320 | - function Orbits(orbiters, data, container, options){ | ||
321 | - this.orbiters = orbiters; | ||
322 | - this.data = data; | 324 | + function Orbits(container, options){ |
323 | this.container = container; | 325 | this.container = container; |
324 | this.options = options != null | 326 | this.options = options != null |
325 | ? options | 327 | ? options |
326 | : {}; | 328 | : {}; |
327 | - console.log("Create orbits"); | ||
328 | this.init(); | 329 | this.init(); |
329 | } | 330 | } |
330 | Orbits.prototype.init = function(){ | 331 | Orbits.prototype.init = function(){ |
331 | - var slug, ref$, config; | ||
332 | - console.log("Initialize orbits", this.data, this.options); | 332 | + console.log("Initializing orbits...", this.options); |
333 | this.margin = { | 333 | this.margin = { |
334 | top: 30, | 334 | top: 30, |
335 | right: 20, | 335 | right: 20, |
336 | bottom: 42, | 336 | bottom: 42, |
337 | left: 60 | 337 | left: 60 |
338 | }; | 338 | }; |
339 | - this.extremum = 1.11 * d3.max(this.data, function(d){ | ||
340 | - return Math.max(Math.abs(d.x), Math.abs(d.y)); | ||
341 | - }); | 339 | + this.data = {}; |
340 | + this.orbiters = {}; | ||
341 | + this.extremum = 1; | ||
342 | this.xScale = d3.scaleLinear().domain([-1 * this.extremum, this.extremum]); | 342 | this.xScale = d3.scaleLinear().domain([-1 * this.extremum, this.extremum]); |
343 | this.yScale = d3.scaleLinear().domain([-1 * this.extremum, this.extremum]); | 343 | this.yScale = d3.scaleLinear().domain([-1 * this.extremum, this.extremum]); |
344 | this.xAxis = d3.axisBottom().ticks(10); | 344 | this.xAxis = d3.axisBottom().ticks(10); |
@@ -361,18 +361,20 @@ | @@ -361,18 +361,20 @@ | ||
361 | this.yAxisTitle.attr('transform', 'rotate(-90)'); | 361 | this.yAxisTitle.attr('transform', 'rotate(-90)'); |
362 | this.sun = this.plotWrapper.append("svg:image").attr('xlink:href', this.options.sun.img).attr('width', '32px').attr('height', '32px'); | 362 | this.sun = this.plotWrapper.append("svg:image").attr('xlink:href', this.options.sun.img).attr('width', '32px').attr('height', '32px'); |
363 | this.sun.append('svg:title').text("Sol"); | 363 | this.sun.append('svg:title').text("Sol"); |
364 | - for (slug in ref$ = this.orbiters) { | ||
365 | - config = ref$[slug]; | ||
366 | - this.initOrbiter(slug, config); | ||
367 | - } | ||
368 | return this.resize(); | 364 | return this.resize(); |
369 | }; | 365 | }; |
370 | Orbits.prototype.orbitersElements = {}; | 366 | Orbits.prototype.orbitersElements = {}; |
371 | - Orbits.prototype.initOrbiter = function(slug, config){ | 367 | + Orbits.prototype.initOrbiter = function(slug, config, data){ |
372 | var orbit_ellipse, orbiter, orbit_line, orbit_section, this$ = this; | 368 | var orbit_ellipse, orbiter, orbit_line, orbit_section, this$ = this; |
369 | + console.log("Initializing target " + slug + "'s orbit...", config, data); | ||
373 | if (slug in this.orbitersElements) { | 370 | if (slug in this.orbitersElements) { |
374 | throw new Error("Second init of " + slug); | 371 | throw new Error("Second init of " + slug); |
375 | } | 372 | } |
373 | + this.extremum = Math.max(this.extremum, 1.11 * d3.max(data, function(d){ | ||
374 | + return Math.max(Math.abs(d.x), Math.abs(d.y)); | ||
375 | + })); | ||
376 | + this.xScale = d3.scaleLinear().domain([-1 * this.extremum, this.extremum]); | ||
377 | + this.yScale = d3.scaleLinear().domain([-1 * this.extremum, this.extremum]); | ||
376 | orbit_ellipse = this.plotWrapper.append("svg:ellipse").classed('orbit orbit_ellipse', true); | 378 | orbit_ellipse = this.plotWrapper.append("svg:ellipse").classed('orbit orbit_ellipse', true); |
377 | orbiter = this.plotWrapper.append("svg:image").attr('xlink:href', config['img']).attr('width', '32px').attr('height', '32px'); | 379 | orbiter = this.plotWrapper.append("svg:image").attr('xlink:href', config['img']).attr('width', '32px').attr('height', '32px'); |
378 | orbit_line = d3.line().x(function(d){ | 380 | orbit_line = d3.line().x(function(d){ |
@@ -380,13 +382,16 @@ | @@ -380,13 +382,16 @@ | ||
380 | }).y(function(d){ | 382 | }).y(function(d){ |
381 | return this$.yScale(d.y); | 383 | return this$.yScale(d.y); |
382 | }); | 384 | }); |
383 | - orbit_section = this.plotWrapper.append('path').datum(this.data).classed('orbit orbit_section', true); | 385 | + orbit_section = this.plotWrapper.append('path').datum(data).classed('orbit orbit_section', true); |
386 | + this.orbiters[slug] = config; | ||
387 | + this.data[slug] = data; | ||
384 | this.orbitersElements[slug] = { | 388 | this.orbitersElements[slug] = { |
385 | orbiter: orbiter, | 389 | orbiter: orbiter, |
386 | orbit_ellipse: orbit_ellipse, | 390 | orbit_ellipse: orbit_ellipse, |
387 | orbit_section: orbit_section, | 391 | orbit_section: orbit_section, |
388 | orbit_line: orbit_line | 392 | orbit_line: orbit_line |
389 | }; | 393 | }; |
394 | + this.resize(); | ||
390 | return this; | 395 | return this; |
391 | }; | 396 | }; |
392 | Orbits.prototype.resize = function(){ | 397 | Orbits.prototype.resize = function(){ |
@@ -423,16 +428,16 @@ | @@ -423,16 +428,16 @@ | ||
423 | cx = width / 2 - c; | 428 | cx = width / 2 - c; |
424 | cy = height / 2; | 429 | cy = height / 2; |
425 | this.yScale.range([0, height]); | 430 | this.yScale.range([0, height]); |
426 | - el['orbit_ellipse'].attr('cx', cx).attr('cy', cy).attr('rx', this.xScale(a) - this.xScale(0)).attr('ry', this.yScale(b) - this.yScale(0)).attr('transform', 'rotate(66,' + (cx + c) + ', ' + cy + ')'); | 431 | + el['orbit_ellipse'].attr('cx', cx).attr('cy', cy).attr('rx', this.xScale(a) - this.xScale(0)).attr('ry', this.yScale(b) - this.yScale(0)); |
427 | this.yScale.range([height, 0]); | 432 | this.yScale.range([height, 0]); |
428 | - data = this.data; | 433 | + data = this.data[slug]; |
429 | el['orbiter'].attr('x', this.xScale(data[data.length - 1].x) - 16); | 434 | el['orbiter'].attr('x', this.xScale(data[data.length - 1].x) - 16); |
430 | el['orbiter'].attr('y', this.yScale(data[data.length - 1].y) - 16); | 435 | el['orbiter'].attr('y', this.yScale(data[data.length - 1].y) - 16); |
431 | return this; | 436 | return this; |
432 | }; | 437 | }; |
433 | Orbits.prototype.repositionOrbiter = function(slug, datum){ | 438 | Orbits.prototype.repositionOrbiter = function(slug, datum){ |
434 | var data, el; | 439 | var data, el; |
435 | - data = this.data; | 440 | + data = this.data[slug]; |
436 | datum == null && (datum = data[data.length - 1]); | 441 | datum == null && (datum = data[data.length - 1]); |
437 | el = this.orbitersElements[slug]; | 442 | el = this.orbitersElements[slug]; |
438 | el['orbiter'].attr('x', this.xScale(datum.x) - 16); | 443 | el['orbiter'].attr('x', this.xScale(datum.x) - 16); |
@@ -443,10 +448,13 @@ | @@ -443,10 +448,13 @@ | ||
443 | return d.t; | 448 | return d.t; |
444 | }).left; | 449 | }).left; |
445 | Orbits.prototype.moveToDate = function(t){ | 450 | Orbits.prototype.moveToDate = function(t){ |
446 | - var slug, ref$, el, data, i, d0, d1, d, results$ = []; | 451 | + var slug, ref$, el, data, i, d0, d1, d; |
452 | + if (!t) { | ||
453 | + console.log("Trying to move to an undefined date"); | ||
454 | + } | ||
447 | for (slug in ref$ = this.orbitersElements) { | 455 | for (slug in ref$ = this.orbitersElements) { |
448 | el = ref$[slug]; | 456 | el = ref$[slug]; |
449 | - data = this.data; | 457 | + data = this.data[slug]; |
450 | i = this.bisectDate(data, t, 1); | 458 | i = this.bisectDate(data, t, 1); |
451 | d0 = data[i - 1]; | 459 | d0 = data[i - 1]; |
452 | d1 = data[i]; | 460 | d1 = data[i]; |
@@ -454,9 +462,9 @@ | @@ -454,9 +462,9 @@ | ||
454 | continue; | 462 | continue; |
455 | } | 463 | } |
456 | d = t - d0.t > d1.t - t ? d1 : d0; | 464 | d = t - d0.t > d1.t - t ? d1 : d0; |
457 | - results$.push(this.repositionOrbiter(slug, d)); | 465 | + this.repositionOrbiter(slug, d); |
458 | } | 466 | } |
459 | - return results$; | 467 | + return this; |
460 | }; | 468 | }; |
461 | return Orbits; | 469 | return Orbits; |
462 | }()); | 470 | }()); |
web/static/js/swapp.ls
1 | # Livescript transpiles to javascript, and is easier on the eyes and brain. | 1 | # Livescript transpiles to javascript, and is easier on the eyes and brain. |
2 | # http://livescript.net | 2 | # http://livescript.net |
3 | 3 | ||
4 | +# To compile it to javascript, and generate `swapp.js` : | ||
5 | +# $ lsc --compile swapp.ls | ||
6 | + | ||
4 | const GOLDEN_RATIO = 2 / (1 + Math.sqrt(5)) | 7 | const GOLDEN_RATIO = 2 / (1 + Math.sqrt(5)) |
5 | 8 | ||
6 | ############################################################################### | 9 | ############################################################################### |
@@ -39,16 +42,19 @@ export class SpaceWeather | @@ -39,16 +42,19 @@ export class SpaceWeather | ||
39 | 42 | ||
40 | resize: -> | 43 | resize: -> |
41 | timeSeries.forEach((ts) -> ts.resize()) | 44 | timeSeries.forEach((ts) -> ts.resize()) |
42 | - orbits?.resize(); | 45 | + @orbits?.resize(); |
43 | 46 | ||
44 | init: -> | 47 | init: -> |
45 | active_sources = [ @sources[k] for k of @sources when @sources[k].config.active ] | 48 | active_sources = [ @sources[k] for k of @sources when @sources[k].config.active ] |
49 | +# @orbits = new Orbits(@configuration.sources, data['hci'], @configuration.orbits_container, @configuration) | ||
50 | + @orbits = new Orbits(@configuration.orbits_container, @configuration) | ||
46 | active_sources.forEach((source) ~> | 51 | active_sources.forEach((source) ~> |
47 | @loadData(source.slug, '2016-01-01T00:00:00', '2023-01-01T00:00:00').then( | 52 | @loadData(source.slug, '2016-01-01T00:00:00', '2023-01-01T00:00:00').then( |
48 | (data) ~> | 53 | (data) ~> |
54 | + console.info "Loaded CSV data for #{source.slug}." | ||
49 | @createTimeSeries(source, data) | 55 | @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, @configuration) | 56 | + console.log "HOOOOOO" |
57 | + @orbits.initOrbiter(source.slug, source.config, data['hci']) | ||
52 | , | 58 | , |
53 | (data) ~> console.error('Failed to load SW data.', data) | 59 | (data) ~> console.error('Failed to load SW data.', data) |
54 | ) | 60 | ) |
@@ -328,12 +334,11 @@ export class Orbits | @@ -328,12 +334,11 @@ export class Orbits | ||
328 | # View of the solar system from above, with orbits segments for selected time | 334 | # View of the solar system from above, with orbits segments for selected time |
329 | # interval, from real data. | 335 | # interval, from real data. |
330 | 336 | ||
331 | - (@orbiters, @data, @container, @options = {}) -> | ||
332 | - console.log "Create orbits" | 337 | + (@container, @options = {}) -> |
333 | @init() | 338 | @init() |
334 | 339 | ||
335 | init: -> | 340 | init: -> |
336 | - console.log "Initialize orbits", @data, @options | 341 | + console.log "Initializing orbits...", @options |
337 | 342 | ||
338 | @margin = { | 343 | @margin = { |
339 | top: 30, | 344 | top: 30, |
@@ -341,11 +346,10 @@ export class Orbits | @@ -341,11 +346,10 @@ export class Orbits | ||
341 | bottom: 42, | 346 | bottom: 42, |
342 | left: 60 | 347 | left: 60 |
343 | } | 348 | } |
344 | - | ||
345 | - @extremum = 1.11 * d3.max(@data, (d) -> | ||
346 | - Math.max(Math.abs(d.x), Math.abs(d.y)) | ||
347 | - ) | ||
348 | 349 | ||
350 | + @data = {} # slug => HCI array | ||
351 | + @orbiters = {} # slug => config | ||
352 | + @extremum = 1 | ||
349 | @xScale = d3.scaleLinear().domain([-1 * @extremum, @extremum]) | 353 | @xScale = d3.scaleLinear().domain([-1 * @extremum, @extremum]) |
350 | @yScale = d3.scaleLinear().domain([-1 * @extremum, @extremum]) | 354 | @yScale = d3.scaleLinear().domain([-1 * @extremum, @extremum]) |
351 | 355 | ||
@@ -381,15 +385,22 @@ export class Orbits | @@ -381,15 +385,22 @@ export class Orbits | ||
381 | .attr('width', '32px').attr('height', '32px') | 385 | .attr('width', '32px').attr('height', '32px') |
382 | @sun.append('svg:title').text("Sol") | 386 | @sun.append('svg:title').text("Sol") |
383 | 387 | ||
384 | - for slug, config of @orbiters | ||
385 | - @initOrbiter(slug, config) | 388 | +# for slug, config of @orbiters |
389 | +# @initOrbiter(slug, config) | ||
386 | 390 | ||
387 | @resize() | 391 | @resize() |
388 | 392 | ||
389 | orbitersElements: {} | 393 | orbitersElements: {} |
390 | - initOrbiter: (slug, config) -> | 394 | + initOrbiter: (slug, config, data) -> |
395 | + console.log("Initializing target #{slug}'s orbit...", config, data) | ||
391 | if slug of @orbitersElements then throw new Error("Second init of #{slug}") | 396 | if slug of @orbitersElements then throw new Error("Second init of #{slug}") |
392 | 397 | ||
398 | + @extremum = Math.max(@extremum, 1.11 * d3.max(data, (d) -> | ||
399 | + Math.max(Math.abs(d.x), Math.abs(d.y)) | ||
400 | + )) | ||
401 | + @xScale = d3.scaleLinear().domain([-1 * @extremum, @extremum]) | ||
402 | + @yScale = d3.scaleLinear().domain([-1 * @extremum, @extremum]) | ||
403 | + | ||
393 | # The order is important, as it will define the default z-order | 404 | # The order is important, as it will define the default z-order |
394 | orbit_ellipse = @plotWrapper.append("svg:ellipse") | 405 | orbit_ellipse = @plotWrapper.append("svg:ellipse") |
395 | .classed('orbit orbit_ellipse', true) | 406 | .classed('orbit orbit_ellipse', true) |
@@ -402,15 +413,19 @@ export class Orbits | @@ -402,15 +413,19 @@ export class Orbits | ||
402 | .y((d) ~> @yScale(d.y)) | 413 | .y((d) ~> @yScale(d.y)) |
403 | 414 | ||
404 | orbit_section = @plotWrapper.append('path') | 415 | orbit_section = @plotWrapper.append('path') |
405 | - .datum(@data) # fixme | 416 | + .datum(data) |
406 | .classed('orbit orbit_section', true) | 417 | .classed('orbit orbit_section', true) |
407 | 418 | ||
419 | + @orbiters[slug] = config | ||
420 | + @data[slug] = data | ||
408 | @orbitersElements[slug] = | 421 | @orbitersElements[slug] = |
409 | orbiter: orbiter | 422 | orbiter: orbiter |
410 | orbit_ellipse: orbit_ellipse | 423 | orbit_ellipse: orbit_ellipse |
411 | orbit_section: orbit_section | 424 | orbit_section: orbit_section |
412 | orbit_line: orbit_line | 425 | orbit_line: orbit_line |
413 | 426 | ||
427 | + @resize() | ||
428 | + | ||
414 | this | 429 | this |
415 | 430 | ||
416 | resize: -> | 431 | resize: -> |
@@ -465,10 +480,10 @@ export class Orbits | @@ -465,10 +480,10 @@ export class Orbits | ||
465 | el['orbit_ellipse'].attr('cx', cx).attr('cy', cy) | 480 | el['orbit_ellipse'].attr('cx', cx).attr('cy', cy) |
466 | .attr('rx', @xScale(a) - @xScale(0)) | 481 | .attr('rx', @xScale(a) - @xScale(0)) |
467 | .attr('ry', @yScale(b) - @yScale(0)) | 482 | .attr('ry', @yScale(b) - @yScale(0)) |
468 | - .attr('transform', 'rotate(66,'+(cx+c)+', '+cy+')') | 483 | +# .attr('transform', 'rotate(66,'+(cx+c)+', '+cy+')') |
469 | @yScale.range([height, 0]) | 484 | @yScale.range([height, 0]) |
470 | 485 | ||
471 | - data = @data # todo: multiple orbiters | 486 | + data = @data[slug] |
472 | 487 | ||
473 | el['orbiter'].attr('x', @xScale(data[data.length - 1].x) - 16) | 488 | el['orbiter'].attr('x', @xScale(data[data.length - 1].x) - 16) |
474 | el['orbiter'].attr('y', @yScale(data[data.length - 1].y) - 16) | 489 | el['orbiter'].attr('y', @yScale(data[data.length - 1].y) - 16) |
@@ -476,24 +491,25 @@ export class Orbits | @@ -476,24 +491,25 @@ export class Orbits | ||
476 | this | 491 | this |
477 | 492 | ||
478 | repositionOrbiter: (slug, datum) -> | 493 | repositionOrbiter: (slug, datum) -> |
479 | - data = @data # todo | 494 | + data = @data[slug] |
480 | datum ?= data[data.length - 1] | 495 | datum ?= data[data.length - 1] |
481 | el = @orbitersElements[slug] | 496 | el = @orbitersElements[slug] |
482 | el['orbiter'].attr('x', @xScale(datum.x) - 16) | 497 | el['orbiter'].attr('x', @xScale(datum.x) - 16) |
483 | el['orbiter'].attr('y', @yScale(datum.y) - 16) | 498 | el['orbiter'].attr('y', @yScale(datum.y) - 16) |
484 | - | ||
485 | this | 499 | this |
486 | 500 | ||
487 | bisectDate: d3.bisector((d) -> d.t).left | 501 | bisectDate: d3.bisector((d) -> d.t).left |
488 | 502 | ||
489 | moveToDate: (t) -> | 503 | moveToDate: (t) -> |
504 | + console.log("Trying to move to an undefined date") unless t | ||
490 | for slug, el of @orbitersElements | 505 | for slug, el of @orbitersElements |
491 | - data = @data # todo: multiple orbiters | 506 | + data = @data[slug] |
492 | i = @bisectDate(data, t, 1) | 507 | i = @bisectDate(data, t, 1) |
493 | d0 = data[i - 1] | 508 | d0 = data[i - 1] |
494 | d1 = data[i] | 509 | d1 = data[i] |
495 | continue unless d1 and d0 | 510 | continue unless d1 and d0 |
496 | d = if t - d0.t > d1.t - t then d1 else d0 | 511 | d = if t - d0.t > d1.t - t then d1 else d0 |
497 | @repositionOrbiter(slug, d) # fixme | 512 | @repositionOrbiter(slug, d) # fixme |
513 | + this | ||
498 | 514 | ||
499 | 515 |
web/view/home.html.jinja2
@@ -165,24 +165,25 @@ var configuration = { | @@ -165,24 +165,25 @@ var configuration = { | ||
165 | img: '{{ static('img/sun_128.png') }}' | 165 | img: '{{ static('img/sun_128.png') }}' |
166 | }, | 166 | }, |
167 | sources : { | 167 | sources : { |
168 | - jupiter: { | ||
169 | - slug: 'jupiter', | ||
170 | - name: 'Jupiter', | 168 | +{% for target in targets if not target.locked%} |
169 | + {% if not loop.first %},{% endif %} | ||
170 | + '{{ target.slug }}': { | ||
171 | + slug: '{{ target.slug }}', | ||
172 | + name: '{{ target.name }}', | ||
171 | active: true, | 173 | active: true, |
172 | - minDate: '1990-01-01T01:30:00', | ||
173 | - maxDate: '2017-02-19T00:00:00', | ||
174 | - orbit: { a: 5.45516759, b: 4.95155843 }, | ||
175 | - img: '{{ static('img/target/jupiter_128.png') }}' | ||
176 | - }, | ||
177 | - mars: { | ||
178 | - slug: 'mars', | ||
179 | - name: 'Mars', | ||
180 | - active: true, | ||
181 | - minDate: '1990-01-01T01:30:00', | ||
182 | - maxDate: '2017-02-19T00:00:00', | ||
183 | - orbit: { a: 5.25516759, b: 4.85155843 }, | ||
184 | - img: '{{ static('img/target/mars_128.png') }}' | 174 | + orbit: { a: {{ target.orbit.semimajor }}, b: {{ target.orbit.semiminor }} }, |
175 | + img: '{{ static('img/target/'~target.slug~'_128.png') }}' | ||
185 | } | 176 | } |
177 | +{% endfor %} | ||
178 | +{# jupiter: {#} | ||
179 | +{# slug: 'jupiter',#} | ||
180 | +{# name: 'Jupiter',#} | ||
181 | +{# active: true,#} | ||
182 | +{# minDate: '1990-01-01T01:30:00',#} | ||
183 | +{# maxDate: '2017-02-19T00:00:00',#} | ||
184 | +{# orbit: { a: 5.45516759, b: 4.95155843 },#} | ||
185 | +{# img: '{{ static('img/target/jupiter_128.png') }}'#} | ||
186 | +{# },#} | ||
186 | }, | 187 | }, |
187 | {# todo @Nicolas Define -somehow- error margins of each parameter #} | 188 | {# todo @Nicolas Define -somehow- error margins of each parameter #} |
188 | parameters : [ | 189 | parameters : [ |
web/view/layout.html.jinja2
@@ -32,7 +32,7 @@ | @@ -32,7 +32,7 @@ | ||
32 | 32 | ||
33 | <header class="header mdl-layout__header"> | 33 | <header class="header mdl-layout__header"> |
34 | <div class="mdl-layout__header-row"> | 34 | <div class="mdl-layout__header-row"> |
35 | - <span class="mdl-layout-title">CDPP / Solar Wind Prediction @ Planets</span> | 35 | + <span class="mdl-layout-title">CDPP / Heliopropa</span> |
36 | <!-- Add spacer, to align navigation to the right --> | 36 | <!-- Add spacer, to align navigation to the right --> |
37 | <div class="mdl-layout-spacer"></div> | 37 | <div class="mdl-layout-spacer"></div> |
38 | <!-- Navigation. We hide it in small screens. --> | 38 | <!-- Navigation. We hide it in small screens. --> |