Blame view

web/static/js/swapp.js 24.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
12
13
14
15
  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;
      this.active = true;
    }
    return Target;
  }());
ae0aa7d2   Goutte   Add an x axis lab...
16
  out$.SpaceWeather = SpaceWeather = (function(){
b60e7acd   Goutte   Rename "source" i...
17
    "The main app, instanciated from an inline script.\nIt defaults to an interval starting a year ago, and ending in seven days.";
ae0aa7d2   Goutte   Add an x axis lab...
18
    SpaceWeather.displayName = 'SpaceWeather';
7d6dee0f   Goutte   Continue refacto ...
19
    var timeSeries, prototype = SpaceWeather.prototype, constructor = SpaceWeather;
ae0aa7d2   Goutte   Add an x axis lab...
20
    function SpaceWeather(configuration){
fe3132dd   Goutte   Refactor even more.
21
      var configs, res$, k, this$ = this;
f75faf5f   Goutte   WIP
22
      this.configuration = configuration;
2038c9fb   Goutte   Add a zoom reset ...
23
      console.info("  _   _      _ _       ____\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...
24
      this.targets = {};
fe3132dd   Goutte   Refactor even more.
25
      res$ = [];
b60e7acd   Goutte   Rename "source" i...
26
27
      for (k in this.configuration.targets) {
        res$.push(this.configuration.targets[k]);
fe3132dd   Goutte   Refactor even more.
28
29
      }
      configs = res$;
b60e7acd   Goutte   Rename "source" i...
30
31
      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.
32
      });
b7fe650c   Goutte   Misc bundle of ol...
33
34
35
36
      this.parameters = {};
      this.configuration['parameters'].forEach(function(p){
        return this$.parameters[p['id']] = p;
      });
ae0aa7d2   Goutte   Add an x axis lab...
37
    }
b60e7acd   Goutte   Rename "source" i...
38
39
40
41
42
43
44
45
46
47
48
    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)";
      var active_targets, res$, k, started_at, stopped_at, this$ = this;
      res$ = [];
      for (k in this.targets) {
        if (this.targets[k].config.active) {
          res$.push(this.targets[k]);
        }
      }
      active_targets = res$;
      this.orbits = new Orbits(this.configuration.orbits_container, this.configuration);
8cb213b9   Goutte   Clean up, and pre...
49
50
51
52
      this.started_at = moment().subtract(1, 'years').hours(0).minutes(0).seconds(0);
      this.stopped_at = moment().add(7, 'days').hours(0).minutes(0).seconds(0);
      started_at = this.started_at.format("YYYY-MM-DDTHH:mm:ss");
      stopped_at = this.stopped_at.format("YYYY-MM-DDTHH:mm:ss");
b60e7acd   Goutte   Rename "source" i...
53
54
55
56
57
58
59
60
61
62
63
64
65
66
      active_targets.forEach(function(target){
        return this$.loadData(target.slug, started_at, stopped_at).then(function(data){
          console.info("Loaded CSV data for " + target.slug + ".");
          this$.createTimeSeries(target, data);
          return this$.orbits.initOrbiter(target.slug, target.config, data['hci']);
        }, function(error){
          return console.error('Failed to load CSV data.', error);
        });
      });
      return window.addEventListener('resize', function(){
        return this$.resize();
      });
    };
    SpaceWeather.prototype.buildDataUrlForTarget = function(target_slug, started_at, stopped_at){
f75faf5f   Goutte   WIP
67
68
      var url;
      url = this.configuration['api']['data_for_interval'];
b60e7acd   Goutte   Rename "source" i...
69
      url = url.replace('<target>', target_slug);
a4a9ef03   Goutte   Cache generated C...
70
71
      url = url.replace('<started_at>', started_at);
      url = url.replace('<stopped_at>', stopped_at);
f75faf5f   Goutte   WIP
72
73
      return url;
    };
b60e7acd   Goutte   Rename "source" i...
74
75
    SpaceWeather.prototype.addTarget = function(target){
      this.targets[target.slug] = target;
f75faf5f   Goutte   WIP
76
77
      return this;
    };
b60e7acd   Goutte   Rename "source" i...
78
79
80
81
82
    SpaceWeather.prototype.showAllTargets = function(){
      var slug, ref$, target;
      for (slug in ref$ = this.targets) {
        target = ref$[slug];
        showTarget(slug);
f75faf5f   Goutte   WIP
83
84
85
      }
      return this;
    };
