Commit 326b749d91ee1280c4fa4b2c324526ac75d95e2f
1 parent
c9712107
Exists in
master
and in
2 other branches
Finally, a decent fix for the time series datetime ticks.
Showing
2 changed files
with
40 additions
and
32 deletions
Show diff stats
web/static/js/main.js
@@ -28,6 +28,7 @@ | @@ -28,6 +28,7 @@ | ||
28 | (function () { | 28 | (function () { |
29 | const global = typeof exports !== 'undefined' && exports || this; | 29 | const global = typeof exports !== 'undefined' && exports || this; |
30 | const GOLDEN_RATIO = 2 / (1 + Math.sqrt(5)); // 0.618… | 30 | const GOLDEN_RATIO = 2 / (1 + Math.sqrt(5)); // 0.618… |
31 | + const RATIO = GOLDEN_RATIO ** 4; // Y/X aspect ratio of the time series | ||
31 | 32 | ||
32 | class Target { | 33 | class Target { |
33 | constructor(slug, name, config) { | 34 | constructor(slug, name, config) { |
@@ -259,13 +260,19 @@ | @@ -259,13 +260,19 @@ | ||
259 | return $('#plots_loader').hide(); | 260 | return $('#plots_loader').hide(); |
260 | } | 261 | } |
261 | 262 | ||
263 | + /** | ||
264 | + * Load the data as CSV for the specified target and interval, | ||
265 | + * and return it in a Promise. | ||
266 | + * | ||
267 | + * @param target_slug | ||
268 | + * @param started_at | ||
269 | + * @param stopped_at | ||
270 | + * @returns {Promise<any>} | ||
271 | + */ | ||
262 | loadData(target_slug, started_at, stopped_at) { | 272 | loadData(target_slug, started_at, stopped_at) { |
263 | - // "Load the data as CSV for the specified target and interval,\nand return it in a Promise."; | ||
264 | - let sw; | ||
265 | - sw = this; | 273 | + let app = this; |
266 | return new Promise((resolve, reject) => { | 274 | return new Promise((resolve, reject) => { |
267 | - let url; | ||
268 | - url = sw.buildDataUrlForTarget(target_slug, started_at, stopped_at); | 275 | + let url = app.buildDataUrlForTarget(target_slug, started_at, stopped_at); |
269 | return d3.csv(url, csv => { | 276 | return d3.csv(url, csv => { |
270 | let timeFormat; | 277 | let timeFormat; |
271 | let data; | 278 | let data; |
@@ -507,16 +514,17 @@ | @@ -507,16 +514,17 @@ | ||
507 | } | 514 | } |
508 | 515 | ||
509 | resizeDomain(started_at, stopped_at, starting_ts) { | 516 | resizeDomain(started_at, stopped_at, starting_ts) { |
510 | - let ref$; | ||
511 | let max_stopped_at; | 517 | let max_stopped_at; |
512 | let formatted_started_at; | 518 | let formatted_started_at; |
513 | let formatted_stopped_at; | 519 | let formatted_stopped_at; |
514 | let zoomedOnVisible; | 520 | let zoomedOnVisible; |
515 | if (stopped_at < started_at) { | 521 | if (stopped_at < started_at) { |
516 | - ref$ = [stopped_at, started_at], started_at = ref$[0], stopped_at = ref$[1]; | 522 | + let tmp_at = started_at; |
523 | + started_at = stopped_at; | ||
524 | + stopped_at = tmp_at; | ||
517 | } | 525 | } |
518 | if (started_at === stopped_at) { | 526 | if (started_at === stopped_at) { |
519 | - console.warn("Please provide distinct start and stop dates."); | 527 | + alert("Please provide distinct start and stop dates."); |
520 | return; | 528 | return; |
521 | } | 529 | } |
522 | max_stopped_at = started_at.clone().add(2, 'years'); | 530 | max_stopped_at = started_at.clone().add(2, 'years'); |
@@ -538,11 +546,11 @@ | @@ -538,11 +546,11 @@ | ||
538 | console.log("Zoom on invisible time series…"); | 546 | console.log("Zoom on invisible time series…"); |
539 | let tsv_zoom_on_next; | 547 | let tsv_zoom_on_next; |
540 | tsv_zoom_on_next = i => { | 548 | tsv_zoom_on_next = i => { |
541 | - let ts; | ||
542 | if (i >= tsv_length) { | 549 | if (i >= tsv_length) { |
543 | resolve(); | 550 | resolve(); |
544 | return; | 551 | return; |
545 | } | 552 | } |
553 | + let ts; | ||
546 | ts = tsv[(i+starting_ts_key)%tsv_length]; | 554 | ts = tsv[(i+starting_ts_key)%tsv_length]; |
547 | ts.zoomIn(started_at, stopped_at) | 555 | ts.zoomIn(started_at, stopped_at) |
548 | .then(() => tsv_zoom_on_next(i + 1)); | 556 | .then(() => tsv_zoom_on_next(i + 1)); |
@@ -583,15 +591,10 @@ | @@ -583,15 +591,10 @@ | ||
583 | } | 591 | } |
584 | } | 592 | } |
585 | 593 | ||
586 | - // return SpaceWeather; | ||
587 | - // })()); | ||
588 | 594 | ||
589 | ///////////////////////////////////////////////////////////////////////////// | 595 | ///////////////////////////////////////////////////////////////////////////// |
590 | //// TIME SERIES //////////////////////////////////////////////////////////// | 596 | //// TIME SERIES //////////////////////////////////////////////////////////// |
591 | 597 | ||
592 | - // global.TimeSeries = TimeSeries = ((() => { | ||
593 | - const RATIO = GOLDEN_RATIO ** 4; | ||
594 | - | ||
595 | class TimeSeries { | 598 | class TimeSeries { |
596 | constructor(parameter, title, target, data, visible, container, options) { | 599 | constructor(parameter, title, target, data, visible, container, options) { |
597 | this.onBrushEnd = this.onBrushEnd.bind(this); | 600 | this.onBrushEnd = this.onBrushEnd.bind(this); |
@@ -650,8 +653,10 @@ | @@ -650,8 +653,10 @@ | ||
650 | if (this.options['stopped_at']) { | 653 | if (this.options['stopped_at']) { |
651 | this.xDataExtent[1] = this.options['stopped_at']; | 654 | this.xDataExtent[1] = this.options['stopped_at']; |
652 | } | 655 | } |
653 | - this.xScale = d3.scaleTime().domain(this.xDataExtent); | 656 | + this.xScale = d3.scaleUtc().domain(this.xDataExtent); |
654 | this.yScale = d3.scaleLinear().domain(this.yDataExtent); | 657 | this.yScale = d3.scaleLinear().domain(this.yDataExtent); |
658 | + | ||
659 | + // http://pubs.opengroup.org/onlinepubs/007908799/xsh/strftime.html | ||
655 | const formatMillisecond = d3.utcFormat(".%L"); | 660 | const formatMillisecond = d3.utcFormat(".%L"); |
656 | const formatSecond = d3.utcFormat(":%S"); | 661 | const formatSecond = d3.utcFormat(":%S"); |
657 | const formatMinute = d3.utcFormat("%H:%M"); | 662 | const formatMinute = d3.utcFormat("%H:%M"); |
@@ -660,33 +665,36 @@ | @@ -660,33 +665,36 @@ | ||
660 | const formatWeek = d3.utcFormat("%b %d"); | 665 | const formatWeek = d3.utcFormat("%b %d"); |
661 | const formatMonth = d3.utcFormat("%B"); | 666 | const formatMonth = d3.utcFormat("%B"); |
662 | const formatYear = d3.utcFormat("%Y"); | 667 | const formatYear = d3.utcFormat("%Y"); |
668 | + const formatDoy = d3.utcFormat("%Y-%j"); | ||
663 | const multiFormat = date => { | 669 | const multiFormat = date => { |
664 | - if (date > d3.timeSecond(date)) { | 670 | + if (date > d3.utcSecond(date)) { |
665 | return formatMillisecond(date); | 671 | return formatMillisecond(date); |
666 | } | 672 | } |
667 | - if (date > d3.timeMinute(date)) { | 673 | + if (date > d3.utcMinute(date)) { |
668 | return formatSecond(date); | 674 | return formatSecond(date); |
669 | } | 675 | } |
670 | - if (date > d3.timeHour(date)) { | 676 | + if (date > d3.utcHour(date)) { |
671 | return formatMinute(date); | 677 | return formatMinute(date); |
672 | } | 678 | } |
673 | - if (date > d3.timeDay(date)) { | 679 | + if (date > d3.utcDay(date)) { |
674 | return formatHour(date); | 680 | return formatHour(date); |
675 | } | 681 | } |
676 | - if (date > d3.timeMonth(date)) { | ||
677 | - if (date > d3.timeWeek(date)) { | ||
678 | - return formatDay(date); | ||
679 | - } else { | ||
680 | - return formatWeek(date); | ||
681 | - } | ||
682 | - } | ||
683 | - if (date > d3.timeYear(date)) { | ||
684 | - return formatMonth(date); | ||
685 | - } | ||
686 | 682 | ||
687 | - return formatYear(date); | 683 | + return formatDoy(date); |
684 | + // if (date > d3.utcMonth(date)) { | ||
685 | + // if (date > d3.utcWeek(date)) { | ||
686 | + // return utcDay(date); | ||
687 | + // } else { | ||
688 | + // return utcWeek(date); | ||
689 | + // } | ||
690 | + // } | ||
691 | + // if (date > d3.utcYear(date)) { | ||
692 | + // return formatMonth(date); | ||
693 | + // } | ||
694 | + // | ||
695 | + // return formatYear(date); | ||
688 | }; | 696 | }; |
689 | - // let formatScience = d3.utcFormat("%Y"); | 697 | + |
690 | this.xAxis = d3.axisBottom().tickFormat(multiFormat).ticks(7); | 698 | this.xAxis = d3.axisBottom().tickFormat(multiFormat).ticks(7); |
691 | this.yAxis = d3.axisLeft().ticks(10); | 699 | this.yAxis = d3.axisLeft().ticks(10); |
692 | this.svg = d3.select(this.container).append('svg'); | 700 | this.svg = d3.select(this.container).append('svg'); |
web/view/layout.html.jinja2
@@ -85,7 +85,7 @@ | @@ -85,7 +85,7 @@ | ||
85 | {# Please use enderjs instead of jquery #} | 85 | {# Please use enderjs instead of jquery #} |
86 | <script type="application/javascript" src="{{ static('js/vendor/jquery-3.2.1.min.js') }}"></script> | 86 | <script type="application/javascript" src="{{ static('js/vendor/jquery-3.2.1.min.js') }}"></script> |
87 | {# Material's js behaves very poorly, performance-wise. #} | 87 | {# Material's js behaves very poorly, performance-wise. #} |
88 | -{# <script type="application/javascript" src="{{ static('js/vendor/material-custom.js') }}"></script>#} | 88 | + <script type="application/javascript" src="{{ static('js/vendor/material-custom.js') }}"></script> |
89 | <script type="application/javascript"> | 89 | <script type="application/javascript"> |
90 | jQuery().ready(function($){ $(".nojs").hide(); }); | 90 | jQuery().ready(function($){ $(".nojs").hide(); }); |
91 | </script> | 91 | </script> |