Blame view

web/static/js/swapp.js 21 KB
438929a4   Goutte   Rewrite the orbit...
1
2
// Generated by LiveScript 1.5.0
(function(){
ae0aa7d2   Goutte   Add an x axis lab...
3
  var GOLDEN_RATIO, SpaceWeather, Source, TimeSeries, Orbits, out$ = typeof exports != 'undefined' && exports || this;
438929a4   Goutte   Rewrite the orbit...
4
  GOLDEN_RATIO = 2 / (1 + Math.sqrt(5));
ae0aa7d2   Goutte   Add an x axis lab...
5
  out$.SpaceWeather = SpaceWeather = (function(){
4cf497e0   Goutte   Make the targets ...
6
    "The main app, instanciated from an inline script.";
ae0aa7d2   Goutte   Add an x axis lab...
7
    SpaceWeather.displayName = 'SpaceWeather';
7d6dee0f   Goutte   Continue refacto ...
8
    var timeSeries, prototype = SpaceWeather.prototype, constructor = SpaceWeather;
ae0aa7d2   Goutte   Add an x axis lab...
9
    function SpaceWeather(configuration){
fe3132dd   Goutte   Refactor even more.
10
      var configs, res$, k, this$ = this;
f75faf5f   Goutte   WIP
11
      this.configuration = configuration;
fe3132dd   Goutte   Refactor even more.
12
      console.info("Creating Space Weather app...", this.configuration);
f75faf5f   Goutte   WIP
13
      this.sources = {};
fe3132dd   Goutte   Refactor even more.
14
15
16
17
18
19
20
21
      res$ = [];
      for (k in this.configuration.sources) {
        res$.push(this.configuration.sources[k]);
      }
      configs = res$;
      configs.forEach(function(source_config){
        return this$.sources[source_config.slug] = new Source(source_config.slug, source_config.name, source_config);
      });
b7fe650c   Goutte   Misc bundle of ol...
22
23
24
25
      this.parameters = {};
      this.configuration['parameters'].forEach(function(p){
        return this$.parameters[p['id']] = p;
      });
ae0aa7d2   Goutte   Add an x axis lab...
26
    }
a4a9ef03   Goutte   Cache generated C...
27
    SpaceWeather.prototype.buildDataUrlForSource = function(source_slug, started_at, stopped_at){
f75faf5f   Goutte   WIP
28
29
30
      var url;
      url = this.configuration['api']['data_for_interval'];
      url = url.replace('<source>', source_slug);
a4a9ef03   Goutte   Cache generated C...
31
32
      url = url.replace('<started_at>', started_at);
      url = url.replace('<stopped_at>', stopped_at);
f75faf5f   Goutte   WIP
33
34
35
36
37
38
39
40
41
42
      return url;
    };
    SpaceWeather.prototype.addSource = function(source){
      this.sources[source.slug] = source;
      return this;
    };
    SpaceWeather.prototype.showAllSources = function(){
      var slug, ref$, source;
      for (slug in ref$ = this.sources) {
        source = ref$[slug];
4cf497e0   Goutte   Make the targets ...
43
        showSource(slug);
f75faf5f   Goutte   WIP
44
45
46
      }
      return this;
    };
4cf497e0   Goutte   Make the targets ...
47
48
49
50
51
52
53
54
    SpaceWeather.prototype.showSource = function(source_slug){
      var this$ = this;
      timeSeries.forEach(function(ts){
        if (ts.source.slug === source_slug && this$.parameters[ts.parameter].active) {
          return $(ts.svg.node()).show();
        }
      });
      this.sources[source_slug].active = true;
f75faf5f   Goutte   WIP
55
56
      return this;
    };
4cf497e0   Goutte   Make the targets ...
57
58
59
60
61
62
63
    SpaceWeather.prototype.hideSource = function(source_slug){
      timeSeries.forEach(function(ts){
        if (ts.source.slug === source_slug) {
          return $(ts.svg.node()).hide();
        }
      });
      this.sources[source_slug].active = false;
f75faf5f   Goutte   WIP
64
65
      return this;
    };
fe3132dd   Goutte   Refactor even more.
66
    SpaceWeather.prototype.resize = function(){
a21f81d9   Goutte   Enable Venus and ...
67
      var ref$;
d49a163c   Goutte   Fix the resize an...
68
69
70
71
72
73
      if ((ref$ = this.orbits) != null) {
        ref$.resize();
      }
      return timeSeries.forEach(function(ts){
        return ts.resize();
      });
fe3132dd   Goutte   Refactor even more.
74
75
    };
    SpaceWeather.prototype.init = function(){
a4a9ef03   Goutte   Cache generated C...
76
      var active_sources, res$, k, started_at, stopped_at, this$ = this;
fe3132dd   Goutte   Refactor even more.
77
78
79
80
81
82
83
      res$ = [];
      for (k in this.sources) {
        if (this.sources[k].config.active) {
          res$.push(this.sources[k]);
        }
      }
      active_sources = res$;
a21f81d9   Goutte   Enable Venus and ...
84
      this.orbits = new Orbits(this.configuration.orbits_container, this.configuration);
a4a9ef03   Goutte   Cache generated C...
85
86
87
88
      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");
a975b380   Goutte   Clean up.
89
      active_sources.forEach(function(source){
a4a9ef03   Goutte   Cache generated C...
90
        return this$.loadData(source.slug, started_at, stopped_at).then(function(data){
a21f81d9   Goutte   Enable Venus and ...
91
          console.info("Loaded CSV data for " + source.slug + ".");
fe3132dd   Goutte   Refactor even more.
92
          this$.createTimeSeries(source, data);
a21f81d9   Goutte   Enable Venus and ...
93
          return this$.orbits.initOrbiter(source.slug, source.config, data['hci']);
fe3132dd   Goutte   Refactor even more.
94
95
96
97
        }, function(data){
          return console.error('Failed to load SW data.', data);
        });
      });
a975b380   Goutte   Clean up.
98
99
100
      return window.addEventListener('resize', function(){
        return this$.resize();
      });
fe3132dd   Goutte   Refactor even more.
101
    };
f75faf5f   Goutte   WIP
102
103
104
105
106
    SpaceWeather.prototype.loadData = function(source_slug, started_at, stopped_at){
      var sw, promise;
      sw = this;
      promise = new Promise(function(resolve, reject){
        var url;
a4a9ef03   Goutte   Cache generated C...
107
108
        url = sw.buildDataUrlForSource(source_slug, started_at, stopped_at);
        return d3.csv(url, function(csv){
f75faf5f   Goutte   WIP
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
          var timeFormat, data;
          timeFormat = d3.timeParse('%Y-%m-%dT%H:%M:%S%Z');
          data = {
            'hci': []
          };
          configuration['parameters'].forEach(function(parameter){
            return data[parameter['id']] = [];
          });
          csv.forEach(function(d){
            var dtime;
            dtime = timeFormat(d['time']);
            configuration['parameters'].forEach(function(parameter){
              var id;
              id = parameter['id'];
              return data[id].push({
                x: dtime,
                y: parseFloat(d[id])
              });
            });
            if (d['xhci'] && d['yhci']) {
              return data['hci'].push({
                t: dtime,
                x: parseFloat(d['xhci']),
                y: parseFloat(d['yhci'])
              });
            }
          });
          return resolve(data);
        });
      });
      return promise;
    };
7d6dee0f   Goutte   Continue refacto ...
141
    timeSeries = [];
fe3132dd   Goutte   Refactor even more.
142
    SpaceWeather.prototype.createTimeSeries = function(source, data){
7d6dee0f   Goutte   Continue refacto ...
143
      var this$ = this;
4816cef4   Goutte   Refactor some more.
144
145
      this.configuration['parameters'].forEach(function(parameter){
        var container, id, title;
b7fe650c   Goutte   Misc bundle of ol...
146
        container = this$.configuration['time_series_container'];
4816cef4   Goutte   Refactor some more.
147
148
149
150
151
        id = parameter['id'];
        title = parameter['title'];
        if (!(id in data)) {
          console.error("No data for id '" + id + "'.", data);
        }
b7fe650c   Goutte   Misc bundle of ol...
152
        return timeSeries.push(new TimeSeries(id, title, source, data[id], this$.parameters[id].active, container));
4816cef4   Goutte   Refactor some more.
153
154
155
156
157
158
159
160
161
162
163
164
165
      });
      return timeSeries.forEach(function(ts){
        ts.options['onMouseOver'] = function(){
          return timeSeries.forEach(function(ts2){
            return ts2.showCursor();
          });
        };
        ts.options['onMouseOut'] = function(){
          return timeSeries.forEach(function(ts2){
            return ts2.hideCursor();
          });
        };
        return ts.options['onMouseMove'] = function(t){
fe3132dd   Goutte   Refactor even more.
166
          var ref$;
4816cef4   Goutte   Refactor some more.
167
168
169
          timeSeries.forEach(function(ts2){
            return ts2.moveCursor(t);
          });
fe3132dd   Goutte   Refactor even more.
170
          return (ref$ = this$.orbits) != null ? ref$.moveToDate(t) : void 8;
4816cef4   Goutte   Refactor some more.
171
172
173
        };
      });
    };
b7fe650c   Goutte   Misc bundle of ol...
174
    SpaceWeather.prototype.enableParameter = function(parameter_slug){
4cf497e0   Goutte   Make the targets ...
175
      var this$ = this;
b7fe650c   Goutte   Misc bundle of ol...
176
177
178
      if (!(parameter_slug in this.parameters)) {
        console.error("Unknown parameter " + parameter_slug + ".");
      }
b7fe650c   Goutte   Misc bundle of ol...
179
      this.parameters[parameter_slug].active = true;
4cf497e0   Goutte   Make the targets ...
180
181
182
183
184
      timeSeries.forEach(function(ts){
        if (ts.parameter === parameter_slug && this$.sources[ts.source.slug].active) {
          return $(ts.svg.node()).show();
        }
      });
b7fe650c   Goutte   Misc bundle of ol...
185
186
187
188
189
190
      return this;
    };
    SpaceWeather.prototype.disableParameter = function(parameter_slug){
      if (!(parameter_slug in this.parameters)) {
        console.error("Unknown parameter " + parameter_slug + ".");
      }
b7fe650c   Goutte   Misc bundle of ol...
191
      this.parameters[parameter_slug].active = false;
4cf497e0   Goutte   Make the targets ...
192
193
194
195
196
      timeSeries.forEach(function(ts){
        if (ts.parameter === parameter_slug) {
          return $(ts.svg.node()).hide();
        }
      });
b7fe650c   Goutte   Misc bundle of ol...
197
198
      return this;
    };
ae0aa7d2   Goutte   Add an x axis lab...
199
200
201
202
203
    return SpaceWeather;
  }());
  Source = (function(){
    Source.displayName = 'Source';
    var prototype = Source.prototype, constructor = Source;
fe3132dd   Goutte   Refactor even more.
204
    function Source(slug, name, config){
ae0aa7d2   Goutte   Add an x axis lab...
205
      this.slug = slug;
fe3132dd   Goutte   Refactor even more.
206
      this.name = name;
f75faf5f   Goutte   WIP
207
      this.config = config;
4cf497e0   Goutte   Make the targets ...
208
      this.active = true;
ae0aa7d2   Goutte   Add an x axis lab...
209
    }
ae0aa7d2   Goutte   Add an x axis lab...
210
211
    return Source;
  }());
438929a4   Goutte   Rewrite the orbit...
212
213
214
  out$.TimeSeries = TimeSeries = (function(){
    TimeSeries.displayName = 'TimeSeries';
    var prototype = TimeSeries.prototype, constructor = TimeSeries;
4cf497e0   Goutte   Make the targets ...
215
216
    function TimeSeries(parameter, title, source, data, active, container, options){
      this.parameter = parameter;
438929a4   Goutte   Rewrite the orbit...
217
      this.title = title;
fe3132dd   Goutte   Refactor even more.
218
      this.source = source;
438929a4   Goutte   Rewrite the orbit...
219
      this.data = data;
b7fe650c   Goutte   Misc bundle of ol...
220
      this.active = active;
438929a4   Goutte   Rewrite the orbit...
221
222
223
224
      this.container = container;
      this.options = options != null
        ? options
        : {};
541e2936   Goutte   Synchronize the t...
225
226
227
      this.onMouseOut = bind$(this, 'onMouseOut', prototype);
      this.onMouseOver = bind$(this, 'onMouseOver', prototype);
      this.onMouseMove = bind$(this, 'onMouseMove', prototype);
b7fe650c   Goutte   Misc bundle of ol...
228
229
230
231
232
      if (this.active) {
        console.info("Creating time series '" + this.title + "'...");
      } else {
        console.info("Creating inactive time series '" + this.title + "'...");
      }
438929a4   Goutte   Rewrite the orbit...
233
234
235
      this.init();
    }
    TimeSeries.prototype.init = function(){
541e2936   Goutte   Synchronize the t...
236
      var dx, this$ = this;
ae0aa7d2   Goutte   Add an x axis lab...
237
      console.info("Initializing time series '" + this.title + "'...", this.data, this.options);
438929a4   Goutte   Rewrite the orbit...
238
239
240
241
      this.margin = {
        top: 30,
        right: 20,
        bottom: 30,
fe3132dd   Goutte   Refactor even more.
242
        left: 80
438929a4   Goutte   Rewrite the orbit...
243
244
245
246
247
248
249
      };
      this.xScale = d3.scaleTime().domain(d3.extent(this.data, function(d){
        return d.x;
      }));
      this.yScale = d3.scaleLinear().domain(d3.extent(this.data, function(d){
        return d.y;
      }));
d49a163c   Goutte   Fix the resize an...
250
      this.xAxis = d3.axisBottom().tickFormat(d3.timeFormat("%Y-%m-%d")).ticks(7);
438929a4   Goutte   Rewrite the orbit...
251
252
253
254
255
256
257
      this.yAxis = d3.axisLeft().ticks(10);
      this.line = d3.line().x(function(d){
        return this$.xScale(d.x);
      }).y(function(d){
        return this$.yScale(d.y);
      });
      this.svg = d3.select(this.container).append('svg');
4cf497e0   Goutte   Make the targets ...
258
      this.svg.attr("class", this.parameter + " " + this.source.slug);
438929a4   Goutte   Rewrite the orbit...
259
260
      this.plotWrapper = this.svg.append('g');
      this.plotWrapper.attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')');
438929a4   Goutte   Rewrite the orbit...
261
      this.path = this.plotWrapper.append('path').datum(this.data).classed('line', true);
2463bd16   Goutte   Add a circle foll...
262
      this.mouseCanvas = this.plotWrapper.append("rect").style("fill", "none").style("pointer-events", "all");
541e2936   Goutte   Synchronize the t...
263
      this.mouseCanvas.on("mouseover", this.onMouseOver).on("mouseout", this.onMouseOut).on("mousemove", this.onMouseMove);
438929a4   Goutte   Rewrite the orbit...
264
265
266
      this.plotWrapper.append('g').classed('x axis', true);
      this.plotWrapper.append('g').classed('y axis', true);
      this.yAxisText = this.plotWrapper.append("text").attr("transform", "rotate(-90)").attr("dy", "1em").style("text-anchor", "middle").text(this.title);
fe3132dd   Goutte   Refactor even more.
267
      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);
81c9b2e8   Goutte   Add the values to...
268
269
      this.focus = this.plotWrapper.append('g').style("display", "none");
      this.cursorCircle = this.focus.append("circle").attr("class", "cursor-circle").attr("r", 3);
541e2936   Goutte   Synchronize the t...
270
271
272
273
274
      dx = 8;
      this.cursorValueShadow = this.focus.append("text").attr("class", "cursor-text cursor-text-shadow").attr("dx", dx).attr("dy", "-.3em");
      this.cursorValue = this.focus.append("text").attr("class", "cursor-text cursor-value").attr("dx", dx).attr("dy", "-.3em");
      this.cursorDateShadow = this.focus.append("text").attr("class", "cursor-text cursor-text-shadow").attr("dx", dx).attr("dy", "1em");
      this.cursorDate = this.focus.append("text").attr("class", "cursor-text cursor-date").attr("dx", dx).attr("dy", "1em");
438929a4   Goutte   Rewrite the orbit...
275
276
277
278
279
      return this.resize();
    };
    TimeSeries.prototype.resize = function(){
      var width, height;
      width = jQuery(this.container).width() - this.margin.left - this.margin.right;
541e2936   Goutte   Synchronize the t...
280
281
282
      height = GOLDEN_RATIO * GOLDEN_RATIO * GOLDEN_RATIO * GOLDEN_RATIO * width;
      this.plotWidth = width;
      this.plotHeight = height;
b7fe650c   Goutte   Misc bundle of ol...
283
      console.log("Resizing time series " + this.title + " : " + width + " x " + height);
438929a4   Goutte   Rewrite the orbit...
284
285
286
287
288
289
      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);
      this.path.attr('d', this.line);
      this.xAxis.scale(this.xScale);
      this.yAxis.scale(this.yScale);
d49a163c   Goutte   Fix the resize an...
290
291
      this.xAxis.ticks(Math.floor(width / 90.0));
      this.yAxis.ticks(Math.floor(height / 18.0));
438929a4   Goutte   Rewrite the orbit...
292
293
      this.svg.select('.x.axis').attr('transform', 'translate(0,' + height + ')').call(this.xAxis);
      this.svg.select('.y.axis').call(this.yAxis);
fe3132dd   Goutte   Refactor even more.
294
295
      this.yAxisText.attr("y", 20 - this.margin.left).attr("x", 0 - height / 2);
      this.yAxisTextSource.attr("y", 0 - this.margin.left).attr("x", 0 - height / 2);
2463bd16   Goutte   Add a circle foll...
296
      this.mouseCanvas.attr("width", width).attr("height", height);
b7fe650c   Goutte   Misc bundle of ol...
297
298
299
      if (!this.active) {
        $(this.svg.node()).hide();
      }
2463bd16   Goutte   Add a circle foll...
300
301
      return this;
    };
541e2936   Goutte   Synchronize the t...
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
    TimeSeries.prototype.onMouseMove = function(){
      var x;
      x = this.xScale.invert(d3.mouse(this.mouseCanvas.node())[0]);
      if (this.options.onMouseMove != null) {
        return this.options.onMouseMove(x);
      } else {
        return this.moveCursor(x);
      }
    };
    TimeSeries.prototype.onMouseOver = function(){
      if (this.options.onMouseOver != null) {
        return this.options.onMouseOver();
      } else {
        return this.showCursor();
      }
    };
    TimeSeries.prototype.onMouseOut = function(){
      if (this.options.onMouseOut != null) {
        return this.options.onMouseOut();
      } else {
        return this.hideCursor();
      }
    };
    TimeSeries.prototype.showCursor = function(){
      return this.focus.style("display", null);
    };
    TimeSeries.prototype.hideCursor = function(){
      return this.focus.style("display", "none");
    };
2463bd16   Goutte   Add a circle foll...
331
332
333
    TimeSeries.prototype.bisectDate = d3.bisector(function(d){
      return d.x;
    }).left;
81c9b2e8   Goutte   Add the values to...
334
    TimeSeries.prototype.timeFormat = d3.timeFormat("%Y-%m-%d %Hh");
541e2936   Goutte   Synchronize the t...
335
336
    TimeSeries.prototype.moveCursor = function(x0){
      var i, d0, d1, d, xx, yy, transform, mirrored, dx;
2463bd16   Goutte   Add a circle foll...
337
338
339
      i = this.bisectDate(this.data, x0, 1);
      d0 = this.data[i - 1];
      d1 = this.data[i];
541e2936   Goutte   Synchronize the t...
340
341
342
      if (!(d1 && d0)) {
        return;
      }
2463bd16   Goutte   Add a circle foll...
343
344
345
      d = x0 - d0.x > d1.x - x0 ? d1 : d0;
      xx = this.xScale(d.x);
      yy = this.yScale(d.y);
81c9b2e8   Goutte   Add the values to...
346
      transform = "translate(" + xx + ", " + yy + ")";
541e2936   Goutte   Synchronize the t...
347
348
349
350
351
      mirrored = this.plotWidth != null && xx > this.plotWidth / 2 ? true : false;
      dx = 8;
      if (mirrored) {
        dx = -1 * dx;
      }
81c9b2e8   Goutte   Add the values to...
352
      this.cursorCircle.attr("transform", transform);
541e2936   Goutte   Synchronize the t...
353
354
355
356
      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);
      this.cursorDate.attr("transform", transform).text(this.timeFormat(d.x)).attr('text-anchor', mirrored ? 'end' : 'start').attr("dx", dx);
      this.cursorDateShadow.attr("transform", transform).text(this.timeFormat(d.x)).attr('text-anchor', mirrored ? 'end' : 'start').attr("dx", dx);
438929a4   Goutte   Rewrite the orbit...
357
358
359
360
361
362
363
      return this;
    };
    return TimeSeries;
  }());
  out$.Orbits = Orbits = (function(){
    Orbits.displayName = 'Orbits';
    var prototype = Orbits.prototype, constructor = Orbits;
a21f81d9   Goutte   Enable Venus and ...
364
    function Orbits(container, options){
438929a4   Goutte   Rewrite the orbit...
365
366
367
368
      this.container = container;
      this.options = options != null
        ? options
        : {};
438929a4   Goutte   Rewrite the orbit...
369
370
371
      this.init();
    }
    Orbits.prototype.init = function(){
a21f81d9   Goutte   Enable Venus and ...
372
      console.log("Initializing orbits...", this.options);
438929a4   Goutte   Rewrite the orbit...
373
374
375
      this.margin = {
        top: 30,
        right: 20,
11662eed   Goutte   Add Y axis label ...
376
        bottom: 42,
438929a4   Goutte   Rewrite the orbit...
377
378
        left: 60
      };
a21f81d9   Goutte   Enable Venus and ...
379
380
381
      this.data = {};
      this.orbiters = {};
      this.extremum = 1;
438929a4   Goutte   Rewrite the orbit...
382
383
384
385
386
387
388
      this.xScale = d3.scaleLinear().domain([-1 * this.extremum, this.extremum]);
      this.yScale = d3.scaleLinear().domain([-1 * this.extremum, this.extremum]);
      this.xAxis = d3.axisBottom().ticks(10);
      this.yAxis = d3.axisLeft().ticks(10);
      this.svg = d3.select(this.container).append('svg');
      this.plotWrapper = this.svg.append('g');
      this.plotWrapper.attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')');
ae0aa7d2   Goutte   Add an x axis lab...
389
390
391
392
393
      this.xAxisLine = this.plotWrapper.append('g').classed('x axis', true);
      this.yAxisLine = this.plotWrapper.append('g').classed('y axis', true);
      this.xAxisTitle = this.xAxisLine.append('text').attr('fill', '#000');
      this.xAxisTitle.style("text-anchor", "middle");
      this.xAxisTitle.append('tspan').text('X');
11662eed   Goutte   Add Y axis label ...
394
      this.xAxisTitle.append('tspan').attr('dy', '3px').text('HEE').attr('font-size', '8px');
ae0aa7d2   Goutte   Add an x axis lab...
395
      this.xAxisTitle.append('tspan').attr('dy', '-3px').text('   (AU)');
11662eed   Goutte   Add Y axis label ...
396
397
398
399
400
401
      this.yAxisTitle = this.yAxisLine.append('text').attr('fill', '#000');
      this.yAxisTitle.style("text-anchor", "middle");
      this.yAxisTitle.append('tspan').text('Y');
      this.yAxisTitle.append('tspan').attr('dy', '3px').text('HEE').attr('font-size', '8px');
      this.yAxisTitle.append('tspan').attr('dy', '-3px').text('   (AU)');
      this.yAxisTitle.attr('transform', 'rotate(-90)');
8bd715ad   Goutte   Use a pixel art i...
402
      this.sun = this.plotWrapper.append("svg:image").attr('xlink:href', this.options.sun.img).attr('width', '32px').attr('height', '32px');
438929a4   Goutte   Rewrite the orbit...
403
      this.sun.append('svg:title').text("Sol");
438929a4   Goutte   Rewrite the orbit...
404
405
406
      return this.resize();
    };
    Orbits.prototype.orbitersElements = {};
a21f81d9   Goutte   Enable Venus and ...
407
    Orbits.prototype.initOrbiter = function(slug, config, data){
438929a4   Goutte   Rewrite the orbit...
408
      var orbit_ellipse, orbiter, orbit_line, orbit_section, this$ = this;
a21f81d9   Goutte   Enable Venus and ...
409
      console.log("Initializing target " + slug + "'s orbit...", config, data);
438929a4   Goutte   Rewrite the orbit...
410
411
412
      if (slug in this.orbitersElements) {
        throw new Error("Second init of " + slug);
      }
a21f81d9   Goutte   Enable Venus and ...
413
414
415
416
417
      this.extremum = Math.max(this.extremum, 1.11 * d3.max(data, function(d){
        return Math.max(Math.abs(d.x), Math.abs(d.y));
      }));
      this.xScale = d3.scaleLinear().domain([-1 * this.extremum, this.extremum]);
      this.yScale = d3.scaleLinear().domain([-1 * this.extremum, this.extremum]);
438929a4   Goutte   Rewrite the orbit...
418
419
420
421
422
423
424
      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');
      orbit_line = d3.line().x(function(d){
        return this$.xScale(d.x);
      }).y(function(d){
        return this$.yScale(d.y);
      });
a21f81d9   Goutte   Enable Venus and ...
425
426
427
      orbit_section = this.plotWrapper.append('path').datum(data).classed('orbit orbit_section', true);
      this.orbiters[slug] = config;
      this.data[slug] = data;
438929a4   Goutte   Rewrite the orbit...
428
429
430
431
432
433
      this.orbitersElements[slug] = {
        orbiter: orbiter,
        orbit_ellipse: orbit_ellipse,
        orbit_section: orbit_section,
        orbit_line: orbit_line
      };
a21f81d9   Goutte   Enable Venus and ...
434
      this.resize();
438929a4   Goutte   Rewrite the orbit...
435
436
437
438
439
440
441
442
443
444
      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);
8bd715ad   Goutte   Use a pixel art i...
445
      this.sun.attr("x", width / 2 - 16).attr("y", height / 2 - 16);
438929a4   Goutte   Rewrite the orbit...
446
447
448
449
450
451
452
453
      for (slug in ref$ = this.orbiters) {
        config = ref$[slug];
        this.resizeOrbiter(slug, config);
      }
      this.xAxis.scale(this.xScale);
      this.yAxis.scale(this.yScale);
      this.svg.select('.x.axis').attr('transform', 'translate(0,' + height + ')').call(this.xAxis);
      this.svg.select('.y.axis').call(this.yAxis);
11662eed   Goutte   Add Y axis label ...
454
455
      this.xAxisTitle.attr("x", width / 2).attr("y", 37);
      this.yAxisTitle.attr("x", -1 * height / 2).attr("y", -30);
438929a4   Goutte   Rewrite the orbit...
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
      return this;
    };
    Orbits.prototype.resizeOrbiter = function(slug, config){
      var width, height, el, a, b, c, cx, cy, data;
      width = jQuery(this.container).width() - this.margin.left - this.margin.right;
      height = 1.0 * width;
      console.log("Resize orbiter " + slug);
      el = this.orbitersElements[slug];
      el['orbit_section'].attr('d', el['orbit_line']);
      a = config['orbit']['a'];
      b = config['orbit']['b'];
      c = Math.sqrt(a * a - b * b);
      cx = width / 2 - c;
      cy = height / 2;
      this.yScale.range([0, height]);
a21f81d9   Goutte   Enable Venus and ...
471
      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));