b60e7acd   Goutte   Rename "source" i...
86
    SpaceWeather.prototype.showTarget = function(target_slug){
4cf497e0   Goutte   Make the targets ...
87
88
      var this$ = this;
      timeSeries.forEach(function(ts){
b60e7acd   Goutte   Rename "source" i...
89
        if (ts.target.slug === target_slug && this$.parameters[ts.parameter].active) {
4cf497e0   Goutte   Make the targets ...
90
91
92
          return $(ts.svg.node()).show();
        }
      });
b60e7acd   Goutte   Rename "source" i...
93
      this.targets[target_slug].active = true;
f75faf5f   Goutte   WIP
94
95
      return this;
    };
b60e7acd   Goutte   Rename "source" i...
96
    SpaceWeather.prototype.hideTarget = function(target_slug){
4cf497e0   Goutte   Make the targets ...
97
      timeSeries.forEach(function(ts){
b60e7acd   Goutte   Rename "source" i...
98
        if (ts.target.slug === target_slug) {
4cf497e0   Goutte   Make the targets ...
99
100
101
          return $(ts.svg.node()).hide();
        }
      });
b60e7acd   Goutte   Rename "source" i...
102
      this.targets[target_slug].active = false;
f75faf5f   Goutte   WIP
103
104
      return this;
    };
fe3132dd   Goutte   Refactor even more.
105
    SpaceWeather.prototype.resize = function(){
a21f81d9   Goutte   Enable Venus and ...
106
      var ref$;
d49a163c   Goutte   Fix the resize an...
107
108
109
110
111
112
      if ((ref$ = this.orbits) != null) {
        ref$.resize();
      }
      return timeSeries.forEach(function(ts){
        return ts.resize();
      });
fe3132dd   Goutte   Refactor even more.
113
    };
b60e7acd   Goutte   Rename "source" i...
114
115
    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.";
f75faf5f   Goutte   WIP
116
117
118
119
      var sw, promise;
      sw = this;
      promise = new Promise(function(resolve, reject){
        var url;
b60e7acd   Goutte   Rename "source" i...
120
        url = sw.buildDataUrlForTarget(target_slug, started_at, stopped_at);
a4a9ef03   Goutte   Cache generated C...
121
        return d3.csv(url, function(csv){
f75faf5f   Goutte   WIP
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
          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 ...
154
    timeSeries = [];
b60e7acd   Goutte   Rename "source" i...
155
    SpaceWeather.prototype.createTimeSeries = function(target, data){
7d6dee0f   Goutte   Continue refacto ...
156
      var this$ = this;
4816cef4   Goutte   Refactor some more.
157
158
      this.configuration['parameters'].forEach(function(parameter){
        var container, id, title;
b7fe650c   Goutte   Misc bundle of ol...
159
        container = this$.configuration['time_series_container'];
4816cef4   Goutte   Refactor some more.
160
161
162
163
164
        id = parameter['id'];
        title = parameter['title'];
        if (!(id in data)) {
          console.error("No data for id '" + id + "'.", data);
        }
b60e7acd   Goutte   Rename "source" i...
165
        return timeSeries.push(new TimeSeries(id, title, target, data[id], this$.parameters[id].active, container));
4816cef4   Goutte   Refactor some more.
166
167
168
169
170
171
172
173
174
175
176
177
178
      });
      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.
179
          var ref$;
4816cef4   Goutte   Refactor some more.
180
181
182
          timeSeries.forEach(function(ts2){
            return ts2.moveCursor(t);
          });
fe3132dd   Goutte   Refactor even more.
183
          return (ref$ = this$.orbits) != null ? ref$.moveToDate(t) : void 8;
4816cef4   Goutte   Refactor some more.
184
185
186
        };
      });
    };
b7fe650c   Goutte   Misc bundle of ol...
187
    SpaceWeather.prototype.enableParameter = function(parameter_slug){
4cf497e0   Goutte   Make the targets ...
188
      var this$ = this;
b7fe650c   Goutte   Misc bundle of ol...
189
190
191
      if (!(parameter_slug in this.parameters)) {
        console.error("Unknown parameter " + parameter_slug + ".");
      }
b7fe650c   Goutte   Misc bundle of ol...
192
      this.parameters[parameter_slug].active = true;
4cf497e0   Goutte   Make the targets ...
193
      timeSeries.forEach(function(ts){
b60e7acd   Goutte   Rename "source" i...
194
        if (ts.parameter === parameter_slug && this$.targets[ts.target.slug].active) {
4cf497e0   Goutte   Make the targets ...
195
196
197
          return $(ts.svg.node()).show();
        }
      });
b7fe650c   Goutte   Misc bundle of ol...
198
199
200
201
202
203
      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...
204
      this.parameters[parameter_slug].active = false;
4cf497e0   Goutte   Make the targets ...
205
206
207
208
209
      timeSeries.forEach(function(ts){
        if (ts.parameter === parameter_slug) {
          return $(ts.svg.node()).hide();
        }
      });
b7fe650c   Goutte   Misc bundle of ol...
210
211
      return this;
    };
8cb213b9   Goutte   Clean up, and pre...
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
    SpaceWeather.prototype.resizeDomain = function(started_at, stopped_at){
      var tmp;
      if (stopped_at < started_at) {
        tmp = started_at;
        started_at = stopped_at;
        stopped_at = started_at;
      }
      if (started_at === stopped_at) {
        console.warn("Please provide different start and stop dates.");
        return;
      }
      if ((this.started_at <= started_at && started_at <= this.stopped_at) && (this.started_at <= stopped_at && stopped_at <= this.stopped_at)) {
        console.info("Resizing the temporal domain without fetching new data...");
        timeSeries.forEach(function(ts){
          return ts.resizeDomain(started_at, stopped_at);
        });
        this.orbits.resizeDomain(started_at, stopped_at);
      }
    };
ae0aa7d2   Goutte   Add an x axis lab...
231
232
    return SpaceWeather;
  }());
