diff --git a/static/moderator.js b/static/moderator.js
index c3309dc26e204cf7b90ea81afcaa1a27d8f71f15..858b5f57d4708a44272801546d04f6aa35c01b25 100644
--- a/static/moderator.js
+++ b/static/moderator.js
@@ -248,3 +248,46 @@ var moderator = {
 };
 
 $( document ).ready( function () {  moderator.init(); } );
+
+$( document ).ready( function () {
+  var l = $(".plot-view");
+  for (var i = 0; i < l.length; i ++) {
+    if (!l[i].id)
+      l[i].id = "plot-"+i;
+		$(l[i]).html('<div class="plot-loader"></div>');
+    $.ajax({
+      divobj: l[i],
+      method: "GET",
+      url: l[i].dataset.url,
+      dataType: "json",
+			error: function (jqXHR, textStatus, errorThrow) {
+				$(this.divobj).html('<div class="plot-error">'+errorThrow+'</div>');
+			},
+      success: function (traces) {
+				var layout = {margin: {l: 30, r: 30, t: 10, b: 70, pad: 0}};
+				for (var i = 0; i < traces.length; i ++) {
+					traces[i].type = this.divobj.dataset.type;
+				}
+				if (this.divobj.dataset.type == "pie")
+					layout.showlegend = false;
+				traces.sort(function (a, b) {
+					asum = 0;
+					bsum = 0;
+					for (var i = 0; i < a.y.length; i++)
+						asum += a.y[i]
+					for (var i = 0; i < b.y.length; i++)
+						bsum += b.y[i]
+					return bsum-asum;
+				});
+				for (var i = 0; i < traces.length; i++)
+					if (i > 20)
+						traces[i].visible = "legendonly";
+				$(this.divobj).html("");
+        Plotly.newPlot(this.divobj.id, traces, layout, { "modeBarButtonsToRemove": ['sendDataToCloud','hoverCompareCartesian'], "displaylogo": false});
+      }
+    });
+  };
+});
+$(window).on("resize", function () {
+	$(".plot-view").each(function () {Plotly.Plots.resize(this)});
+});
diff --git a/static/style.css b/static/style.css
index cc1b3e312d2b0825f614e115c4a892be895a5e96..5b442c6921d0b5cb7d428121ce3b1bdc0b7d5e39 100644
--- a/static/style.css
+++ b/static/style.css
@@ -72,3 +72,49 @@
 		background-color: #f5f5f5;
 	}
 }
+
+.plot-view {
+	height: 600px;
+}
+
+.plot-loader {
+  position: absolute;
+  left: 50%;
+  top: 50%;
+	margin: -75px 0 0 -75px;
+  border: 10px solid #f3f3f3;
+  border-radius: 50%;
+  border-top: 10px solid #3498db;
+  width: 100px;
+  height: 100px;
+  -webkit-animation: spin 1s linear infinite;
+  animation: spin 1s linear infinite;
+}
+
+.plot-error {
+	position: absolute;
+  left: 50%;
+  top: 50%;
+	margin-right: -50%;
+	margin-bottom: -50%;
+	transform: translate(-50%, -50%);
+}
+
+.plot-error {
+
+}
+
+@-webkit-keyframes spin {
+  0% { -webkit-transform: rotate(0deg); }
+  100% { -webkit-transform: rotate(360deg); }
+}
+
+@-webkit-keyframes spin {
+  0% { -webkit-transform: rotate(0deg); }
+  100% { -webkit-transform: rotate(360deg); }
+}
+
+@keyframes spin {
+  0% { transform: rotate(0deg); }
+  100% { transform: rotate(360deg); }
+}
diff --git a/stats.py b/stats.py
index e383645a7b798541a118becf93ce78e1319cdbf5..48c1022df6c61d09b76934334c177458beeb4a21 100644
--- a/stats.py
+++ b/stats.py
@@ -10,12 +10,12 @@ def stats():
 	return render_template('stats.html')
 
 statsqueries = {}
