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 | 32 | |
33 | 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 | 38 | - [x] Change the default interval (from 2 months in the past to one in the future) |
37 | 39 | - [x] Prepare horizontal lines in the time series |
38 | 40 | - [x] Add buttons to the orbits plot zoom to inner or outer heliosphere | ... | ... |
web/static/js/swapp.js
... | ... | @@ -14,7 +14,7 @@ |
14 | 14 | return Target; |
15 | 15 | }()); |
16 | 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 | 18 | SpaceWeather.displayName = 'SpaceWeather'; |
19 | 19 | var API_TIME_FORMAT, INPUT_TIME_FORMAT, prototype = SpaceWeather.prototype, constructor = SpaceWeather; |
20 | 20 | API_TIME_FORMAT = "YYYY-MM-DDTHH:mm:ss"; |
... | ... | @@ -452,6 +452,7 @@ |
452 | 452 | TimeSeries.displayName = 'TimeSeries'; |
453 | 453 | var RATIO, prototype = TimeSeries.prototype, constructor = TimeSeries; |
454 | 454 | function TimeSeries(parameter, title, target, data, visible, container, options){ |
455 | + var now, res$, i$, ref$, len$, d; | |
455 | 456 | this.parameter = parameter; |
456 | 457 | this.title = title; |
457 | 458 | this.target = target; |
... | ... | @@ -466,6 +467,15 @@ |
466 | 467 | this.onMouseOut = bind$(this, 'onMouseOut', prototype); |
467 | 468 | this.onMouseOver = bind$(this, 'onMouseOver', prototype); |
468 | 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 | 479 | this.init(); |
470 | 480 | } |
471 | 481 | TimeSeries.prototype.toString = function(){ |
... | ... | @@ -543,6 +553,7 @@ |
543 | 553 | this.pathWrapper = this.plotWrapper.append('g'); |
544 | 554 | this.pathWrapper.attr("clip-path", "url(#" + clipId + ")"); |
545 | 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 | 557 | this.horizontalLines = []; |
547 | 558 | if (this.options['horizontalLines']) { |
548 | 559 | for (i$ = 0, len$ = (ref$ = this.options['horizontalLines']).length; i$ < len$; ++i$) { |
... | ... | @@ -582,6 +593,7 @@ |
582 | 593 | this.svg.attr('width', width + this.margin.right + this.margin.left).attr('height', height + this.margin.top + this.margin.bottom); |
583 | 594 | this.clip.attr("width", width).attr("height", height); |
584 | 595 | this.path.attr('d', this.line); |
596 | + this.predictiveDataPath.attr('d', this.line); | |
585 | 597 | for (i$ = 0, len$ = (ref$ = this.horizontalLines).length; i$ < len$; ++i$) { |
586 | 598 | line = ref$[i$]; |
587 | 599 | lineValue = this.yScale(line['config']['value']) + this.margin.top; |
... | ... | @@ -695,12 +707,14 @@ |
695 | 707 | t = this.svg.transition().duration(750); |
696 | 708 | this.svg.select('.x.axis').transition(t).call(this.xAxis); |
697 | 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 | 712 | } else { |
700 | 713 | console.debug("Applying zoom to hidden " + this + "…"); |
701 | 714 | this.svg.select('.x.axis').call(this.xAxis); |
702 | 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 | 720 | TimeSeries.prototype.showCursor = function(){ | ... | ... |
web/static/js/swapp.ls
... | ... | @@ -358,6 +358,11 @@ export class TimeSeries |
358 | 358 | # title : string, more descriptive, shown on the left of the Y axis |
359 | 359 | # target : target object, like described in configuration |
360 | 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 | 366 | @init() |
362 | 367 | |
363 | 368 | toString: -> "#{@title} of #{@target.name}" |
... | ... | @@ -433,6 +438,9 @@ export class TimeSeries |
433 | 438 | @path = @pathWrapper.append('path') |
434 | 439 | .datum(@data) |
435 | 440 | .classed('line', true) |
441 | + @predictiveDataPath = @pathWrapper.append('path') | |
442 | + .datum(@predictiveData) | |
443 | + .classed('predictive-line', true) | |
436 | 444 | |
437 | 445 | @horizontalLines = [] |
438 | 446 | if @options['horizontalLines'] |
... | ... | @@ -513,6 +521,7 @@ export class TimeSeries |
513 | 521 | .attr("height", height) |
514 | 522 | |
515 | 523 | @path.attr('d', @line) |
524 | + @predictiveDataPath.attr('d', @line) | |
516 | 525 | |
517 | 526 | for line in @horizontalLines |
518 | 527 | lineValue = @yScale(line['config']['value']) + @margin.top |
... | ... | @@ -621,11 +630,13 @@ export class TimeSeries |
621 | 630 | @svg.select('.x.axis').transition(t).call(@xAxis); |
622 | 631 | @svg.select('.y.axis').transition(t).call(@yAxis); |
623 | 632 | @path.transition(t).attr('d', @line) |
633 | + @predictiveDataPath.transition(t).attr('d', @line) | |
624 | 634 | else |
625 | 635 | console.debug("Applying zoom to hidden #{@}…") |
626 | 636 | @svg.select('.x.axis').call(@xAxis); |
627 | 637 | @svg.select('.y.axis').call(@yAxis); |
628 | 638 | @path.attr('d', @line) |
639 | + @predictiveDataPath.attr('d', @line) | |
629 | 640 | |
630 | 641 | showCursor: -> |
631 | 642 | @focus.style("display", null) | ... | ... |
web/view/home.html.jinja2
... | ... | @@ -98,6 +98,20 @@ |
98 | 98 | <br> |
99 | 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 | 115 | {# <span class="mdl-layout-title">{{ icon('database') }} Inputs</span>#} |
102 | 116 | {##} |
103 | 117 | {# <section class="section-drawer">#} |
... | ... | @@ -308,6 +322,11 @@ |
308 | 322 | stroke: steelblue; |
309 | 323 | stroke-width: 1px; |
310 | 324 | } |
325 | + path.predictive-line { | |
326 | + fill: none; | |
327 | + stroke: #4cf561; | |
328 | + stroke-width: 2px; | |
329 | + } | |
311 | 330 | circle.cursor-circle { |
312 | 331 | fill: black; |
313 | 332 | stroke: rgba(20, 20, 20, 0.48); | ... | ... |