Blame view

web/static/js/swapp.js 31.6 KB
438929a4   Goutte   Rewrite the orbit...
1
2
// Generated by LiveScript 1.5.0
(function(){
b60e7acd   Goutte   Rename "source" i...
3
  var GOLDEN_RATIO, Target, SpaceWeather, TimeSeries, Orbits, out$ = typeof exports != 'undefined' && exports || this;
438929a4   Goutte   Rewrite the orbit...
4
  GOLDEN_RATIO = 2 / (1 + Math.sqrt(5));
b60e7acd   Goutte   Rename "source" i...
5
6
7
8
9
10
11
  Target = (function(){
    Target.displayName = 'Target';
    var prototype = Target.prototype, constructor = Target;
    function Target(slug, name, config){
      this.slug = slug;
      this.name = name;
      this.config = config;
2c0e1515   Goutte   Refactor loading ...
12
      this.active = this.config.active;
b60e7acd   Goutte   Rename "source" i...
13
14
15
    }
    return Target;
  }());
ae0aa7d2   Goutte   Add an x axis lab...
16
  out$.SpaceWeather = SpaceWeather = (function(){
6bb225d6   Goutte   Link the time ser...
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)";
ae0aa7d2   Goutte   Add an x axis lab...
18
    SpaceWeather.displayName = 'SpaceWeather';
243cd8a4   Goutte   Timestamp party c...
19
    var API_TIME_FORMAT, INPUT_TIME_FORMAT, prototype = SpaceWeather.prototype, constructor = SpaceWeather;
2c0e1515   Goutte   Refactor loading ...
20
    API_TIME_FORMAT = "YYYY-MM-DDTHH:mm:ss";
243cd8a4   Goutte   Timestamp party c...
21
    INPUT_TIME_FORMAT = "YYYY-MM-DD";
ae0aa7d2   Goutte   Add an x axis lab...
22
    function SpaceWeather(configuration){
fe3132dd   Goutte   Refactor even more.
23
      var configs, res$, k, this$ = this;
f75faf5f   Goutte   WIP
24
      this.configuration = configuration;
05e269d1   Goutte   Show an error mes...
25
      console.info("©2017\n  _   _      _ _       ____\n | | | | ___| (_) ___ |  _ \\ _ __ ___  _ __   __ _\n | |_| |/ _ \\ | |/ _ \\| |_) | '__/ _ \\| '_ \\ / _` |\n |  _  |  __/ | | (_) |  __/| | | (_) | |_) | (_| |\n |_| |_|\\___|_|_|\\___/|_|_  |_|_ \\___/| .__/ \\__,_|\n | |__  _   _   / ___|  _ \\|  _ \\|  _ \\_|\n | '_ \\| | | | | |   | | | | |_) | |_) |\n | |_) | |_| | | |___| |_| |  __/|  __/\n |_.__/ \\__, |  \\____|____/|_|   |_|\n        |___/\n\nThe full source of this website is available at :\nhttps://gitlab.irap.omp.eu/CDPP/SPACEWEATHERONLINE");
b60e7acd   Goutte   Rename "source" i...
26
      this.targets = {};
fe3132dd   Goutte   Refactor even more.
27
      res$ = [];
b60e7acd   Goutte   Rename "source" i...
28
29
      for (k in this.configuration.targets) {
        res$.push(this.configuration.targets[k]);
fe3132dd   Goutte   Refactor even more.
30
31
      }
      configs = res$;
b60e7acd   Goutte   Rename "source" i...
32
33
      configs.forEach(function(target_config){
        return this$.targets[target_config.slug] = new Target(target_config.slug, target_config.name, target_config);
fe3132dd   Goutte   Refactor even more.
34
      });
b7fe650c   Goutte   Misc bundle of ol...
35
36
37
38
      this.parameters = {};
      this.configuration['parameters'].forEach(function(p){
        return this$.parameters[p['id']] = p;
      });
7994cf1a   Goutte   Hunt bugs.
39
      this.orbiter = null;
243cd8a4   Goutte   Timestamp party c...
40
      this.timeSeries = [];
ae0aa7d2   Goutte   Add an x axis lab...
41
    }
b60e7acd   Goutte   Rename "source" i...
42
43
    SpaceWeather.prototype.init = function(){
      "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)";
2c0e1515   Goutte   Refactor loading ...
44
      var started_at, stopped_at, this$ = this;
9bfa6c42   Goutte   More bug hunting.
45
      started_at = moment().subtract(1, 'year').hours(0).minutes(0).seconds(0);
97d6cb96   Goutte   Change default ti...
46
      stopped_at = moment().add(1, 'week').hours(0).minutes(0).seconds(0);
7994cf1a   Goutte   Hunt bugs.
47
      this.setStartAndStop(started_at, stopped_at);
2c0e1515   Goutte   Refactor loading ...
48
      this.loadAndCreatePlots(started_at, stopped_at);
b60e7acd   Goutte   Rename "source" i...
49
50
51
52
53
      return window.addEventListener('resize', function(){
        return this$.resize();
      });
    };
    SpaceWeather.prototype.buildDataUrlForTarget = function(target_slug, started_at, stopped_at){
f75faf5f   Goutte   WIP
54
55
      var url;
      url = this.configuration['api']['data_for_interval'];
b60e7acd   Goutte   Rename "source" i...
56
      url = url.replace('<target>', target_slug);
a4a9ef03   Goutte   Cache generated C...
57
58
      url = url.replace('<started_at>', started_at);
      url = url.replace('<stopped_at>', stopped_at);
f75faf5f   Goutte   WIP
59
60
      return url;
    };
6b149919   Goutte   Add a Download bu...
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
    SpaceWeather.prototype.buildDownloadUrl = function(){
      var ref$, started_at, stopped_at, targets, t, url;
      ref$ = this.getDomain(), started_at = ref$[0], stopped_at = ref$[1];
      targets = (function(){
        var results$ = [];
        for (t in this.targets) {
          if (this.targets[t].active) {
            results$.push(t);
          }
        }
        return results$;
      }.call(this)).sort().join('-');
      url = this.configuration['api']['download'];
      url = url.replace('<targets>', targets);
      url = url.replace('<started_at>', started_at.format(API_TIME_FORMAT));
      url = url.replace('<stopped_at>', stopped_at.format(API_TIME_FORMAT));
      return url;
    };
b60e7acd   Goutte   Rename "source" i...
79
80
    SpaceWeather.prototype.addTarget = function(target){
      this.targets[target.slug] = target;
f75faf5f   Goutte   WIP
81
82
      return this;
    };
6bb225d6   Goutte   Link the time ser...
83
    SpaceWeather.prototype.enableTarget = function(target_slug){
4cf497e0   Goutte   Make the targets ...
84
      var this$ = this;
243cd8a4   Goutte   Timestamp party c...
85
      this.timeSeries.forEach(function(ts){
b60e7acd   Goutte   Rename "source" i...
86
        if (ts.target.slug === target_slug && this$.parameters[ts.parameter].active) {
6bb225d6   Goutte   Link the time ser...
87
          return ts.show();
4cf497e0   Goutte   Make the targets ...
88
89
        }
      });
b60e7acd   Goutte   Rename "source" i...
90
      this.targets[target_slug].active = true;
f75faf5f   Goutte   WIP
91
92
      return this;
    };
6bb225d6   Goutte   Link the time ser...
93
    SpaceWeather.prototype.disableTarget = function(target_slug){
243cd8a4   Goutte   Timestamp party c...
94
      this.timeSeries.forEach(function(ts){
b60e7acd   Goutte   Rename "source" i...
95
        if (ts.target.slug === target_slug) {
6bb225d6   Goutte   Link the time ser...
96
          return ts.hide();
4cf497e0   Goutte   Make the targets ...
97
98
        }
      });
b60e7acd   Goutte   Rename "source" i...
99
      this.targets[target_slug].active = false;
f75faf5f   Goutte   WIP
100
101
      return this;
    };
fe3132dd   Goutte   Refactor even more.
102
    SpaceWeather.prototype.resize = function(){
a21f81d9   Goutte   Enable Venus and ...
103
      var ref$;
d49a163c   Goutte   Fix the resize an...
104
105
106
      if ((ref$ = this.orbits) != null) {
        ref$.resize();
      }
243cd8a4   Goutte   Timestamp party c...
107
      return this.timeSeries.forEach(function(ts){
d49a163c   Goutte   Fix the resize an...
108
109
        return ts.resize();
      });
fe3132dd   Goutte   Refactor even more.
110
    };
2c0e1515   Goutte   Refactor loading ...
111
    SpaceWeather.prototype.showLoader = function(){
05e269d1   Goutte   Show an error mes...
112
      return $('#plots_loader').show();
2c0e1515   Goutte   Refactor loading ...
113
    };
9c0c4509   Goutte   Add a loader to t...
114
    SpaceWeather.prototype.hideLoader = function(){
05e269d1   Goutte   Show an error mes...
115
      return $('#plots_loader').hide();
9c0c4509   Goutte   Add a loader to t...
116
    };
b60e7acd   Goutte   Rename "source" i...
117
118
    SpaceWeather.prototype.loadData = function(target_slug, started_at, stopped_at){
      "Load the data as CSV for the specified target and interval,\nand return it in a Promise.";
2c0e1515   Goutte   Refactor loading ...
119
      var sw;
f75faf5f   Goutte   WIP
120
      sw = this;
2c0e1515   Goutte   Refactor loading ...
121
      return new Promise(function(resolve, reject){
f75faf5f   Goutte   WIP
122
        var url;
b60e7acd   Goutte   Rename "source" i...
123
        url = sw.buildDataUrlForTarget(target_slug, started_at, stopped_at);
a4a9ef03   Goutte   Cache generated C...
124
        return d3.csv(url, function(csv){
f75faf5f   Goutte   WIP
125
          var timeFormat, data;
9bfa6c42   Goutte   More bug hunting.
126
          console.debug("Requested CSV for " + target_slug + "...", csv);
f75faf5f   Goutte   WIP
127
128
129
130
131
132
133
          timeFormat = d3.timeParse('%Y-%m-%dT%H:%M:%S%Z');
          data = {
            'hci': []
          };
          configuration['parameters'].forEach(function(parameter){
            return data[parameter['id']] = [];
          });
a245c676   Goutte   Commit generated ...
134
135
136
          if (!csv) {
            reject("CSV is empty or nonexistent at URL '" + url + "'.");
          }
9bfa6c42   Goutte   More bug hunting.
137
138
139
          if (!csv.length) {
            reject("CSV is empty at '" + url + "'.");
          }
f75faf5f   Goutte   WIP
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
          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);
        });
      });
2c0e1515   Goutte   Refactor loading ...
162
163
    };
    SpaceWeather.prototype.loadAndCreatePlots = function(started_at, stopped_at){
243cd8a4   Goutte   Timestamp party c...
164
      "started_at: moment(.js) object\nstopped_at: moment(.js) object";
5e099488   Goutte   Fix that loading ...
165
      var k, this$ = this;
2c0e1515   Goutte   Refactor loading ...
166
      this.showLoader();
7994cf1a   Goutte   Hunt bugs.
167
168
169
      this.started_at = started_at;
      this.stopped_at = stopped_at;
      this.orbits = new Orbits(this.configuration.orbits_container, this.configuration);
243cd8a4   Goutte   Timestamp party c...
170
171
      started_at = started_at.format(API_TIME_FORMAT);
      stopped_at = stopped_at.format(API_TIME_FORMAT);
5e099488   Goutte   Fix that loading ...
172
173
174
175
      return (function(){
        var results$ = [];
        for (k in this.targets) {
          results$.push(this.targets[k]);
2c0e1515   Goutte   Refactor loading ...
176
        }
5e099488   Goutte   Fix that loading ...
177
178
        return results$;
      }.call(this)).forEach(function(target){
2c0e1515   Goutte   Refactor loading ...
179
180
        var targetButton;
        console.info("Loading CSV data of " + target.name + "…");
4900d232   Goutte   Add the time inte...
181
        targetButton = $(".targets-filters .target." + target.slug);
2c0e1515   Goutte   Refactor loading ...
182
        targetButton.addClass('loading');
27097d87   Goutte   Change the error ...
183
        targetButton.removeClass('failed');
2c0e1515   Goutte   Refactor loading ...
184
        return this$.loadData(target.slug, started_at, stopped_at).then(function(data){
9bfa6c42   Goutte   More bug hunting.
185
          console.info("Loaded CSV data of " + target.name + ".", data);
2c0e1515   Goutte   Refactor loading ...
186
187
188
          this$.createTimeSeries(target, data);
          this$.orbits.initOrbiter(target.slug, target.config, data['hci']);
          targetButton.removeClass('loading');
5e099488   Goutte   Fix that loading ...
189
190
191
192
193
          if (target.active) {
            return this$.hideLoader();
          } else {
            return this$.disableTarget(target.slug);
          }
2c0e1515   Goutte   Refactor loading ...
194
        }, function(error){
9bfa6c42   Goutte   More bug hunting.
195
          console.error("Failed loading CSV data of " + target.name + ".", error);
27097d87   Goutte   Change the error ...
196
197
          alert("There was an error with " + target.name + ".\nPlease retry.");
          targetButton.addClass('failed');
9bfa6c42   Goutte   More bug hunting.
198
199
          targetButton.removeClass('loading');
          return this$.hideLoader();
2c0e1515   Goutte   Refactor loading ...
200
201
202
203
        });
      });
    };
    SpaceWeather.prototype.clearPlots = function(){
2c0e1515   Goutte   Refactor loading ...
204
      this.orbits.clear();
243cd8a4   Goutte   Timestamp party c...
205
      this.timeSeries.forEach(function(ts){
2c0e1515   Goutte   Refactor loading ...
206
207
208
        return ts.clear();
      });
      this.orbits = null;
243cd8a4   Goutte   Timestamp party c...
209
      this.timeSeries = [];
2c0e1515   Goutte   Refactor loading ...
210
      return this;
f75faf5f   Goutte   WIP
211
    };
b60e7acd   Goutte   Rename "source" i...
212
    SpaceWeather.prototype.createTimeSeries = function(target, data){
7d6dee0f   Goutte   Continue refacto ...
213
      var this$ = this;
4816cef4   Goutte   Refactor some more.
214
215
      this.configuration['parameters'].forEach(function(parameter){
        var container, id, title;
b7fe650c   Goutte   Misc bundle of ol...
216
        container = this$.configuration['time_series_container'];
4816cef4   Goutte   Refactor some more.
217
218
219
220
221
        id = parameter['id'];
        title = parameter['title'];
        if (!(id in data)) {
          console.error("No data for id '" + id + "'.", data);
        }
243cd8a4   Goutte   Timestamp party c...
222
        return this$.timeSeries.push(new TimeSeries(id, title, target, data[id], this$.parameters[id].active, container));
4816cef4   Goutte   Refactor some more.
223
      });
243cd8a4   Goutte   Timestamp party c...
224
      this.timeSeries.forEach(function(ts){
4816cef4   Goutte   Refactor some more.
225
        ts.options['onMouseOver'] = function(){
243cd8a4   Goutte   Timestamp party c...
226
          this$.timeSeries.forEach(function(ts2){
4816cef4   Goutte   Refactor some more.
227
228
            return ts2.showCursor();
          });
9c0c4509   Goutte   Add a loader to t...
229
          return true;
4816cef4   Goutte   Refactor some more.
230
231
        };
        ts.options['onMouseOut'] = function(){
243cd8a4   Goutte   Timestamp party c...
232
          this$.timeSeries.forEach(function(ts2){
4816cef4   Goutte   Refactor some more.
233
234
            return ts2.hideCursor();
          });
9c0c4509   Goutte   Add a loader to t...
235
          return true;
4816cef4   Goutte   Refactor some more.
236
        };
c3008fb2   Goutte   Clean up and refa...
237
        ts.options['onMouseMove'] = function(t){
fe3132dd   Goutte   Refactor even more.
238
          var ref$;
243cd8a4   Goutte   Timestamp party c...
239
          this$.timeSeries.forEach(function(ts2){
4816cef4   Goutte   Refactor some more.
240
241
            return ts2.moveCursor(t);
          });
9c0c4509   Goutte   Add a loader to t...
242
243
244
245
          if ((ref$ = this$.orbits) != null) {
            ref$.moveToDate(t);
          }
          return true;
4816cef4   Goutte   Refactor some more.
246
        };
c3008fb2   Goutte   Clean up and refa...
247
        ts.options['onBrushEnd'] = function(sta, sto){
243cd8a4   Goutte   Timestamp party c...
248
          this$.resizeDomain(moment(sta), moment(sto));
9c0c4509   Goutte   Add a loader to t...
249
          return true;
c3008fb2   Goutte   Clean up and refa...
250
251
        };
        return ts.options['onDblClick'] = function(){
9c0c4509   Goutte   Add a loader to t...
252
253
254
255
256
257
          var ref$;
          this$.resetZoom();
          if ((ref$ = $("#zoom_controls_help")) != null) {
            ref$.remove();
          }
          return true;
c3008fb2   Goutte   Clean up and refa...
258
        };
4816cef4   Goutte   Refactor some more.
259
      });
243cd8a4   Goutte   Timestamp party c...
260
      return this.timeSeries;
4816cef4   Goutte   Refactor some more.
261
    };
b7fe650c   Goutte   Misc bundle of ol...
262
    SpaceWeather.prototype.enableParameter = function(parameter_slug){
4cf497e0   Goutte   Make the targets ...
263
      var this$ = this;
b7fe650c   Goutte   Misc bundle of ol...
264
265
266
      if (!(parameter_slug in this.parameters)) {
        console.error("Unknown parameter " + parameter_slug + ".");
      }
b7fe650c   Goutte   Misc bundle of ol...
267
      this.parameters[parameter_slug].active = true;
243cd8a4   Goutte   Timestamp party c...
268
      this.timeSeries.forEach(function(ts){
b60e7acd   Goutte   Rename "source" i...
269
        if (ts.parameter === parameter_slug && this$.targets[ts.target.slug].active) {
6bb225d6   Goutte   Link the time ser...
270
          return ts.show();
4cf497e0   Goutte   Make the targets ...
271
272
        }
      });
b7fe650c   Goutte   Misc bundle of ol...
273
274
275
276
277
278
      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...
279
      this.parameters[parameter_slug].active = false;
243cd8a4   Goutte   Timestamp party c...
280
      this.timeSeries.forEach(function(ts){
4cf497e0   Goutte   Make the targets ...
281
        if (ts.parameter === parameter_slug) {
6bb225d6   Goutte   Link the time ser...
282
          return ts.hide();
4cf497e0   Goutte   Make the targets ...
283
284
        }
      });
b7fe650c   Goutte   Misc bundle of ol...
285
286
      return this;
    };
a06a0a67   Goutte   Prepare the time ...
287
288
289
290
291
292
    SpaceWeather.prototype.getDomain = function(){
      if (this.current_started_at != null && this.current_stopped_at != null) {
        return [this.current_started_at, this.current_stopped_at];
      }
      return [this.started_at, this.stopped_at];
    };
8cb213b9   Goutte   Clean up, and pre...
293
    SpaceWeather.prototype.resizeDomain = function(started_at, stopped_at){
1754789b   Goutte   Decorate and clea...
294
      var ref$, max_stopped_at, formatted_started_at, formatted_stopped_at;
8cb213b9   Goutte   Clean up, and pre...
295
      if (stopped_at < started_at) {
7994cf1a   Goutte   Hunt bugs.
296
        ref$ = [stopped_at, started_at], started_at = ref$[0], stopped_at = ref$[1];
8cb213b9   Goutte   Clean up, and pre...
297
298
      }
      if (started_at === stopped_at) {
6bb225d6   Goutte   Link the time ser...
299
        console.warn("Please provide distinct start and stop dates.");
8cb213b9   Goutte   Clean up, and pre...
300
301
        return;
      }
1754789b   Goutte   Decorate and clea...
302
303
304
305
306
      max_stopped_at = started_at.clone().add(2, 'years');
      if (stopped_at > max_stopped_at) {
        console.warn("The time interval was truncated beacuse it was bigger than two years.");
        stopped_at = max_stopped_at;
      }
243cd8a4   Goutte   Timestamp party c...
307
308
309
      this.setStartAndStop(started_at, stopped_at);
      formatted_started_at = started_at.format();
      formatted_stopped_at = stopped_at.format();
8cb213b9   Goutte   Clean up, and pre...
310
      if ((this.started_at <= started_at && started_at <= this.stopped_at) && (this.started_at <= stopped_at && stopped_at <= this.stopped_at)) {
243cd8a4   Goutte   Timestamp party c...
311
312
        console.info("Resizing the temporal domain from " + formatted_started_at + " to " + formatted_stopped_at + " without fetching new data…");
        this.timeSeries.forEach(function(ts){
6bb225d6   Goutte   Link the time ser...
313
314
315
316
          if (!ts.visible) {
            return ts.zoomIn(started_at, stopped_at);
          }
        });
243cd8a4   Goutte   Timestamp party c...
317
        this.timeSeries.forEach(function(ts){
6bb225d6   Goutte   Link the time ser...
318
319
320
          if (ts.visible) {
            return ts.zoomIn(started_at, stopped_at);
          }
8cb213b9   Goutte   Clean up, and pre...
321
322
        });
        this.orbits.resizeDomain(started_at, stopped_at);
243cd8a4   Goutte   Timestamp party c...
323
324
325
326
327
      } else {
        console.info("Resizing the temporal domain from " + formatted_started_at + " to " + formatted_stopped_at + " and fetching new data…");
        console.warn("This might take a while… Why not see what else we're up to on http://cdpp.eu while you're waiting?");
        this.clearPlots();
        this.loadAndCreatePlots(started_at, stopped_at);
8cb213b9   Goutte   Clean up, and pre...
328
      }
243cd8a4   Goutte   Timestamp party c...
329
      return this;
8cb213b9   Goutte   Clean up, and pre...
330
    };
6bb225d6   Goutte   Link the time ser...
331
    SpaceWeather.prototype.resetZoom = function(){
243cd8a4   Goutte   Timestamp party c...
332
      this.timeSeries.forEach(function(ts){
6bb225d6   Goutte   Link the time ser...
333
334
        return ts.resetZoom();
      });
243cd8a4   Goutte   Timestamp party c...
335
336
337
338
339
      this.orbits.resetZoom();
      this.setStartAndStop(this.started_at, this.stopped_at);
      return this;
    };
    SpaceWeather.prototype.setStartAndStop = function(started_at, stopped_at){
7994cf1a   Goutte   Hunt bugs.
340
      console.info("Setting time interval from " + started_at + " to " + stopped_at + "…");
243cd8a4   Goutte   Timestamp party c...
341
342
343
344
345
      this.current_started_at = started_at;
      this.current_stopped_at = stopped_at;
      $("#started_at").val(started_at.format(INPUT_TIME_FORMAT));
      $("#stopped_at").val(stopped_at.format(INPUT_TIME_FORMAT));
      return this;
6bb225d6   Goutte   Link the time ser...
346
    };
ae0aa7d2   Goutte   Add an x axis lab...
347
348
    return SpaceWeather;
  }());