438929a4   Goutte   Rewrite the orbit...
472
      this.yScale.range([height, 0]);
a21f81d9   Goutte   Enable Venus and ...
473
      data = this.data[slug];
438929a4   Goutte   Rewrite the orbit...
474
475
476
477
      el['orbiter'].attr('x', this.xScale(data[data.length - 1].x) - 16);
      el['orbiter'].attr('y', this.yScale(data[data.length - 1].y) - 16);
      return this;
    };
ae0aa7d2   Goutte   Add an x axis lab...
478
479
    Orbits.prototype.repositionOrbiter = function(slug, datum){
      var data, el;
a21f81d9   Goutte   Enable Venus and ...
480
      data = this.data[slug];
ae0aa7d2   Goutte   Add an x axis lab...
481
482
483
484
485
486
487
488
489
490
      datum == null && (datum = data[data.length - 1]);
      el = this.orbitersElements[slug];
      el['orbiter'].attr('x', this.xScale(datum.x) - 16);
      el['orbiter'].attr('y', this.yScale(datum.y) - 16);
      return this;
    };
    Orbits.prototype.bisectDate = d3.bisector(function(d){
      return d.t;
    }).left;
    Orbits.prototype.moveToDate = function(t){
a21f81d9   Goutte   Enable Venus and ...
491
492
493
494
      var slug, ref$, el, data, i, d0, d1, d;
      if (!t) {
        console.log("Trying to move to an undefined date");
      }
ae0aa7d2   Goutte   Add an x axis lab...
495
496
      for (slug in ref$ = this.orbitersElements) {
        el = ref$[slug];
a21f81d9   Goutte   Enable Venus and ...
497
        data = this.data[slug];
ae0aa7d2   Goutte   Add an x axis lab...
498
499
500
501
502
503
504
        i = this.bisectDate(data, t, 1);
        d0 = data[i - 1];
        d1 = data[i];
        if (!(d1 && d0)) {
          continue;
        }
        d = t - d0.t > d1.t - t ? d1 : d0;
a21f81d9   Goutte   Enable Venus and ...
505
        this.repositionOrbiter(slug, d);
ae0aa7d2   Goutte   Add an x axis lab...
506
      }
a21f81d9   Goutte   Enable Venus and ...
507
      return this;
ae0aa7d2   Goutte   Add an x axis lab...
508
    };
438929a4   Goutte   Rewrite the orbit...
509
510
    return Orbits;
  }());
2463bd16   Goutte   Add a circle foll...
511
512
513
  function bind$(obj, key, target){
    return function(){ return (target || obj)[key].apply(obj, arguments) };
  }
438929a4   Goutte   Rewrite the orbit...
514
}).call(this);