Merge branch 'add_charts' into 'master'
Add charts See merge request !8
This commit is contained in:
commit
99df28a015
|
@ -179,7 +179,7 @@ def create_pit_stop_form(vid):
|
|||
form.litres.default = last_pitstop.litres
|
||||
form.date.default = date.today()
|
||||
form.process()
|
||||
return render_template('newPitStopForm.html', form=form, vehicle = vehicle)
|
||||
return render_template('newPitStopForm.html', form=form, vehicle=vehicle)
|
||||
|
||||
|
||||
@app.route('/pitstops', methods=['GET'])
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from rollerverbrauch import app
|
||||
import hashlib
|
||||
|
||||
|
||||
@app.template_filter('none_filter')
|
||||
|
@ -7,3 +8,15 @@ def none_filter(value):
|
|||
return ''
|
||||
else:
|
||||
return value
|
||||
|
||||
|
||||
@app.template_filter('md5')
|
||||
def md5_filter(value):
|
||||
m = hashlib.md5()
|
||||
m.update(str(value).encode('UTF-8'))
|
||||
return m.hexdigest()
|
||||
|
||||
|
||||
@app.template_filter('str')
|
||||
def str_filter(value):
|
||||
return str(value)
|
||||
|
|
|
@ -1 +1,80 @@
|
|||
|
||||
function createChart(id, data, unit) {
|
||||
return AmCharts.makeChart(id, {
|
||||
"type": "serial",
|
||||
//"theme": "chalk",
|
||||
//"marginRight": 40,
|
||||
//"marginLeft": 40,
|
||||
//"autoMarginOffset": 20,
|
||||
"mouseWheelZoomEnabled":true,
|
||||
"dataDateFormat": "YYYY-MM-DD",
|
||||
"valueAxes": [{
|
||||
"id": "v1",
|
||||
"axisAlpha": 0,
|
||||
"position": "left",
|
||||
"ignoreAxisWidth":true,
|
||||
// "title": unit
|
||||
}],
|
||||
"balloon": {
|
||||
"borderThickness": 1,
|
||||
"shadowAlpha": 10,
|
||||
},
|
||||
"graphs": [{
|
||||
"id": "g1",
|
||||
"balloon":{
|
||||
"drop":false,
|
||||
"adjustBorderColor":false,
|
||||
"color":"#ffffff",
|
||||
},
|
||||
"bullet": "round",
|
||||
"bulletBorderAlpha": 1,
|
||||
"bulletColor": "#000000",
|
||||
"bulletSize": 5,
|
||||
"hideBulletsCount": 50,
|
||||
"lineThickness": 2,
|
||||
// "title": unit,
|
||||
//"useLineColorForBulletBorder": true,
|
||||
"valueField": "value",
|
||||
"balloonText": "<span style='font-size:18px;'>[[value]] "+unit+"</span>"
|
||||
}],
|
||||
"chartScrollbar": {
|
||||
"graph": "g1",
|
||||
"oppositeAxis":false,
|
||||
"offset":30,
|
||||
"scrollbarHeight": 80,
|
||||
"backgroundAlpha": 0,
|
||||
"selectedBackgroundAlpha": 0.1,
|
||||
"selectedBackgroundColor": "#888888",
|
||||
"graphFillAlpha": 0,
|
||||
"graphLineAlpha": 0.5,
|
||||
"selectedGraphFillAlpha": 0,
|
||||
"selectedGraphLineAlpha": 1,
|
||||
"autoGridCount":true,
|
||||
"color":"#AAAAAA"
|
||||
},
|
||||
"chartCursor": {
|
||||
"pan": true,
|
||||
"valueLineEnabled": true,
|
||||
"valueLineBalloonEnabled": true,
|
||||
"cursorAlpha":1,
|
||||
"cursorColor":"#258cbb",
|
||||
"limitToGraph":"g1",
|
||||
"valueLineAlpha":0.2,
|
||||
"valueZoomable":true
|
||||
},
|
||||
"valueScrollbar":{
|
||||
"oppositeAxis":false,
|
||||
"offset":50,
|
||||
"scrollbarHeight":10
|
||||
},
|
||||
"categoryField": "date",
|
||||
"categoryAxis": {
|
||||
"parseDates": true,
|
||||
"dashLength": 1,
|
||||
// "minorGridEnabled": true
|
||||
},
|
||||
"export": {
|
||||
"enabled": true
|
||||
},
|
||||
"dataProvider": data
|
||||
});
|
||||
}
|
||||
|
|
|
@ -59,6 +59,31 @@
|
|||
{% endmacro %}
|
||||
|
||||
|
||||
{% macro chartScript(divId, data, unit)%}
|
||||
{% set hash = divId | md5 %}
|
||||
|
||||
data_{{ hash }} = [{% for stop in data %}{
|
||||
"date": "{{stop.date}}",
|
||||
"value": {{stop.value}}
|
||||
}{% if not loop.last %},{%endif%}
|
||||
{% endfor%}
|
||||
]
|
||||
var chart_{{ hash }} = createChart('{{divId}}', data_{{ hash }}, '{{unit}}');
|
||||
|
||||
function zoom_chart_{{ hash }}() {
|
||||
chart_{{ hash }}.zoomToIndexes(
|
||||
chart_{{ hash }}.dataProvider.length - 40,
|
||||
chart_{{ hash }}.dataProvider.length - 1
|
||||
);
|
||||
}
|
||||
|
||||
chart_{{ hash }}.addListener("rendered", zoom_chart_{{ hash }});
|
||||
|
||||
zoom_chart_{{ hash }}()
|
||||
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
<!doctype html>
|
||||
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang=""> <![endif]-->
|
||||
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang=""> <![endif]-->
|
||||
|
@ -94,6 +119,10 @@
|
|||
<!-- Latest compiled and minified JavaScript -->
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='main.css') }}">
|
||||
<script src="https://www.amcharts.com/lib/3/amcharts.js"></script>
|
||||
<script src="https://www.amcharts.com/lib/3/serial.js"></script>
|
||||
<script src="https://www.amcharts.com/lib/3/themes/patterns.js"></script>
|
||||
<script src="{{ url_for('static', filename='main.js') }}"></script>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-inverse navbar-fixed-top">
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
{% block body %}
|
||||
<div id="content">
|
||||
<ul id="tabs" class="nav nav-tabs" data-tabs="tabs">
|
||||
<ul id="vehicle_tabs" class="nav nav-tabs" data-tabs="tabs">
|
||||
{% for vehicle in data %}
|
||||
<li {% if loop.first %}class="active" {%endif %}>
|
||||
<a href="#v{{vehicle.id}}" id="i{{vehicle.id}}" data-toggle="tab">
|
||||
|
@ -11,7 +11,7 @@
|
|||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<div id="my-tab-content" class="tab-content">
|
||||
<div id="vehicle_contetn" class="tab-content">
|
||||
{% for vehicle in data %}
|
||||
<div class="tab-pane {% if loop.first %}active{% endif %}" id="v{{vehicle.id}}">
|
||||
<h3>{{vehicle.name}}</h3>
|
||||
|
@ -43,6 +43,55 @@
|
|||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<ul id="charts_tabs" class="nav nav-tabs" data-tabs="tabs">
|
||||
<li class="active">
|
||||
<a href="#v{{vehicle.id}}_c1" id="i{{vehicle.id}}_c1" data-toggle="tab">
|
||||
Fuelled litres
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#v{{vehicle.id}}_c2" id="i{{vehicle.id}}_c2" data-toggle="tab">
|
||||
Odometer
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#v{{vehicle.id}}_c3" id="i{{vehicle.id}}_c3" data-toggle="tab">
|
||||
Consumption
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div id="my-tab-content" class="tab-content">
|
||||
<div class="tab-pane active" id="v{{vehicle.id}}_c1">
|
||||
{% if vehicle.pitstop_count > 0 %}
|
||||
<div id="fuelledChartDiv{{vehicle.id}}" style="width:100%; height:500px;"></div>
|
||||
<script type="text/javascript">
|
||||
{{ chartScript('fuelledChartDiv'+vehicle.id|str, vehicle.litres, 'l') }}
|
||||
</script>
|
||||
{% else %}
|
||||
not enough data.
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="tab-pane " id="v{{vehicle.id}}_c2">
|
||||
{% if vehicle.pitstop_count > 0 %}
|
||||
<div id="odometerChartDiv{{vehicle.id}}" style="width:100%; height:500px;"></div>
|
||||
<script type="text/javascript">
|
||||
{{ chartScript('odometerChartDiv'+vehicle.id|str, vehicle.odometers, 'km') }}
|
||||
</script>
|
||||
{% else %}
|
||||
not enough data.
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="tab-pane " id="v{{vehicle.id}}_c3">
|
||||
{% if vehicle.pitstop_count > 0 %}
|
||||
<div id="averageUsageDiv{{vehicle.id}}" style="width:100%; height:500px;"></div>
|
||||
<script type="text/javascript">
|
||||
{{ chartScript('averageUsageDiv'+vehicle.id|str, vehicle.average_litres, 'l/100 km') }}
|
||||
</script>
|
||||
{% else %}
|
||||
not enough data.
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
@ -51,7 +100,7 @@
|
|||
|
||||
<script type="text/javascript">
|
||||
jQuery(document).ready(function ($) {
|
||||
$('#tabs').tab();
|
||||
$('#vehicle_tabs').tab();
|
||||
if(window.location.hash != "") {
|
||||
$('a[href="' + window.location.hash + '"]').click()
|
||||
}
|
||||
|
@ -59,4 +108,6 @@
|
|||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -11,14 +11,31 @@ class VehicleStats:
|
|||
self.overall_litres = 0
|
||||
self.average_litres_fuelled = 0
|
||||
self.average_litres_used = 0
|
||||
self.litres = []
|
||||
self.average_litres = []
|
||||
self.odometers = []
|
||||
|
||||
if self.pitstop_count > 0:
|
||||
for pitstop in vehicle.pitstops:
|
||||
self.overall_litres += pitstop.litres
|
||||
self.litres.append(StatsEvent(pitstop.date, pitstop.litres))
|
||||
self.odometers.append(StatsEvent(pitstop.date, pitstop.odometer))
|
||||
self.average_litres_fuelled = self.overall_litres / self.pitstop_count
|
||||
if self.pitstop_count > 1:
|
||||
self.overall_distance = vehicle.pitstops[-1].odometer - vehicle.pitstops[0].odometer
|
||||
self.average_distance = self.overall_distance / (self.pitstop_count - 1)
|
||||
self.average_litres_used = 100 * (self.overall_litres - vehicle.pitstops[0].litres) / self.overall_distance
|
||||
for index in range(1, self.pitstop_count):
|
||||
last_ps = vehicle.pitstops[index - 1]
|
||||
current_ps = vehicle.pitstops[index]
|
||||
self.average_litres.append(StatsEvent(current_ps.date, round(100 * current_ps.litres/(current_ps.odometer - last_ps.odometer),2)))
|
||||
print(index)
|
||||
|
||||
|
||||
class StatsEvent:
|
||||
def __init__(self, date, value):
|
||||
self.date = date
|
||||
self.value = value
|
||||
|
||||
|
||||
def db_log_add(entity):
|
||||
|
|
Loading…
Reference in New Issue