-statsqueries['formats_views'] = "SELECT formats.description AS x, count(DISTINCT log.id) AS y FROM log JOIN videos ON (videos.id = log.video) JOIN formats ON (formats.id = videos.video_format) GROUP BY formats.id"
-statsqueries['course_count'] = "SELECT semester AS x, count(id) AS y FROM courses GROUP BY semester"
-statsqueries['lectures_count'] = "SELECT semester AS x, count(lectures.id) AS y FROM lectures JOIN courses ON (courses.id = lectures.course_id) GROUP BY semester"
-statsqueries['categories_courses'] = "SELECT courses.subject AS x, count(courses.id) AS y FROM courses GROUP BY courses.subject ORDER BY y DESC LIMIT 100"
-statsqueries['organizer_courses'] = "SELECT courses.organizer AS x, count(courses.id) AS y FROM courses GROUP BY courses.organizer ORDER BY y DESC LIMIT 100"
-statsqueries['categories_lectures'] = "SELECT courses.subject AS x, count(lectures.id) AS y FROM lectures JOIN courses ON (courses.id = lectures.course_id) WHERE lectures.visible GROUP BY courses.subject ORDER BY y DESC LIMIT 100"
+statsqueries['formats_views'] = "SELECT formats.description AS labels, count(DISTINCT log.id) AS `values` FROM log JOIN videos ON (videos.id = log.video) JOIN formats ON (formats.id = videos.video_format) GROUP BY formats.id"
+statsqueries['course_count'] = 'SELECT semester AS x, count(id) AS y FROM courses WHERE semester != "" GROUP BY semester'
+statsqueries['lectures_count'] = 'SELECT semester AS x, count(lectures.id) AS y FROM lectures JOIN courses ON (courses.id = lectures.course_id) WHERE semester != "" GROUP BY semester'
+statsqueries['categories_courses'] = "SELECT courses.subject AS labels, count(courses.id) AS `values` FROM courses GROUP BY courses.subject ORDER BY labels DESC LIMIT 100"
+statsqueries['organizer_courses'] = "SELECT courses.organizer AS labels, count(courses.id) AS `values` FROM courses GROUP BY courses.organizer ORDER BY labels DESC LIMIT 100"
+statsqueries['categories_lectures'] = "SELECT courses.subject AS labels, count(lectures.id) AS `values` FROM lectures JOIN courses ON (courses.id = lectures.course_id) WHERE lectures.visible GROUP BY courses.subject ORDER BY `values` DESC LIMIT 100"
 statsqueries['lecture_views'] = "SELECT lectures.time AS x, count(DISTINCT log.id) AS y FROM log JOIN videos ON (videos.id = log.video) JOIN lectures ON (lectures.id = videos.lecture_id) WHERE (lectures.course_id = ?) GROUP BY lectures.id ORDER BY lectures.time"
 
 def plotly_date_handler(obj):
@@ -28,14 +28,15 @@ def stats_generic(req, param=None):
 	if req not in statsqueries:
 		return 404, 'Not found'
 	rows = query(statsqueries[req], *(statsqueries[req].count('?')*[param]))
-	res = {'x':[], 'y':[]}
+	res = {}
 	for row in rows:
-		if row['x'] != '':
-			res['x'].append(row['x'])
-		else:
-			res['x'].append('leer')
-		res['y'].append(row['y'])
-	return Response(json.dumps(res, default=plotly_date_handler),  mimetype='application/json')
+		for key, val in row.items():
+			if key not in res:
+				res[key] = []
+			res[key].append(val)
+	import time
+	time.sleep(10)
+	return Response(json.dumps([res], default=plotly_date_handler),  mimetype='application/json')
 
 @app.route('/stats/viewsperday/<req>')
 @app.route('/stats/viewsperday/<req>/<param>')
@@ -70,12 +71,11 @@ def stats_viewsperday(req, param=""):
 			data[row['date']] = {}
 		data[row['date']][row['trace']] = row['y']
 	end = date.today()
-	x = []
-	y = [{'name': trace, 'vals': []} for trace in traces]
+	res = [{'name': trace, 'x': [], 'y': []} for trace in traces]
 	while start and start <= end:
-		x.append(start)
-		for trace in y:
-			trace['vals'].append(data.get(start, {}).get(trace['name'], 0))
+		for trace in res:
+			trace['x'].append(start)
+			trace['y'].append(data.get(start, {}).get(trace['name'], 0))
 		start += timedelta(days=1)
