mirror of
https://github.com/sartography/uva-covid19-testing-communicator.git
synced 2025-02-24 21:08:06 +00:00
334 lines
10 KiB
HTML
334 lines
10 KiB
HTML
<!-- Main content -->
|
|
<div class="main-content">
|
|
|
|
<!-- Top navbar -->
|
|
<nav class="navbar navbar-top navbar-expand-md navbar-dark" id="navbar-main">
|
|
<div class="container-fluid">
|
|
|
|
<!-- Brand -->
|
|
<a class="h4 mb-0 text-white text-uppercase d-none d-lg-inline-block" href="./index.html">UVA Communicator
|
|
Dashboard</a>
|
|
</div>
|
|
</nav>
|
|
|
|
<!-- Header -->
|
|
{% include 'includes/top-stats.html' %}
|
|
<script src="{{url_for('static', filename='assets/js/graph.js')}}"></script>
|
|
|
|
<!-- Page content -->
|
|
<div class="container-fluid mt--7">
|
|
<div class="row">
|
|
<div class="col-xl-8 mb-4 mb-xl-0">
|
|
<div class="card bg-gradient-default shadow">
|
|
<div class="card-header bg-transparent">
|
|
<div class="row align-items-center">
|
|
<div class="col">
|
|
<h6 class="text-uppercase text-light ls-1 mb-1">Overview</h6>
|
|
<h2 id="chart-title" class="text-white mb-0">Location Activity</h2>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
|
|
<!-- Chart -->
|
|
<div class="chart">
|
|
<canvas id="data-chart" class="chart-canvas"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-xl-4 mb-xl-0">
|
|
<div class="card shadow">
|
|
<form action="{{ action }}" method="post" id="pageForm">
|
|
{{ form.csrf_token() }}
|
|
<div class="card-header border-0">
|
|
<div class="row align-items-center">
|
|
<div class="col">
|
|
<h3 class="mb-0">Search</h3>
|
|
</div>
|
|
<div class="col text-right mr-2">
|
|
<button class="btn btn-sm btn-primary" onclick="$('input[name=\'dateRange\']').val('');submitform();">Search Today</button>
|
|
</div>
|
|
<div class="col text-right mr-2">
|
|
<button type="submit" class="btn btn-sm btn-primary">Run Search</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="table-responsive">
|
|
<!-- Projects table -->
|
|
<table class="table align-items-center table-flush">
|
|
<tbody>
|
|
<input type="hidden" name = "currently_showing" />
|
|
{% for field in form if field.name != "csrf_token" %}
|
|
{% if field.name != "currently_showing" %}
|
|
<tr>
|
|
|
|
<div class="form-field {{ field.widget.input_type }}">
|
|
<td>
|
|
<div class="form-field-label">{{ field.label() }}:</div>
|
|
</td>
|
|
<td>
|
|
{% if field.name == "dateRange" %}
|
|
<input type="text" name="{{field.name}}" />
|
|
{%else%}
|
|
<div class="form-field-input">{{ field }}</div>
|
|
|
|
{% for error in field.errors %}
|
|
<div class="form-field-error">{{ error }}</div>
|
|
|
|
{% endfor %}
|
|
{% endif %}
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
<div class="row mt-4">
|
|
<div class="col mb-5 mb-xl-0">
|
|
<div class="card shadow">
|
|
<div class="card-header border-0">
|
|
<div class="row align-items-center">
|
|
<div class="col">
|
|
<h3 class="mb-0">Additional Stats:</h3>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card-body row">
|
|
<div class="chart col">
|
|
<canvas id="week-chart" class="chart-canvas"></canvas>
|
|
</div>
|
|
<div class="chart col">
|
|
<canvas id="time-chart" class="chart-canvas"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mt-2">
|
|
<div class="col mb-5 mb-xl-0">
|
|
<div class="card shadow">
|
|
<div class="card-header border-0">
|
|
<div class="row align-items-center">
|
|
<div class="col">
|
|
<h3 class="mb-0">Records to be processed</h3>
|
|
</div>
|
|
<div class="col text-right">
|
|
<a href="{{ url_for('index') }}?download=true" class="btn btn-sm btn-primary">Download all</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="table-responsive">
|
|
|
|
<!-- Projects table -->
|
|
{{ table }}
|
|
</div>
|
|
<div class="row justify-content-center">
|
|
{{ pagination.links }}
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
|
|
|
|
<script>
|
|
function random_rgba() {
|
|
var o = Math.round, r = Math.random, s = 255;
|
|
return 'rgba(' + o(r()*s) + ',' + o(r()*s) + ',' + o(r()*s) + ',1)';
|
|
}
|
|
var dat = JSON.parse('{{dates | tojson }}');
|
|
var color_idx = 0;
|
|
function dict2datasets(data) {
|
|
var datasets = [];
|
|
Object.keys(data).forEach(function (key) {
|
|
color_idx += 1;
|
|
datasets.push(
|
|
{
|
|
label: key,
|
|
fill: true,
|
|
borderColor: random_rgba(),
|
|
borderSkipped: "bottom",
|
|
borderWidth: 4,
|
|
borderCapStyle: 'butt',
|
|
data: data[key],
|
|
})
|
|
});
|
|
return datasets;
|
|
}
|
|
|
|
var overall_chart_data = JSON.parse('{{overall_chart_data | tojson }}');
|
|
var overall_chart = dict2datasets(overall_chart_data);
|
|
|
|
|
|
var location_charts = {};
|
|
var location_chart_data = JSON.parse('{{location_charts_data | tojson }}');
|
|
|
|
Object.keys(location_chart_data).forEach(function (station) {
|
|
location_charts[station] = dict2datasets(location_chart_data[station])
|
|
});
|
|
|
|
var overall_stat_data = JSON.parse('{{overall_stat_data | tojson }}');
|
|
var location_stats_data = JSON.parse('{{location_stats_data | tojson }}');
|
|
|
|
var weekday_totals = JSON.parse('{{ weekday_totals | tojson }}');
|
|
var hour_totals = JSON.parse('{{ hour_totals | tojson }}');
|
|
|
|
var per_weekday = new Chart(document.getElementById('week-chart').getContext('2d'), {
|
|
type: 'horizontalBar',
|
|
data: {
|
|
labels: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
|
|
datasets: [
|
|
{
|
|
label: "Total Samples",
|
|
backgroundColor: ["#3e95cd", "#8e5ea2", "#3cba9f", "#e8c3b9", "#c45850", "#7e3eb2", "#1c41bf"],
|
|
data: weekday_totals
|
|
}
|
|
]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
legend: {
|
|
display: false
|
|
},
|
|
title: {
|
|
display: true,
|
|
text: 'Average Count By Day For {{dates.range}}'
|
|
}
|
|
}
|
|
});
|
|
|
|
var per_hour = new Chart(document.getElementById('time-chart').getContext('2d'), {
|
|
type: 'horizontalBar',
|
|
data: {
|
|
labels: ["1 AM", "2 AM", "3 AM", "4 AM", "5 AM", "6 AM", "7 AM", "8 AM", "9 AM", "10 AM", "11 AM", "12 AM", "1 PM", "2 PM", "3 PM", "4 PM", "5 PM", "6 PM", "7 PM", "8 PM", "9 PM", "10 PM", "11 PM", "12 PM",],
|
|
datasets: [
|
|
{
|
|
label: "Sample Count",
|
|
backgroundColor: ["#3e95cd", "#3e95cd", "#3e95cd", "#3e95cd", "#3e95cd", "#3e95cd", "#3e95cd", "#3e95cd", "#3e95cd", "#3e95cd", "#3e95cd", "#3e95cd", "#3e95cd", "#3e95cd", "#3e95cd", "#3e95cd", "#3e95cd", "#3e95cd", "#3e95cd", "#3e95cd", "#3e95cd", "#3e95cd", "#3e95cd", "#3e95cd",],
|
|
data: hour_totals
|
|
}
|
|
]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
legend: {
|
|
display: false
|
|
},
|
|
title: {
|
|
display: true,
|
|
text: 'Average Count By Hour For {{dates.range}}'
|
|
}
|
|
}
|
|
});
|
|
|
|
var per_location = new Chart(document.getElementById('data-chart').getContext('2d'), {
|
|
// The type of chart we want to create
|
|
type: 'bar',
|
|
data: {datasets: overall_chart,
|
|
labels: JSON.parse('{{chart_ticks | tojson }}')
|
|
},
|
|
|
|
// Configuration options go here
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
title: {
|
|
display: false,
|
|
},
|
|
scales: {
|
|
xAxes: [{ stacked: true }],
|
|
yAxes: [{
|
|
ticks: {
|
|
beginAtZero:true
|
|
},
|
|
stacked: true
|
|
}]
|
|
},
|
|
legend: {
|
|
display: true,
|
|
position: "right",
|
|
onClick: location_legend,
|
|
labels: {
|
|
usePointStyle: true,
|
|
fontColor: '#FFFFFF',
|
|
fontSize: 15,
|
|
padding: 20,
|
|
fontStyle: 'bold'
|
|
}
|
|
},
|
|
}
|
|
});
|
|
|
|
function station_legend(e, legendItem) {
|
|
showLocation("");
|
|
};
|
|
|
|
function location_legend(e, legendItem) {
|
|
showLocation(per_location.data.datasets[legendItem.datasetIndex].label);
|
|
};
|
|
|
|
function showLocation(loc_code) {
|
|
console.log(loc_code);
|
|
if (loc_code != ""){
|
|
$('#chart-title').text("Station Activity @ " + loc_code);
|
|
per_location.config.data.datasets = location_charts[loc_code];
|
|
per_location.config.options.legend.onClick = station_legend;
|
|
$('#stats_today').text(location_stats_data[loc_code].today);
|
|
$('#stats_one_week').text(location_stats_data[loc_code].one_week_ago);
|
|
$('#stats_two_weeks').text(location_stats_data[loc_code].two_week_ago);
|
|
// $('#stats_avg').text(location_stats_data[loc_code].average);
|
|
|
|
$('#location').val(loc_code);
|
|
$('input[name="currently_showing"]').val(loc_code);
|
|
per_location.update();
|
|
} else {
|
|
per_location.config.data.datasets = overall_chart;
|
|
per_location.config.options.legend.onClick = location_legend;
|
|
|
|
$('#stats_today').text(overall_stat_data.today);
|
|
$('#stats_one_week').text(overall_stat_data.one_week_ago);
|
|
$('#stats_two_weeks').text(overall_stat_data.two_week_ago);
|
|
|
|
$('#chart-title').text("Location Activity");
|
|
$('#location').val("");
|
|
|
|
$('input[name="currently_showing"]').val("");
|
|
per_location.update();
|
|
}
|
|
}
|
|
|
|
showLocation($('input[name="currently_showing"]').val());
|
|
</script>
|
|
<script>
|
|
// var auto_refresh = setInterval(
|
|
// function () {
|
|
// submitform();
|
|
// }, 30000);
|
|
function submitform() {
|
|
$("#pageForm").submit();
|
|
}
|
|
|
|
$(function() {
|
|
$('input[name="dateRange"]').daterangepicker({
|
|
opens: 'left',
|
|
});
|
|
});
|
|
$('input[name="dateRange"]').val('{{dates.range}}');
|
|
</script> |