Skip to content

Instantly share code, notes, and snippets.

@yjacolin
Forked from jsanz/README.md
Last active September 8, 2015 20:33
Show Gist options
  • Save yjacolin/4e12fb49abb033912331 to your computer and use it in GitHub Desktop.
Save yjacolin/4e12fb49abb033912331 to your computer and use it in GitHub Desktop.
OSGeo Charter Members

D3 tests with OSGeo Charter Members data

What is this repository for?

This is a simple exercise to learn D3 basics using a data set I have at hand, the charter members of the Open Source Geospatial Foundation OSGeo.

It is intentionally simple, as I've tried to use the core D3 features, without the help of any other third party library except the d3.geo.projection plugin because I love the Robinson projection. Yes, I have a comfortable pair of running shoes, etc.

Check the viz.

Comments are welcomed

Don't hesitate to comment about the visual aspect or the source code if you think that it can be more readable, less buggier, etc. Let me say it again: I'm learning :bowtie:.

firstname lastname year country
Aaron Racicot 2007 United States of America
Alessandro Furieri 2013 Italy
Alex Mandel 2010 United States of America
Andrea Aime 2012 Italy
Andreas Hocevar 2010 Austria
Andrew Ross 2008 Canada
Andrew Turner 2008 United States of America
Andrey V. Kiselev 2006 Russia
Angelos Tzotsos 2012 Greece
Anita Graser 2012 Austria
Anne Ghisla 2010 Italy
Ari Jolma 2006 Finland
Arnulf Christl 2006 Germany
Astrid Emde 2010 Germany
Athina Trakas 2008 Germany
Barend Köbben 2012 Netherlands
Bart van den Eijnden 2006 Netherlands
Bob Basques 2011 United States of America
Borys Jurgiel 2013 Poland
Brian Case 2011 United States of America
Brian Hamlin 2012 United States of America
Cameron Shorter 2006 Australia
César Medina 2012 Chile
Charlie Schweik 2008 United States of America
Chris Holmes 2006 United States of America
Claude Philipona 2006 Switzerland
Codrina Maria Ilie 2013 Romania
Daisuke Yoshida 2009 Japan
Dan Ames 2013 United States of America
Dane Springmeyer 2009 United States of America
Daniel Kastl 2013 Germany
Daniel McInerney 2013 Ireland
Daniel Morissette 2006 Canada
Danilo Furtado 2010 Portugal
Dave McIlhagga 2006 Canada
David Bitner 2009 United States of America
Dimitris Kotzinos 2012 Greece
Dirk Frigne 2013 Belgium
Doug Newcomb 2012 United States of America
Duarte Carreira 2009 Portugal
Eli Adam 2013 United States of America
Emmanuel Polidario Sambale 2011 Philippines
Eric Lemoine 2011 France
Even Rouault 2011 France
François Prunayre 2013 France
Frank Warmerdam 2006 Canada
G. Hanumantha Rao 2011 India
Gabriel Roldán 2011 Argentina
Gary Lang 2006 United States of America
Gary Sherman 2006 United States of America
Gavin Fleming 2010 South Africa
Gérald Fenoy 2009 France
Giovanni Manghi 2009 Portugal
Hardeep S. Rai 2009 India
Haris Kurtagic 2009 Slovenia
Harish Kumar Solanki 2013 India
Helena Mitasova 2006 United States of America
Helmut Kudrnovsky 2013 Austria
Helton Uchoa 2006 Brazil
Hirofumi Hayashi 2010 Japan
Howard Butler 2006 United States of America
Ian Edwards 2013 United Kingdom
Ian Turton 2006 United States of America
Jachym Cepicky 2011 Czech Republic
Jackie Ng 2009 Australia
James MacGill 2006 United States of America
Jan Jezek 2012 Czech Republic
Jan-Oliver Wagner 2007 Germany
Jean-Roc Morreale 2012 France
Jeff McKenna 2006 Canada
Jeroen Ticheler 2006 Netherlands
Jo Cook 2010 United Kingdom
Jody Garnett 2006 Australia
John Graham 2007 United States of America
Jon Scarbrough 2006 United States of America
Jorge Sanz 2008 Spain
Jorge Gustavo Rocha 2009 Portugal
Josh Livni 2009 United States of America
Julien-Samuel Lacroix 2008 Canada
Just van den Broecke 2013 Netherlands
Justin Bronn 2009 United States of America
Justin de Olivera 2006 United States of America
K.S. Rajan 2009 India
Karel Charvat 2012 Czech Republic
Landon Blake 2007 United States of America
Lluís Vicens 2011 Spain
Luca Delucchi 2011 Italy
Luis W. Sevilla 2008 Spain
Marc Jansen 2013 Germany
Marco Lechner 2013 Germany
Margherita di Leo 2011 Italy
Maria Arias de Reyna 2013 Spain
Maria Brovelli 2010 Italy
Mark Cave-Ayland 2009 United Kingdom
Mark Lucas 2006 United States of America
Markus Muller 2008 New Zealand
Markus Neteler 2006 Italy
Martin Daly 2011 United Kingdom
Martin Davis 2008 Canada
Martin Landa 2011 Czech Republic
Massimiliano Cannata 2012 Italy
Massimo di Stefano 2011 Italy
Mateusz チチoskot 2007 United Kingdom
Mauricio Miranda 2012 Argentina
Maxim Dubinin 2013 Russia
Michael Adair 2006 Canada
Michael P. Gerlek 2006 United States of America
Micho García 2013 Spain
Milena Nowotarska 2010 Poland
Minpa Lee 2013 South Korea
Nathan Woodrow 2013 Australia
Ned Horning 2006 United States of America
Nicolas Bozon 2011 France
Nikos Ves 2013 Greece
Nobusuke Iwasaki 2013 Japan
Norman Vine 2006 United States of America
Paolo Cavallini 2008 Italy
Paolo Corti 2013 Italy
Paul Ramsey 2006 Canada
Paul Spencer 2006 Canada
Pedro-Juan Ferrer Matoses 2012 Spain
Pekka Sarkola 2013 Finland
Pericles Nacionales 2006 United States of America
Peter Batty 2009 United States of America
Peter Baumann 2013 Germany
Peter Löwe 2012 Germany
Phillip Davis 2013 United States of America
Praveen K. Sinha 2012 India
Puneet Kishor 2007 United States of America
Ragi Yaser Burhum 2012 Peru
Ravi Kumar Vundavilli 2006 India
Regina Obe 2009 United States of America
Rich Steele 2006 United States of America
Rob Atkinson 2007 Australia
Robert Bray 2006 Canada
Robert Szczepanek 2009 Poland
S. Narendra Prasad 2008 India
Sandro Santilli 2009 Italy
Sanghee Shin 2011 South Korea
Sarawut Ninsawat 2013 Thailand
Schuyler D. Erle 2006 United States of America
Serena Coetzee 2012 South Africa
Sergio Acosta y Lara 2013 Uruguay
Silvana Camboim 2013 Brazil
Simone Giannecchini 2007 Italy
Stephen Woodbridge 2011 United States of America
Steve Lime 2006 United States of America
Suchith Anand 2011 United Kingdom
Taichi Furuhashi 2013 Japan
Tamas Szekeres 2007 Hungary
Thierry Badard 2008 Canada
Thomas Bonfort 2012 France
Thomas E. Burk 2006 United States of America
Till Adams 2013 Germany
Tim Sutton 2011 South Africa
Toru Mori 2006 Japan
Tuong Thuy VU 2013 Malaysia
Tyler Mitchell 2006 Canada
Vasile Craciunescu 2012 Romania
Venkatesh Raghavan 2006 Japan
Victor Olaya 2012 Spain
Vincent Picavet 2013 France
Volker Mische 2013 Germany
Wolf Bergenheim 2008 Finland
Xianfeng Song 2011 China
Yann Chemin 2013 Sri Lanka
Yewondwossen Assefa 2007 Canada
Yoicihi Kayama 2011 Japan
Yves Jacolin 2008 France
Geoff Zeiss 2008 Canada
Alan Boudreault 2009 Canada
Michael Smith 2012 United States of America
Rafael Medeiros Sperb 2006 Brazil
Yoichi SEINO 2013 Japan
Christopher Schmidt 2007 United States of America
Tom Kralidis 2007 Canada
Victor Ferreira 2009 Portugal
Tim Schaub 2009 United States of America
Jo Walsh 2006 United Kingdom
Mark Leslie 2013 Australia
Alejandro Díaz 2014 Spain
Alexander Bruy 2014 Ukraine
Alexandre Neto 2014 Portugal
Andrea Antonello 2014 Italy
Andreea Marin 2014 Romania
Anna Petrasova 2014 Czech Republic
Ariel Nuñez 2014 Colombia
BJ Jang 2014 South Korea
Bruce Bannerman 2014 Australia
Carolina Arias 2014 Italy
Chaitanya Kumar 2014 India
Chris Helm 2014 United States of America
Christian Mayer 2014 Germany
Christos Iosifidis 2014 Greece
Dan Little 2014 United States of America
Darrell Fuhirman 2014 United States of America
David Fawcett 2014 United States of America
David Percy 2014 United States of America
Florin Iosub 2014 Romania
Hugo Santos 2014 Portugal
Ionuț Iosifescu 2014 Switzerland
Ivan Minčik 2014 Slovakia
Iván Sánchez Ortega 2014 Norway
Jeffrey Johnson 2014 United States of America
Jeremy Morley 2014 United Kingdom
Jim Klassen 2014 United States of America
Johan Van de Wauw 2014 Belgium
Jorge Arévalo 2014 Spain
Jose Santos 2014 Portugal
José García 2014 Spain
Jukka Rahkonen 2014 Finland
Kate Chapman 2014 United States of America
Kristin Bott 2014 United States of America
Luciene Delzari 2014 Brazil
Marie Silvestre 2014 France
Miguel Ángel Blanco 2014 Argentina
Milan Antonovic 2014 Switzerland
Mohammed Rashad 2014 India
Moisés Arcos 2014 Spain
Nadiia Gorash 2014 Ukraine
Nikos Alexandris 2014 Greece
Nimalika Fernando 2014 Sri Lanka
Oliver Tonhofer 2014 Germany
Olivier Courtin 2014 France
Patricio Soriano 2014 Spain
Paul Meems 2014 Netherlands
Pieter De Graef 2014 Belgium
Pirmin Kalberer 2014 Switzerland
Régis Haubourg 2014 France
Santosh Gaikwad 2014 India
Silvia Franceschi 2014 Italy
Simon Mercier 2014 Canada
Simone Dalmasso 2014 Italy
Sittichai Choosumrong 2014 Thailand
Stephan Meißl 2014 Austria
Steven Feldman 2014 United Kingdom
Takayuki Nuimura 2014 Japan
Tanya Haddad 2014 United States of America
Thijs van Menen 2014 Netherlands
Thomas Gratier 2014 France
Toshikazu Seto 2014 Japan
Vivien Deparday 2014 France
Václav Petras 2014 Czech Republic
Zoltan Siki 2014 Hungary
Lene Fischer 2015 Denmark
Didier Richard 2015 France
Etienne Delay 2015 France
Julien Michel 2015 France
Pedro Venancio 2015 Portugal
Kari Salovaara 2015 Finland
Peter Mooney 2015 Ireland
Vicky Vergara 2015 Mexico
Kurt Menke 2015 United States of America
Alexander Salveson Nossum 2015 Norway
Asger Sigurd Petersen 2015 Denmark
Marco Minghini 2015 Italy
Gert-Jan van der Weijden 2015 Netherlands
Ko Nagase 2015 Japan
Moritz Lennert 2015 Belgium
Daria Svidzinska 2015 Ukraine
Jean-Marie Arsac 2015 France
Jürgen E. Fischer 2015 Germany
Asahi Kosuke 2015 Japan
Byeong-Hyeok Yu 2015 South Korea
Kevin Smith 2015 Canada
Oliver May 2015 Belgium
Maëlle Vercauteren 2015 Belgium
Elżbieta Wołoszyńska-Wiśniewska 2015 Poland
Oscar López 2015 Argentina
Gonzalo Gabriel Pérez 2015 Argentina
Kenya Tamura 2015 Japan
Hans Gregers Petersen 2015 Denmark
Sebastiaan Couwenberg 2015 Netherlands
Mayumi Kubo 2015 Japan
Go Yonezawa 2015 Japan
Marc Vloemans 2015 Netherlands
Javier Díaz 2015 Argentina
Yuichiro Nishimura 2015 Japan
Alex Morega 2015 Romania
David Bianco 2015 United States of America
Alvin Natividad 2015 Philippines
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>OSGeo Charter Members</title>
<link rel="stylesheet" href="http://getbootstrap.com/dist/css/bootstrap.min.css">
<style>
/* styles from scss file */
.axis path, .axis line {
fill: none;
stroke: #47aa42;
shape-rendering: crispEdges;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
fill: #47aa42; }
.graph .bar { fill: #47aa42; }
.graph rect.bar:hover {fill: orange; }
.graph .label {
fill: #f2faf1;
font-family: sans-serif;
font-size: 12px;
}
.graph .xaxe {
font-family: sans-serif;
font-size: 11px;
fill: #47aa42;
}
.graph .map .stroke {
fill: none;
stroke: #000;
stroke-width: 3px;
}
.graph .map .fill {fill: #fff; }
.graph .map .graticule {
fill: none;
stroke: #777;
stroke-width: 0.5px;
stroke-opacity: 0.5;
}
.graph .map .land {fill: #222; }
.graph .map .boundary {
fill: none;
stroke: #fff;
stroke-width: 0.5px;
}
h2 span.glyphicon {font-size: 15px; }
.inline-list span {display: inline-block;}
.highlighted {background-color: yellow; }
</style>
</head>
<body>
<!--[if lt IE 10]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<![endif]-->
<div class="container">
<div class="header">
<h1 class="text-muted">OSGeo Charter Members</h1>
</div>
<div class="row">
<div class="col-lg-12"><p>
<a href="https://gist.github.com/jsanz/779f9b9954b92461fa50">Gist</a> ·
<a href="http://bl.ocks.org/jsanz/779f9b9954b92461fa50">bl.ocks.org</a>
</p></div>
</div>
<div id="byYear">
<div class="row">
<div class="col-lg-12"><h2>Charter Members by year added</h2></div>
</div>
<div class="row">
<div class="col-lg-12 graph"></div>
</div>
</div>
<div id="byRegion">
<div class="row">
<div class="col-lg-12"><h2>Charter Members by region</h2></div>
</div>
<div class="row">
<div class="col-lg-12"><p id="chartersByRegion" class="inline-list"></p></div>
</div>
<div class="row">
<div class="col-lg-6 graph"></div>
<div class="col-lg-6 graphDetail"></div>
</div>
</div>
<div id="byCountry">
<div class="row">
<div class="col-lg-12"><h2>Charter Members by country</a></h2></div>
</div>
<div class="row">
<div class="col-lg-12"><p id="chartersByCountry" class="inline-list"></p></div>
</div>
<div class="row" >
<div class="col-lg-12 graph"></div>
</div>
</div>
<div class="footer">
<p><span class="glyphicon glyphicon-heart"></span> Jorge Sanz 2014</p>
</div>
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js" charset="utf-8"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3-geo-projection/0.2.9/d3.geo.projection.min.js" charset="utf-8"></script>
<script src="main.js"></script>
</body>
</html>
/*
* First attempt wit D3:
* This script loads a CSV file with OSGeo Charter Members
* information and presents it in several ways.
*
* Author: Jorge Sanz
* Date: 14/07/27
*/
/* almost stupid and optimistic way to normalize strings for comparison */
var norm = function(string){
return ( string + "" ).toLowerCase().trim();
}
/*
* Function to generate the bar chart for
* charters by year
*/
var processDataByYear = function(csv_data){
/* Graph for the year */
var w = 500;
var h = 250;
var barPadding = 2;
var padding = 20;
var xoffset = 30;
/* group the data by year */
var dataByYear = d3.nest()
.key(function(d) { return d.year;})
.sortKeys(d3.ascending)
.entries(csv_data);
var svg = d3.select('#byYear .graph')
.append("svg")
.attr("width", w)
.attr("height", h)
.attr("class","graph");
var yScale = d3.scale.linear()
.domain([0, d3.max(dataByYear, function(d) { return d.values.length; })])
.rangeRound([h - padding, 0]);
var xScale = d3.scale.ordinal()
.domain(d3.range(dataByYear.length))
.rangeRoundBands([0, w - xoffset], 0.05);
svg.selectAll("rect")
.data(dataByYear)
.enter()
.append("rect")
.attr("x", function(d, i) {
return xScale(i) + xoffset;
})
.attr("y", function(d) {
return yScale(d.values.length);
})
.attr("width", xScale.rangeBand())
.attr("height", function(d) {
return h - yScale(d.values.length) - padding;
})
.attr("class","bar");
svg.append("g")
.selectAll("text")
.data(dataByYear)
.enter()
.append("text")
.text(function(d) {
return d.values.length;
})
.attr("text-anchor", "middle")
.attr("x", function(d, i) {
return xScale(i) + xoffset + xScale.rangeBand()/2;
})
.attr("y", function(d) {
return yScale(d.values.length) + 14;
})
.attr("class", "label");
svg.append("g")
.selectAll("text")
.data(dataByYear)
.enter()
.append("text")
.text(function(d) {
return d.key;
})
.attr("text-anchor", "middle")
.attr("x", function(d, i) {
prop = ( w - xoffset) / dataByYear.length;
return i * prop + (prop - barPadding) / 2 + xoffset;
})
.attr("y", function(d) {
return h;
})
.attr("class", "label xaxe");
//Define X axis
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.ticks(5);
//Create X axis
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + xoffset + ",0)")
.call(yAxis);
};
/*
* Function to process the countries geojson
* join it with charters data and
* produce the pie chart and the map
*/
var processDataByCountry = function(csv_data, countries){
/* group the data by country */
var w = 700,
h = 350,
colors = ["#ccc","#41ab5d","#238b45","#005a32"],
buckets = colors.length;
var quantize = d3.scale.quantile()
.domain([0,1,5,15,100])
.range(d3.range(buckets));
var dataByCountry = d3.nest()
.key(function(d) { return d.country;})
.rollup(function(d) {
return d3.sum(d, function(g) {return 1; });
})
.sortKeys(d3.ascending)
.entries(csv_data);
d3.select('#chartersByCountry')
.selectAll('span')
.data(dataByCountry)
.enter()
.append('span')
.attr("id",function(d,i){
return "charter-country-text-" + i;
})
.text(function(country,i){
result = country.key + " (" + country.values + ")";
return i < dataByCountry.length - 1 ? result + " · " : result;
})
.style("color", function(d) {return colors[quantize(d.values)]});
// data by Country
//Define map projection
var projection = d3.geo.robinson()
.scale(110)
.translate([w / 2, h / 2])
.precision(.1);
//Define path generator
var path = d3.geo.path()
.projection(projection);
var graticule = d3.geo.graticule();
// CREATE THE SVG
var svgMap = d3.select('#byCountry .graph')
.append("svg")
.attr("class","map")
.attr("width", w)
.attr("height", h);
svgMap.append("path")
.datum(graticule)
.attr("class", "graticule")
.attr("d", path);
//Merge the ag. data and GeoJSON
var dataByCountryPushed = [];
var features_with_charters = countries.features.map(function(country){
var result = {
'type' : 'Feature',
'geometry' : country.geometry,
'properties' : {
'admin' : country.properties.admin,
'region' : country.properties.region_wb,
'charters' : 0
}
};
//find data into the dataByCountry
for (i in dataByCountry){
if (norm(dataByCountry[i].key) == norm(country.properties.admin)){
result.properties['charters'] = dataByCountry[i].values;
dataByCountryPushed.push(dataByCountry[i]);
break;
}
}
return result;
});
var countriesCharters = {'type':'FeatureCollection','features':features_with_charters};
if (dataByCountry.length != dataByCountryPushed.length){
dataByCountry.forEach(function(d){if (dataByCountryPushed.indexOf(d)==-1){console.log(d);}})
}
svgMap.selectAll("path")
.data(countriesCharters.features)
.enter()
.append("path")
.attr("d", path)
.style("fill", function(d) {
color = colors[quantize(d.properties.charters)]
return color;
})
.on("mouseover",function(d){
var r = -1;
for (i in dataByCountry){
if (norm(d.properties.admin) === norm(dataByCountry[i].key)){
r = i;
break;
}
}
if (r != -1)
d3.select("#charter-country-text-"+i)
.classed("highlighted",true);
})
.on("mouseout",function(d){
var r = -1;
for (i in dataByCountry){
if (norm(d.properties.admin) === norm(dataByCountry[i].key)){
r = i;
break;
}
}
if (r != -1)
d3.select("#charter-country-text-"+i)
.classed("highlighted",false);
});;
// Regroup by regiov_wb
/* normalize countries and regions */
var dataByRegion = d3.nest()
.key(function(d) {
region = d.properties.region
return region;
})
.rollup(function(d) {
return {
'totalCharters' : d3.sum(d, function(g) {return g.properties.charters; }),
'countries' : d.map(function(country){
return {
'country' : country.properties.admin,
'charters': country.properties.charters
}
})
}
})
.sortKeys(d3.ascending)
.entries(countriesCharters.features.filter(function(d){return d.properties.charters>0;}));
var color = d3.scale.category10();
// Populate the list
d3.select('#chartersByRegion')
.selectAll('span')
.data(dataByRegion,function(d){return d.key})
.enter()
.append('span')
.attr("style", function(d, i) {
return "color:" + color(i);
})
.attr("id",function(d,i){
return "charter-region-text-" + i;
})
.text(function(d,i){
result = d.key + " (" + d.values.totalCharters + ")";
return i < dataByRegion.length - 1 ? result + " · " : result;
});
// Graph for the year
var pie = d3.layout.pie().value(function(d){return d.values.totalCharters});
var w = 200;
var h = 200;
var outerRadius = w / 2;
var innerRadius = 0;
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);
var svgPie = d3.select('#byRegion .graph')
.append("svg")
.attr("width", w)
.attr("height", h)
.attr("class","graph");
var arcs = svgPie.append("g")
.attr("class","pieArcs")
.selectAll("g.arc")
.data(pie(dataByRegion))
.enter()
.append("g")
.attr("class", "arc")
.attr("transform", "translate(" + outerRadius + ", " + outerRadius + ")")
.append("path")
.attr("fill", function(d, i) {
return color(i);
})
.attr("d", arc)
.on("mouseover",function(d,i){
d3.select('.graphDetail')
.append('h2')
.text(d.data.key);
d3.select('.graphDetail')
.append('p')
.attr("class","inline-list")
.selectAll('span')
.data(d.data.values.countries)
.enter()
.append('span')
.text(function(l,i){
result = l.country + " (" + l.charters + ")";
return i < d.data.values.countries.length - 1 ? result + " · " : result;
});
d3.select("#charter-region-text-"+i)
.classed("highlighted",true);
})
.on("mouseout",function(d,i){
d3.select('.graphDetail h2').remove();
d3.select('.graphDetail p').remove();
d3.select("#charter-region-text-"+i)
.classed("highlighted",false);
});
};
/*
* Where the action begins
*/
d3.csv("charters.csv", function(csv_data){
processDataByYear(csv_data);
d3.json("countries.json", function(error, countries) {
processDataByCountry(csv_data,countries);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment