Changeset - 51ac306b4e1a
[Not reviewed]
version_5
0 1 5
Dennis Fink - 10 years ago 2015-07-26 00:23:10
dennis.fink@c3l.lu
Added worldmap
6 files changed with 210 insertions and 0 deletions:
0 comments (0 inline, 0 general)
ennstatus/__init__.py
Show inline comments
 
@@ -59,6 +59,9 @@ def create_app():
 
    from .status.views import status_page
 
    app.register_blueprint(status_page, url_prefix='/status')
 

	
 
    from .statistics.views import statistics_page
 
    app.register_blueprint(statistics_page, url_prefix='/stats')
 

	
 
    from .log import init_logging
 
    init_logging(app)
 

	
ennstatus/static/css/map.css
Show inline comments
 
new file 100644
 
.country {
 
	stroke: #000;
 
	stroke-linejoin: round;
 
	stroke-width: 0.1px;
 
}
ennstatus/static/js/worldmap.js
Show inline comments
 
new file 100644
 
d3.select(window).on("resize", throttle);
 
	
 
var zoom = d3.behavior.zoom()
 
	.scaleExtent([1, 9])
 
	.on("zoom", move);
 

	
 
var width = document.getElementById('chart').offsetWidth;
 
var height = width / 2;
 

	
 
var topo, projection, path, svg, g;
 

	
 
var graticule = d3.geo.graticule();
 

	
 
var tooltip = d3.select("#chart").append("div").attr("class", "tooltip hidden");
 

	
 
setup(width, height);
 

	
 
function setup(width, height) {
 
	projection = d3.geo.mercator()
 
		.translate([(width / 2), (height / 2)])
 
		.scale(width / 2 / Math.PI)
 

	
 
	path = d3.geo.path().projection(projection);
 

	
 
	svg = d3.select("#chart").append("svg")
 
		.attr("width", width)
 
		.attr("height", height)
 
		.call(zoom)
 
		.append("g");
 

	
 
	g = svg.append("g")
 
		.on("click", click);
 
}
 

	
 
d3.json("/static/data/world-topo-min.json", function(error, world) {
 
	var countries = topojson.feature(world, world.objects.countries).features;
 

	
 
	topo = countries;
 
	draw(topo);
 
});
 

	
 
function draw(topo) {
 

	
 
	svg.append("path")
 
		.datum(graticule)
 
		.attr("class", "graticule")
 
		.attr("d", path);
 

	
 
	g.append("path")
 
		.datum({type: "LineString", coordinates: [[-180, 0], [-90, 0], [0, 0], [90, 0], [180, 0]]})
 
		.attr("class", "equator")
 
		.attr("d", path);
 

	
 
	var country = g.selectAll(".country").data(topo);
 
	d3.json("/stats/data/worldmap", function(err, data) {
 

	
 

	
 
		var colorscale = d3.scale.threshold().domain([2, 4, 8, 16, 32, 48]).range(["#f2f0f7", "#dadaeb", "#bcbddc", "#9e9ac8", "#756bb1", "#54278f"])
 

	
 
		country.enter().insert("path")
 
			.attr("class", "country")
 
			.attr("d", path)
 
			.attr("id", function(d, i) { return d.id; })
 
			.attr("title", function(d, i) { 
 
				if (d.properties.name in data) {
 
					return "<p>" + d.properties.name + "</p>" + data[d.properties.name];
 
				} else {
 
					return d.properties.name;
 
				}
 
			})
 
			.style("fill", function(d, i) { 
 
				if (d.properties.name in data) {
 
					return colorscale(data[d.properties.name]);
 
				} else {
 
					return "#fdf6e3";
 
				}
 
			});
 

	
 
		var offsetL = document.getElementById('chart').offsetLet+20;
 
		var offsetT = document.getElementById('chart').offsetTop+10;
 

	
 
		country.on("mousemove", function(d, i) {
 
	
 
			var mouse = d3.mouse(svg.node()).map(function(d) { return parseInt(d); });
 

	
 
			tooltip.classed("hidden", false)
 
				.attr("style", "left:"+(mouse[0]+offsetL)+"px;top:"+(mouse[1]+offsetT)+"px")
 
				.html(function(d, i) {
 
					if (d.properties.name in data) {
 
						return d.properties.name + " " + data[d.properties.name];
 
					} else {
 
						return d.properties.name;
 
					}
 
				})
 
		})
 
		.on("mouseout", function(d, i) {
 
			tooltip.classed("hidden", true);
 
		});
 

	
 

	
 
	});
 
};
 

	
 

	
 
