Add registration country pie chart for to present at the meeting, add

meeting stats test, fix a couple of bugs
 - Legacy-Id: 13267
This commit is contained in:
Ole Laursen 2017-05-05 10:33:56 +00:00
parent a2b8819cfe
commit aff12f708a
6 changed files with 106 additions and 10 deletions

View file

@ -14,6 +14,10 @@ $(document).ready(function () {
var chart = Highcharts.chart('chart', window.chartConf);
}
if (window.pieChartConf) {
var pieChart = Highcharts.chart('pie-chart', window.pieChartConf);
}
/*
$(".popover-details").each(function () {
var stdNameRegExp = new RegExp("^(rfc|bcp|fyi|std)[0-9]+$", 'i');

View file

@ -7,7 +7,7 @@ from tastypie.cache import SimpleCache
from ietf import api
from ietf.api import ToOneField # pyflakes:ignore
from ietf.stats.models import CountryAlias, AffiliationIgnoredEnding, AffiliationAlias
from ietf.stats.models import CountryAlias, AffiliationIgnoredEnding, AffiliationAlias, MeetingRegistration
from ietf.name.resources import CountryNameResource
@ -50,3 +50,20 @@ class AffiliationAliasResource(ModelResource):
}
api.stats.register(AffiliationAliasResource())
class MeetingRegistrationResource(ModelResource):
class Meta:
queryset = MeetingRegistration.objects.all()
serializer = api.Serializer()
cache = SimpleCache()
#resource_name = 'meetingregistration'
filtering = {
"id": ALL,
"meeting": ALL_WITH_RELATIONS,
"first_name": ALL,
"last_name": ALL,
"affiliation": ALL,
"country_code": ALL,
"person": ALL_WITH_RELATIONS
}
api.stats.register(MeetingRegistrationResource())

View file

@ -8,15 +8,15 @@ from django.urls import reverse as urlreverse
from ietf.utils.test_data import make_test_data, make_review_data
from ietf.utils.test_utils import login_testing_unauthorized, TestCase, unicontent
from ietf.stats.models import MeetingRegistration
from ietf.stats.utils import get_meeting_registration_data
import ietf.stats.views
from ietf.submit.models import Submission
from ietf.doc.models import Document, DocAlias, State, RelatedDocument, NewRevisionDocEvent
from ietf.meeting.factories import MeetingFactory
from ietf.person.models import Person
from ietf.name.models import FormalLanguageName, DocRelationshipName
from ietf.name.models import FormalLanguageName, DocRelationshipName, CountryName
from ietf.stats.models import MeetingRegistration, CountryAlias
from ietf.stats.utils import get_meeting_registration_data
class StatisticsTests(TestCase):
def test_stats_index(self):
@ -98,6 +98,42 @@ class StatisticsTests(TestCase):
if not stats_type.startswith("yearly"):
self.assertTrue(q('table.stats-data'))
def test_meeting_stats(self):
# create some data for the statistics
make_test_data()
meeting = MeetingFactory(type_id='ietf', date=datetime.date.today(), number="96")
MeetingRegistration.objects.create(first_name='John', last_name='Smith', country_code='US', meeting=meeting)
CountryAlias.objects.get_or_create(alias="US", country=CountryName.objects.get(slug="US"))
MeetingRegistration.objects.create(first_name='Jaume', last_name='Guillaume', country_code='FR', meeting=meeting)
CountryAlias.objects.get_or_create(alias="FR", country=CountryName.objects.get(slug="FR"))
# check redirect
url = urlreverse(ietf.stats.views.meeting_stats)
authors_url = urlreverse(ietf.stats.views.meeting_stats, kwargs={ "stats_type": "overview" })
r = self.client.get(url)
self.assertEqual(r.status_code, 302)
self.assertTrue(authors_url in r["Location"])
# check various stats types
for stats_type in ["overview", "country", "continent"]:
url = urlreverse(ietf.stats.views.meeting_stats, kwargs={ "stats_type": stats_type })
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
q = PyQuery(r.content)
self.assertTrue(q('#chart'))
if stats_type == "overview":
self.assertTrue(q('table.stats-data'))
for stats_type in ["country", "continent"]:
url = urlreverse(ietf.stats.views.meeting_stats, kwargs={ "stats_type": stats_type, "num": meeting.number })
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
q = PyQuery(r.content)
self.assertTrue(q('#chart'))
self.assertTrue(q('table.stats-data'))
def test_known_country_list(self):
make_test_data()

View file

@ -766,6 +766,7 @@ def meeting_stats(request, num=None, stats_type=None):
return HttpResponseRedirect(build_meeting_stats_url(number=num, stats_type_override=possible_stats_types[0][0]))
chart_data = []
piechart_data = []
table_data = []
stats_title = ""
template_name = stats_type
@ -795,7 +796,7 @@ def meeting_stats(request, num=None, stats_type=None):
for r in registrations:
name = (r.first_name + " " + r.last_name).strip()
c = country_mapping.get(r.country_code)
bins[c.name if c else None].add(name)
bins[c.name if c else ""].add(name)
if c and c.in_eu:
bins[eu_name].add(name)
@ -810,8 +811,15 @@ def meeting_stats(request, num=None, stats_type=None):
series_data.append((country, len(names)))
table_data.append((country, percentage, names))
if country and country != eu_name:
piechart_data.append({ "name": country, "y": percentage })
series_data.sort(key=lambda t: t[1], reverse=True)
series_data = series_data[:30]
series_data = series_data[:20]
piechart_data.sort(key=lambda d: d["y"], reverse=True)
pie_cut_off = 8
piechart_data = piechart_data[:pie_cut_off] + [{ "name": "Other", "y": sum(d["y"] for d in piechart_data[pie_cut_off:])}]
chart_data.append({ "data": series_data })
@ -825,7 +833,7 @@ def meeting_stats(request, num=None, stats_type=None):
for r in registrations:
name = (r.first_name + " " + r.last_name).strip()
c = country_mapping.get(r.country_code)
bins[c.continent.name if c else None].add(name)
bins[c.continent.name if c else ""].add(name)
prune_unknown_bin_with_known(bins)
total_registrations = count_bins(bins)
@ -916,6 +924,7 @@ def meeting_stats(request, num=None, stats_type=None):
return render(request, "stats/meeting_stats.html", {
"chart_data": mark_safe(json.dumps(chart_data)),
"piechart_data": mark_safe(json.dumps(piechart_data)),
"table_data": table_data,
"stats_title": stats_title,
"possible_stats_types": possible_stats_types,

View file

@ -74,5 +74,5 @@
<script src="{% static 'highcharts/highcharts.js' %}"></script>
<script src="{% static 'highcharts/modules/exporting.js' %}"></script>
<script src="{% static 'highcharts/modules/offline-exporting.js' %}"></script>
<script src="{% static 'ietf/js/document-stats.js' %}"></script>
<script src="{% static 'ietf/js/stats.js' %}"></script>
{% endblock %}

View file

@ -42,6 +42,36 @@
};
</script>
<div id="pie-chart"></div>
<script>
var pieChartConf = {
chart: {
type: 'pie'
},
plotOptions: {
pie: {
animation: false,
dataLabels: {
enabled: true,
format: "{point.name}: {point.percentage:.1f}%"
},
enableMouseTracking: false
}
},
title: {
text: "Countries at IETF {{ meeting.number }}"
},
tooltip: {
},
series: [ {
name: "Countries",
colorByPoint: true,
data: {{ piechart_data }}
}]
};
</script>
<h3>Data</h3>
<table class="table table-condensed stats-data">
@ -65,5 +95,5 @@
<p>EU (European Union) is not a country, but has been added for reference, as the sum of
all current EU member countries:
{% for c in eu_countries %}{{ c.name }}{% if not forloop.last %}, {% endif %}{% endfor %}.</p>
{% for c in eu_countries %}{{ c.name }}{% if not forloop.last %}, {% endif %}{% endfor %}.
</p>