-	return Response(json.dumps({'times': x, 'views': y}, default=plotly_date_handler),  mimetype='application/json')
+	return Response(json.dumps(res, default=plotly_date_handler),  mimetype='application/json')
 
diff --git a/templates/course.html b/templates/course.html
index 0b02b864137f8d22d7876be65c13388a89bb50ab..ba850fc9c1b35e02f602554d7b15aaecd20058bb 100644
--- a/templates/course.html
+++ b/templates/course.html
@@ -4,7 +4,6 @@
 {% from 'macros.html' import moderator_checkbox %}
 {% from 'macros.html' import preview %}
 {% from 'macros.html' import moderator_permissioneditor %}
-{% from 'macros.html' import stats_viewsperday, stats_generic %}
 
 {% extends "base.html" %}
 {% block title %}- {{course.title}}{% endblock %}
@@ -47,10 +46,8 @@
 				</tbody>
 			</table>
 		</div>
-		<div id="statview" class="col-xs-6" style="height:600px"></div>
-		{{stats_viewsperday("statview", "course", "Abrufer pro Tag", param=course.id)}}
-		<div id="lecture_views" class="col-xs-6" style="height:600px"></div>
-		{{stats_generic("lecture_views", "lecture_views", "Abrufe pro Aufnahme", param=course.id, type="bar")}}
+		<div class="col-xs-6 plot-view" data-url="{{url_for('stats_viewsperday', req="course", param=course.id)}}"></div>
+		<div class="col-xs-6 plot-view" data-type="bar" data-url="{{url_for('stats_generic', req="lecture_views", param=course.id)}}"></div>
 		{% endif %}
 	</div>
 </div>
diff --git a/templates/lecture.html b/templates/lecture.html
index d7705bf32a98c3be61c1a478c8e04cda1a670dd8..d3561fb71fe7fc33952b60436d9e3833dae3339c 100644
--- a/templates/lecture.html
+++ b/templates/lecture.html
@@ -5,7 +5,6 @@
 {% from 'macros.html' import moderator_editor %}
 {% from 'macros.html' import moderator_delete %}
 {% from 'macros.html' import moderator_checkbox %}
-{% from 'macros.html' import stats_viewsperday %}
 {% set page_border = 1 -%}
 
 {% extends "base.html" %}
@@ -59,8 +58,7 @@
 					{% endfor %}
 					</table>
 				</div>
-				<div id="statview" class="col-xs-12" style="height:600px"></div>
-				{{stats_viewsperday("statview", "lecture", "Abrufer pro Tag", param=lecture.id)}}
+				<div class="col-xs-12 plot-view" data-url="{{url_for('stats_viewsperday', req="lecture", param=lecture.id)}}"></div>
 			{% endif %}
 		</div>
 	</div>
diff --git a/templates/macros.html b/templates/macros.html
index a7de6566a945f814e5d51c8f9ac53830d90e1281..87de4e31bdd5d04859a769a5d9d800ef8ff21905 100644
--- a/templates/macros.html
+++ b/templates/macros.html
@@ -305,39 +305,3 @@ $('#embedcodebtn').popover(
 	});
 </script>
 {% endmacro %}
