Commit cdf79b238419f6e9245601ab83c2895326cfe25b
1 parent
780828a8
Exists in
master
and in
2 other branches
Give the future data another color.
Showing
4 changed files
with
50 additions
and
4 deletions
Show diff stats
CHANGELOG.md
@@ -32,7 +32,9 @@ | @@ -32,7 +32,9 @@ | ||
32 | 32 | ||
33 | ## 1.0.0-rc7 | 33 | ## 1.0.0-rc7 |
34 | 34 | ||
35 | -- [ ] Give the future data another color | 35 | + |
36 | +- [ ] Add disabled layer buttons | ||
37 | +- [x] Give the future data another color | ||
36 | - [x] Change the default interval (from 2 months in the past to one in the future) | 38 | - [x] Change the default interval (from 2 months in the past to one in the future) |
37 | - [x] Prepare horizontal lines in the time series | 39 | - [x] Prepare horizontal lines in the time series |
38 | - [x] Add buttons to the orbits plot zoom to inner or outer heliosphere | 40 | - [x] Add buttons to the orbits plot zoom to inner or outer heliosphere |
web/static/js/swapp.js
@@ -14,7 +14,7 @@ | @@ -14,7 +14,7 @@ | ||
14 | return Target; | 14 | return Target; |
15 | }()); | 15 | }()); |
16 | out$.SpaceWeather = SpaceWeather = (function(){ | 16 | out$.SpaceWeather = SpaceWeather = (function(){ |
17 | - "The main app, instanciated from an inline script.\nIt defaults to an interval starting a month ago, and ending in a month.\n(both at midnight)"; | 17 | + "The main app, instanciated from an inline script.\nIt defaults to an interval starting two months ago, and ending in a month.\n(both at midnight)"; |
18 | SpaceWeather.displayName = 'SpaceWeather'; | 18 | SpaceWeather.displayName = 'SpaceWeather'; |
19 | var API_TIME_FORMAT, INPUT_TIME_FORMAT, prototype = SpaceWeather.prototype, constructor = SpaceWeather; | 19 | var API_TIME_FORMAT, INPUT_TIME_FORMAT, prototype = SpaceWeather.prototype, constructor = SpaceWeather; |
20 | API_TIME_FORMAT = "YYYY-MM-DDTHH:mm:ss"; | 20 | API_TIME_FORMAT = "YYYY-MM-DDTHH:mm:ss"; |
@@ -452,6 +452,7 @@ | @@ -452,6 +452,7 @@ | ||
452 | TimeSeries.displayName = 'TimeSeries'; | 452 | TimeSeries.displayName = 'TimeSeries'; |
453 | var RATIO, prototype = TimeSeries.prototype, constructor = TimeSeries; | 453 | var RATIO, prototype = TimeSeries.prototype, constructor = TimeSeries; |
454 | function TimeSeries(parameter, title, target, data, visible, container, options){ | 454 | function TimeSeries(parameter, title, target, data, visible, container, options){ |
455 | + var now, res$, i$, ref$, len$, d; | ||
455 | this.parameter = parameter; | 456 | this.parameter = parameter; |
456 | this.title = title; | 457 | this.title = title; |
457 | this.target = target; | 458 | this.target = target; |
@@ -466,6 +467,15 @@ | @@ -466,6 +467,15 @@ | ||
466 | this.onMouseOut = bind$(this, 'onMouseOut', prototype); | 467 | this.onMouseOut = bind$(this, 'onMouseOut', prototype); |
467 | this.onMouseOver = bind$(this, 'onMouseOver', prototype); | 468 | this.onMouseOver = bind$(this, 'onMouseOver', prototype); |
468 | this.onMouseMove = bind$(this, 'onMouseMove', prototype); | 469 | this.onMouseMove = bind$(this, 'onMouseMove', prototype); |
470 | + now = moment(); | ||
471 | + res$ = []; | ||
472 | + for (i$ = 0, len$ = (ref$ = this.data).length; i$ < len$; ++i$) { | ||
473 | + d = ref$[i$]; | ||
474 | + if (moment(d.x) >= now) { | ||
475 | + res$.push(d); | ||
476 | + } | ||
477 | + } | ||
478 | + this.predictiveData = res$; | ||
469 | this.init(); | 479 | this.init(); |
470 | } | 480 | } |
471 | TimeSeries.prototype.toString = function(){ | 481 | TimeSeries.prototype.toString = function(){ |
@@ -543,6 +553,7 @@ | @@ -543,6 +553,7 @@ | ||
543 | this.pathWrapper = this.plotWrapper.append('g'); | 553 | this.pathWrapper = this.plotWrapper.append('g'); |
544 | this.pathWrapper.attr("clip-path", "url(#" + clipId + ")"); | 554 | this.pathWrapper.attr("clip-path", "url(#" + clipId + ")"); |
545 | this.path = this.pathWrapper.append('path').datum(this.data).classed('line', true); | 555 | this.path = this.pathWrapper.append('path').datum(this.data).classed('line', true); |
556 | + this.predictiveDataPath = this.pathWrapper.append('path').datum(this.predictiveData).classed('predictive-line', true); | ||
546 | this.horizontalLines = []; | 557 | this.horizontalLines = []; |
547 | if (this.options['horizontalLines']) { | 558 | if (this.options['horizontalLines']) { |
548 | for (i$ = 0, len$ = (ref$ = this.options['horizontalLines']).length; i$ < len$; ++i$) { | 559 | for (i$ = 0, len$ = (ref$ = this.options['horizontalLines']).length; i$ < len$; ++i$) { |
@@ -582,6 +593,7 @@ | @@ -582,6 +593,7 @@ | ||
582 | this.svg.attr('width', width + this.margin.right + this.margin.left).attr('height', height + this.margin.top + this.margin.bottom); | 593 | this.svg.attr('width', width + this.margin.right + this.margin.left).attr('height', height + this.margin.top + this.margin.bottom); |
583 | this.clip.attr("width", width).attr("height", height); | 594 | this.clip.attr("width", width).attr("height", height); |
584 | this.path.attr('d', this.line); | 595 | this.path.attr('d', this.line); |
596 | + this.predictiveDataPath.attr('d', this.line); | ||
585 | for (i$ = 0, len$ = (ref$ = this.horizontalLines).length; i$ < len$; ++i$) { | 597 | for (i$ = 0, len$ = (ref$ = this.horizontalLines).length; i$ < len$; ++i$) { |
586 | line = ref$[i$]; | 598 | line = ref$[i$]; |
587 | lineValue = this.yScale(line['config']['value']) + this.margin.top; | 599 | lineValue = this.yScale(line['config']['value']) + this.margin.top; |
@@ -695,12 +707,14 @@ | @@ -695,12 +707,14 @@ | ||
695 | t = this.svg.transition().duration(750); | 707 | t = this.svg.transition().duration(750); |
696 | this.svg.select('.x.axis').transition(t).call(this.xAxis); | 708 | this.svg.select('.x.axis').transition(t).call(this.xAxis); |
697 | this.svg.select('.y.axis').transition(t).call(this.yAxis); | 709 | this.svg.select('.y.axis').transition(t).call(this.yAxis); |
698 | - return this.path.transition(t).attr('d', this.line); | 710 | + this.path.transition(t).attr('d', this.line); |
711 | + return this.predictiveDataPath.transition(t).attr('d', this.line); | ||
699 | } else { | 712 | } else { |
700 | console.debug("Applying zoom to hidden " + this + "…"); | 713 | console.debug("Applying zoom to hidden " + this + "…"); |
701 | this.svg.select('.x.axis').call(this.xAxis); | 714 | this.svg.select('.x.axis').call(this.xAxis); |
702 | this.svg.select('.y.axis').call(this.yAxis); | 715 | this.svg.select('.y.axis').call(this.yAxis); |
703 | - return this.path.attr('d', this.line); | 716 | + this.path.attr('d', this.line); |
717 | + return this.predictiveDataPath.attr('d', this.line); | ||
704 | } | 718 | } |
705 | }; | 719 | }; |
706 | TimeSeries.prototype.showCursor = function(){ | 720 | TimeSeries.prototype.showCursor = function(){ |
web/static/js/swapp.ls
@@ -358,6 +358,11 @@ export class TimeSeries | @@ -358,6 +358,11 @@ export class TimeSeries | ||
358 | # title : string, more descriptive, shown on the left of the Y axis | 358 | # title : string, more descriptive, shown on the left of the Y axis |
359 | # target : target object, like described in configuration | 359 | # target : target object, like described in configuration |
360 | # data : list of {x: <datetime>, y: <float>} | 360 | # data : list of {x: <datetime>, y: <float>} |
361 | + # options: object with the following properties | ||
362 | + # started_at (Moment obj) | ||
363 | + # stopped_at (Moment obj) | ||
364 | + now = moment() | ||
365 | + @predictiveData = [d for d in @data when moment(d.x) >= now] | ||
361 | @init() | 366 | @init() |
362 | 367 | ||
363 | toString: -> "#{@title} of #{@target.name}" | 368 | toString: -> "#{@title} of #{@target.name}" |
@@ -433,6 +438,9 @@ export class TimeSeries | @@ -433,6 +438,9 @@ export class TimeSeries | ||
433 | @path = @pathWrapper.append('path') | 438 | @path = @pathWrapper.append('path') |
434 | .datum(@data) | 439 | .datum(@data) |
435 | .classed('line', true) | 440 | .classed('line', true) |
441 | + @predictiveDataPath = @pathWrapper.append('path') | ||
442 | + .datum(@predictiveData) | ||
443 | + .classed('predictive-line', true) | ||
436 | 444 | ||
437 | @horizontalLines = [] | 445 | @horizontalLines = [] |
438 | if @options['horizontalLines'] | 446 | if @options['horizontalLines'] |
@@ -513,6 +521,7 @@ export class TimeSeries | @@ -513,6 +521,7 @@ export class TimeSeries | ||
513 | .attr("height", height) | 521 | .attr("height", height) |
514 | 522 | ||
515 | @path.attr('d', @line) | 523 | @path.attr('d', @line) |
524 | + @predictiveDataPath.attr('d', @line) | ||
516 | 525 | ||
517 | for line in @horizontalLines | 526 | for line in @horizontalLines |
518 | lineValue = @yScale(line['config']['value']) + @margin.top | 527 | lineValue = @yScale(line['config']['value']) + @margin.top |
@@ -621,11 +630,13 @@ export class TimeSeries | @@ -621,11 +630,13 @@ export class TimeSeries | ||
621 | @svg.select('.x.axis').transition(t).call(@xAxis); | 630 | @svg.select('.x.axis').transition(t).call(@xAxis); |
622 | @svg.select('.y.axis').transition(t).call(@yAxis); | 631 | @svg.select('.y.axis').transition(t).call(@yAxis); |
623 | @path.transition(t).attr('d', @line) | 632 | @path.transition(t).attr('d', @line) |
633 | + @predictiveDataPath.transition(t).attr('d', @line) | ||
624 | else | 634 | else |
625 | console.debug("Applying zoom to hidden #{@}…") | 635 | console.debug("Applying zoom to hidden #{@}…") |
626 | @svg.select('.x.axis').call(@xAxis); | 636 | @svg.select('.x.axis').call(@xAxis); |
627 | @svg.select('.y.axis').call(@yAxis); | 637 | @svg.select('.y.axis').call(@yAxis); |
628 | @path.attr('d', @line) | 638 | @path.attr('d', @line) |
639 | + @predictiveDataPath.attr('d', @line) | ||
629 | 640 | ||
630 | showCursor: -> | 641 | showCursor: -> |
631 | @focus.style("display", null) | 642 | @focus.style("display", null) |
web/view/home.html.jinja2
@@ -98,6 +98,20 @@ | @@ -98,6 +98,20 @@ | ||
98 | <br> | 98 | <br> |
99 | <hr class="clear"> | 99 | <hr class="clear"> |
100 | 100 | ||
101 | +{# <span class="mdl-layout-title">{{ icon('database') }} Layers</span>#} | ||
102 | +{##} | ||
103 | +{# <section class="section-drawer">#} | ||
104 | +{#{% for layer in config.layers %}#} | ||
105 | +{# <label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="option-layer-{{ layer.slug }}" title="{{ layer.desc }}">#} | ||
106 | +{# <input type="radio" id="option-layer-{{ layer.slug }}" class="mdl-radio__button" name="layer_slug" value="{{ layer.slug }}" {{ 'checked' if layer.slug == layer_slug }}>#} | ||
107 | +{# <span class="mdl-radio__label">{{ layer.name }}</span>#} | ||
108 | +{# </label>#} | ||
109 | +{# <br />#} | ||
110 | +{#{% endfor %}#} | ||
111 | +{# </section>#} | ||
112 | +{##} | ||
113 | +{# <hr class="clear">#} | ||
114 | + | ||
101 | {# <span class="mdl-layout-title">{{ icon('database') }} Inputs</span>#} | 115 | {# <span class="mdl-layout-title">{{ icon('database') }} Inputs</span>#} |
102 | {##} | 116 | {##} |
103 | {# <section class="section-drawer">#} | 117 | {# <section class="section-drawer">#} |
@@ -308,6 +322,11 @@ | @@ -308,6 +322,11 @@ | ||
308 | stroke: steelblue; | 322 | stroke: steelblue; |
309 | stroke-width: 1px; | 323 | stroke-width: 1px; |
310 | } | 324 | } |
325 | + path.predictive-line { | ||
326 | + fill: none; | ||
327 | + stroke: #4cf561; | ||
328 | + stroke-width: 2px; | ||
329 | + } | ||
311 | circle.cursor-circle { | 330 | circle.cursor-circle { |
312 | fill: black; | 331 | fill: black; |
313 | stroke: rgba(20, 20, 20, 0.48); | 332 | stroke: rgba(20, 20, 20, 0.48); |