function redraw() {
 
  width = document.getElementById('chart').offsetWidth;
 
  height = width / 2;
 
  d3.select('svg').remove();
 
  setup(width,height);
 
  draw(topo);
 
}
 

	
 

	
 
function move() {
 

	
 
  var t = d3.event.translate;
 
  var s = d3.event.scale; 
 
  zscale = s;
 
  var h = height/4;
 

	
 

	
 
  t[0] = Math.min(
 
    (width/height)  * (s - 1), 
 
    Math.max( width * (1 - s), t[0] )
 
  );
 

	
 
  t[1] = Math.min(
 
    h * (s - 1) + h * s, 
 
    Math.max(height  * (1 - s) - h * s, t[1])
 
  );
 

	
 
  zoom.translate(t);
 
  g.attr("transform", "translate(" + t + ")scale(" + s + ")");
 

	
 
  //adjust the country hover stroke width based on zoom level
 
  d3.selectAll(".country").style("stroke-width", 1.5 / s);
 

	
 
}
 

	
 

	
 
var throttleTimer;
 
function throttle() {
 
	  window.clearTimeout(throttleTimer);
 
	      throttleTimer = window.setTimeout(function() {
 
		            redraw();
 
			        }, 200);
 
}
 

	
 
function click() {
 
	  var latlon = projection.invert(d3.mouse(this));
 
	    console.log(latlon);
 
}
ennstatus/statistics/__init__.py
Show inline comments
 
new file 100644
ennstatus/statistics/views.py
Show inline comments
 
new file 100644
 
from collections import defaultdict
 

	
 
from flask import Blueprint, render_template, current_app, jsonify
 

	
 
from ennstatus.status.functions import split_all_servers_to_types
 

	
 
statistics_page = Blueprint('statistics', __name__)
 

	
 

	
 
@statistics_page.route('/worldmap')
 
def worldmap():
 
    return render_template('statistics/worldmap.html')
 

	
 

	
 
@statistics_page.route('/data/worldmap')
 
def data_worldmap():
 
    servers = split_all_servers_to_types()
 
    countries = defaultdict(int)
 

	
 
    for key, value in servers.items():
 
        for server in value:
 
            countries[server['country']] += 1
 

	
 
    maximum = max(countries.values())
 

	
 
    countries['max'] = maximum
 

	
 
    return jsonify(countries)
ennstatus/templates/statistics/worldmap.html
Show inline comments
 
new file 100644
 
{% extends "base.html"%}
 

	
 
{% set title = "index" %}
 

	
 
{% block styles %}
 
  {{ super() }}
 
  <link rel="stylesheet" href="{{ url_for('static', filename='css/map.css') }}" />
 
{% endblock %}
 

	
 
{% block content %}
 
  <div class="col-md-12">
 
    <div id="chart">
 
    </div>
 
  </div>
 
{% endblock %}
 

	
 
{% block scripts %}
 
  {{ super() }}
 
  <script src="{{ url_for('static', filename="js/d3/d3.min.js") }}"></script>
 
  <script src="{{ url_for('static', filename="js/topojson/topojson.js") }}"></script>
 
  <script src="{{ url_for('static', filename="js/worldmap.js") }}"></script>
 
{% endblock %}
0 comments (0 inline, 0 general)