Skip to content

Instantly share code, notes, and snippets.

@luluwuluying
Created February 22, 2016 21:20
Show Gist options
  • Save luluwuluying/c3c703286bf4ceb4ea6a to your computer and use it in GitHub Desktop.
Save luluwuluying/c3c703286bf4ceb4ea6a to your computer and use it in GitHub Desktop.
Week 6: Line Plot
<!DOCTYPE html>
<!-- Modification of an example by Scott Murray from Knight D3 course -->
<html lang="en">
<head>
<meta charset="utf-8">
<title>Line Chart with Multiple Lines</title>
<style type="text/css">
body {
background-color: white;
font-family: Helvetica, Arial, sans-serif;
margin: auto;
}
h1 {
font-size: 24px;
margin-top: 20px;
margin-left:20px;
margin-right: 250px;
color:steelblue;
}
p {
font-size: 14px;
margin: 10px 0 0 0;
margin-left:20px;
margin-right: 250px;
color: grey;
}
svg {
background-color: white;
}
.axis path,
.axis line {
fill: none;
stroke: gray;
stroke-width: 1px;
}
.line {
fill: none;
stroke: orange;
stroke-width: 1px;
stroke-opacity: 80%;
}
.line.unfocused{
stroke-opacity: 40%;
}
.line.focused {
stroke-width: 5px;
stroke-opacity: 100%;
stroke: steelblue;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
}
.tooltip {
position: absolute;
z-index: 10;
}
.tooltip p {
background-color: white;
border: none;
padding: 2px;
}
.grouptext{
stroke: steelblue;
font-family: sans-serif;
font-size: 11px;
}
</style>
</head>
<body>
<h1>Wireless mobile broadband subscriptions</h1>
<p>Broadband access refers to technologies that provide access to the Internet at download speeds of 256 kbit/s or greater. It includes both fixed broadband technologies and wireless broadband technologies. Fixed broadband technologies corresponds to DSL, cable modem, fiber-to-the-home and other fixed technologies (such as broadband over power-line and leased lines). Wireless broadband penetration technologies correspond to satellite, terrestrial fixed wireless, as well as terrestrial mobile wireless. Source: <a href="https://data.oecd.org/broadband/wireless-mobile-broadband-subscriptions.htm#indicator-chart">Broadband database</a></p>
<p>Definition of Wireless mobile broadband subscriptions: Wireless mobile broadband subscriptions are mobile subscriptions that advertise data speeds of 256 kbit/s or greater. The subscription must allow access to the Internet via HTTP and must have been used to make a data connection via Internet Protocol (IP) in the previous three months. Standard SMS and MMS messaging do not count as an active Internet data connection even if they are delivered via IP. This indicator is measured in number of subscriptions per 100 inhabitants.</p>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<script type="text/javascript">
//Dimensions and padding
var fullwidth = 900;
var fullheight = 600;
var margin = { top: 20, right: 150, bottom: 40, left: 100};
var width = fullwidth - margin.left - margin.right;
var height = fullheight - margin.top - margin.bottom;
//Set up date formatting and years
var dateFormat = d3.time.format("%Y");
var xScale = d3.time.scale()
.range([ 0, width]);
var yScale = d3.scale.linear()
.range([0, height]);
//Configure axis generators
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(5)
.tickFormat(function(d) {
return dateFormat(d);
})
.innerTickSize([10]);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.innerTickSize([10]);
var line = d3.svg.line()
.x(function(d) {
return xScale(dateFormat.parse(d.year));
})
.y(function(d) {
return yScale(+d.amount);
})
;
// add a tooltip to the page - not to the svg itself!
var tooltip = d3.select("body")
.append("div")
.attr("class", "tooltip");
//Create the empty SVG image
var svg = d3.select("body")
.append("svg")
.attr("width", fullwidth)
.attr("height", fullheight)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
//Load data
d3.csv("wireless.csv", function(data) {
// or you could get this by doing:
var years = d3.keys(data[0]).slice(0, 5); //
//Create a new, empty array to hold our restructured dataset
var dataset = [];
//Loop once for each row in data
data.forEach(function (d, i) {
var myWireless = [];
//Loop through all the years - and get the emissions for this data element
years.forEach(function (y) {
// If value is not empty
if (d[y]) {
//Add a new object to the new emissions data array - for year, amount
myWireless.push({
country: d.Country,
year: y,
amount: d[y] // this is the value for, for example, d["2004"]
});
}
});
//Create new object with this country's name and empty array
// d is the current data row... from data.forEach above.
dataset.push( {
country: d.Country,
wireless: myWireless // we just built this!
} );
}); // end of the data.forEach loop
//Uncomment to log the original data to the console
// console.log(data);
//Uncomment to log the newly restructured dataset to the console
console.log(dataset);
//Set scale domains - max and min of the years
xScale.domain(
d3.extent(years, function(d) {
return dateFormat.parse(d);
}));
// max of emissions to 0 (reversed, remember) - [max, 0] for y scale
yScale.domain([
d3.max(dataset, function(d) {
return d3.max(d.wireless, function(d) {
return +d.amount;
});
}),
0
]);
//Make a group for each country - just for the data binding
var groups = svg.selectAll("g.lines")
.data(dataset)
.enter()
.append("g")
.attr("class", "lines");
//Within each group, create a new line/path,
//binding just the emissions data to each one
groups.selectAll("path")
.data(function(d) { // because there's a group with data per country already...
return [ d.wireless ]; // it has to be an array for the line function
})
.enter()
.append("path")
.attr("class", "line")
.attr("d", line) // calls the line function you defined above, using that array
.style("stroke" ,function(d){
if (d.Country ==="OECDTotal"){
return "red";
}
});
//Axes
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
// here we add the mouseover and mouseout effect, and use the id we created to style it.
// this is on the g elements, because the country name is in the data there.
// the line itself has data of an array of x,y values.
d3.selectAll("g.lines")
.on("mouseover", mouseoverFunc)
.on("mouseout", mouseoutFunc)
.on("mousemove", mousemoveFunc); // this version calls a named function.
svg.append("text")
.attr("class", "xlabel")
.attr("transform", "translate(" + width/2 + " ," +
height + ")")
.style("text-anchor", "middle")
.attr("dy", "40")
.text("Year");
svg.append("text")
.attr("class", "y label")
.attr("x", -width/2+100)
.attr("transform", "rotate(-90)")
.style("text-anchor", "middle")
.attr("dy", "-60")
.text("Wireless mobile broadband subscriptions Per 100 inhabitants");
groups.append("text")
.attr("class","grouptext")
.datum(function(d) { return {name: d.country, value: d.wireless[d.wireless.length - 1]}; })
.attr("transform", function(d) {
return "translate(" + xScale(dateFormat.parse(d.value.year)) + "," + yScale(+d.value.amount) + ")";
})
.attr("x", 3)
.attr("dy", ".35em")
.text(function(d) {
if (d.value && +d.value.amount > 125) {
return d.name;
}
if (d.value && +d.value.amount < 35) {
return d.name;
}
})
}); // end of data csv
function mouseoverFunc(d) {
// line styling:
// this is the g element. select it, then the line inside it!
//console.log(d, this);
d3.selectAll("path.line").classed("unfocused", true);
// now undo the unfocus on the current line and set to focused.
d3.select(this).select("path.line").classed("unfocused", false).classed("focused", true);
tooltip
.style("display", null) // this removes the display none setting from it
.html("<p>" + d.country + "</p>");
}
function mouseoutFunc() {
// this removes special classes for focusing from all lines. Back to default.
d3.selectAll("path.line").classed("unfocused", false).classed("focused", false);
tooltip.style("display", "none"); // this sets it to invisible!
}
function mousemoveFunc(d) {
//console.log("events", window.event, d3.event);
tooltip
.style("top", (d3.event.pageY - 10) + "px" )
.style("left", (d3.event.pageX + 10) + "px");
}
</script>
</body>
</html>
Country 2010 2011 2012 2013 2014
Australia 56.12 91.99 102.22 113.11 114.37
Austria 33.02 46 58.06 64.48 67.11
Belgium 9.56 18.96 32.91 51.51 57.72
Canada 29.48 38.4 45.52 51.68 54.25
Chile 8.45 17.97 28.27 35.57 49.82
Czech Republic 5.16 38.16 45.01 53.29 65.14
Denmark 63.92 83.51 97.34 102.26 115.51
Estonia 17.46 42.31 73.34 90.67 114.15
Finland 84.32 87.04 106.31 123.18 138
France 35.55 42.49 50 55.46 64.68
Germany 25.93 34.97 41.04 53.81 63.82
Greece 24.98 37.13 45.79 36.39 41.48
Hungary 8.79 17.2 23.16 26.48 34.28
Iceland 45.61 57.94 71.5 76 87.26
Ireland 44.46 58.72 64.09 67.53 82.08
Israel 48.63 51.53 51.23 50.52 49.88
Italy 38.21 44.92 50.36 61.76 70.9
Japan 76.31 81.94 85.41 111.98 124.11
Korea 95.78 102.12 103.03 103.33 106.48
Luxembourg 49.99 63.88 79.42 86.06 84.37
Mexico 4.22 12.45 20.91 29.24 42.51
Netherlands 38.02 52.52 61.18 64.21 68.99
New Zealand 38.67 66.26 71.13 84.99 98.78
Norway 74.38 76.08 83.57 89.6 87.98
OECDTotal 43.99 55.92 62.49 72.03 81.29
Poland 48 49.67 58.03 54.53 55.29
Portugal 24.27 27.7 33.04 37.27 45.75
Slovak Republic 20.79 32.35 35.43 50.43 59.91
Slovenia 24.19 29.02 35.34 40.26 46.97
Spain 27.5 64.53 53.4 67.33 78.06
Sweden 83.81 97.27 104.79 109.8 115.55
Switzerland 43.69 50.7 54.89 70.47 83.08
Turkey 9.89 19.89 26.33 31.9 42.19
United Kingdom 43.48 53.62 64.96 74.74 84.82
United States 61.02 77.63 86.19 94.17 103.95
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment