Skip to content

Commit aff12f7

Browse files
committed
Add registration country pie chart for to present at the meeting, add
meeting stats test, fix a couple of bugs - Legacy-Id: 13267
1 parent a2b8819 commit aff12f7

File tree

6 files changed

+106
-10
lines changed

6 files changed

+106
-10
lines changed

ietf/static/ietf/js/stats.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ $(document).ready(function () {
1414

1515
var chart = Highcharts.chart('chart', window.chartConf);
1616
}
17+
18+
if (window.pieChartConf) {
19+
var pieChart = Highcharts.chart('pie-chart', window.pieChartConf);
20+
}
1721
/*
1822
$(".popover-details").each(function () {
1923
var stdNameRegExp = new RegExp("^(rfc|bcp|fyi|std)[0-9]+$", 'i');

ietf/stats/resources.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from ietf import api
88
from ietf.api import ToOneField # pyflakes:ignore
99

10-
from ietf.stats.models import CountryAlias, AffiliationIgnoredEnding, AffiliationAlias
10+
from ietf.stats.models import CountryAlias, AffiliationIgnoredEnding, AffiliationAlias, MeetingRegistration
1111

1212

1313
from ietf.name.resources import CountryNameResource
@@ -50,3 +50,20 @@ class Meta:
5050
}
5151
api.stats.register(AffiliationAliasResource())
5252

53+
class MeetingRegistrationResource(ModelResource):
54+
class Meta:
55+
queryset = MeetingRegistration.objects.all()
56+
serializer = api.Serializer()
57+
cache = SimpleCache()
58+
#resource_name = 'meetingregistration'
59+
filtering = {
60+
"id": ALL,
61+
"meeting": ALL_WITH_RELATIONS,
62+
"first_name": ALL,
63+
"last_name": ALL,
64+
"affiliation": ALL,
65+
"country_code": ALL,
66+
"person": ALL_WITH_RELATIONS
67+
}
68+
api.stats.register(MeetingRegistrationResource())
69+

ietf/stats/tests.py

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88

99
from ietf.utils.test_data import make_test_data, make_review_data
1010
from ietf.utils.test_utils import login_testing_unauthorized, TestCase, unicontent
11-
from ietf.stats.models import MeetingRegistration
12-
from ietf.stats.utils import get_meeting_registration_data
1311
import ietf.stats.views
1412

1513
from ietf.submit.models import Submission
1614
from ietf.doc.models import Document, DocAlias, State, RelatedDocument, NewRevisionDocEvent
1715
from ietf.meeting.factories import MeetingFactory
1816
from ietf.person.models import Person
19-
from ietf.name.models import FormalLanguageName, DocRelationshipName
17+
from ietf.name.models import FormalLanguageName, DocRelationshipName, CountryName
18+
from ietf.stats.models import MeetingRegistration, CountryAlias
19+
from ietf.stats.utils import get_meeting_registration_data
2020

2121
class StatisticsTests(TestCase):
2222
def test_stats_index(self):
@@ -98,6 +98,42 @@ def test_document_stats(self):
9898
if not stats_type.startswith("yearly"):
9999
self.assertTrue(q('table.stats-data'))
100100

101+
def test_meeting_stats(self):
102+
# create some data for the statistics
103+
make_test_data()
104+
meeting = MeetingFactory(type_id='ietf', date=datetime.date.today(), number="96")
105+
MeetingRegistration.objects.create(first_name='John', last_name='Smith', country_code='US', meeting=meeting)
106+
CountryAlias.objects.get_or_create(alias="US", country=CountryName.objects.get(slug="US"))
107+
MeetingRegistration.objects.create(first_name='Jaume', last_name='Guillaume', country_code='FR', meeting=meeting)
108+
CountryAlias.objects.get_or_create(alias="FR", country=CountryName.objects.get(slug="FR"))
109+
110+
# check redirect
111+
url = urlreverse(ietf.stats.views.meeting_stats)
112+
113+
authors_url = urlreverse(ietf.stats.views.meeting_stats, kwargs={ "stats_type": "overview" })
114+
115+
r = self.client.get(url)
116+
self.assertEqual(r.status_code, 302)
117+
self.assertTrue(authors_url in r["Location"])
118+
119+
# check various stats types
120+
for stats_type in ["overview", "country", "continent"]:
121+
url = urlreverse(ietf.stats.views.meeting_stats, kwargs={ "stats_type": stats_type })
122+
r = self.client.get(url)
123+
self.assertEqual(r.status_code, 200)
124+
q = PyQuery(r.content)
125+
self.assertTrue(q('#chart'))
126+
if stats_type == "overview":
127+
self.assertTrue(q('table.stats-data'))
128+
129+
for stats_type in ["country", "continent"]:
130+
url = urlreverse(ietf.stats.views.meeting_stats, kwargs={ "stats_type": stats_type, "num": meeting.number })
131+
r = self.client.get(url)
132+
self.assertEqual(r.status_code, 200)
133+
q = PyQuery(r.content)
134+
self.assertTrue(q('#chart'))
135+
self.assertTrue(q('table.stats-data'))
136+
101137
def test_known_country_list(self):
102138
make_test_data()
103139

ietf/stats/views.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,7 @@ def build_meeting_stats_url(number=None, stats_type_override=Ellipsis, get_overr
766766
return HttpResponseRedirect(build_meeting_stats_url(number=num, stats_type_override=possible_stats_types[0][0]))
767767

768768
chart_data = []
769+
piechart_data = []
769770
table_data = []
770771
stats_title = ""
771772
template_name = stats_type
@@ -795,7 +796,7 @@ def get_country_mapping(registrations):
795796
for r in registrations:
796797
name = (r.first_name + " " + r.last_name).strip()
797798
c = country_mapping.get(r.country_code)
798-
bins[c.name if c else None].add(name)
799+
bins[c.name if c else ""].add(name)
799800

800801
if c and c.in_eu:
801802
bins[eu_name].add(name)
@@ -810,8 +811,15 @@ def get_country_mapping(registrations):
810811
series_data.append((country, len(names)))
811812
table_data.append((country, percentage, names))
812813

814+
if country and country != eu_name:
815+
piechart_data.append({ "name": country, "y": percentage })
816+
813817
series_data.sort(key=lambda t: t[1], reverse=True)
814-
series_data = series_data[:30]
818+
series_data = series_data[:20]
819+
820+
piechart_data.sort(key=lambda d: d["y"], reverse=True)
821+
pie_cut_off = 8
822+
piechart_data = piechart_data[:pie_cut_off] + [{ "name": "Other", "y": sum(d["y"] for d in piechart_data[pie_cut_off:])}]
815823

816824
chart_data.append({ "data": series_data })
817825

@@ -825,7 +833,7 @@ def get_country_mapping(registrations):
825833
for r in registrations:
826834
name = (r.first_name + " " + r.last_name).strip()
827835
c = country_mapping.get(r.country_code)
828-
bins[c.continent.name if c else None].add(name)
836+
bins[c.continent.name if c else ""].add(name)
829837

830838
prune_unknown_bin_with_known(bins)
831839
total_registrations = count_bins(bins)
@@ -916,6 +924,7 @@ def get_country_mapping(registrations):
916924

917925
return render(request, "stats/meeting_stats.html", {
918926
"chart_data": mark_safe(json.dumps(chart_data)),
927+
"piechart_data": mark_safe(json.dumps(piechart_data)),
919928
"table_data": table_data,
920929
"stats_title": stats_title,
921930
"possible_stats_types": possible_stats_types,

ietf/templates/stats/document_stats.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,5 +74,5 @@ <h5>Options</h5>
7474
<script src="{% static 'highcharts/highcharts.js' %}"></script>
7575
<script src="{% static 'highcharts/modules/exporting.js' %}"></script>
7676
<script src="{% static 'highcharts/modules/offline-exporting.js' %}"></script>
77-
<script src="{% static 'ietf/js/document-stats.js' %}"></script>
77+
<script src="{% static 'ietf/js/stats.js' %}"></script>
7878
{% endblock %}

ietf/templates/stats/meeting_stats_country.html

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,36 @@ <h3>{{ stats_title }}</h3>
4242
};
4343
</script>
4444

45+
<div id="pie-chart"></div>
46+
47+
<script>
48+
var pieChartConf = {
49+
chart: {
50+
type: 'pie'
51+
},
52+
plotOptions: {
53+
pie: {
54+
animation: false,
55+
dataLabels: {
56+
enabled: true,
57+
format: "{point.name}: {point.percentage:.1f}%"
58+
},
59+
enableMouseTracking: false
60+
}
61+
},
62+
title: {
63+
text: "Countries at IETF {{ meeting.number }}"
64+
},
65+
tooltip: {
66+
},
67+
series: [ {
68+
name: "Countries",
69+
colorByPoint: true,
70+
data: {{ piechart_data }}
71+
}]
72+
};
73+
</script>
74+
4575
<h3>Data</h3>
4676

4777
<table class="table table-condensed stats-data">
@@ -65,5 +95,5 @@ <h3>Data</h3>
6595

6696
<p>EU (European Union) is not a country, but has been added for reference, as the sum of
6797
all current EU member countries:
68-
{% for c in eu_countries %}{{ c.name }}{% if not forloop.last %}, {% endif %}{% endfor %}.</p>
69-
98+
{% for c in eu_countries %}{{ c.name }}{% if not forloop.last %}, {% endif %}{% endfor %}.
99+
</p>

0 commit comments

Comments
 (0)