438929a4   Goutte   Rewrite the orbit...
349
350
  out$.TimeSeries = TimeSeries = (function(){
    TimeSeries.displayName = 'TimeSeries';
123313cb   Goutte   Clip the paths of...
351
    var RATIO, prototype = TimeSeries.prototype, constructor = TimeSeries;
c3008fb2   Goutte   Clean up and refa...
352
    function TimeSeries(parameter, title, target, data, visible, container, options){
4cf497e0   Goutte   Make the targets ...
353
      this.parameter = parameter;
438929a4   Goutte   Rewrite the orbit...
354
      this.title = title;
b60e7acd   Goutte   Rename "source" i...
355
      this.target = target;
6bb225d6   Goutte   Link the time ser...
356
      this.visible = visible;
438929a4   Goutte   Rewrite the orbit...
357
358
359
360
      this.container = container;
      this.options = options != null
        ? options
        : {};
08569a6b   Goutte   Add a zooming bru...
361
      this.onBrushEnd = bind$(this, 'onBrushEnd', prototype);
2038c9fb   Goutte   Add a zoom reset ...
362
      this.onDoubleClick = bind$(this, 'onDoubleClick', prototype);
541e2936   Goutte   Synchronize the t...
363
364
365
      this.onMouseOut = bind$(this, 'onMouseOut', prototype);
      this.onMouseOver = bind$(this, 'onMouseOver', prototype);
      this.onMouseMove = bind$(this, 'onMouseMove', prototype);
6bb225d6   Goutte   Link the time ser...
366
      this.setData(data);
438929a4   Goutte   Rewrite the orbit...
367
368
      this.init();
    }
2038c9fb   Goutte   Add a zoom reset ...
369
370
371
    TimeSeries.prototype.toString = function(){
      return this.title + " of " + this.target.name;
    };
6bb225d6   Goutte   Link the time ser...
372
373
374
375
376
377
378
379
380
    TimeSeries.prototype.setData = function(data){
      this.data = data;
      this.xDataExtent = d3.extent(this.data, function(d){
        return d.x;
      });
      return this.yDataExtent = d3.extent(this.data, function(d){
        return d.y;
      });
    };
438929a4   Goutte   Rewrite the orbit...
381
    TimeSeries.prototype.init = function(){
123313cb   Goutte   Clip the paths of...
382
      var clipId, dx, this$ = this;
c3008fb2   Goutte   Clean up and refa...
383
      console.info("Initializing plot of " + this + "…");
438929a4   Goutte   Rewrite the orbit...
384
385
386
387
      this.margin = {
        top: 30,
        right: 20,
        bottom: 30,
fe3132dd   Goutte   Refactor even more.
388
        left: 80
438929a4   Goutte   Rewrite the orbit...
389
      };
6bb225d6   Goutte   Link the time ser...
390
391
      this.xScale = d3.scaleTime().domain(this.xDataExtent);
      this.yScale = d3.scaleLinear().domain(this.yDataExtent);
08569a6b   Goutte   Add a zooming bru...
392
      this.xAxis = d3.axisBottom().ticks(7);
438929a4   Goutte   Rewrite the orbit...
393
394
395
396
397
398
399
      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');
b60e7acd   Goutte   Rename "source" i...
400
      this.svg.attr("class", this.parameter + " " + this.target.slug);
438929a4   Goutte   Rewrite the orbit...
401
402
      this.plotWrapper = this.svg.append('g');
      this.plotWrapper.attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')');
123313cb   Goutte   Clip the paths of...
403
404
405
406
407
      clipId = "ts-clip-" + this.parameter + "-" + this.target.slug;
      this.clip = this.svg.append("defs").append("svg:clipPath").attr("id", clipId).append("svg:rect").attr("x", 0).attr("y", 0);
      this.pathWrapper = this.plotWrapper.append('g');
      this.pathWrapper.attr("clip-path", "url(#" + clipId + ")");
      this.path = this.pathWrapper.append('path').datum(this.data).classed('line', true);
08569a6b   Goutte   Add a zooming bru...
408
409
      this.brush = this.plotWrapper.append("g").attr("class", "brush");
      this.mouseCanvas = this.plotWrapper.append("rect").style("fill", "none");
438929a4   Goutte   Rewrite the orbit...
410
411
412
      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);
b60e7acd   Goutte   Rename "source" i...
413
      this.yAxisTextTarget = this.plotWrapper.append("text").attr("transform", "rotate(-90)").attr("dy", "1em").style("text-anchor", "middle").style("font-style", "oblique").text(this.target.name);
81c9b2e8   Goutte   Add the values to...
414
415
      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...
416
417
418
419
420
      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...
421
422
      return this.resize();
    };