438929a4   Goutte   Rewrite the orbit...
233
234
235
  out$.TimeSeries = TimeSeries = (function(){
    TimeSeries.displayName = 'TimeSeries';
    var prototype = TimeSeries.prototype, constructor = TimeSeries;
b60e7acd   Goutte   Rename "source" i...
236
    function TimeSeries(parameter, title, target, data, active, container, options){
4cf497e0   Goutte   Make the targets ...
237
      this.parameter = parameter;
438929a4   Goutte   Rewrite the orbit...
238
      this.title = title;
b60e7acd   Goutte   Rename "source" i...
239
      this.target = target;
438929a4   Goutte   Rewrite the orbit...
240
      this.data = data;
b7fe650c   Goutte   Misc bundle of ol...
241
      this.active = active;
438929a4   Goutte   Rewrite the orbit...
242
243
244
245
      this.container = container;
      this.options = options != null
        ? options
        : {};
08569a6b   Goutte   Add a zooming bru...
246
      this.onBrushEnd = bind$(this, 'onBrushEnd', prototype);
2038c9fb   Goutte   Add a zoom reset ...
247
      this.onDoubleClick = bind$(this, 'onDoubleClick', prototype);
541e2936   Goutte   Synchronize the t...
248
249
250
      this.onMouseOut = bind$(this, 'onMouseOut', prototype);
      this.onMouseOver = bind$(this, 'onMouseOver', prototype);
      this.onMouseMove = bind$(this, 'onMouseMove', prototype);
438929a4   Goutte   Rewrite the orbit...
251
252
      this.init();
    }
2038c9fb   Goutte   Add a zoom reset ...
253
254
255
    TimeSeries.prototype.toString = function(){
      return this.title + " of " + this.target.name;
    };
438929a4   Goutte   Rewrite the orbit...
256
    TimeSeries.prototype.init = function(){
541e2936   Goutte   Synchronize the t...
257
      var dx, this$ = this;
2038c9fb   Goutte   Add a zoom reset ...
258
      console.info("Initializing time series " + this + "...");
438929a4   Goutte   Rewrite the orbit...
259
260
261
262
      this.margin = {
        top: 30,
        right: 20,
        bottom: 30,
fe3132dd   Goutte   Refactor even more.
263
        left: 80
438929a4   Goutte   Rewrite the orbit...
264
265
266
267
268
269
270
      };
      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;
      }));