-
-{% macro stats_generic(id, req, title, param=None, type="scatter") %}
-<script>
-	$.ajax({
-		method: "GET",
-		url: "{{url_for('stats_generic', req=req, param=param)}}",
-		dataType: "json",
-		error: moderator.api.handleapierror,
-		success: function (data) {
-			var layout = {
-				"title": "{{title}}",
-				"showlegend": false
-			};
-			Plotly.newPlot("{{id}}", [{"x": data.x, "y": data.y, "type": "{{type}}"}], layout, { "modeBarButtonsToRemove": ['sendDataToCloud','hoverCompareCartesian'], "displaylogo": false});
-		}
-	});
-</script>
-{% endmacro %}
-
-{% macro stats_pie(id, req, title, showlegend=True, param=None) %}
-<script>
-	$.ajax({
-		method: "GET",
-		url: "{{url_for('stats_generic', req=req, param=param)}}",
-		dataType: "json",
-		error: moderator.api.handleapierror,
-		success: function (data) {
-			var layout = {
-				"title": "{{title}}",
-				"showlegend": {% if showledgend %}true{% else %}false{% endif %}
-			};
-			Plotly.newPlot("{{id}}", [{"labels": data.x, "values": data.y, "type": "pie"}], layout, { "modeBarButtonsToRemove": ['sendDataToCloud','hoverCompareCartesian'], "displaylogo": false});
-		}
-	});
-</script>
-{% endmacro %}
diff --git a/templates/stats.html b/templates/stats.html
index eafcd20a26e98009981bea31db7945d3036b6fc0..c7cb96aab7b11b643767610fe6534465afd8ae93 100644
--- a/templates/stats.html
+++ b/templates/stats.html
@@ -1,11 +1,4 @@
-{% from 'macros.html' import stats_viewsperday, stats_generic, stats_pie %}
 {% extends "base.html" %}
-
-{% block header %}
-{{ super() }}
-		<script src="{{url_for('static', filename='plotly.min.js')}}"></script>
-{% endblock %}
-
 {% block content %}
 <div class="panel-group">
 	<div class="panel panel-default">
@@ -14,24 +7,17 @@
 		</div>
 		<div class="panel-body">
 			<div class="row col-xs-12">
-				<div id="course_count" class="col-xs-6" style="height:600px"></div>
-				{{stats_generic("course_count", "course_count", "Veranstaltungen pro Jahr")}}
-				<div id="lectures_count" class="col-xs-6" style="height:600px"></div>
-				{{stats_generic("lectures_count", "lectures_count", "Aufnahmen pro Jahr")}}
-				<div id="formats_views" class="col-xs-6" style="height:600px"></div>
-				{{stats_pie("formats_views", "formats_views", "Formatnutzung")}}
-				<div id="organizer_courses" class="col-xs-6" style="height:600px"></div>
-				{{stats_pie("organizer_courses", "organizer_courses", "Veranstaltungne nach Dozent", showlegend=False)}}
-				<div id="categories_courses" class="col-xs-6" style="height:600px"></div>
-				{{stats_pie("categories_courses", "categories_courses", "Veranstaltungen nach Kategorie", showlegend=False)}}
-				<div id="categories_lectures" class="col-xs-6" style="height:600px"></div>
-				{{stats_pie("categories_lectures", "categories_lectures", "Aufnahmen nach Kategorie", showlegend=False)}}
-				<div id="statview" class="col-xs-12" style="height:600px"></div>
-				{{stats_viewsperday("statview", "global", "Abrufer pro Tag")}}
-				<div id="courseviewsperday" class="col-xs-12" style="height:600px"></div>
-				{{stats_viewsperday("courseviewsperday", "courses", "Abrufer pro Tag")}}
+				<div class="col-xs-12 col-md-6 plot-view" data-url="{{url_for('stats_generic', req="course_count")}}"></div>
+				<div class="col-xs-12 col-md-6 plot-view" data-url="{{url_for('stats_generic', req="lectures_count")}}"></div>
+				<div class="col-xs-12 col-md-6 plot-view" data-type="pie" data-url="{{url_for('stats_generic', req="categories_courses")}}"></div>
+				<div class="col-xs-12 col-md-6 plot-view" data-type="pie" data-url="{{url_for('stats_generic', req="categories_lectures")}}"></div>
+				<!--<div class="col-xs-12 col-md-6 plot-view" data-type="pie" data-url="{{url_for('stats_generic', req="organizer_courses")}}"></div>-->
+				<!--<div class="col-xs-12 col-md-6 plot-view" data-type="pie" data-url="{{url_for('stats_generic', req="formats_views")}}"></div>-->
+				<div class="col-xs-12 plot-view" data-url="{{url_for('stats_viewsperday', req="global")}}"></div>
+				<div class="col-xs-12 plot-view" data-url="{{url_for('stats_viewsperday', req="courses")}}"></div>
 			</div>
-	i	</div>
+		</div>
 	</div>
 </div>
+</script>
 {% endblock %}