123313cb   Goutte   Clip the paths of...
423
    RATIO = GOLDEN_RATIO * GOLDEN_RATIO * GOLDEN_RATIO * GOLDEN_RATIO;
438929a4   Goutte   Rewrite the orbit...
424
425
    TimeSeries.prototype.resize = function(){
      var width, height;
123313cb   Goutte   Clip the paths of...
426
427
      width = Math.ceil($(this.container).width() - this.margin.left - this.margin.right);
      height = Math.ceil(RATIO * width);
541e2936   Goutte   Synchronize the t...
428
429
      this.plotWidth = width;
      this.plotHeight = height;
123313cb   Goutte   Clip the paths of...
430
      console.debug("Resizing " + this + ": " + width + " x " + height + "…");
438929a4   Goutte   Rewrite the orbit...
431
432
433
      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);
123313cb   Goutte   Clip the paths of...
434
      this.clip.attr("width", width).attr("height", height);
438929a4   Goutte   Rewrite the orbit...
435
436
437
      this.path.attr('d', this.line);
      this.xAxis.scale(this.xScale);
      this.yAxis.scale(this.yScale);
d49a163c   Goutte   Fix the resize an...
438
439
      this.xAxis.ticks(Math.floor(width / 90.0));
      this.yAxis.ticks(Math.floor(height / 18.0));