08569a6b   Goutte   Add a zooming bru...
271
      this.xAxis = d3.axisBottom().ticks(7);
438929a4   Goutte   Rewrite the orbit...
272
273
274
275
276
277
278
      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...
279
      this.svg.attr("class", this.parameter + " " + this.target.slug);
438929a4   Goutte   Rewrite the orbit...
280
281
      this.plotWrapper = this.svg.append('g');
      this.plotWrapper.attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')');
438929a4   Goutte   Rewrite the orbit...
282
      this.path = this.plotWrapper.append('path').datum(this.data).classed('line', true);
08569a6b   Goutte   Add a zooming bru...
283
284
      this.brush = this.plotWrapper.append("g").attr("class", "brush");
      this.mouseCanvas = this.plotWrapper.append("rect").style("fill", "none");
438929a4   Goutte   Rewrite the orbit...
285
286
287
      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...
288
      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...
289
290
      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...
291
292
293
294
295
      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...
296
297
298
299
300
      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...
301
302
303
      height = GOLDEN_RATIO * GOLDEN_RATIO * GOLDEN_RATIO * GOLDEN_RATIO * width;
      this.plotWidth = width;
      this.plotHeight = height;
438929a4   Goutte   Rewrite the orbit...
304
305
306
307
308
309
      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...
310
311
      this.xAxis.ticks(Math.floor(width / 90.0));
      this.yAxis.ticks(Math.floor(height / 18.0));
438929a4   Goutte   Rewrite the orbit...
312
313
      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.
314
      this.yAxisText.attr("y", 20 - this.margin.left).attr("x", 0 - height / 2);
b60e7acd   Goutte   Rename "source" i...
315
      this.yAxisTextTarget.attr("y", 0 - this.margin.left).attr("x", 0 - height / 2);
2463bd16   Goutte   Add a circle foll...
316
      this.mouseCanvas.attr("width", width).attr("height", height);
08569a6b   Goutte   Add a zooming bru...
317
      if (this.brushFunction == null) {
2038c9fb   Goutte   Add a zoom reset ...
318
        console.log("Creating the zooming brush for " + this + "...");
08569a6b   Goutte   Add a zooming bru...
319
320
        this.brushFunction = d3.brushX().extent([[0, 0], [width, height]]).handleSize(0).on("end", this.onBrushEnd);
        this.brush.call(this.brushFunction);
2038c9fb   Goutte   Add a zoom reset ...
321
        this.svg.select(".brush .overlay").on("mouseover.swappcursor", this.onMouseOver).on("mouseout.swappcursor", this.onMouseOut).on("mousemove.swappcursor", this.onMouseMove).on("dblclick", this.onDoubleClick);
08569a6b   Goutte   Add a zooming bru...
322
      }
b7fe650c   Goutte   Misc bundle of ol...
323
324
325
      if (!this.active) {
        $(this.svg.node()).hide();
      }
2463bd16   Goutte   Add a circle foll...
326
327
      return this;
    };
2038c9fb   Goutte   Add a zoom reset ...
328
    TimeSeries.prototype.resizeDomain = function(startDate, stopDate){};
541e2936   Goutte   Synchronize the t...
329
330
331
332
    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 ...
333
        return this.options.onMouseMove(x);
541e2936   Goutte   Synchronize the t...
334
      } else {
2038c9fb   Goutte   Add a zoom reset ...
335
        return this.moveCursor(x);
541e2936   Goutte   Synchronize the t...
336
      }
541e2936   Goutte   Synchronize the t...
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
    };
    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 ...
352
353
354
355
    TimeSeries.prototype.onDoubleClick = function(){
      console.debug("Resetting zoom of " + this + ".");
      return this.resetZoom();
    };
