{% extends 'layout.html.jinja2' %} {% set menu_section = 'home' %} {% block title %}Home{% endblock %} {# This is the main template file, along with the layout. #} {# The engine is Jinja2, close to Twig (yet not as good) #} {% block content %} {% macro target_button(target) -%} <img width="64px" height="64px" src="{{ static('img/target/'~target.slug~'_128.png') }}" title="{{ target.title }}" alt="{{ target.name }}" class="target {{ target.slug }} {{ 'locked' if target.locked else 'active' }}" data-target-slug="{{ target.slug }}" > {%- endmacro %} <div id="plots_loader"> <p class="loader-text">Loading Heliopropa…<br>This might take a while.</p> <div id="plots_loader_img1" class="img"></div> <div id="plots_loader_img2" class="img"></div> <div id="plots_loader_img3" class="img"></div> <div id="plots_loader_img4" class="img"></div> <div id="plots_loader_img5" class="img"></div> </div> <div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer"> <div class="mdl-layout__drawer"> <span class="mdl-layout-title">Time Interval</span> <form id="form_time_interval" action="#"> <div class="mdl-textfield mdl-js-textfield"> <input type="date" id="started_at" name="started_at" title="The date of the beginning of the interval to observe." class="mdl-textfield__input"> <input type="date" id="stopped_at" name="stopped_at" title="The date of the end of the interval to observe. (exclusive)" class="mdl-textfield__input"> </div> <input type="submit" id="apply_new_interval" value="Load new interval" title="This may take a while if you request a bigger interval." class="mdl-button mdl-js-button mdl-js-ripple-effect"> </form> <br> <hr class="clear"> <span class="mdl-layout-title">Planets</span> <section class="targets-filters"> {% for target in planets %} {{ target_button(target) }} {% endfor %} </section> <br> <hr class="clear"> <span class="mdl-layout-title">Probes & Comets</span> <section class="targets-filters"> {% for target in probes %} {{ target_button(target) }} {% endfor %} {% for target in comets %} {{ target_button(target) }} {% endfor %} </section> <br> <hr class="clear"> <span class="mdl-layout-title">Parameters</span> <nav id="parameters" class="mdl-navigation"> {# todo: generate this from config #} <a class="mdl-navigation__link parameter active" data-ts-slug="pdyn" href="#">Dynamic Pressure</a> <a class="mdl-navigation__link parameter" data-ts-slug="magn" href="#">B Tangential</a> <a class="mdl-navigation__link parameter" data-ts-slug="vlen" href="#">Velocity</a> <a class="mdl-navigation__link parameter" data-ts-slug="temp" href="#">Temperature</a> <a class="mdl-navigation__link parameter" data-ts-slug="dens" href="#">Density</a> <a class="mdl-navigation__link parameter" data-ts-slug="angl" href="#">Angle Target-Sun-Earth</a> </nav> <div class="mdl-layout-spacer"></div> <main class="mdl-layout__content"> <div class="page-content" style="text-align:center;font-style:italic;"> <p> {{ visits }} visits since 2017 </p> </div> </main> </div> <main id="plots_wrapper" class="mdl-layout__content"> <div class="mdl-grid"> <div class="mdl-cell mdl-cell--4-col"> <section id="orbits"></section> </div> <div class="mdl-cell mdl-cell--8-col"> <section id="time_series"> <p id="zoom_controls_help" class="help mdl-cell--8-col">Drag to zoom in, double click to zoom out.</p> </section> </div> </div> {# <div class="loader"><div class="hole"></div></div>#} </main> </div> {% endblock %} {% block styles %} <style> html, body { {# background-color: #322e3f;#} {# color: #e3e3e3;#} } #plots_wrapper { {# position: relative;#} } #plots_loader { position: absolute; top: 0; left: 0; bottom: 0; right: 0; height: 100%; width: 100%; background-color: #fff; z-index: 1000; } #plots_loader .loader-text { width: 200px; height: 30px; position: absolute; top: -240px; left: -32px; bottom: 0; right: 0; margin: auto; text-align: center; font-size: 1.0em; font-style: italic; color: darkgrey; } #plots_loader .img { width: 100px; height: 100px; border-radius: 100%; position: absolute; border: 1px solid #6978ff; animation: up 1s; animation-iteration-count: infinite; transition: 2s; border-bottom: none; border-right: none; animation-timing-function: linear; margin-left: -70px; margin-top: -70px; left: 50%; top: 50%; } @keyframes up { from { transform: rotate(0deg); } 50% { transform: rotate(180deg); } 100% { transform: rotate(360deg); } } #plots_loader #plots_loader_img2 { width: 90px; height: 90px; left: 50.35%; top: 50.7%; animation-delay: .2s; } #plots_loader #plots_loader_img3 { width: 80px; height: 80px; left: 50.70%; top: 51.4%; animation-delay: .4s; } #plots_loader #plots_loader_img4 { width: 70px; height: 70px; left: 51.05%; top: 52.1%; animation-delay: .6s; } #plots_loader #plots_loader_img5 { width: 60px; height: 60px; left: 51.40%; top: 52.8%; animation-delay: .8s; } #time_series .help { position: absolute; text-align: center; font-size: 0.9em; font-style: italic; color: darkgrey; display: none; } #time_series:hover .help { display: block; } .axis path, .axis line { fill: none; {# stroke: #f4f4f4;#} shape-rendering: crispEdges; stroke-width: 1px; } svg text { {# fill: #f4f4f4;#} } #time_series svg .brush .selection { fill: #efa02c; fill-opacity: 0.382; } path.line { fill: none; stroke: steelblue; stroke-width: 1px; } circle.cursor-circle { fill: black; stroke: rgba(20, 20, 20, 0.48); } text.cursor-text { {# font-family: 'Ubuntu', 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', 'Verdana', sans-serif;#} {# font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;#} font-family: "Ubuntu Mono", 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace; text-align: right; } text.cursor-text-shadow { stroke: white; stroke-width: 5px; opacity: 0.777 } path.orbit.orbit_section { fill: none; stroke: steelblue; stroke-width: 3px; } ellipse.orbit.orbit_ellipse { fill: none; stroke: #a3a3a3; stroke-width: 1px; stroke-dasharray: 5px; } #form_time_interval { padding-left: 30px; } #form_time_interval .mdl-textfield { padding-top: 0; } #started_at, #stopped_at { width: 85%; } .targets-filters { padding-left: 17px; } .targets-filters .target { float: left; cursor: pointer; } .targets-filters .target:not(.active) { -webkit-filter: grayscale(100%); -moz-filter: grayscale(100%); -o-filter: grayscale(100%); -ms-filter: grayscale(100%); filter: grayscale(100%); } .targets-filters .target.locked { cursor: not-allowed; } .targets-filters .target.loading { {# margin: 20px;#} {# width: 100px;#} {# height: 100px;#} {# background: #f00;#} -webkit-animation-name: spin; -webkit-animation-duration: 4000ms; -webkit-animation-iteration-count: infinite; -webkit-animation-timing-function: linear; -moz-animation-name: spin; -moz-animation-duration: 4000ms; -moz-animation-iteration-count: infinite; -moz-animation-timing-function: linear; -ms-animation-name: spin; -ms-animation-duration: 4000ms; -ms-animation-iteration-count: infinite; -ms-animation-timing-function: linear; animation-name: spin; animation-duration: 4000ms; animation-iteration-count: infinite; animation-timing-function: linear; } #orbits { {# background-image: url('{{ static('img/orbitals_background.png') }}');#} {# background-repeat: repeat;#} {# background-size: 42%;#} } #parameters .parameter { outline: 0; } #parameters .parameter.active { background-color: #c8d3e1; } #time_series svg { cursor: crosshair; } </style> {% endblock %} {% block scripts_footer %} <script type="application/javascript" src="{{ static('js/vendor/d3-custom.js') }}"></script> <script type="application/javascript" src="{{ static('js/vendor/moment.min.js') }}"></script> <script type="application/javascript" src="{{ static('js/swapp.js') }}"></script> <script type="application/javascript"> var configuration = { time_series_container: '#time_series', orbits_container: '#orbits', api : { 'data_for_interval': "{{ request.url_root }}<target>_<started_at>_<stopped_at>.csv" }, sun: { img: '{{ static('img/sun_128.png') }}' }, targets : { {% for target in targets if not target.locked %} {% if not loop.first %},{% endif %} '{{ target.slug }}': { slug: '{{ target.slug }}', name: '{{ target.name }}', active: true, orbit: { a: {{ target.orbit.semimajor }}, b: {{ target.orbit.semiminor }} }, img: '{{ static('img/target/'~target.slug~'_128.png') }}' } {% endfor %} }, {# todo @Nicolas Define -somehow- error margins of each parameter ? #} {# todo: generate this from config #} parameters : [ { id: 'pdyn', title: "Dyn. Pressure (nPa)", active: true, unit: "nPa" }, { id: 'magn', title: "Magnetism (nT)", active: false, unit: "nT" }, { id: 'vlen', title: "Velocity (km/s)", active: false, unit: "km/s" }, { id: 'temp', title: "Temperature (K)", active: false, unit: "K" }, { id: 'dens', title: "Density N (cm⁻³)", active: false, unit: "cm⁻³" }, { id: 'angl', title: "Angle T-S-E (deg)", active: false, unit: "deg" } ] }; var sw; jQuery().ready(function($){ // Space Weather app itself, handling data downloads and plot draws. sw = new SpaceWeather(configuration); sw.init(); // User Interface (except plots' interactivity, such as mouse hovers) var parameters = $('#parameters'); var isLastParameterEnabled = function(parameter_id) { var s = 0; parameters.find('.parameter[data-ts-slug]').each(function(i,p) { if ($(p).hasClass('active')) s++; }); return s < 2; }; var isLastTargetEnabled = function(target_slug) { var s = 0; $(".targets-filters .target:not(.locked)").each(function(i,p) { if ($(p).hasClass('active') && ! $(p).hasClass('loading')) s++; }); return s < 2; }; parameters.find(".parameter").click(function(e){ var switch_on = ! $(this).hasClass('active'); var parameter_slug = $(this).attr('data-ts-slug'); if (switch_on) { sw.enableParameter(parameter_slug); $(this).addClass('active'); } else if ( ! isLastParameterEnabled(parameter_slug)) { sw.disableParameter(parameter_slug); $(this).removeClass('active'); } return false; }); $(".targets-filters .target:not(.locked)").on("click", function(e){ if ($(this).hasClass('loading')) return false; var switch_on = ! $(this).hasClass('active'); var target_slug = $(this).attr('data-target-slug'); if (switch_on) { sw.enableTarget(target_slug); $(this).addClass('active'); } else if ( ! isLastTargetEnabled(target_slug)) { sw.disableTarget(target_slug); $(this).removeClass('active'); } return false; }); $('#apply_new_interval').on("click", function(e){ var started_at = moment($("#started_at").val()); var stopped_at = moment($("#stopped_at").val()); sw.resizeDomain(started_at, stopped_at); return false; }) }); </script> {% endblock %}