438929a4   Goutte   Rewrite the orbit...
440
441
      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.
442
      this.yAxisText.attr("y", 20 - this.margin.left).attr("x", 0 - height / 2);
b60e7acd   Goutte   Rename "source" i...
443
      this.yAxisTextTarget.attr("y", 0 - this.margin.left).attr("x", 0 - height / 2);
2463bd16   Goutte   Add a circle foll...
444
      this.mouseCanvas.attr("width", width).attr("height", height);
08569a6b   Goutte   Add a zooming bru...
445
      if (this.brushFunction == null) {
c3008fb2   Goutte   Clean up and refa...
446
        console.debug("Creating the zooming brush for " + this + "…");
08569a6b   Goutte   Add a zooming bru...
447
448
        this.brushFunction = d3.brushX().extent([[0, 0], [width, height]]).handleSize(0).on("end", this.onBrushEnd);
        this.brush.call(this.brushFunction);
c3008fb2   Goutte   Clean up and refa...
449
        this.svg.select(".brush .overlay").on("mouseover.swapp", this.onMouseOver).on("mouseout.swapp", this.onMouseOut).on("mousemove.swapp", this.onMouseMove).on("dblclick.swapp", this.onDoubleClick);
08569a6b   Goutte   Add a zooming bru...
450
      }
6bb225d6   Goutte   Link the time ser...
451
452
      if (!this.visible) {
        this.hide();
b7fe650c   Goutte   Misc bundle of ol...
453
      }
2463bd16   Goutte   Add a circle foll...
454
455
      return this;
    };
2c0e1515   Goutte   Refactor loading ...
456
457
458
459
    TimeSeries.prototype.clear = function(){
      $(this.svg.node()).remove();
      return this.visible = false;
    };
6bb225d6   Goutte   Link the time ser...
460
461
462
463
464
465
466
467
    TimeSeries.prototype.show = function(){
      $(this.svg.node()).show();
      return this.visible = true;
    };
    TimeSeries.prototype.hide = function(){
      $(this.svg.node()).hide();
      return this.visible = false;
    };
541e2936   Goutte   Synchronize the t...
468
469
470
471
    TimeSeries.prototype.onMouseMove = function(){
      var x;
      x = this.xScale.invert(d3.mouse(this.mouseCanvas.node())[0]);
      if (this.options.onMouseMove != null) {
2038c9fb   Goutte   Add a zoom reset ...
472
        return this.options.onMouseMove(x);
541e2936   Goutte   Synchronize the t...
473
      } else {
2038c9fb   Goutte   Add a zoom reset ...
474
        return this.moveCursor(x);
541e2936   Goutte   Synchronize the t...
475
      }
541e2936   Goutte   Synchronize the t...
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
    };
    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();
      }
    };
2038c9fb   Goutte   Add a zoom reset ...
491
    TimeSeries.prototype.onDoubleClick = function(){
c3008fb2   Goutte   Clean up and refa...
492
493
494
495
496
      if (this.options.onDblClick != null) {
        return this.options.onDblClick();
      } else {
        return this.resetZoom();
      }
2038c9fb   Goutte   Add a zoom reset ...
497
    };
08569a6b   Goutte   Add a zooming bru...
498
499
500
    TimeSeries.prototype.onBrushEnd = function(){
      var s, minmax;
      s = d3.event.selection;
08569a6b   Goutte   Add a zooming bru...
501
502
      if (s) {
        minmax = [s[0], s[1]].map(this.xScale.invert, this.xScale);
08569a6b   Goutte   Add a zooming bru...
503
        this.brush.call(this.brushFunction.move, null);
c3008fb2   Goutte   Clean up and refa...
504
505
506
507
508
        if (this.options.onBrushEnd != null) {
          return this.options.onBrushEnd(minmax[0], minmax[1]);
        } else {
          return this.zoomIn(minmax[0], minmax[1]);
        }
2038c9fb   Goutte   Add a zoom reset ...
509
510
511
512
513
      }
    };
    TimeSeries.prototype.zoomIn = function(startDate, stopDate){
      var ref$, minDate, maxDate;
      console.debug("Zooming in " + this + " from " + startDate + " to " + stopDate + ".");
6bb225d6   Goutte   Link the time ser...
514
      ref$ = this.xDataExtent, minDate = ref$[0], maxDate = ref$[1];
2038c9fb   Goutte   Add a zoom reset ...
515
516
517
518
519
      if (startDate < minDate) {
        startDate = minDate;
      }
      if (stopDate > maxDate) {
        stopDate = maxDate;
08569a6b   Goutte   Add a zooming bru...
520
      }
2038c9fb   Goutte   Add a zoom reset ...
521
522
523
524
      this.xScale.domain([startDate, stopDate]);
      return this.applyZoom();
    };
    TimeSeries.prototype.resetZoom = function(){
6bb225d6   Goutte   Link the time ser...
525
526
      this.xScale.domain(this.xDataExtent);
      this.yScale.domain(this.yDataExtent);
2038c9fb   Goutte   Add a zoom reset ...
527
      return this.applyZoom();
08569a6b   Goutte   Add a zooming bru...
528
    };