08569a6b   Goutte   Add a zooming bru...
356
357
358
    TimeSeries.prototype.onBrushEnd = function(){
      var s, minmax;
      s = d3.event.selection;
08569a6b   Goutte   Add a zooming bru...
359
360
      if (s) {
        minmax = [s[0], s[1]].map(this.xScale.invert, this.xScale);
08569a6b   Goutte   Add a zooming bru...
361
        this.brush.call(this.brushFunction.move, null);
2038c9fb   Goutte   Add a zoom reset ...
362
363
364
365
366
367
368
369
370
371
372
373
374
375
        return this.zoomIn(minmax[0], minmax[1]);
      }
    };
    TimeSeries.prototype.zoomIn = function(startDate, stopDate){
      var ref$, minDate, maxDate;
      console.debug("Zooming in " + this + " from " + startDate + " to " + stopDate + ".");
      ref$ = d3.extent(this.data, function(d){
        return d.x;
      }), minDate = ref$[0], maxDate = ref$[1];
      if (startDate < minDate) {
        startDate = minDate;
      }
      if (stopDate > maxDate) {
        stopDate = maxDate;
08569a6b   Goutte   Add a zooming bru...
376
      }
2038c9fb   Goutte   Add a zoom reset ...
377
378
379
380
381
382
383
384
385
386
387
      this.xScale.domain([startDate, stopDate]);
      return this.applyZoom();
    };
    TimeSeries.prototype.resetZoom = function(){
      this.xScale.domain(d3.extent(this.data, function(d){
        return d.x;
      }));
      this.yScale.domain(d3.extent(this.data, function(d){
        return d.y;
      }));
      return this.applyZoom();
08569a6b   Goutte   Add a zooming bru...
388
    };
2038c9fb   Goutte   Add a zoom reset ...
389
    TimeSeries.prototype.applyZoom = function(){
08569a6b   Goutte   Add a zooming bru...
390
391
392
393
394
395
      var t;
      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);
    };
541e2936   Goutte   Synchronize the t...
396
397
398
399
400
401
    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...
402
403
404
    TimeSeries.prototype.bisectDate = d3.bisector(function(d){
      return d.x;
    }).left;
81c9b2e8   Goutte   Add the values to...
405
    TimeSeries.prototype.timeFormat = d3.timeFormat("%Y-%m-%d %Hh");
