Skip to content

Instantly share code, notes, and snippets.

@BMPMS
Last active December 14, 2016 15:21
Show Gist options
  • Save BMPMS/32cfa44714206cf7c79bb5d1e60657bc to your computer and use it in GitHub Desktop.
Save BMPMS/32cfa44714206cf7c79bb5d1e60657bc to your computer and use it in GitHub Desktop.
PISA Visualisation

Objective: Visualise the PISA 2012 summary data in the best possible way.

Description: Data Analyst Nanodegree assignment. The PISA survey gathers a huge amount of data which you could devote a lifetime to analysing.

Data: My visualisation is an attempt to improve on the official key findings snapshot that can be found here (http://www.oecd.org/pisa/keyfindings/PISA-2012-results-snapshot-Volume-I-ENG.pdf). The data I used was a combination from three spreadsheets provided by PISA: summary data (http://dx.doi.org/10.1787/888932937035), reading additional data academic level (http://dx.doi.org/10.1787/888932935705) and science additional data academic level (http://dx.doi.org/10.1787/888932935724).

Process:

  1. Download, clean and reformat data using pisa_map.py, final formatted data in pisa_map_data.csv
  2. Download world_countries.json and check that the country names match those in my data
  3. Javascript and d3 code in index.html and pop_up.html.
  4. Basic Martini Glass process:
  • draw() - draws the svg map
  • start_animation() - loads the data and runs the animation
  • after_animation() - adds instruction boxes and sets page up for user interaction

Enjoy!

<!DOCTYPE html>
<html>
<title>PISA 2012 Visualisation</title>
<link rel="stylesheet" type="text/css" href="pisa.css" media="screen" />
<head>
<meta charset="utf-8">
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="pisa.js"></script>
</head>
<body>
<table id='maint' width='100%' cellspacing="0" cellpadding="0" style='table-layout: fixed'>
<tr id='title'>
<td colspan='11' >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PISA 2010 Educational Survey: How does the world compare?</td>
<td colspan='1' style='color:white; font-size:14px; text-align: right;'><span id='skip'>Skip Intro</span>&nbsp;&nbsp;</td>
</tr>
<tr id='subjects'>
<td colspan='4' id='maths'>MATHS</td>
<td colspan='4' id='reading'>READING</td>
<td colspan='4' id='science'>SCIENCE</td>
</tr>
<tr id='categories'>
<td colspan='3' id='ranking'>ranking</td>
<td colspan='3' id='low'>low achievers</td>
<td colspan='3' id='high'>top performers</td>
<td colspan='3' id='progress'>progress</td>
</tr>
<tr><td colspan='12' id='map'></td></tr>
<tr id='catexp'><td colspan='12'><br>
<b>ranking:</b> from 1st to last based on the average test score for the given subject<br>
<b>top performers:</b> higher than average % of pupils performing at top levels (5 and 6).<br>
<b>low achievers:</b> higher than average % of pupils performing at low levels (below 2)<br>
<b>progress:</b> higher average score than previous years</td></tr>
<tr id='exp'><td colspan='12'><br>The PISA survey (https://www.oecd.org/pisa/) has run every 3 years since 2000 assessing students between 15 years 3 months and 16 years 2 months. The complete survey includes 7 hours of test material, each student takes a different 2 hour combination of these tests. Cyprus and Vietnam have not been included as they had incomplete data.
<br><br></td></tr>
</table>
<script type="text/javascript">
/*
Use D3 to load the GeoJSON file
*/
d3.json("new_world_countries.json", draw);
</script>
</body>
</html>
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
#title{
text-align: center;
font: normal normal normal 24px/1 Helvetica, arial, sans-serif;
color:black;
background-color: lightgrey;
height: 45px;
margin: 0;
width: 100%;
}
#subjects{
text-align: center;
font: normal normal normal 24px/1 Helvetica, arial, sans-serif;
color:white;
height: 45px;
margin: 0;
width: 100%;
}
#categories{
text-align: center;
font: normal normal normal 24px/1 Helvetica, arial, sans-serif;
color:black;
border-style: solid;
border
border-color: grey;
height: 45px;
margin: 0.5;
width: 100%;
border-collapse: collapse;
}
#ranking,#high,#low,#progress{
border-color: grey;
border-style: solid;
border-width: thin;
}
#maths{
background-color: blue;
}
#skip{
color: blue;
}
#reading{
background-color: red;
}
#science{
background-color: green;
}
#catexp{
text-align: center;
font: normal normal normal 12px/1 Helvetica, arial, sans-serif;
color:black;
background-color: lightgrey;
}
#exp{
text-align: center;
font: normal normal normal 10px/1 Helvetica, arial, sans-serif;
color:black;
background-color: lightgrey;
}
body{
text-align: center;
background-color: white;
}
select{
font: normal normal normal 14px/1 Helvetica, arial, sans-serif;
}
svg{
text-align: center;
background-color: white;
}
function draw(geo_data) {
//country and subject ranking arrays (populated from data)
var countries = [];
var mathsranks = {};
var readingranks = {};
var scienceranks = {};
function openPopup (d) {
var cindex = countries.indexOf(d.properties.name)
if(cindex !== -1) {
var left = (screen.width/2)-(800/2);
var top = (screen.height/2)-(600/2);
specs = 'toolbar=no, location=no, directories=no, status=no, menubar=no,'
specs = specs + ' scrollbars=no, resizable=no, copyhistory=no, width=700, '
specs = specs + 'height=530, top='+top+', left='+left
url = 'popup.html?country=' + d.properties.name
title = 'PISA statistics for ' + d.properties.name
window.open(url, title, specs);
}
}
//draw svg, projection and world map
var svg = d3.select("#map")
.append("svg")
.attr("width", 1000)
.attr("height", 430)
.append('g')
.attr('class', 'map');
var projection = d3.geo.mercator()
.scale(170)
.translate([1000 / 2.4, 430 / 1.6]);
var path = d3.geo.path().projection(projection);
var map = svg.selectAll('path')
.data(geo_data.features)
.enter()
.append('path')
.attr('d', path)
.attr('class','feature')
.style('fill', 'white')
.style('stroke', 'grey')
.style('stroke-width', 0.5)
.on('click',openPopup);
start_animation()
function plot_points(data) {
//variables used by change_map function
var subject = '';
var category = '';
var colour = 'white';
//build countries and subject rankings arrays from data.
data.forEach(function(d) {
countries.push(d['country']);
mathsranks[d['maths_ranking']] = d['country'];
readingranks[d['reading_ranking']] = d['country'];
scienceranks[d['science_ranking']] = d['country'];
});
//sets all countries to grey or white depending on whether part
function blank(d) {
var cindex = countries.indexOf(d.properties.name)
if(cindex !== -1) {
return 'lightGrey';
} else {
return 'white';
}
}
function getcountry(d){
//used change_map function to label individual countries
var cindex = countries.indexOf(d.properties.name)
if(cindex !== -1) {
return d.properties.name;
} else {
return '';
}
}
function progress(cindex, fieldname){
//progress category - colours country correctly according to subject if on the list
if (data[cindex][fieldname] > 0){
return colours[subject];
} else {
return 'lightGrey';
}
}
function highlow(cindex, fieldname){
//high or low performance categories - colours country correctly according to subject if on the list
if (data[cindex][fieldname] == 'True'){
return colours[subject];
} else {
return 'lightGrey';
}
}
function ranking(cindex, fieldname){
//ranking category - colours and gradients countries correctly according to subject if on the list
var new_colour = d3.scale.linear()
.domain([1, 59])
.range([colour, "white"]);
return new_colour(data[cindex][fieldname]);
}
function fill_colour(d){
//returns appropriate fill colour using functions above if necessary
var cindex = countries.indexOf(d.properties.name)
var fieldname = subject + '_' + category
if( cindex !== -1) {
if (category == 'ranking') {
return ranking(cindex,fieldname)
}
if (category == 'low'){
return highlow(cindex,fieldname)
}
if (category == 'high'){
return highlow(cindex,fieldname)
}
if (category == 'progress'){
return progress(cindex,fieldname)
} else {
return 'white';
}
} else {
return 'white';
}
}
var subjects =['maths','reading','science'];
var categories =['ranking','high','low','progress'];
var colours = {maths:"blue", reading:"red",science:"green"};
function choose_subject(subject){
// highlights the subject just selected and sets others to background color grey
if (subject != ''){
substr = '#' + subject
d3.select(substr)
.style('background-color', colours[subject]);
}
for (s in subjects) {
substr = '#' + subjects[s]
if (subjects[s] != subject){
d3.select(substr)
.style('background-color', 'grey');
}
}
}
function choose_category(category){
// highlights the category just selected and sets others to background color grey
if (category != ''){
substr = '#' + category
d3.select(substr)
.style('background-color', 'yellow');
}
for (c in categories) {
substr = '#' + categories[c]
if (categories[c] != category){
d3.select(substr)
.style('background-color', 'white');
}
}
}
function change_map(new_subject, new_category){
// changes the map, either on request or as part of the animation
choose_subject(new_subject)
choose_category(new_category)
subject = new_subject
category = new_category
colour = colours[subject]
svg.selectAll('path')
.style('fill', fill_colour)
.append("svg:title")
.text(getcountry);
}
function update(loopint) {
//animation loop
if(loopint==1){
change_map('reading','ranking')
}
if(loopint==2){
change_map('science','ranking')
}
if(loopint==3){
change_map('maths','low')
}
if(loopint==4){
change_map('reading','low')
}
if(loopint==5){
change_map('science','low')
}
if(loopint==6){
change_map('maths','high')
}
if(loopint==7){
change_map('reading','high')
}
if(loopint==8){
change_map('science','high')
}
if (loopint==9){
change_map('maths','progress')
}
if (loopint==10){
change_map('reading','progress')
}
if (loopint==11){
change_map('science','progress')
}
if(loopint>11){
clearInterval(subj_interval);
after_animation()
}
}
function skipit(){
//called by Skip Intro button.
clearInterval(subj_interval);
after_animation()
d3.select('#skip')
.style('visibility','hidden')
}
d3.select('#skip')
.on('click',function(){skipit()})
change_map('maths', 'ranking')
var loopint = 1;
var subj_interval = setInterval(function() {
update(loopint);
loopint++;
},2500)
function add_instructions(){
//add instructions after animation has run its course
x = document.getElementById("maint").offsetWidth
x = (x - 600)/2
svg.append('rect').transition().duration(500).attr('width', 600)
.attr('height', 135)
.attr('x', x)
.attr('y', 50)
.style('fill', 'lightYellow')
.attr('stroke', 'black')
svg.append('rect').transition().duration(500).attr('width', 420)
.attr('height', 50)
.attr('x', x+90)
.attr('y', 210)
.style('fill', 'MistyRose')
.attr('stroke', 'black')
svg.selectAll('rect').on('click',function(){hide_instructions()})
var msg = []
msg.push("There are 9 consistent high performers: China, South Korea, Japan, Singapore,")
msg.push('Australia, New Zealand, Finland, Canada and Leichtenstein. Six of which are ')
msg.push('in the top 10: China, South Korea, Japan, Singapore, Finland and Leichtenstein.')
msg.push(' ')
msg.push('The UK is around average on all subjects but this is only 3% off low achievement.')
msg.push('Why are we doing so badly, particularly against our peers in Europe?')
msg.push(' ')
msg.push(' ')
msg.push('Click on SUBJECT + CATEGORY to see the map again.')
msg.push('Click on a COUNTRY for more detailed statistics.')
y = 70
for (m in msg){
svg.append('text').text(msg[m])
.attr('x', x+10)
.attr('y', y)
.style("font-size","16px")
.style('font-family','Helvetica, arial, sans-serif')
.style('text-align','center')
.attr('fill', 'black')
y = y + 20;
if (m == 7){
x = x + 90
}
}
svg.selectAll('text').on('click',function(){hide_instructions()})
}
function hide_instructions(){
svg.selectAll('rect').style('visibility','hidden')
svg.selectAll('text').style('visibility','hidden')
}
function after_animation(){
//make all subjects, categories and map blank
choose_subject('')
choose_category('')
svg.selectAll('path')
.style('fill', blank)
.append("svg:title")
.text(getcountry);
add_instructions()
//set up subject and category buttons
d3.select('#maths')
.on('click',function(){subject_click('maths')})
d3.select('#reading')
.on('click',function(){subject_click('reading')})
d3.select('#science')
.on('click',function(){subject_click('science')})
d3.select('#low')
.on('click',function(){category_click('low')})
d3.select('#high')
.on('click',function(){category_click('high')})
d3.select('#ranking')
.on('click',function(){category_click('ranking')})
d3.select('#progress')
.on('click',function(){category_click('progress')})
var subjectvalue= "";
var categoryvalue = "";
function subject_click(subject){
hide_instructions()
choose_subject(subject)
subjectvalue = subject
if (categoryvalue != ""){
change_map(subjectvalue,categoryvalue)
}
}
function category_click(category){
hide_instructions()
choose_category(category)
categoryvalue= category
if (subjectvalue != ""){
change_map(subjectvalue,categoryvalue)
}
}
};
};
function start_animation(){
d3.csv("pisa_map_data.csv", function(d) {
d['maths_meanscore'] = +d['maths_meanscore'] ;
d['maths_lowperform'] = +d['maths_lowperform'] ;
d['maths_highperform'] = +d['maths_highperform'] ;
d['maths_progress'] = +d['maths_progress'] ;
d['maths_ranking'] = +d['maths_ranking'] ;
d['reading_meanscore'] = +d['reading_meanscore'] ;
d['reading_lowperform'] = +d['reading_lowperform'] ;
d['reading_highperform'] = +d['reading_highperform'] ;
d['reading_progress'] = +d['reading_progress'] ;
d['reading_ranking'] = +d['reading_ranking'] ;
d['science_meanscore'] = +d['science_meanscore'] ;
d['science_lowperform'] = +d['science_lowperform'] ;
d['science_highperform'] = +d['science_highperform'] ;
d['science_progress'] = +d['science_progress'] ;
d['science_ranking'] = +d['science_ranking'] ;
return d;
}, plot_points);
}
};
import pandas as pd
import numpy as np
filename = 'pisa_data.csv'
mypisa = pd.DataFrame()
joinpisa = {}
countrylist = ['Chinese Taipei','Hong Kong-China','Macao-China','Shanghai-China']
chinalist = ['Chinese Taipei','Hong Kong-China','Macao-China','Shanghai-China']
x = 0
mypisa = pd.read_csv(filename)
mypisa['maths_progress'] = mypisa['maths_progress'].astype(float)
mypisa['country'] = mypisa['country'].astype(str)
for index,row in mypisa.iterrows():
if row.country in countrylist:
joinpisa[row.country] = np.array(row)
def buildarrays(clist,joinpisa,newname):
count = len(clist)
x=0
newval = 0
mylist = []
mylist.append(str(newname))
for i in range(1,13):
while x < count:
newval = newval + float(joinpisa[clist[x]][i])
x = x + 1
if i == 1 or i == 5 or i == 9:
mylist.append(int(newval/count))
else:
mylist.append(float(newval/count))
x = 0
newval = 0
return mylist
newchina = buildarrays(chinalist,joinpisa,'China')
for c in chinalist:
mypisa = mypisa[mypisa.country != c]
mypisa.loc[len(mypisa)] = newchina
mypisa['overall_meanscore'] = mypisa[["maths_meanscore", "reading_meanscore",'science_meanscore']].mean(axis=1)
def ranking(pisa, subject):
ranking = subject + '_ranking'
meanscore = subject + '_meanscore'
x = 1
print(pisa.head())
pisa[ranking]=0
pisa.sort_values(meanscore,inplace=True,ascending=False)
for index,row in pisa.iterrows():
pisa.set_value(index,ranking,x)
x = x + 1
return pisa
mypisa = ranking(mypisa,'maths')
mypisa = ranking(mypisa,'reading')
mypisa = ranking(mypisa,'science')
mypisa = ranking(mypisa,'overall')
print(mypisa.head(15))
def performance(pisa,subject):
low_colname = subject + '_lowperform'
high_colname = subject + '_highperform'
low_name = subject + '_low'
high_name = subject + '_high'
for index,row in mypisa.iterrows():
if row.country =='OECD average':
oecd_low = row[low_colname]
oecd_high = row[high_colname]
pisa[low_name] = False
pisa[high_name] = False
for index,row in mypisa.iterrows():
print(row[low_colname],oecd_low)
if row[low_colname] > oecd_low:
pisa.set_value(index,low_name,True)
if row[high_colname] > oecd_high:
pisa.set_value(index,high_name,True)
return pisa
mypisa = performance(mypisa,'maths')
mypisa = performance(mypisa,'reading')
mypisa = performance(mypisa,'science')
mypisa = mypisa[mypisa.country != 'OECD average']
print(mypisa.head())
mypisa.to_csv('pisa_map_data.csv')
country maths_meanscore maths_lowperform maths_highperform maths_progress reading_meanscore reading_lowperform reading_highperform reading_progress science_meanscore science_progress science_lowperform science_highperform overall_meanscore maths_ranking reading_ranking science_ranking overall_ranking maths_low maths_high reading_low reading_high science_low science_high
51 Singapore 573 8.3 40.0 3.8 542 9.9 21.2 5.4 551 3.3 9.6 22.7 555.3333333333334 1 1 1 1 False True False True False True
60 China 568 8.975 37.65 2.05 536 8.175 15.175 3.05 544 1.0 6.7250000000000005 14.725 549.3333333333334 2 4 4 2 False True False True False True
30 South Korea 554 9.1 30.9 1.1 536 7.6 14.1 0.9 538 2.6 6.6 11.7 542.6666666666666 3 3 6 3 False True False True False True
27 Japan 536 11.1 23.7 0.4 538 9.8 18.5 1.5 547 2.6 8.5 18.2 540.3333333333334 4 2 2 4 False True False True False True
16 Finland 519 12.3 15.3 -2.8 524 11.3 13.5 -1.7 545 -3.0 7.7 17.1 529.3333333333334 9 5 3 5 False True False True False True
15 Estonia 521 10.5 14.6 0.9 516 9.1 8.3 2.4 541 1.5 5.0 12.8 526.0 8 10 5 6 False True False False False True
32 Liechtenstein 535 14.1 24.8 0.3 516 12.4 10.9 1.3 525 0.4 10.4 10.1 525.3333333333334 5 9 9 7 False True False True False True
7 Canada 518 13.8 16.4 -1.4 523 10.9 12.9 -0.9 525 -1.5 10.4 11.3 522.0 11 6 8 8 False True False True False True
44 Poland 518 14.4 16.7 2.6 518 10.6 10.0 2.8 526 4.6 9.0 10.8 520.6666666666666 10 8 7 9 False True False True False True
39 Netherlands 523 14.8 19.3 -1.6 511 14.0 9.8 -0.1 522 -0.5 13.1 11.8 518.6666666666666 7 13 12 10 False True False True False True
56 Switzerland 531 12.4 21.4 0.6 509 13.7 9.1 1.0 515 0.6 12.8 9.3 518.3333333333334 6 15 15 11 False True False True False True
18 Germany 514 17.7 17.5 1.4 508 14.5 8.9 1.8 524 1.4 12.2 12.2 515.3333333333334 13 16 10 12 False True False True False True
24 Ireland 501 16.9 10.7 -0.6 523 9.6 11.4 -0.9 522 2.3 11.1 10.7 515.3333333333334 17 7 11 13 False False False True False True
2 Australia 504 19.7 14.8 -2.2 512 14.2 11.7 -1.4 521 -0.9 13.6 13.6 512.3333333333334 15 11 13 14 False True False True False True
4 Belgium 515 18.9 19.4 -1.6 509 16.1 11.8 0.1 505 -0.8 17.7 9.1 509.6666666666667 12 14 20 15 False True False True False True
40 New Zealand 500 22.6 15.0 -2.5 512 16.3 14.0 -1.1 516 -2.5 16.3 13.4 509.3333333333333 19 12 14 16 False True False True False True
61 United Kingdom 494 21.8 11.8 -0.3 499 16.6 8.8 0.7 514 -0.1 15.0 11.2 502.3333333333333 23 19 17 17 False False False True False True
3 Austria 506 18.7 14.3 -0.0 490 19.5 5.5 -0.2 506 -0.8 15.8 7.9 500.6666666666667 14 25 19 18 False True True False False False
13 Czech Republic 499 21.0 12.9 -2.5 493 16.9 6.1 -0.5 508 -1.0 13.8 7.6 500.0 20 23 18 19 False True False False False False
17 France 495 22.4 12.9 -1.5 505 18.9 12.9 0.0 499 0.6 18.7 7.9 499.6666666666667 21 17 23 20 False True True True True False
53 Slovenia 501 20.1 13.7 -0.6 481 21.1 5.0 -2.2 514 -0.8 12.9 9.6 498.6666666666667 16 35 16 21 False True True False False True
14 Denmark 500 16.8 10.0 -1.8 496 14.6 5.4 0.1 498 0.4 16.7 6.8 498.0 18 21 24 22 False False False False False False
41 Norway 489 22.3 9.4 -0.3 504 16.2 10.2 0.1 495 1.3 19.6 7.5 496.0 27 18 28 24 False False False True True False
31 Latvia 491 19.9 8.0 0.5 489 17.0 4.2 1.9 502 2.0 12.4 4.4 494.0 25 26 21 25 False False False False False False
62 United States 481 25.8 8.8 0.3 498 16.6 7.9 -0.3 497 1.4 18.1 7.5 492.0 33 20 25 26 True False False False True False
26 Italy 485 24.7 9.9 2.7 490 19.5 6.7 0.5 494 3.0 18.7 6.1 489.6666666666667 29 24 29 27 True False True False True False
34 Luxembourg 490 24.3 11.2 -0.3 488 22.2 8.9 0.7 491 0.9 22.2 8.2 489.6666666666667 26 27 31 28 True False True True True False
54 Spain 484 23.6 8.0 0.1 488 18.3 5.5 -0.3 496 1.3 15.7 4.8 489.3333333333333 30 29 27 29 True False True False False False
45 Portugal 487 24.9 10.6 2.8 488 18.8 5.8 1.6 489 2.5 19.0 4.5 488.0 28 28 33 30 True False True False True False
21 Hungary 477 28.1 9.3 -1.3 488 19.7 5.6 1.0 494 -1.6 18.0 5.9 486.3333333333333 36 30 30 31 True False True False True False
22 Iceland 493 21.5 11.2 -2.2 483 21.0 5.8 -1.3 478 -2.0 24.0 5.2 484.6666666666667 24 33 36 32 False False True False True False
33 Lithuania 479 26.0 8.1 -1.4 477 21.2 3.3 1.1 496 1.3 16.1 5.1 484.0 34 36 26 33 True False True False False False
12 Croatia 471 29.9 7.0 0.6 485 18.7 4.4 1.2 491 -0.3 17.3 4.6 482.3333333333333 37 32 32 34 True False True False False False
55 Sweden 478 27.1 8.0 -3.3 483 22.7 7.9 -2.8 485 -3.1 22.2 6.3 482.0 35 34 35 35 True False True False True False
48 Russia 482 24.0 7.8 1.1 475 22.3 4.6 1.1 486 1.0 18.8 4.3 481.0 32 39 34 36 True False True False True False
25 Israel 466 33.5 9.4 4.2 486 23.6 9.6 3.7 470 2.8 28.9 5.8 474.0 38 31 38 37 True False True True True False
52 Slovak Republic 482 27.5 11.0 -1.4 463 28.2 4.4 -0.1 471 -2.7 26.9 4.9 472.0 31 40 37 38 True False True False True False
19 Greece 453 35.7 3.9 1.1 477 22.6 5.1 0.5 467 -1.1 25.5 2.5 465.6666666666667 39 37 39 39 True False True False True False
59 Turkey 448 42.0 5.9 3.2 475 21.6 4.3 4.1 463 6.4 26.4 1.8 462.0 41 38 40 40 True False True False True False
49 Serbia 449 38.9 4.6 2.2 446 33.1 2.2 7.6 445 1.5 35.0 1.7 446.6666666666667 40 41 42 41 True False True False True False
47 Romania 445 40.8 3.2 4.9 438 37.3 1.6 1.1 439 3.4 37.3 0.9 440.6666666666667 42 45 45 42 True False True False True False
6 Bulgaria 439 43.8 4.1 4.2 436 39.4 4.3 0.4 446 2.0 36.9 3.1 440.3333333333333 43 46 41 43 True False True False True False
57 Thailand 427 49.7 2.6 1.0 441 33.0 0.8 1.1 444 3.9 33.6 0.9 437.3333333333333 45 42 44 44 True False True False True False
8 Chile 423 51.5 1.6 1.9 441 33.0 0.6 3.1 445 1.1 34.5 1.0 436.3333333333333 46 43 43 45 True False True False True False
11 Costa Rica 407 59.9 0.6 -1.2 441 32.4 0.6 -1.0 429 -0.6 39.3 0.2 425.6666666666667 51 44 46 46 True False True False True False
37 Mexico 413 54.7 0.6 3.1 424 41.1 0.4 1.1 415 0.9 47.0 0.1 417.3333333333333 48 47 50 47 True False True False True False
29 Kazakhstan 432 45.2 0.9 9.0 393 57.1 0.0 0.8 425 8.1 41.9 0.2 416.6666666666667 44 58 47 48 True False True False True False
38 Montenegro 410 56.6 1.0 1.7 422 43.3 1.0 5.0 410 -0.3 50.7 0.4 414.0 49 48 51 49 True False True False True False
36 Malaysia 421 51.8 1.3 8.1 398 52.7 0.1 -7.8 420 -1.4 45.5 0.3 413.0 47 54 48 50 True False True False True False
63 Uruguay 409 55.8 1.4 -1.4 411 47.0 0.9 -1.8 416 -2.1 46.9 1.0 412.0 50 49 49 51 True False True False True False
5 Brazil 391 67.1 0.8 4.1 410 49.2 0.5 1.2 405 2.3 53.7 0.3 402.0 53 50 54 52 True False True False True False
28 Jordan 386 68.6 0.6 0.2 399 50.7 0.1 -0.3 409 -2.1 49.6 0.2 398.0 56 53 52 53 True False True False True False
1 Argentina 388 66.5 0.3 1.2 396 53.6 0.5 -1.6 406 2.4 50.9 0.2 396.6666666666667 54 55 53 54 True False True False True False
58 Tunisia 388 67.7 0.8 3.1 404 49.3 0.2 3.8 398 2.2 55.3 0.1 396.6666666666667 55 51 56 55 True False True False True False
0 Albania 394 60.7 0.8 5.6 394 52.3 1.2 4.1 397 2.2 53.1 0.4 395.0 52 57 57 56 True False True False True False
10 Colombia 376 73.8 0.3 1.1 403 51.4 0.3 3.0 399 1.8 56.2 0.1 392.6666666666667 58 52 55 57 True False True False True False
23 Indonesia 375 75.7 0.3 0.7 396 55.2 0.1 2.3 382 -1.9 66.6 0.0 384.3333333333333 59 56 59 58 True False True False True False
46 Qatar 376 69.6 2.0 9.2 388 57.1 1.6 12.0 384 5.4 62.6 1.5 382.6666666666667 57 59 58 59 True False True False True False
43 Peru 368 74.6 0.6 1.0 384 59.9 0.5 5.2 373 1.3 68.5 0.0 375.0 60 60 60 60 True False True False True False
table{
border-collapse: collapse;
}
table,th,td{
border: 0px solid lightGrey;
}
#country{
text-align: center;
font: normal normal normal 24px/1 Helvetica, arial, sans-serif;
background-color: lightGrey;
margin: 0 auto;
}
svg{
text-align: center;
}
#mathsdiv{
text-align: center;
font: normal normal normal 14px/1 Helvetica, arial, sans-serif;
color: blue;
}
#readingdiv{
text-align: center;
font: normal normal normal 14px/1 Helvetica, arial, sans-serif;
color: red;
}
#sciencediv{
text-align: center;
font: normal normal normal 14px/1 Helvetica, arial, sans-serif;
color: green;
}
#myheader{
margin: 0 auto;
text-align: center;
font: normal normal normal 16px/1 Helvetica, arial, sans-serif;
color: #000000;
font-weight: bold;
}
#subject{
margin: 2 auto;
text-align: left;
font: normal normal normal 14px/1 Helvetica, arial, sans-serif;
font-weight: bold;
}
#mathspiechart{
text-align: center;
vertical-align: middle;
}
#pie{
font: normal normal normal 10px/1 Helvetica, arial, sans-serif;
text-align: center;
vertical-align: middle;
}
#averages{
font: normal normal normal 10px/1 Helvetica, arial, sans-serif;
text-align: left;
vertical-align: baseline;
}
#mathsarrow,#readingarrow,#sciencearrow {
text-align: center;
vertical-align: middle;
font: normal normal normal 10px/1 Helvetica, arial, sans-serif;
}
#mathsbarchart{
text-align: center;
vertical-align: middle;
}
#readingbarchart{
text-align: center;
vertical-align: middle;
}
#sciencebarchart{
text-align: center;
vertical-align: middle;
}
#readingpiechart{
text-align: center;
vertical-align: middle;
}
#sciencepiechart{
text-align: center;
vertical-align: middle;
<html>
<head>
<link rel="stylesheet" type="text/css" href="popup.css" media="screen" />
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://dimplejs.org/dist/dimple.v2.2.0.min.js"></script>
<script>
function drawpie(subject, low, high){
var middle = 100-low-high
var pie_data = [
{'subject':subject,'percent': low,'type' : 'under2'},
{'subject':subject,'percent': middle,'type' : 'level34'},
{'subject':subject,'percent': high,'type' : 'level56'}
];
svgname = '#' + subject + 'piechart';
var svg = dimple.newSvg(svgname, '150px', '80px');
var myPChart = new dimple.chart(svg, pie_data);
var colours = {maths:"blue", reading:"red", science:"green"};
var lightercolours = {maths:"#0099FF", reading:"FF9999", science:"66CC66"};
myPChart._assignedColors['under2'] = new dimple.color(lightercolours[subject]);
myPChart._assignedColors['level34'] = new dimple.color('lightGrey');
myPChart._assignedColors['level56'] = new dimple.color(colours[subject]);
myPChart.addMeasureAxis("p", "percent");
myPChart.setBounds(20,18,'75%','75%');
var s = myPChart.addSeries("type", dimple.plot.pie);
s.getTooltipText = function (e) {
mystr = e.pValue + '%'
return [
mystr
];
};
myPChart.draw();
};
function drawbar(subject, myscore, myranking){
chartname = '#' + subject + 'barchart'
var svg = dimple.newSvg(chartname,'300px','120px');
oecd_mean = {'maths':494, 'reading':496, 'science':501}
var data = [
{'subject':subject,'score': myscore,'oecd_average': oecd_mean[subject]}
];
var colours = {maths:"blue", reading:"red", science:"green"};
var myChart = new dimple.chart(svg, data);
myChart.defaultColors = [
new dimple.color(colours[subject]),
new dimple.color("darkGrey")
];
var y = myChart.addCategoryAxis("y", "subject");
var x = myChart.addMeasureAxis("x", "score");
var o = myChart.addMeasureAxis("x", "oecd_average");
var s = myChart.addSeries("subject", dimple.plot.bar);
var oecd = myChart.addSeries("oecd_average", dimple.plot.bubble, [o, y]);
debugger;
y.hidden = true;
o.hidden = true;
myChart.setBounds(10, 30,'90%','40%');
o.overrideMax = 620;
x.overrideMax = 620;
x.showGridlines = false;
x.ticks = 3;
myChart.draw();
x.titleShape.remove();
//I've kept this line long as I'd argue it makes the code more readable
if (myranking == 1 || myranking == 21 || myranking == 31 || myranking == 41 || myranking == 51){
ranking = "overall ranking: " + myranking + "st";
} else if (myranking == 2 || myranking == 22 || myranking == 32 ||
myranking == 42 || myranking == 52){
ranking = "overall ranking: " + myranking + "nd";
} else if (myranking == 3 || myranking == 23 || myranking == 33 ||
myranking == 43 || myranking == 53){
ranking = "overall ranking: " + myranking + "rd";
} else {
ranking = "overall ranking: " + myranking + "th";
}
svg.append("text")
.attr("y", 60)
.attr("x", 100)
.style("text-anchor", "middle")
.style("font-size", "14px")
.style("font-family", "Helvetica, arial, sans-serif")
.style("fill", "#ecf0f1")
.text(ranking);
};
function drawgraphs(d){
//these lines are better longer too?
drawbar('maths', parseInt(d[0]['maths_meanscore']), parseInt(d[0]['maths_ranking']))
drawbar('reading', parseInt(d[0]['reading_meanscore']), parseInt(d[0]['reading_ranking']))
drawbar('science', parseInt(d[0]['science_meanscore']), parseInt(d[0]['science_ranking']))
drawpie('maths', parseInt(d[0]['maths_lowperform']), parseInt(d[0]['maths_highperform']))
drawpie('reading', parseInt(d[0]['reading_lowperform']), parseInt(d[0]['reading_highperform']))
drawpie('science', parseInt(d[0]['science_lowperform']), parseInt(d[0]['science_highperform']))
function progress(prog,subject,colour){
imagename = subject + "img"
divname = subject + "div"
imagelink ='http://github.com/BMPMS/Udacity/blob/master/'
//longer lines there because of pesky image links.
if (prog < 0){
if (subject == 'maths'){
newimg = "https://cloud.githubusercontent.com/assets/18613602/16158271/765b7b46-34b4-11e6-8a75-615cd7c3f49f.gif"
}
if (subject == 'science'){
newimg = 'https://cloud.githubusercontent.com/assets/18613602/16158464/3a24983c-34b5-11e6-8b1f-382e64cc04b6.gif'
}
if (subject == 'reading'){
newimg = 'https://cloud.githubusercontent.com/assets/18613602/16158470/3ecb2428-34b5-11e6-8fd5-3ba3c41ce0fa.gif'
}
document.getElementById(imagename).src=newimg;
}
if (prog == 0){
newimg = "https://cloud.githubusercontent.com/assets/18613602/16158463/3a240886-34b5-11e6-8333-3a66db8aeb86.gif"
document.getElementById(imagename).src=newimg;
}
if (prog > 0){
if (subject == 'maths'){
newimg = "https://cloud.githubusercontent.com/assets/18613602/16158458/360f6844-34b5-11e6-845e-a222b3aadcfa.gif"
}
if (subject == 'science'){
newimg = 'https://cloud.githubusercontent.com/assets/18613602/16158465/3a279b68-34b5-11e6-8641-888d4e78b753.gif'
}
if (subject == 'reading'){
newimg = 'https://cloud.githubusercontent.com/assets/18613602/16158469/3ec8e82a-34b5-11e6-95a5-f71c2a34cbed.gif'
}
document.getElementById(imagename).src=newimg;
}
document.getElementById(divname).innerHTML = prog;
};
progress(d[0]['maths_progress'], 'maths', 'blue');
progress(d[0]['reading_progress'], 'reading', 'red');
progress(d[0]['science_progress'], 'science', 'green');
}
function getcountry(cvalue){
mycountry = cvalue;
if (mycountry.indexOf("%20") !== -1){
mycountry = mycountry.split('%20');
var text = '';
for (i = 0; i < mycountry.length; i++) {
text += mycountry[i] + " ";
}
mycountry = text.trim();
}
return mycountry;
}
function startpopup(){
d3.csv("pisa_map_data.csv", function(d) {
mycountry = getcountry(window.location.search.split('=')[1]);
if (mycountry.indexOf("%20") !== -1){
mycountry = mycountry.split('%20');
var text = '';
for (i = 0; i < mycountry.length; i++) {
text += mycountry[i] + " ";
}
mycountry = text.trim();
}
if (d.country == mycountry){
d['maths_meanscore'] = +d['maths_meanscore'] ;
d['maths_lowperform'] = +d['maths_lowperform'] ;
d['maths_highperform'] = +d['maths_highperform'] ;
d['maths_progress'] = +d['maths_progress'] ;
d['maths_ranking'] = +d['maths_ranking'] ;
d['reading_meanscore'] = +d['reading_meanscore'] ;
d['reading_lowperform'] = +d['reading_lowperform'] ;
d['reading_highperform'] = +d['reading_highperform'] ;
d['reading_progress'] = +d['reading_progress'] ;
d['reading_ranking'] = +d['reading_ranking'] ;
d['science_meanscore'] = +d['science_meanscore'] ;
d['science_lowperform'] = +d['science_lowperform'] ;
d['science_highperform'] = +d['science_highperform'] ;
d['science_progress'] = +d['science_progress'] ;
d['science_ranking'] = +d['science_ranking'] ;
return d;
}
}, drawgraphs);
}</script>
</head>
<script>
startpopup()
</script>
<body>
<table height="100%" width="100%">
<tbody>
<tr style="height: 8%;">
<td id='country'colspan=4 >
<script>
mycountry = getcountry(window.location.search.split('=')[1]);
document.getElementById('country').innerHTML = mycountry.toUpperCase();
</script>
</td>
</tr>
<tr style="height: 9%;">
<td id='myheader' width="12%">
</td>
<td id='myheader' width="48%">
average score</td>
<td id='myheader' width="25%">
academic level
</td>
<td id='myheader' width="15%">
progress
</td>
</tr>
<tr style="height: 25%;">
<td style='color: blue;' id='subject'>&nbsp;MATHS</td>
<td id="mathsbarchart" ></td>
<td id='pie'><div id="mathspiechart"></div><br><span style='color: #0099FF;'>
low (under Level 2)</span><br><span style='color:lightGrey'>
mid range (level 2 to 4)</span>
<br><span style='color: Blue;'>high (Level 5 and 6)</span><br></td>
<td id='mathsarrow'><img id='mathsimg' width='30px' height='30px'><br><br>
<div id='mathsdiv'></div><br><br></td>
</tr>
<tr style="height: 25%;">
<td style='color: red;' id='subject'>&nbsp;READING</td>
<td id="readingbarchart" ></td>
<td id='pie'><div id="readingpiechart"></div><br><br>
<span style='color: #FF9999;'>low (under Level 2)</span><br>
<span style='color:lightGrey'>mid range (level 2 to 4)</span><br>
<span style='color: red;'>high (Level 5 and 6)</span><br></td>
<td id='readingarrow'><img id='readingimg' width='30px' height='30px'><br><br>
<div id='readingdiv'></div><br><br></td>
</tr>
<tr style="height: 25%;">
<td style='color: green;'id='subject'>&nbsp;SCIENCE</td>
<td id="sciencebarchart"></td>
<td id='pie'><div id="sciencepiechart"></div><br><br>
<span style='color: #66CC66;'>low (under Level 2)</span><br>
<span style='color:lightGrey'>mid range (level 2 to 4)</span><br>
<span style='color: green;'>high (Level 5 and 6)</span><br></td>
<td id='sciencearrow'><img id='scienceimg' width='30px' height='30px'><br><br>
<div id='sciencediv'></div><br><br></td>
</tr>
<tr>
<td colspan=4 height='8%' id='averages'>
<br>
<b>OECD average academic levels:</b>
maths (low 23%, high 12.6%), reading (low 18%, high 9%), science (low 18%, high 8%)<br>
<b>OECD average progress:</b>maths -0.3%, reading 0.3%, science 0.5%
</
</tr>
</tbody>
</table>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment