commit
06076dea29
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true,
|
||||
"jquery": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"rules": {
|
||||
"indent": [
|
||||
"error",
|
||||
4
|
||||
],
|
||||
"linebreak-style": [
|
||||
"error",
|
||||
"unix"
|
||||
],
|
||||
"quotes": [
|
||||
"error",
|
||||
"single"
|
||||
],
|
||||
"semi": [
|
||||
"error",
|
||||
"always"
|
||||
],
|
||||
"curly": [
|
||||
"error",
|
||||
"all"
|
||||
],
|
||||
"one-var-declaration-per-line": [
|
||||
"error",
|
||||
"always"
|
||||
],
|
||||
"new-cap": "error"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
{
|
||||
"rules": {
|
||||
"color-hex-case": "lower",
|
||||
"color-no-invalid-hex": true,
|
||||
|
||||
"font-family-no-duplicate-names": true,
|
||||
"font-family-name-quotes": "always-where-recommended",
|
||||
|
||||
"function-calc-no-unspaced-operator": true,
|
||||
"function-comma-space-after": "always",
|
||||
"function-comma-space-before": "never",
|
||||
"function-name-case": "lower",
|
||||
"function-parentheses-space-inside": "never",
|
||||
"function-whitespace-after": "always",
|
||||
"function-url-no-scheme-relative": true,
|
||||
"function-url-quotes": "always",
|
||||
|
||||
"number-no-trailing-zeros": true,
|
||||
|
||||
"string-no-newline": true,
|
||||
"string-quotes": "single",
|
||||
|
||||
"length-zero-no-unit": true,
|
||||
|
||||
"unit-case": "lower",
|
||||
"unit-no-unknown": true,
|
||||
|
||||
"value-keyword-case": lower,
|
||||
|
||||
"value-list-comma-space-after": "always-single-line",
|
||||
"value-list-comma-space-before": "never",
|
||||
|
||||
"property-case": "lower",
|
||||
"property-no-unknown": true,
|
||||
|
||||
"keyframe-declaration-no-important": true,
|
||||
|
||||
"declaration-colon-space-after": "always",
|
||||
"declaration-colon-space-before": "never",
|
||||
"declaration-no-important": true,
|
||||
|
||||
"declaration-block-trailing-semicolon": "always",
|
||||
"declaration-block-single-line-max-declarations": 1,
|
||||
"declaration-block-semicolon-space-before": "never",
|
||||
"declaration-block-semicolon-newline-after": "always-multi-line",
|
||||
"declaration-block-no-shorthand-property-overrides": true,
|
||||
"declaration-block-no-duplicate-properties": true,
|
||||
|
||||
"block-no-empty": true,
|
||||
"block-closing-brace-empty-line-before": "never",
|
||||
"block-closing-brace-newline-after": "always",
|
||||
"block-closing-brace-newline-before": "always-multi-line",
|
||||
"block-closing-brace-space-before": "always-single-line",
|
||||
"block-opening-brace-newline-after": "always-multi-line",
|
||||
"block-opening-brace-space-after": "always-single-line",
|
||||
"block-opening-brace-space-before": "always",
|
||||
|
||||
"selector-attribute-brackets-space-inside": "never",
|
||||
"selector-attribute-operator-space-after": "never",
|
||||
"selector-attribute-operator-space-before": "never",
|
||||
"selector-combinator-space-after": "always",
|
||||
"selector-combinator-space-before": "always",
|
||||
"selector-pseudo-class-no-unknown": true,
|
||||
"selector-pseudo-element-no-unknown": true,
|
||||
"selector-pseudo-class-case": "lower",
|
||||
"selector-pseudo-element-case": "lower",
|
||||
"selector-type-case": "lower",
|
||||
"selector-type-no-unknown": true,
|
||||
"selector-max-empty-lines": 0,
|
||||
|
||||
"rule-empty-line-before": "always-multi-line",
|
||||
|
||||
"media-feature-name-case": "lower",
|
||||
"media-feature-name-no-unknown": true,
|
||||
"media-feature-colon-space-after": "always",
|
||||
"media-feature-colon-space-before": "never",
|
||||
"media-feature-parentheses-space-inside": "never",
|
||||
|
||||
"comment-no-empty": true,
|
||||
|
||||
"indentation": 4,
|
||||
"max-nesting-depth": 6,
|
||||
"no-duplicate-selectors": true,
|
||||
"no-eol-whitespace": true,
|
||||
"no-extra-semicolons": true,
|
||||
"no-unknown-animations": true,
|
||||
"no-invalid-double-slash-comments": true,
|
||||
"no-missing-end-of-source-newline": true,
|
||||
"max-empty-lines": 1
|
||||
}
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
language: python
|
||||
dist: trusty
|
||||
python:
|
||||
- "2.7"
|
||||
install:
|
||||
- pip install flake8
|
||||
- npm install -g jshint
|
||||
- npm install -g eslint stylelint
|
||||
script:
|
||||
- flake8 .
|
||||
- jshint .
|
||||
- eslint 'db/static/js/*.js'
|
||||
- stylelint 'db/static/css/*.css'
|
||||
|
|
|
@ -4,7 +4,7 @@ SatNOGS DB is a transmitter suggestions and crowd-sourcing app.
|
|||
|
||||
## Install and Contribute
|
||||
|
||||
See the [documentation](http://docs.satnogs.org/db/).
|
||||
See the [documentation](http://docs.satnogs.org/en/stable/db/).
|
||||
|
||||
## Join
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
"d3": "3.5.x",
|
||||
"chart.js": "^2.4.0",
|
||||
"moment": "2.10.6",
|
||||
"bootstrap-daterangepicker": "2.1.x"
|
||||
"bootstrap-daterangepicker": "2.1.x",
|
||||
"mapbox.js": "2.2.x"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
from optparse import make_option
|
||||
from orbit import satellite
|
||||
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
|
@ -7,18 +6,25 @@ from db.base.models import Satellite
|
|||
|
||||
|
||||
class Command(BaseCommand):
|
||||
option_list = BaseCommand.option_list + (
|
||||
make_option('--delete',
|
||||
action='store_true',
|
||||
dest='delete',
|
||||
default=False,
|
||||
help='Delete Satellite'),
|
||||
)
|
||||
args = '<Satellite Identifiers>'
|
||||
help = 'Updates/Inserts Name for certain Satellites'
|
||||
|
||||
def add_arguments(self, parser):
|
||||
# Positional arguments
|
||||
parser.add_argument('satellite_identifiers',
|
||||
nargs='+',
|
||||
metavar='<Satellite Identifier>')
|
||||
|
||||
# Named (optional) arguments
|
||||
parser.add_argument(
|
||||
'--delete',
|
||||
action='store_true',
|
||||
dest='delete',
|
||||
default=False,
|
||||
help='Delete Satellite'
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
for item in args:
|
||||
for item in options['satellite_identifiers']:
|
||||
if options['delete']:
|
||||
try:
|
||||
Satellite.objects.get(norad_cat_id=item).delete()
|
||||
|
|
|
@ -48,6 +48,13 @@ class Satellite(models.Model):
|
|||
pending = Suggestion.objects.filter(satellite=self.id).count()
|
||||
return pending
|
||||
|
||||
@property
|
||||
def has_telemetry_data(self):
|
||||
demoddata = 0
|
||||
for transmitter in self.transmitters.all():
|
||||
demoddata += DemodData.objects.filter(transmitter=transmitter).count()
|
||||
return demoddata
|
||||
|
||||
def __unicode__(self):
|
||||
return '{0} - {1}'.format(self.norad_cat_id, self.name)
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import logging
|
||||
import requests
|
||||
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.contrib.auth.models import User
|
||||
|
@ -52,9 +53,18 @@ def satellite(request, norad):
|
|||
suggestions = Suggestion.objects.filter(satellite=satellite)
|
||||
modes = Mode.objects.all()
|
||||
|
||||
url = '{0}{1}'.format(settings.SATELLITE_POSITION_ENDPOINT, norad)
|
||||
|
||||
try:
|
||||
sat_position = requests.get(url).json()
|
||||
except:
|
||||
sat_position = ''
|
||||
|
||||
return render(request, 'base/satellite.html', {'satellite': satellite,
|
||||
'suggestions': suggestions,
|
||||
'modes': modes})
|
||||
'suggestions': suggestions, 'modes': modes,
|
||||
'sat_position': sat_position,
|
||||
'mapbox_id': settings.MAPBOX_MAP_ID,
|
||||
'mapbox_token': settings.MAPBOX_TOKEN})
|
||||
|
||||
|
||||
@login_required
|
||||
|
|
|
@ -195,3 +195,10 @@ DATABASES = {'default': dj_database_url.parse(DATABASE_URL)}
|
|||
# NETWORK API
|
||||
NETWORK_API_ENDPOINT = getenv('NETWORK_API_ENDPOINT', 'https://network.satnogs.org/api/')
|
||||
DATA_FETCH_DAYS = getenv('DATA_FETCH_DAYS', 10)
|
||||
SATELLITE_POSITION_ENDPOINT = getenv('SATELLITE_POSITION_ENDPOINT',
|
||||
'https://network.satnogs.org/satellite_position/')
|
||||
|
||||
# Mapbox API
|
||||
MAPBOX_GEOCODE_URL = 'https://api.tiles.mapbox.com/v4/geocode/mapbox.places/'
|
||||
MAPBOX_MAP_ID = getenv('MAPBOX_MAP_ID', '')
|
||||
MAPBOX_TOKEN = getenv('MAPBOX_TOKEN', '')
|
||||
|
|
|
@ -2,61 +2,56 @@
|
|||
==================== */
|
||||
|
||||
@font-face {
|
||||
font-family: 'ClearSans';
|
||||
font-family: ClearSans;
|
||||
src: url('../fonts/ClearSans-Regular.eot');
|
||||
src: url('../fonts/ClearSans-Regular.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/ClearSans-Regular.woff') format('woff'),
|
||||
url('../fonts/ClearSans-Regular.ttf') format('truetype'),
|
||||
url('../fonts/ClearSans-Regular.svg#open_sans') format('svg');
|
||||
url('../fonts/ClearSans-Regular.woff') format('woff'),
|
||||
url('../fonts/ClearSans-Regular.ttf') format('truetype'),
|
||||
url('../fonts/ClearSans-Regular.svg#open_sans') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'ClearSans';
|
||||
font-family: ClearSans;
|
||||
src: url('../fonts/ClearSans-Bold.eot');
|
||||
src: url('../fonts/ClearSans-Bold.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/ClearSans-Bold.woff') format('woff'),
|
||||
url('../fonts/ClearSans-Bold.ttf') format('truetype'),
|
||||
url('../fonts/ClearSans-Bold.svg#open_sansbold') format('svg');
|
||||
url('../fonts/ClearSans-Bold.woff') format('woff'),
|
||||
url('../fonts/ClearSans-Bold.ttf') format('truetype'),
|
||||
url('../fonts/ClearSans-Bold.svg#open_sansbold') format('svg');
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'ClearSans';
|
||||
font-family: ClearSans;
|
||||
src: url('../fonts/ClearSans-BoldItalic.eot');
|
||||
src: url('../fonts/ClearSans-BoldItalic.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/ClearSans-BoldItalic.woff') format('woff'),
|
||||
url('../fonts/ClearSans-BoldItalic.ttf') format('truetype'),
|
||||
url('../fonts/ClearSans-BoldItalic.svg#open_sansbold_italic') format('svg');
|
||||
url('../fonts/ClearSans-BoldItalic.woff') format('woff'),
|
||||
url('../fonts/ClearSans-BoldItalic.ttf') format('truetype'),
|
||||
url('../fonts/ClearSans-BoldItalic.svg#open_sansbold_italic') format('svg');
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'ClearSans';
|
||||
font-family: ClearSans;
|
||||
src: url('../fonts/ClearSans-Italic.eot');
|
||||
src: url('../fonts/ClearSans-Italic.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/ClearSans-Italic.woff') format('woff'),
|
||||
url('../fonts/ClearSans-Italic.ttf') format('truetype'),
|
||||
url('../fonts/ClearSans-Italic.svg#open_sansitalic') format('svg');
|
||||
url('../fonts/ClearSans-Italic.woff') format('woff'),
|
||||
url('../fonts/ClearSans-Italic.ttf') format('truetype'),
|
||||
url('../fonts/ClearSans-Italic.svg#open_sansitalic') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Generic
|
||||
==================== */
|
||||
|
||||
body {
|
||||
font-size:14px;
|
||||
font-size: 14px;
|
||||
line-height: 1.3;
|
||||
font-family:'ClearSans';
|
||||
font-family: ClearSans;
|
||||
}
|
||||
|
||||
.alert-debug {
|
||||
|
@ -90,9 +85,8 @@ body {
|
|||
}
|
||||
|
||||
.error {
|
||||
margin-top: 40px;
|
||||
margin-top: 40px auto 0 auto;
|
||||
width: 500px;
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
@ -117,13 +111,13 @@ body {
|
|||
width: 80px;
|
||||
}
|
||||
|
||||
.stats {
|
||||
.statistics {
|
||||
text-align: center;
|
||||
text-shadow: 1px 1px 2px rgba(150, 150, 150, 0.77) !important;
|
||||
text-shadow: 1px 1px 2px rgba(150, 150, 150, 0.77);
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.stats > img {
|
||||
.statistics > img {
|
||||
max-width: 20px;
|
||||
}
|
||||
|
||||
|
@ -146,25 +140,57 @@ body {
|
|||
a.satellite-item {
|
||||
min-height: 120px;
|
||||
padding: 10px;
|
||||
border: 1px solid #FFF;
|
||||
border: 1px solid #ffffff;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
background-image: linear-gradient(to bottom, #FFF 0px, #F4F4F4 100%);
|
||||
background-image: linear-gradient(to bottom, #ffffff 0, #f4f4f4 100%);
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
border: medium none;
|
||||
box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.15);
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
a.satellite-item:hover {
|
||||
box-shadow: 0px 2px 5px #808080;
|
||||
box-shadow: 0 2px 5px #808080;
|
||||
transition: all 0.3s ease-out 0s;
|
||||
}
|
||||
|
||||
.satellite-title {
|
||||
font-weight: bold;
|
||||
font-size: 1.2em;
|
||||
display: inline-block;
|
||||
min-height: 30px;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.satellite-title .badge {
|
||||
margin-top: -3px;
|
||||
}
|
||||
|
||||
.satellite-names {
|
||||
font-size: 1.1em;
|
||||
margin-bottom: 10px;
|
||||
font-weight: normal;
|
||||
float: right;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#map {
|
||||
width: 100%;
|
||||
height: 250px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.leaflet-left {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mapbox-improve-map {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.satellite-suggest {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.satellite-img {
|
||||
|
@ -176,13 +202,13 @@ a.satellite-item:hover {
|
|||
|
||||
.satellite-img-full {
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
max-height: 250px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.satellite-transmitters {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.satellite-transmitters > span {
|
||||
|
@ -193,7 +219,7 @@ a.satellite-item:hover {
|
|||
}
|
||||
|
||||
.panel-transmitter {
|
||||
margin: 20px 0px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.panel-first {
|
||||
|
@ -240,7 +266,7 @@ footer {
|
|||
}
|
||||
|
||||
.stage-notice {
|
||||
background-color: #D74545;
|
||||
background-color: #d74545;
|
||||
color: white;
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
|
@ -248,33 +274,43 @@ footer {
|
|||
z-index: 20;
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.stage-notice a {
|
||||
color: #ffff00;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
|
||||
#map {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.satellite-img-full {
|
||||
max-width: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Statistics page
|
||||
==================== */
|
||||
|
||||
.stats {
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.stats-hud {
|
||||
padding: 15px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.stats-hud-num {
|
||||
display: block;
|
||||
font-size: 2em;
|
||||
font-size: 2em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
/* Telemetry D3 visualisation
|
||||
============================= */
|
||||
|
||||
|
@ -287,6 +323,10 @@ svg.chart {
|
|||
margin: 10px 50px;
|
||||
}
|
||||
|
||||
#telemetry {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#telemetry-descriptors {
|
||||
padding: 0;
|
||||
}
|
||||
|
@ -304,17 +344,17 @@ svg.chart {
|
|||
position: absolute;
|
||||
background: #286090;
|
||||
color: #fff;
|
||||
font-family: 'ClearSans';
|
||||
font-family: ClearSans;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
padding: 5px 5px 6px 5px;
|
||||
border: 0px;
|
||||
border: 0;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.tick line, .domain {
|
||||
fill: none;
|
||||
stroke: #ddd;
|
||||
fill: none;
|
||||
stroke: #ddd;
|
||||
}
|
||||
|
||||
.line {
|
||||
|
@ -326,18 +366,18 @@ svg.chart {
|
|||
/* Telemetry Datepicker */
|
||||
|
||||
.datepicker {
|
||||
border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
padding-bottom: 25px;
|
||||
}
|
||||
|
||||
.datepicker input {
|
||||
font-family: 'ClearSans';
|
||||
font-family: ClearSans;
|
||||
font-size: 13px;
|
||||
padding: 5px 10px;
|
||||
border: none;
|
||||
box-shadow: inset 0px 0px 8px rgba(0,0,0,0.3);
|
||||
border-bottom-right-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
box-shadow: inset 0 0 8px rgba(0, 0, 0, 0.3);
|
||||
border-bottom-right-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
@ -349,4 +389,4 @@ svg.chart {
|
|||
|
||||
.daterangepicker {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
|
@ -1,3 +1,4 @@
|
|||
/* global d3 Backbone moment _ */
|
||||
// D3 visualisation
|
||||
|
||||
d3.lineChart = function(telemetry_key, unit) {
|
||||
|
@ -10,9 +11,9 @@ d3.lineChart = function(telemetry_key, unit) {
|
|||
var svg;
|
||||
|
||||
// Define the div for the tooltip
|
||||
var div = d3.select("body").append("div")
|
||||
.attr("class", "chart-tooltip")
|
||||
.style("opacity", 0);
|
||||
var div = d3.select('body').append('div')
|
||||
.attr('class', 'chart-tooltip')
|
||||
.style('opacity', 0);
|
||||
|
||||
function render(selection) {
|
||||
selection.each(function(_data) {
|
||||
|
@ -21,7 +22,7 @@ d3.lineChart = function(telemetry_key, unit) {
|
|||
|
||||
|
||||
var x1 = d3.scale.ordinal()
|
||||
.domain(_data.map(function(d, i){
|
||||
.domain(_data.map(function(d){
|
||||
return parseDate(d.telemetry.observation_datetime);
|
||||
}))
|
||||
.rangePoints([0, chartW]);
|
||||
|
@ -29,17 +30,17 @@ d3.lineChart = function(telemetry_key, unit) {
|
|||
var y1;
|
||||
|
||||
switch(_data.length) {
|
||||
case 1:
|
||||
y1 = d3.scale.linear()
|
||||
.domain([0, d3.max(_data, function(d, i){ return +d.telemetry.damod_data[telemetry_key]; })])
|
||||
.range([chartH, 0])
|
||||
.nice(4);
|
||||
break;
|
||||
default:
|
||||
y1 = d3.scale.linear()
|
||||
.domain(d3.extent(_data, function(d, i){ return +d.telemetry.damod_data[telemetry_key]; }))
|
||||
case 1:
|
||||
y1 = d3.scale.linear()
|
||||
.domain([0, d3.max(_data, function(d){ return +d.telemetry.damod_data[telemetry_key]; })])
|
||||
.range([chartH, 0])
|
||||
.nice(4);
|
||||
break;
|
||||
default:
|
||||
y1 = d3.scale.linear()
|
||||
.domain(d3.extent(_data, function(d){ return +d.telemetry.damod_data[telemetry_key]; }))
|
||||
.range([chartH, 0])
|
||||
.nice(4);
|
||||
}
|
||||
|
||||
var xAxis = d3.svg.axis()
|
||||
|
@ -74,83 +75,83 @@ d3.lineChart = function(telemetry_key, unit) {
|
|||
.transition()
|
||||
.call(yAxis);
|
||||
|
||||
svg.selectAll(".x-axis-group.axis text") // select all the text elements for the xaxis
|
||||
.attr("transform", function(d) {
|
||||
return "translate(-50,50)rotate(-45)";
|
||||
svg.selectAll('.x-axis-group.axis text') // select all the text elements for the xaxis
|
||||
.attr('transform', function() {
|
||||
return 'translate(-50,50)rotate(-45)';
|
||||
});
|
||||
|
||||
// Axis labels
|
||||
svg.append("text")
|
||||
.attr("transform", "translate(" + (chartW + config.margin.right + 18) + " ," + (chartH + 10) + ")")
|
||||
.style("text-anchor", "middle")
|
||||
.text("Observation Datetime");
|
||||
svg.append('text')
|
||||
.attr('transform', 'translate(' + (chartW + config.margin.right + 18) + ' ,' + (chartH + 10) + ')')
|
||||
.style('text-anchor', 'middle')
|
||||
.text('Observation Datetime');
|
||||
|
||||
svg.append("text")
|
||||
.attr("transform", "rotate(-90)")
|
||||
.attr("y", 40)
|
||||
.attr("x", 0 - (chartH / 2))
|
||||
.attr("dy", "1em")
|
||||
.style("text-anchor", "middle")
|
||||
.text("Value (" + unit + ")");
|
||||
svg.append('text')
|
||||
.attr('transform', 'rotate(-90)')
|
||||
.attr('y', 40)
|
||||
.attr('x', 0 - (chartH / 2))
|
||||
.attr('dy', '1em')
|
||||
.style('text-anchor', 'middle')
|
||||
.text('Value (' + unit + ')');
|
||||
|
||||
switch(_data.length) {
|
||||
case 1:
|
||||
// Add the scatterplot
|
||||
svg.selectAll("dot")
|
||||
.data(_data)
|
||||
.enter().append("circle")
|
||||
.attr("r", 4)
|
||||
.attr("cx", function(d, i) { return chartW / 2 + config.margin.left; })
|
||||
.attr("cy", function(d) { return y1(d.telemetry.damod_data[telemetry_key]) + config.margin.top; })
|
||||
.attr("class", "circle")
|
||||
.on("mouseover", function(d) {
|
||||
div.transition()
|
||||
.duration(200)
|
||||
.style("opacity", 1);
|
||||
div.html(d.telemetry.damod_data[telemetry_key] + ' (' + unit + ')')
|
||||
.style("left", (d3.event.pageX) + "px")
|
||||
.style("top", (d3.event.pageY - 26) + "px");
|
||||
})
|
||||
.on("mouseout", function(d) {
|
||||
div.transition()
|
||||
.duration(500)
|
||||
.style("opacity", 0);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
var xInterval = chartW / (_data.length - 1);
|
||||
case 1:
|
||||
// Add the scatterplot
|
||||
svg.selectAll('dot')
|
||||
.data(_data)
|
||||
.enter().append('circle')
|
||||
.attr('r', 4)
|
||||
.attr('cx', function() { return chartW / 2 + config.margin.left; })
|
||||
.attr('cy', function(d) { return y1(d.telemetry.damod_data[telemetry_key]) + config.margin.top; })
|
||||
.attr('class', 'circle')
|
||||
.on('mouseover', function(d) {
|
||||
div.transition()
|
||||
.duration(200)
|
||||
.style('opacity', 1);
|
||||
div.html(d.telemetry.damod_data[telemetry_key] + ' (' + unit + ')')
|
||||
.style('left', (d3.event.pageX) + 'px')
|
||||
.style('top', (d3.event.pageY - 26) + 'px');
|
||||
})
|
||||
.on('mouseout', function() {
|
||||
div.transition()
|
||||
.duration(500)
|
||||
.style('opacity', 0);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
var xInterval = chartW / (_data.length - 1);
|
||||
|
||||
// Define the line
|
||||
var valueline = d3.svg.line()
|
||||
.x(function(d,i) { return (xInterval*i + config.margin.left); })
|
||||
.y(function(d) { return y1(d.telemetry.damod_data[telemetry_key]) + config.margin.top; });
|
||||
// Define the line
|
||||
var valueline = d3.svg.line()
|
||||
.x(function(d,i) { return (xInterval*i + config.margin.left); })
|
||||
.y(function(d) { return y1(d.telemetry.damod_data[telemetry_key]) + config.margin.top; });
|
||||
|
||||
// Add the valueline path
|
||||
svg.append("path")
|
||||
.attr("class", "line")
|
||||
.attr("d", valueline(_data));
|
||||
// Add the valueline path
|
||||
svg.append('path')
|
||||
.attr('class', 'line')
|
||||
.attr('d', valueline(_data));
|
||||
|
||||
// Add the scatterplot
|
||||
svg.selectAll("dot")
|
||||
.data(_data)
|
||||
.enter().append("circle")
|
||||
.attr("r", 4)
|
||||
.attr("cx", function(d, i) { return xInterval*i + config.margin.left; })
|
||||
.attr("cy", function(d) { return y1(d.telemetry.damod_data[telemetry_key]) + config.margin.top; })
|
||||
.attr("class", "circle")
|
||||
.on("mouseover", function(d) {
|
||||
div.transition()
|
||||
.duration(200)
|
||||
.style("opacity", 1);
|
||||
div.html(d.telemetry.damod_data[telemetry_key] + ' (' + unit + ')')
|
||||
.style("left", (d3.event.pageX) + "px")
|
||||
.style("top", (d3.event.pageY - 26) + "px");
|
||||
})
|
||||
.on("mouseout", function(d) {
|
||||
div.transition()
|
||||
.duration(500)
|
||||
.style("opacity", 0);
|
||||
});
|
||||
// Add the scatterplot
|
||||
svg.selectAll('dot')
|
||||
.data(_data)
|
||||
.enter().append('circle')
|
||||
.attr('r', 4)
|
||||
.attr('cx', function(d, i) { return xInterval*i + config.margin.left; })
|
||||
.attr('cy', function(d) { return y1(d.telemetry.damod_data[telemetry_key]) + config.margin.top; })
|
||||
.attr('class', 'circle')
|
||||
.on('mouseover', function(d) {
|
||||
div.transition()
|
||||
.duration(200)
|
||||
.style('opacity', 1);
|
||||
div.html(d.telemetry.damod_data[telemetry_key] + ' (' + unit + ')')
|
||||
.style('left', (d3.event.pageX) + 'px')
|
||||
.style('top', (d3.event.pageY - 26) + 'px');
|
||||
})
|
||||
.on('mouseout', function() {
|
||||
div.transition()
|
||||
.duration(500)
|
||||
.style('opacity', 0);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
@ -159,108 +160,6 @@ d3.lineChart = function(telemetry_key, unit) {
|
|||
return render;
|
||||
};
|
||||
|
||||
// Retreive Satellite Id
|
||||
|
||||
var satelliteId = $('#telemetry-block').data('satid');
|
||||
|
||||
// Backbone Models
|
||||
|
||||
var TelemetryData = Backbone.Model.extend({});
|
||||
|
||||
// Backbone Collections
|
||||
|
||||
var TelemetryCollection = Backbone.Collection.extend({
|
||||
url:"/api/telemetry/?satellite=" + satelliteId
|
||||
});
|
||||
|
||||
var TelemetryDescriptors = TelemetryCollection.extend({
|
||||
parse: function(response){
|
||||
if(response.length !== 0) {
|
||||
return response[0].appendix;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var TelemetryValues = TelemetryCollection.extend({
|
||||
comparator: function(collection){
|
||||
return( collection.get('telemetry').observation_datetime );
|
||||
},
|
||||
byDate: function (start_date, end_date) {
|
||||
filtered = this.filter(function (model) {
|
||||
var date = parseDateFilter(model.get('telemetry').observation_datetime);
|
||||
return ( date >= start_date && date <= end_date );
|
||||
});
|
||||
return new TelemetryValues(filtered);
|
||||
}
|
||||
});
|
||||
|
||||
// Backbone Views
|
||||
|
||||
var TelemetryDescriptorsView = Backbone.View.extend({
|
||||
el: "#telemetry-descriptors",
|
||||
template: _.template($('#telemetryDescriptorsTemplate').html()),
|
||||
initialize: function(){
|
||||
this.listenTo(this.collection, 'add reset change remove', this.renderItem);
|
||||
this.collection.fetch();
|
||||
},
|
||||
renderItem: function (model) {
|
||||
this.$el.append(this.template(model.toJSON()));
|
||||
$('#telemetry-descriptors li:first-child').addClass('active');
|
||||
}
|
||||
});
|
||||
|
||||
var TelemetryChartView = Backbone.View.extend({
|
||||
el: ".chart",
|
||||
chart: null,
|
||||
chartSelection: null,
|
||||
initialize: function() {
|
||||
this.collection.fetch();
|
||||
this.updateDates(moment().subtract(7, 'days').format('YYYY/MM/DD'), moment().format('YYYY/MM/DD'));
|
||||
this.renderPlaceholder();
|
||||
this.collection.on('update filter', this.render, this);
|
||||
chart = d3.lineChart();
|
||||
},
|
||||
events: {
|
||||
"click .telemetry-key": "updateKey",
|
||||
},
|
||||
render: function() {
|
||||
if (this.collection.length > 0) {
|
||||
$('#telemetry-descriptors').show();
|
||||
$('#data-available').empty();
|
||||
d3.select('svg').remove();
|
||||
var data = this.collection.toJSON();
|
||||
this.chartSelection = d3.select(this.el)
|
||||
.datum(data)
|
||||
.call(d3.lineChart(data[0].appendix[0].key, data[0].appendix[0].unit));
|
||||
} else {
|
||||
this.renderPlaceholder();
|
||||
}
|
||||
},
|
||||
renderPlaceholder: function() {
|
||||
$('#telemetry-descriptors').hide();
|
||||
$('#data-available').html("<p>There is no data available for the selected dates.</p>");
|
||||
d3.select('svg').remove();
|
||||
},
|
||||
updateKey: function(e){
|
||||
d3.select('svg').remove();
|
||||
this.chartSelection.call(d3.lineChart($(e.currentTarget).data("key"), $(e.currentTarget).data("unit")));
|
||||
var active = $(e.currentTarget);
|
||||
active.addClass('active');
|
||||
$('li').not(active).removeClass('active');
|
||||
},
|
||||
updateDates: function(start_date, end_date){
|
||||
this.collection = telemetryValues.byDate(start_date, end_date);
|
||||
this.render();
|
||||
},
|
||||
});
|
||||
|
||||
// Fetch data and render views
|
||||
|
||||
var telemetryDescriptorsView = new TelemetryDescriptorsView({ collection: new TelemetryDescriptors() });
|
||||
var telemetryValues = new TelemetryValues();
|
||||
var telemetryChartView = new TelemetryChartView({collection: telemetryValues});
|
||||
|
||||
|
||||
// Parse datetime values
|
||||
|
||||
function parseDate (date) {
|
||||
|
@ -273,19 +172,129 @@ function parseDateFilter (date) {
|
|||
return res;
|
||||
}
|
||||
|
||||
$('input[name="daterange"]').daterangepicker(
|
||||
{
|
||||
locale: {
|
||||
format: 'YYYY/MM/DD'
|
||||
// Check if Satellite has telemetry data
|
||||
|
||||
var has_telemetry_data = $('.satellite-title').data('telemetry');
|
||||
|
||||
if (has_telemetry_data) {
|
||||
$('#telemetry').show();
|
||||
|
||||
// Retreive Satellite id
|
||||
|
||||
var satelliteId = $('#telemetry-block').data('satid');
|
||||
|
||||
|
||||
// Backbone Models
|
||||
|
||||
Backbone.Model.extend({});
|
||||
|
||||
// Backbone Collections
|
||||
|
||||
var TelemetryCollection = Backbone.Collection.extend({
|
||||
url:'/api/telemetry/?satellite=' + satelliteId
|
||||
});
|
||||
|
||||
var TelemetryDescriptors = TelemetryCollection.extend({
|
||||
parse: function(response){
|
||||
if(response.length !== 0) {
|
||||
return response[0].appendix;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var TelemetryValues = TelemetryCollection.extend({
|
||||
comparator: function(collection){
|
||||
return( collection.get('telemetry').observation_datetime );
|
||||
},
|
||||
dateLimit: {
|
||||
"days": 60
|
||||
byDate: function (start_date, end_date) {
|
||||
var filtered = this.filter(function (model) {
|
||||
var date = parseDateFilter(model.get('telemetry').observation_datetime);
|
||||
return ( date >= start_date && date <= end_date );
|
||||
});
|
||||
return new TelemetryValues(filtered);
|
||||
}
|
||||
});
|
||||
|
||||
// Backbone Views
|
||||
|
||||
var TelemetryDescriptorsView = Backbone.View.extend({
|
||||
el: '#telemetry-descriptors',
|
||||
template: _.template($('#telemetryDescriptorsTemplate').html()),
|
||||
initialize: function(){
|
||||
this.listenTo(this.collection, 'add reset change remove', this.renderItem);
|
||||
this.collection.fetch();
|
||||
},
|
||||
autoApply: true,
|
||||
startDate: moment().subtract(7, 'days').format('YYYY/MM/DD'),
|
||||
endDate: moment().format('YYYY/MM/DD'),
|
||||
},
|
||||
function(start, end, label) {
|
||||
telemetryChartView.updateDates(start.format('YYYYMMDD'), end.format('YYYYMMDD'));
|
||||
}
|
||||
);
|
||||
renderItem: function (model) {
|
||||
this.$el.append(this.template(model.toJSON()));
|
||||
$('#telemetry-descriptors li:first-child').addClass('active');
|
||||
}
|
||||
});
|
||||
|
||||
var TelemetryChartView = Backbone.View.extend({
|
||||
el: '.chart',
|
||||
chart: null,
|
||||
chartSelection: null,
|
||||
initialize: function() {
|
||||
this.collection.fetch();
|
||||
this.updateDates(moment().subtract(7, 'days').format('YYYY/MM/DD'), moment().format('YYYY/MM/DD'));
|
||||
this.renderPlaceholder();
|
||||
this.collection.on('update filter', this.render, this);
|
||||
d3.lineChart();
|
||||
},
|
||||
events: {
|
||||
'click .telemetry-key': 'updateKey',
|
||||
},
|
||||
render: function() {
|
||||
if (this.collection.length > 0) {
|
||||
$('#telemetry-descriptors').show();
|
||||
$('#data-available').empty();
|
||||
d3.select('svg').remove();
|
||||
var data = this.collection.toJSON();
|
||||
this.chartSelection = d3.select(this.el)
|
||||
.datum(data)
|
||||
.call(d3.lineChart(data[0].appendix[0].key, data[0].appendix[0].unit));
|
||||
} else {
|
||||
this.renderPlaceholder();
|
||||
}
|
||||
},
|
||||
renderPlaceholder: function() {
|
||||
$('#telemetry-descriptors').hide();
|
||||
$('#data-available').html('<p>There is no data available for the selected dates.</p>');
|
||||
d3.select('svg').remove();
|
||||
},
|
||||
updateKey: function(e){
|
||||
d3.select('svg').remove();
|
||||
this.chartSelection.call(d3.lineChart($(e.currentTarget).data('key'), $(e.currentTarget).data('unit')));
|
||||
var active = $(e.currentTarget);
|
||||
active.addClass('active');
|
||||
$('li').not(active).removeClass('active');
|
||||
},
|
||||
updateDates: function(start_date, end_date){
|
||||
this.collection = telemetryValues.byDate(start_date, end_date);
|
||||
this.render();
|
||||
},
|
||||
});
|
||||
|
||||
// Fetch data and render views
|
||||
|
||||
new TelemetryDescriptorsView({ collection: new TelemetryDescriptors() });
|
||||
var telemetryValues = new TelemetryValues();
|
||||
var telemetryChartView = new TelemetryChartView({collection: telemetryValues});
|
||||
|
||||
$('input[name="daterange"]').daterangepicker(
|
||||
{
|
||||
locale: {
|
||||
format: 'YYYY/MM/DD'
|
||||
},
|
||||
dateLimit: {
|
||||
'days': 60
|
||||
},
|
||||
autoApply: true,
|
||||
startDate: moment().subtract(7, 'days').format('YYYY/MM/DD'),
|
||||
endDate: moment().format('YYYY/MM/DD'),
|
||||
},
|
||||
function(start, end) {
|
||||
telemetryChartView.updateDates(start.format('YYYYMMDD'), end.format('YYYYMMDD'));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ $(document).ready(function() {
|
|||
});
|
||||
|
||||
var t = $('input');
|
||||
t.bind('propertychange keyup input paste', function(event) {
|
||||
t.bind('propertychange keyup input paste', function() {
|
||||
var term = t.val().toLowerCase();
|
||||
if (term !== '') {
|
||||
$('.satellite-group-item').hide();
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*global L */
|
||||
|
||||
$(document).ready(function() {
|
||||
'use strict';
|
||||
|
||||
var mapboxid = $('div#map').data('mapboxid');
|
||||
var mapboxtoken = $('div#map').data('mapboxtoken');
|
||||
var lat = $('.satellite-title').data('position-lat');
|
||||
var lon = $('.satellite-title').data('position-lon');
|
||||
|
||||
L.mapbox.accessToken = mapboxtoken;
|
||||
L.mapbox.config.FORCE_HTTPS = true;
|
||||
var map = L.mapbox.map('map', mapboxid, {
|
||||
zoomControl: false
|
||||
}).setView([lat, lon], 3);
|
||||
|
||||
var myLayer = L.mapbox.featureLayer().addTo(map);
|
||||
|
||||
var geojson = {
|
||||
type: 'FeatureCollection',
|
||||
features: [{
|
||||
'type': 'Feature',
|
||||
'geometry': {
|
||||
'type': 'Point',
|
||||
'coordinates': [lon, lat]
|
||||
},
|
||||
'properties': {
|
||||
'icon': {
|
||||
'iconUrl': '/static/img/satellite-marker.png',
|
||||
'iconSize': [32, 32],
|
||||
'iconAnchor': [16, 16],
|
||||
}
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
myLayer.on('layeradd', function(e) {
|
||||
var marker = e.layer,
|
||||
feature = marker.feature;
|
||||
|
||||
marker.setIcon(L.icon(feature.properties.icon));
|
||||
});
|
||||
|
||||
myLayer.setGeoJSON(geojson);
|
||||
});
|
|
@ -1,74 +1,83 @@
|
|||
$.getJSON( "/statistics/", function( data ) {
|
||||
/* global Chart */
|
||||
|
||||
var i, r, g, b, a;
|
||||
// Create colors for Mode Chart
|
||||
var mode_colors = [];
|
||||
for (i = 0; i < data.mode_label.length; i++) {
|
||||
r = Math.floor(data.mode_data[i]* 10);
|
||||
b = Math.floor(0.3 * 255);
|
||||
g = Math.floor(data.mode_data[i]* 10);
|
||||
a = 0.5;
|
||||
color = "rgba(" + r + "," + g + "," + b + "," + a + ")";
|
||||
mode_colors.push(color);
|
||||
}
|
||||
$(document).ready(function() {
|
||||
|
||||
// Create colors for Band Chart
|
||||
var band_colors = [];
|
||||
for (i = 0; i < data.band_label.length; i++) {
|
||||
b = Math.floor(0.1 * 255);
|
||||
g = Math.floor(data.band_data[i]);
|
||||
r = Math.floor(data.band_data[i]);
|
||||
a = 0.5;
|
||||
color = "rgba(" + r + "," + g + "," + b + "," + a + ")";
|
||||
band_colors.push(color);
|
||||
}
|
||||
$.getJSON('/statistics/', function( data ) {
|
||||
|
||||
// Global chart configuration
|
||||
Chart.defaults.global.legend.display = false;
|
||||
Chart.defaults.global.title.display = true;
|
||||
Chart.defaults.global.title.fontSize = 16;
|
||||
Chart.defaults.global.title.fontColor= '#444';
|
||||
|
||||
//Mode Chart
|
||||
var mode_c = document.getElementById("modes");
|
||||
var modeChart = new Chart(mode_c, {
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
labels: data.mode_label,
|
||||
datasets: [{
|
||||
backgroundColor: mode_colors,
|
||||
data: data.mode_data,
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
title : {
|
||||
text: data.mode_data.length + ' Modes'
|
||||
}
|
||||
var i;
|
||||
var r;
|
||||
var g;
|
||||
var b;
|
||||
var a;
|
||||
// Create colors for Mode Chart
|
||||
var mode_colors = [];
|
||||
for (i = 0; i < data.mode_label.length; i++) {
|
||||
r = Math.floor(data.mode_data[i]* 10);
|
||||
b = Math.floor(0.3 * 255);
|
||||
g = Math.floor(data.mode_data[i]* 10);
|
||||
a = 0.5;
|
||||
var color = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';
|
||||
mode_colors.push(color);
|
||||
}
|
||||
});
|
||||
|
||||
//Band Chart
|
||||
var band_c = document.getElementById("bands");
|
||||
var bandChart = new Chart(band_c, {
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
labels: data.band_label,
|
||||
datasets: [{
|
||||
backgroundColor: band_colors,
|
||||
data: data.band_data,
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
title : {
|
||||
text: data.band_data.length + ' Bands'
|
||||
}
|
||||
// Create colors for Band Chart
|
||||
var band_colors = [];
|
||||
for (i = 0; i < data.band_label.length; i++) {
|
||||
b = Math.floor(0.1 * 255);
|
||||
g = Math.floor(data.band_data[i]);
|
||||
r = Math.floor(data.band_data[i]);
|
||||
a = 0.5;
|
||||
color = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';
|
||||
band_colors.push(color);
|
||||
}
|
||||
});
|
||||
|
||||
//HUD Stats
|
||||
$('#stats-alive').html(data.transmitters_alive);
|
||||
$('#stats-transmitters').html(data.transmitters);
|
||||
$('#stats-satellites').html(data.total_satellites);
|
||||
// Global chart configuration
|
||||
Chart.defaults.global.legend.display = false;
|
||||
Chart.defaults.global.title.display = true;
|
||||
Chart.defaults.global.title.fontSize = 16;
|
||||
Chart.defaults.global.title.fontColor= '#444';
|
||||
|
||||
//Mode Chart
|
||||
var mode_c = document.getElementById('modes');
|
||||
new Chart(mode_c, {
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
labels: data.mode_label,
|
||||
datasets: [{
|
||||
backgroundColor: mode_colors,
|
||||
data: data.mode_data,
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
title : {
|
||||
text: data.mode_data.length + ' Modes'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//Band Chart
|
||||
var band_c = document.getElementById('bands');
|
||||
new Chart(band_c, {
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
labels: data.band_label,
|
||||
datasets: [{
|
||||
backgroundColor: band_colors,
|
||||
data: data.band_data,
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
title : {
|
||||
text: data.band_data.length + ' Bands'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//HUD Stats
|
||||
$('#stats-alive').html(data.transmitters_alive);
|
||||
$('#stats-transmitters').html(data.transmitters);
|
||||
$('#stats-satellites').html(data.total_satellites);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -14,27 +14,27 @@
|
|||
<div class="col-md-4">
|
||||
<div class="row hidden-xs hidden-sm">
|
||||
<div class="{% if suggestions %}col-md-3{% else %}col-md-4{% endif %}">
|
||||
<p class="stats">
|
||||
<p class="statistics">
|
||||
<img src="{% static 'img/satellites.png' %}">
|
||||
{{ satellites.count }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="{% if suggestions %}col-md-3{% else %}col-md-4{% endif %}">
|
||||
<p class="stats">
|
||||
<p class="statistics">
|
||||
<img src="{% static 'img/transmitters.png' %}">
|
||||
{{ transmitters }}
|
||||
</p>
|
||||
</div>
|
||||
{% if suggestions %}
|
||||
<div class="col-md-3">
|
||||
<p class="stats">
|
||||
<p class="statistics">
|
||||
<img src="{% static 'img/suggestions.png' %}">
|
||||
{{ suggestions }}
|
||||
</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="{% if suggestions %}col-md-3{% else %}col-md-4{% endif %}">
|
||||
<p class="stats">
|
||||
<p class="statistics">
|
||||
<img src="{% static 'img/contributors.png' %}">
|
||||
{{ contributors }}
|
||||
</p>
|
||||
|
@ -63,9 +63,12 @@
|
|||
<div class="satellite-title">{{ sat.norad_cat_id }} - {{ sat.name }}</div>
|
||||
<div>{{ sat.names }}</div>
|
||||
<div class="satellite-transmitters">
|
||||
{% for transmitter in sat.transmitters.all %}
|
||||
{% for transmitter in sat.transmitters.all|slice:":5" %}
|
||||
<span class="label label-default">{{ transmitter.description }}</span>
|
||||
{% endfor %}
|
||||
{% if sat.transmitters.all.count > 5 %}
|
||||
<span class="label label-default">+{{ sat.transmitters.all.count|add:"-5" }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
|
||||
{% block css %}
|
||||
<link rel="stylesheet" href="{% static 'lib/bootstrap-daterangepicker/daterangepicker.css' %}">
|
||||
{% endblock %}
|
||||
<link rel="stylesheet" href="{% static 'lib/mapbox.js/mapbox.css' %}">
|
||||
{% endblock css %}
|
||||
|
||||
{% block top %}{% endblock %}
|
||||
|
||||
|
@ -18,19 +19,23 @@
|
|||
<div class="col-md-12 satellite-panels">
|
||||
<div class="panel panel-default panel-satellite">
|
||||
<div class="panel-heading">
|
||||
<div class="satellite-title">
|
||||
<div class="satellite-title" data-telemetry="{{ satellite.has_telemetry_data }}"
|
||||
data-position-lat="{{ sat_position.lat }}" data-position-lon="{{ sat_position.lon }}">
|
||||
{{ satellite }}
|
||||
</div>
|
||||
{% if satellite.names %}
|
||||
<div class="satellite-names hidden-xs">{{ satellite.names }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="row panel-body">
|
||||
<div class="col-md-3 panel-satellite">
|
||||
<div>
|
||||
{{ satellite.names }}
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
<div>
|
||||
<img src="{{ satellite.get_image }}" alt="{{ satellite.name }}" class="satellite-img-full">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-9">
|
||||
<div id="map" data-mapboxid="{{ mapbox_id }}" data-mapboxtoken="{{ mapbox_token }}"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -42,28 +47,26 @@
|
|||
<div class="panel panel-default panel-satellite">
|
||||
<div class="panel-heading">
|
||||
<div class="satellite-title">
|
||||
Transmitters
|
||||
</div>
|
||||
</div>
|
||||
<div class="row panel-body">
|
||||
<div class="col-md-3 panel-satellite">
|
||||
Transmitters <span class="badge">{{ satellite.transmitters.count }}</span>
|
||||
{% if suggestions %}
|
||||
<div class="suggestions-counter label label-primary">
|
||||
<div class="suggestions-counter label label-default">
|
||||
{{ suggestions.count }} suggestion{{ suggestions.count|pluralize }} pending
|
||||
</div>
|
||||
{% endif %}
|
||||
<div>
|
||||
<button type="button"
|
||||
class="btn btn-primary"
|
||||
data-toggle="modal" data-target="#NewSuggestionModal">
|
||||
Suggest New Transmitter
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<div class="satellite-suggest pull-right">
|
||||
<button type="button"
|
||||
class="btn btn-primary btn-sm"
|
||||
data-toggle="modal" data-target="#NewSuggestionModal">
|
||||
<span class="glyphicon glyphicon-plus" title="Suggest edits"></span> Suggest New Transmitter
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row panel-body">
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
{% for transmitter in satellite.transmitters.all %}
|
||||
<div class="col-md-6">
|
||||
<div class="col-md-4">
|
||||
<div class="panel {% if transmitter.alive %}panel-primary{% else %}panel-danger{% endif %} panel-transmitter">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">
|
||||
|
@ -183,7 +186,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if forloop.counter|divisibleby:2 %}
|
||||
{% if forloop.counter|divisibleby:3 %}
|
||||
</div>
|
||||
{% if not loop.last %}
|
||||
<div class="row">
|
||||
|
@ -202,7 +205,7 @@
|
|||
<hr>
|
||||
<div class="row">
|
||||
{% for suggestion in suggestions %}
|
||||
<div class="col-md-6">
|
||||
<div class="col-md-4">
|
||||
<div class="panel panel-{% if suggestion.transmitter %}info{% else %}warning{% endif %} panel-transmitter">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">
|
||||
|
@ -380,5 +383,7 @@
|
|||
<script src="{% static 'lib/d3/d3.min.js' %}"></script>
|
||||
<script src="{% static 'lib/moment/moment.js' %}"></script>
|
||||
<script src="{% static 'lib/bootstrap-daterangepicker/daterangepicker.js' %}"></script>
|
||||
<script src="{% static 'lib/mapbox.js/mapbox.js' %}"></script>
|
||||
<script src="{% static 'js/app.backbone.js' %}"></script>
|
||||
<script src="{% static 'js/map.js' %}"></script>
|
||||
{% endblock %}
|
||||
|
|
Loading…
Reference in New Issue