541e2936   Goutte   Synchronize the t...
406
    TimeSeries.prototype.moveCursor = function(x0){
8cb213b9   Goutte   Clean up, and pre...
407
      var i, d0, d1, d, xx, yy, mirrored, dx, transform;
2463bd16   Goutte   Add a circle foll...
408
409
410
      i = this.bisectDate(this.data, x0, 1);
      d0 = this.data[i - 1];
      d1 = this.data[i];
541e2936   Goutte   Synchronize the t...
411
412
413
      if (!(d1 && d0)) {
        return;
      }
2463bd16   Goutte   Add a circle foll...
414
415
416
      d = x0 - d0.x > d1.x - x0 ? d1 : d0;
      xx = this.xScale(d.x);
      yy = this.yScale(d.y);
541e2936   Goutte   Synchronize the t...
417
418
419
420
421
      mirrored = this.plotWidth != null && xx > this.plotWidth / 2 ? true : false;
      dx = 8;
      if (mirrored) {
        dx = -1 * dx;
      }
8cb213b9   Goutte   Clean up, and pre...
422
      transform = "translate(" + xx + ", " + yy + ")";
81c9b2e8   Goutte   Add the values to...
423
      this.cursorCircle.attr("transform", transform);
541e2936   Goutte   Synchronize the t...
424
425
426
427
      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...
428
429
430
431
432
      return this;
    };
    return TimeSeries;
  }());
  out$.Orbits = Orbits = (function(){
8cb213b9   Goutte   Clean up, and pre...
433
    "View of the solar system from above, with orbits segments for selected time\ninterval, from real data.";
438929a4   Goutte   Rewrite the orbit...
434
435
    Orbits.displayName = 'Orbits';
    var prototype = Orbits.prototype, constructor = Orbits;
a21f81d9   Goutte   Enable Venus and ...
436
    function Orbits(container, options){
438929a4   Goutte   Rewrite the orbit...
437
438
439
440
      this.container = container;
      this.options = options != null
        ? options
        : {};
438929a4   Goutte   Rewrite the orbit...
441
442
443
      this.init();
    }
    Orbits.prototype.init = function(){
a21f81d9   Goutte   Enable Venus and ...
444
      console.log("Initializing orbits...", this.options);
438929a4   Goutte   Rewrite the orbit...
445
446
447
      this.margin = {
        top: 30,
        right: 20,
11662eed   Goutte   Add Y axis label ...
448
        bottom: 42,
438929a4   Goutte   Rewrite the orbit...
449
450
        left: 60
      };
a21f81d9   Goutte   Enable Venus and ...
451
452
453
      this.data = {};
      this.orbiters = {};
      this.extremum = 1;
438929a4   Goutte   Rewrite the orbit...
454
455
456
457
458
459
460
      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...
461
462
463
464
465
      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 ...
466
      this.xAxisTitle.append('tspan').attr('dy', '3px').text('HEE').attr('font-size', '8px');
ae0aa7d2   Goutte   Add an x axis lab...
467
      this.xAxisTitle.append('tspan').attr('dy', '-3px').text('   (AU)');
11662eed   Goutte   Add Y axis label ...
468
469
470
471
472
473
      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...
474
      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...
475
      this.sun.append('svg:title').text("Sol");
3ee0b596   Goutte   Fix an annoying b...
476
      $(this.svg.node()).hide();
438929a4   Goutte   Rewrite the orbit...
477
478
479
      return this.resize();
    };
    Orbits.prototype.orbitersElements = {};
a21f81d9   Goutte   Enable Venus and ...
480
    Orbits.prototype.initOrbiter = function(slug, config, data){
438929a4   Goutte   Rewrite the orbit...
481
      var orbit_ellipse, orbiter, orbit_line, orbit_section, this$ = this;
a21f81d9   Goutte   Enable Venus and ...
482
      console.log("Initializing target " + slug + "'s orbit...", config, data);
438929a4   Goutte   Rewrite the orbit...
483
484
485
      if (slug in this.orbitersElements) {
        throw new Error("Second init of " + slug);
      }
a21f81d9   Goutte   Enable Venus and ...
486
487
488
489
490
      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...
491
492
493
494
495
496
497
      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 ...
498
499
500
      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...
501
502
503
504
505
506
      this.orbitersElements[slug] = {
        orbiter: orbiter,
        orbit_ellipse: orbit_ellipse,
        orbit_section: orbit_section,
        orbit_line: orbit_line
      };
a21f81d9   Goutte   Enable Venus and ...
507
      this.resize();
3ee0b596   Goutte   Fix an annoying b...
508
      $(this.svg.node()).show();
438929a4   Goutte   Rewrite the orbit...
509
510
511
512
513
514
      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;
438929a4   Goutte   Rewrite the orbit...
515
516
517
      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...
518
      this.sun.attr("x", width / 2 - 16).attr("y", height / 2 - 16);
438929a4   Goutte   Rewrite the orbit...
519
520
521
522
523
524
525
526
      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 ...
527
528
      this.xAxisTitle.attr("x", width / 2).attr("y", 37);
      this.yAxisTitle.attr("x", -1 * height / 2).attr("y", -30);
438929a4   Goutte   Rewrite the orbit...
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
      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 ...
544
      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...
545
      this.yScale.range([height, 0]);
a21f81d9   Goutte   Enable Venus and ...
546
      data = this.data[slug];
438929a4   Goutte   Rewrite the orbit...
547
548
549
550
      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...
551
552
    Orbits.prototype.repositionOrbiter = function(slug, datum){
      var data, el;
a21f81d9   Goutte   Enable Venus and ...
553
      data = this.data[slug];
ae0aa7d2   Goutte   Add an x axis lab...
554
555
556
557
558
559
560
561
562
563
      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 ...
564
565
566
567
      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...
568
569
      for (slug in ref$ = this.orbitersElements) {
        el = ref$[slug];
a21f81d9   Goutte   Enable Venus and ...
570
        data = this.data[slug];
ae0aa7d2   Goutte   Add an x axis lab...
571
572
573
574
575
576
577
        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 ...
578
        this.repositionOrbiter(slug, d);
ae0aa7d2   Goutte   Add an x axis lab...
579
      }
a21f81d9   Goutte   Enable Venus and ...
580
      return this;
ae0aa7d2   Goutte   Add an x axis lab...
581
    };
8cb213b9   Goutte   Clean up, and pre...
582
    Orbits.prototype.resizeDomain = function(started_at, stopped_at){};
438929a4   Goutte   Rewrite the orbit...
583
584
    return Orbits;
  }());
2463bd16   Goutte   Add a circle foll...
585
586
587
  function bind$(obj, key, target){
    return function(){ return (target || obj)[key].apply(obj, arguments) };
  }
438929a4   Goutte   Rewrite the orbit...
588
}).call(this);