home.html.jinja2 8.67 KB
{% extends 'layout.html.jinja2' %}
{% set menu_section = 'home' %}
{% block title %}Home{% endblock %}

{% block content %}

<div class="row expanded">
  <div class="column large-4">
    <section id="orbits"></section>
    <section id="orbiters_filters">
      <img src="{{ static('img/planet/jupiter_128.png') }}" width="64px" height="64px" alt="Jupiter">
      <img src="{{ static('img/planet/earth_128.png') }}" width="64px" height="64px" alt="Earth (locked)" class="locked">
      <img src="{{ static('img/planet/mars_128.png') }}" width="64px" height="64px" alt="Mars (locked)" class="locked">
    </section>
    <hr class="clear">
    <p>Measures</p>
    <p>Options</p>
  </div>
  <div class="column large-8">
    <section id="time_series"></section>
  </div>
</div>

{% endblock %}


{% block styles %}
  <style>
    html, body {
      background-color: #322e3f;
      color: #e3e3e3;
    }
    .axis path, .axis line {
      fill: none;
      stroke: #f4f4f4;
      shape-rendering: crispEdges;
      stroke-width: 1px;
    }
    svg text {
      fill: #f4f4f4;
    }
    path.line {
      fill: none;
      stroke: steelblue;
      stroke-width: 1px;
    }
    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;
    }
    #orbiters_filters img {
      float: left;
    }
    #orbiters_filters img.locked {
      -webkit-filter: grayscale(100%);
         -moz-filter: grayscale(100%);
           -o-filter: grayscale(100%);
          -ms-filter: grayscale(100%);
              filter: grayscale(100%);
    }

    #orbits {
      background-image: url('{{ static('img/orbitals_background.png') }}');
      background-repeat: repeat;
      background-size: 42%;
    }
  </style>
{% endblock %}


{% block scripts_footer %}
<script type="application/javascript" src="{{ static('js/d3.min.js') }}"></script>
<script type="application/javascript">

// Sorry, no ES6. Feel free to refactor.

var swApp = (function (window, d3, $) {

  var $time_series = $("#time_series");
  var $orbits = $("#orbits");

  var orbiters = {
    jupiter: {
      name: "Jupiter",
      orbit: { a: 5.45516759, b: 4.95155843 },
      img: "{{ static('img/planet/jupiter_128.png') }}"
    }
  };

  var plotTimeSeries = function(data, options) {
    console.log("Init time series with data", data, options);

    var xScale, yScale, xAxis, yAxis, yAxisText;
    var line;
    var svg, plotWrapper, path;
    var width, height;
    var margin = {
      top: 30,
      right: 20,
      bottom: 30,
      left: 60
    };

    // INIT SCALES
    xScale = d3.scaleTime().domain(d3.extent(data, function (d) {
      return d.x;
    }));
    yScale = d3.scaleLinear().domain(d3.extent(data, function (d) {
      return d.y;
    }));

    // INIT AXISES
    xAxis = d3.axisBottom()
        .ticks(7, ",f")
        .tickFormat(d3.timeFormat("%Y-%m-%d"));
    yAxis = d3.axisLeft()
        .ticks(10);


    // INIT LINE
    line = d3.line()
        .x(function (d) { return xScale(d.x) })
        .y(function (d) { return yScale(d.y) });

    // INIT SVG
    svg = d3.select('#time_series').append('svg');

    plotWrapper = svg.append('g');

    path = plotWrapper.append('path')
        .datum(data)
        .classed('line', true);

    plotWrapper.append('g')
        .classed('x axis', true);
    plotWrapper.append('g')
        .classed('y axis', true);
    yAxisText = plotWrapper.append("text")
        .attr("transform", "rotate(-90)")
        .attr("dy", "1em")
        .style("text-anchor", "middle")
        .text(options['title']);

    // -- wip refactor resize

    width = $time_series.width() - margin.left - margin.right;
    height = .618 * .618 * width;

    xScale.range([0, width]);
    yScale.range([height, 0]);

    svg.attr('width', width + margin.right + margin.left)
        .attr('height', height + margin.top + margin.bottom);

    plotWrapper.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

    path.attr('d', line);

    xAxis.scale(xScale);
    yAxis.scale(yScale);

    if (width < 600) { xAxis.ticks(3); }

    svg.select('.x.axis')
        .attr('transform', 'translate(0,' + height + ')')
        .call(xAxis);

    svg.select('.y.axis')
        .call(yAxis);

    yAxisText.attr("y", 0 - margin.left).attr("x", 0 - (height / 2));
  };

  var plotOrbits = function(data, options) {
    console.log("Init orbits with data", data, options);


    var xScale, yScale, xAxis, yAxis, xAxisText, yAxisText;
    var line;
    var svg, plotWrapper, orbital_orbit_section, orbital_orbit_ellipse, sun;
    var width, height;
    var margin = {
      top: 30,
      right: 20,
      bottom: 30,
      left: 60
    };

    // INIT SCALES
    var extremum = 1.11 * d3.max(data, function (d) {
      return Math.max(Math.abs(d.x), Math.abs(d.y));
    });

    console.info("Extremum", extremum);

    xScale = d3.scaleLinear().domain([-1 * extremum, extremum]);
    yScale = d3.scaleLinear().domain([-1 * extremum, extremum]);

    xAxis = d3.axisBottom().ticks(10);
    yAxis = d3.axisLeft().ticks(10);

    // INIT LINE
    line = d3.line()
        .x(function (d) { return xScale(d.x) })
        .y(function (d) { return yScale(d.y) });

    // INIT SVG
    svg = d3.select('#orbits').append('svg');

    plotWrapper = svg.append('g');

    // Sun
    sun = plotWrapper.append("svg:circle");
    sun.append('svg:title').text("Sol");

    // haxx wip
    var orbital_config = orbiters['jupiter'];

    orbital_orbit_ellipse = plotWrapper.append("svg:ellipse")
        .classed('orbit orbit_ellipse', true);

{#    var test_square = plotWrapper.append("svg:rect");#}

    var orbital_element = plotWrapper.append("svg:image");
    orbital_element.attr('xlink:href', orbital_config['img']);
    orbital_element.attr('width', '32px').attr('height', '32px');

    orbital_orbit_section = plotWrapper.append('path')
        .datum(data)
        .classed('orbit orbit_section', true);

    plotWrapper.append('g').classed('x axis', true);
    plotWrapper.append('g').classed('y axis', true);

    // ---- wip: refactor resizing from here

    width = $orbits.width() - margin.left - margin.right;
    height = width * 1.0;

    xScale.range([0, width]);
    yScale.range([height, 0]);
{#    yScale.range([0, height]);#}

    svg.attr('width', width + margin.right + margin.left)
        .attr('height', height + margin.top + margin.bottom);

    plotWrapper.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

    sun.attr("cx", width / 2).attr("cy", height / 2).attr("r", 17).style("fill", "yellow");

    orbital_orbit_section.attr('d', line);

    var a = orbital_config['orbit']['a'];
    var b = orbital_config['orbit']['b'];
    var c = Math.sqrt(a*a-b*b);
    var cx = (width / 2) - c;
    var cy = (height / 2);
    yScale.range([0, height]);
    orbital_orbit_ellipse.attr('cx', cx).attr('cy', cy)
        .attr('rx', xScale(a) - xScale(0))
        .attr('ry', yScale(b) - yScale(0))
        .attr('transform', 'rotate(66,'+(cx+c)+', '+cy+')');
    yScale.range([height, 0]);

{#    test_square.attr('x', cx).attr('y', cy);#}
{#    test_square.attr('width', 20).attr('height', 20);#}
{#    test_square.attr('style', 'fill:red;');#}
{#    test_square.attr('transform', 'rotate(45,'+0+', '+0+')');#}

    orbital_element.attr('x', xScale(data[data.length - 1].x) - 16);
    orbital_element.attr('y', yScale(data[data.length - 1].y) - 16);

    xAxis.scale(xScale);
    yAxis.scale(yScale);

    //if (width < 600) { xAxis.ticks(3); }

    svg.select('.x.axis')
        .attr('transform', 'translate(0,' + height + ')')
        .call(xAxis);

    svg.select('.y.axis')
        .call(yAxis);

  };

  return {
    plotTimeSeries: plotTimeSeries,
    plotOrbits: plotOrbits
  };
})(window, d3, jQuery);


jQuery().ready(function($){
  d3.csv("{{ url_for('get_csv') }}", function(csv){
    var timeFormat = d3.timeParse('%Y-%m-%dT%H:%M:%S%Z');
    var data = {'pdyn': [], 'magn': [], 'vlen': []};
    csv.forEach(function (d) {
      data['pdyn'].push({x: timeFormat(d['time']), y: parseFloat(d['pdyn'])});
      data['magn'].push({x: timeFormat(d['time']), y: parseFloat(d['magn'])});
      data['vlen'].push({x: timeFormat(d['time']), y: parseFloat(d['vlen'])});
    });
    swApp.plotTimeSeries(data['pdyn'], {title: 'Dynamic Pressure (nPa)'});
    swApp.plotTimeSeries(data['magn'], {title: 'Magnetism (nT)'});
    swApp.plotTimeSeries(data['vlen'], {title: 'Velocity (km/s)'});
  });
  d3.csv("{{ url_for('get_astral_coordinates_csv') }}", function(csv){
    var data = [];
    csv.forEach(function (d) {
      data.push({x: parseFloat(d['x_hci']), y: parseFloat(d['y_hci'])});
    });
    swApp.plotOrbits(data, {});
  });

});
</script>

{% endblock %}