2038c9fb   Goutte   Add a zoom reset ...
529
    TimeSeries.prototype.applyZoom = function(){
08569a6b   Goutte   Add a zooming bru...
530
      var t;
6bb225d6   Goutte   Link the time ser...
531
      if (this.visible) {
c3008fb2   Goutte   Clean up and refa...
532
        console.debug("Applying zoom to visible " + this + "…");
6bb225d6   Goutte   Link the time ser...
533
534
535
536
537
        t = this.svg.transition().duration(750);
        this.svg.select('.x.axis').transition(t).call(this.xAxis);
        this.svg.select('.y.axis').transition(t).call(this.yAxis);
        return this.path.transition(t).attr('d', this.line);
      } else {
c3008fb2   Goutte   Clean up and refa...
538
        console.debug("Applying zoom to hidden " + this + "…");
6bb225d6   Goutte   Link the time ser...
539
540
541
542
        this.svg.select('.x.axis').call(this.xAxis);
        this.svg.select('.y.axis').call(this.yAxis);
        return this.path.attr('d', this.line);
      }
08569a6b   Goutte   Add a zooming bru...
543
    };
541e2936   Goutte   Synchronize the t...
544
545
546
547
548
549
    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...
550
551
552
    TimeSeries.prototype.bisectDate = d3.bisector(function(d){
      return d.x;
    }).left;
81c9b2e8   Goutte   Add the values to...
553
    TimeSeries.prototype.timeFormat = d3.timeFormat("%Y-%m-%d %Hh");
541e2936   Goutte   Synchronize the t...
554
    TimeSeries.prototype.moveCursor = function(x0){
8cb213b9   Goutte   Clean up, and pre...
555
      var i, d0, d1, d, xx, yy, mirrored, dx, transform;
2463bd16   Goutte   Add a circle foll...
556
557
558
      i = this.bisectDate(this.data, x0, 1);
      d0 = this.data[i - 1];
      d1 = this.data[i];
541e2936   Goutte   Synchronize the t...
559
560
561
      if (!(d1 && d0)) {
        return;
      }
2463bd16   Goutte   Add a circle foll...
562
563
564
      d = x0 - d0.x > d1.x - x0 ? d1 : d0;
      xx = this.xScale(d.x);
      yy = this.yScale(d.y);
541e2936   Goutte   Synchronize the t...
565
566
567
568
569
      mirrored = this.plotWidth != null && xx > this.plotWidth / 2 ? true : false;
      dx = 8;
      if (mirrored) {
        dx = -1 * dx;
      }
8cb213b9   Goutte   Clean up, and pre...
570
      transform = "translate(" + xx + ", " + yy + ")";
81c9b2e8   Goutte   Add the values to...
571
      this.cursorCircle.attr("transform", transform);
541e2936   Goutte   Synchronize the t...
572
573
574
575
      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...
576
577
578
579
580
      return this;
    };
    return TimeSeries;
  }());
  out$.Orbits = Orbits = (function(){
8cb213b9   Goutte   Clean up, and pre...
581
    "View of the solar system from above, with orbits segments for selected time\ninterval, from real data.";
438929a4   Goutte   Rewrite the orbit...
582
583
    Orbits.displayName = 'Orbits';
    var prototype = Orbits.prototype, constructor = Orbits;
a21f81d9   Goutte   Enable Venus and ...
584
    function Orbits(container, options){
438929a4   Goutte   Rewrite the orbit...
585
586
587
588
      this.container = container;
      this.options = options != null
        ? options
        : {};
438929a4   Goutte   Rewrite the orbit...
589
590
591
      this.init();
    }
    Orbits.prototype.init = function(){
c3008fb2   Goutte   Clean up and refa...
592
      console.log("Initializing plot of orbits…");
438929a4   Goutte   Rewrite the orbit...
593
594
595
      this.margin = {
        top: 30,
        right: 20,
11662eed   Goutte   Add Y axis label ...
596
        bottom: 42,
438929a4   Goutte   Rewrite the orbit...
597
598
        left: 60
      };
a21f81d9   Goutte   Enable Venus and ...
599
600
      this.data = {};
      this.orbiters = {};
7994cf1a   Goutte   Hunt bugs.
601
      this.orbitersElements = {};
a21f81d9   Goutte   Enable Venus and ...
602
      this.extremum = 1;
438929a4   Goutte   Rewrite the orbit...
603
604
605
606
607
608
609
      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...
610
611
612
613
614
      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 ...
615
      this.xAxisTitle.append('tspan').attr('dy', '3px').text('HEE').attr('font-size', '8px');
ae0aa7d2   Goutte   Add an x axis lab...
616
      this.xAxisTitle.append('tspan').attr('dy', '-3px').text('   (AU)');
11662eed   Goutte   Add Y axis label ...
617
618
619
620
621
622
      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...
623
      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...
624
      this.sun.append('svg:title').text("Sol");
3ee0b596   Goutte   Fix an annoying b...
625
      $(this.svg.node()).hide();
438929a4   Goutte   Rewrite the orbit...
626
627
      return this.resize();
    };
a21f81d9   Goutte   Enable Venus and ...
628
    Orbits.prototype.initOrbiter = function(slug, config, data){
438929a4   Goutte   Rewrite the orbit...
629
      var orbit_ellipse, orbiter, orbit_line, orbit_section, this$ = this;
ebe77ce4   Goutte   Clean up.
630
      console.info("Initializing orbit of " + config.name + "…");
438929a4   Goutte   Rewrite the orbit...
631
632
633
      if (slug in this.orbitersElements) {
        throw new Error("Second init of " + slug);
      }
a21f81d9   Goutte   Enable Venus and ...
634
635
636
637
638
      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...
639
640
641
642
643
644
645
      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 ...
646
647
648
      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...
649
650
651
652
653
654
      this.orbitersElements[slug] = {
        orbiter: orbiter,
        orbit_ellipse: orbit_ellipse,
        orbit_section: orbit_section,
        orbit_line: orbit_line
      };
a21f81d9   Goutte   Enable Venus and ...
655
      this.resize();
3ee0b596   Goutte   Fix an annoying b...
656
      $(this.svg.node()).show();
438929a4   Goutte   Rewrite the orbit...
657
658
      return this;
    };
2c0e1515   Goutte   Refactor loading ...
659
660
661
    Orbits.prototype.clear = function(){
      return $(this.svg.node()).remove();
    };
438929a4   Goutte   Rewrite the orbit...
662
663
    Orbits.prototype.resize = function(){
      var width, height, slug, ref$, config;
667eeb24   Goutte   Resize the domain...
664
665
666
      width = Math.ceil($(this.container).width() - this.margin.left - this.margin.right);
      height = Math.ceil(1.0 * width);
      console.debug("Resizing orbits : " + width + " × " + height + "…");
438929a4   Goutte   Rewrite the orbit...
667
668
669
      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...
670
      this.sun.attr("x", width / 2 - 16).attr("y", height / 2 - 16);
438929a4   Goutte   Rewrite the orbit...
671
672
      for (slug in ref$ = this.orbiters) {
        config = ref$[slug];
667eeb24   Goutte   Resize the domain...
673
        this.resizeOrbiter(slug, config, width, height);
438929a4   Goutte   Rewrite the orbit...
674
675
676
677
678
      }
      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 ...
679
680
      this.xAxisTitle.attr("x", width / 2).attr("y", 37);
      this.yAxisTitle.attr("x", -1 * height / 2).attr("y", -30);
438929a4   Goutte   Rewrite the orbit...
681
682
      return this;
    };
667eeb24   Goutte   Resize the domain...
683
684
685
    Orbits.prototype.resizeOrbiter = function(slug, config, width, height){
      var el, a, b, c, cx, cy, data;
      console.debug("Resizing orbit of " + slug + "…");
438929a4   Goutte   Rewrite the orbit...
686
687
688
689
690
691
692
693
      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 ...
694
      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...
695
      this.yScale.range([height, 0]);
a21f81d9   Goutte   Enable Venus and ...
696
      data = this.data[slug];
438929a4   Goutte   Rewrite the orbit...
697
698
699
700
      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...
701
702
    Orbits.prototype.repositionOrbiter = function(slug, datum){
      var data, el;
a21f81d9   Goutte   Enable Venus and ...
703
      data = this.data[slug];
ae0aa7d2   Goutte   Add an x axis lab...
704
705
706
707
708
709
710
711
712
713
      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 ...
714
715
      var slug, ref$, el, data, i, d0, d1, d;
      if (!t) {
667eeb24   Goutte   Resize the domain...
716
        console.warn("Trying to move to an undefined date !");
a21f81d9   Goutte   Enable Venus and ...
717
      }
ae0aa7d2   Goutte   Add an x axis lab...
718
719
      for (slug in ref$ = this.orbitersElements) {
        el = ref$[slug];
a21f81d9   Goutte   Enable Venus and ...
720
        data = this.data[slug];
ae0aa7d2   Goutte   Add an x axis lab...
721
722
723
724
725
726
727
        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 ...
728
        this.repositionOrbiter(slug, d);
ae0aa7d2   Goutte   Add an x axis lab...
729
      }
a21f81d9   Goutte   Enable Venus and ...
730
      return this;
ae0aa7d2   Goutte   Add an x axis lab...
731
    };
667eeb24   Goutte   Resize the domain...
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
    Orbits.prototype.resizeDomain = function(started_at, stopped_at){
      var slug, ref$, config, el, data, results$ = [];
      for (slug in ref$ = this.orbiters) {
        config = ref$[slug];
        el = this.orbitersElements[slug];
        data = this.data[slug].filter(fn$);
        el['orbit_section'].datum(data);
        results$.push(el['orbit_section'].attr('d', el['orbit_line']));
      }
      return results$;
      function fn$(d){
        var ref$;
        return started_at <= (ref$ = d.t) && ref$ <= stopped_at;
      }
    };
    Orbits.prototype.resetZoom = function(){
      var slug, ref$, config, el, results$ = [];
      for (slug in ref$ = this.orbiters) {
        config = ref$[slug];
        el = this.orbitersElements[slug];
        el['orbit_section'].datum(this.data[slug]);
        results$.push(el['orbit_section'].attr('d', el['orbit_line']));
      }
      return results$;
    };
438929a4   Goutte   Rewrite the orbit...
757
758
    return Orbits;
  }());
2463bd16   Goutte   Add a circle foll...
759
760
761
  function bind$(obj, key, target){
    return function(){ return (target || obj)[key].apply(obj, arguments) };
  }
438929a4   Goutte   Rewrite the orbit...
762
}).call(this);