forked from majomo's block:
forked from anonymous's block:
forked from anonymous's block:
license: mit |
Geography | Year | Household_Count | Average_Household_Income | Average_Shelter_Cost | Average_STIR | |
---|---|---|---|---|---|---|
NEWFOUNDLAND and LABRADOR | 2011 | 201875 | 70936 | 754 | 18.3 | |
PRINCE EDWARD ISLAND | 2011 | 53620 | 68301 | 817 | 20.1 | |
NOVA SCOTIA | 2011 | 369760 | 69362 | 838 | 20.7 | |
NEW BRUNSWICK | 2011 | 298955 | 67122 | 757 | 19 | |
QUEBEC | 2011 | 3224260 | 68926 | 834 | 21.3 | |
ONTARIO | 2011 | 4600055 | 89873 | 1175 | 22.8 | |
MANITOBA | 2011 | 423200 | 74940 | 846 | 19.2 | |
SASKATCHEWAN | 2011 | 359375 | 81353 | 910 | 19.6 | |
ALBERTA | 2011 | 1285165 | 106241 | 1249 | 21.1 | |
BRITISH COLUMBIA | 2011 | 1610540 | 82674 | 1136 | 23.4 | |
YUKON | 2011 | 12950 | 92906 | 1084 | 19.2 | |
NORTHWEST TERRITORIES | 2011 | 14150 | 116039 | 1350 | 17.5 | |
NUNAVUT | 2011 | 8545 | 100417 | 852 | 11.1 |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>Core Housing Need in Canada</title> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script> | |
<link href='https://fonts.googleapis.com/css?family=Open+Sans+Condensed:300,700,300italic' rel='stylesheet' type='text/css'> | |
<style type="text/css"> | |
body { | |
margin: 0; | |
background-color: #fff; | |
font-family: Helvetica,Arial,sans-serif; | |
} | |
#container { | |
max-width: 700px; | |
position: relative; | |
margin-left: 20px; | |
margin-right: auto; | |
margin-top: 20px; | |
padding: 10px 50px; | |
background-color: #fff; | |
box-shadow: 2px 2px 2px 2px #ccc; | |
} | |
#chartbox { | |
max-width: 650px; | |
position: absolute; | |
top: 20px; | |
left: 850px; | |
padding: 10px; | |
box-shadow: 2px 2px 2px 2px #ccc; | |
/* visibility: hidden; */ | |
} | |
#mapBox { | |
max-width: 650px; | |
position: absolute; | |
top: 20px; | |
left: 1230px; | |
padding: 10px; | |
box-shadow: 2px 2px 2px 2px #ccc; | |
/* visibility: hidden; */ | |
} | |
p { | |
font-size: 16px; | |
color: #4e5a64; | |
margin: 15px 0 50px; | |
} | |
h1 { | |
font-weight: 700; | |
color: #4e5a64; | |
font-size: 32px; | |
} | |
h2 { | |
font-weight: 500; | |
color: #4e5a64; | |
font-size: 22px; | |
} | |
a:link { | |
text-decortion: none; | |
color: gray; | |
} | |
a:hover { | |
text-decoration: underline; | |
} | |
a:visited { | |
color: gray; | |
} | |
a:active { | |
color: #87ceeb; | |
} | |
svg { | |
background-color: #fff; | |
} | |
g.bar text { | |
font-size: 14px; | |
font-weight: 550; | |
text-anchor: end; | |
opacity: 0; | |
fill: #fff; | |
stroke: none; | |
} | |
g.bar:hover text { | |
opacity: 1; | |
} | |
.axis path,.axis line { | |
fill: none; | |
stroke: #4e5a64; | |
} | |
.axis text { | |
font-family: sans-serif; | |
font-size: 12px; | |
fill: #4e5a64; | |
stroke: none; | |
} | |
.y.axis path,.y.axis line { | |
opacity: 0; | |
} | |
path { stroke:#fff ; | |
stroke-width: .9px; | |
fill: #BDD684; | |
} | |
path:hover{ | |
fill: #5e6b42; | |
} | |
#mapBox { | |
background-color: white; | |
margin: auto; | |
max-width: 800px; | |
} | |
.header, | |
.info, | |
{ | |
margin: auto; | |
max-width: 800px; | |
} | |
#tooltip { | |
z-index: 1; | |
position: absolute; | |
width: auto; | |
height: auto; | |
padding: 6px; | |
background-color: white; | |
opacity: 1; | |
-webkit-border-radius: 10px; | |
-moz-border-radius: 10px; | |
border-radius: 10px; | |
-webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); | |
-moz-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); | |
box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); | |
pointer-events: none; | |
} | |
#tooltip.hidden { | |
display: none; | |
} | |
#tooltip p { | |
margin: 0; | |
font-family: 'Open Sans Condensed', sans-serif; | |
font-size: 1em; | |
line-height: 1; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="container"> | |
<h1>Core Housing Need in Canada - Part 1</h1> | |
<p>A household is said to be in core housing need if its housing falls | |
below at least one of the adequacy, affordability or suitability, | |
standards and it would have to spend 30% or more of its total | |
before-tax income to pay the median rent of alternative local housing | |
that is acceptable (meets all three housing standards).<br> | |
- Adequate housing are reported by their residents as not requiring any | |
major repairs.<br> | |
- Affordable dwellings costs less than 30% of total before-tax | |
household income.<br> | |
- Suitable housing has enough bedrooms for the size and make-up of | |
resident households, according to National Occupancy Standard (NOS) | |
requirements.</p> | |
<h2>What do Canadians earn?</h2> | |
<p>Average Household Income ($) by Province and Territory - 2011<br> | |
Source: <a href="http://cmhc.beyond2020.com/">Canada Mortgage and | |
Housing Corporation</a>, 2015</p> | |
</div> | |
<div id="chartbox"> | |
<h1>Regional Profile</h1> | |
</div> | |
<div id="mapBox"> | |
</div> | |
<script type="text/javascript"> | |
var w = 650; | |
var h = 450; | |
var padding = [20, 10, 30, 220]; //Top, right, bottom, left | |
var widthScale = d3.scale.linear() | |
.range([0, w - padding[1] - padding[3]]); | |
var heightScale = d3.scale.ordinal() | |
.rangeBands([padding[1], h / 1.2 - padding[1]], 0.1); | |
var xAxis = d3.svg.axis() | |
.scale(widthScale) | |
.orient("bottom") | |
.ticks(7) | |
//.tickFormat(function(d){return "$" + d; }) | |
//Sets up the axis with $ sign and , seperators. | |
.tickFormat(d3.format("$,.0f")); | |
var yAxis = d3.svg.axis() | |
.scale(heightScale) | |
.orient("left"); | |
var svg = d3.select("#container") | |
.append("svg") | |
.attr("width", w) | |
.attr("height", h); | |
var svg2 = d3.select("#chartbox") | |
.append("svg") | |
.attr("width", w / 2) | |
.attr("height", h * 1.5) | |
.attr("id", "redLine"); | |
/* | |
var recto = d3.select("g") | |
.attr("id", "blueLine"); | |
*/ | |
/* | |
============================ | |
*/ | |
d3.csv("coreHousingNeed-prov-tert.csv", function(data) | |
{ | |
data.sort(function(a, b){ | |
return d3.descending(+a.Average_Household_Income, +b.Average_Household_Income); | |
}); | |
widthScale.domain([0, d3.max(data, function(d){ | |
return +d.Average_Household_Income; | |
})]); | |
heightScale.domain(data.map(function(d){ | |
return d.Geography; | |
})); | |
/* | |
var recto2 = svg.selectAll("g") | |
.data(data) | |
.enter() | |
.append("g") | |
.on("click", function() | |
{ | |
// Determine if current line is visible | |
var active = blueLine.active ? false : true, | |
newOpacity = active ? 0 : 1; | |
// Hide or show the elements | |
d3.select("#blueLine") | |
.transition() | |
.duration(2000) | |
.style("opacity", newOpacity); | |
// Update whether or not the elements are active | |
blueLine.active = active; | |
}) | |
*/ | |
var groups = svg.selectAll("g") | |
.data(data) | |
.enter() | |
.append("g") | |
.attr("class", "bar"); | |
//"bar" class help us differentiate these groups | |
//from the groups created later for axes | |
var group = svg2.selectAll("g") | |
.data(data) | |
.enter() | |
.append("g") | |
.on("click", function(){ | |
// Determine if current line is visible | |
var active = redLine.active ? false : true, | |
newOpacity = active ? 0 : 1; | |
// Hide or show the elements | |
d3.select("#redLine") | |
.transition() | |
.duration(2000) | |
.style("opacity", newOpacity); | |
// Update whether or not the elements are active | |
redLine.active = active; | |
}); | |
//.attr("class", "bar"); | |
//Add a rect to each group | |
var rects = groups.append("rect") | |
.attr("x", padding[3]) | |
.attr("id", "blueLine") | |
.attr("y", function(d){ | |
return heightScale(d.Geography); | |
}) | |
.attr("width", 0) | |
.attr("height", heightScale.rangeBand()) | |
//.attr("fill", "green"); | |
.on("click", function(d){ | |
console.log(d); | |
}) | |
.attr({ | |
fill: function(d) | |
{ | |
if (d.Average_Household_Income > 90000){ | |
return "#FF0033"; | |
} | |
else if (d.Average_Household_Income < 70000){ | |
return "#CCCCFF"; | |
} | |
else{ | |
return "#33CCFF"; | |
} | |
} | |
}); | |
/* | |
.on("click", function(){ | |
// Determine if current line is visible | |
var active = blueLine.active ? false : true, | |
newOpacity = active ? 0 : 1; | |
// Hide or show the elements | |
d3.select("#blueLine") | |
.transition() | |
.duration(2000) | |
.style("opacity", newOpacity); | |
// Update whether or not the elements are active | |
blueLine.active = active; | |
}) | |
*/ | |
var numFormat = d3.format("$,"); | |
//Add a text element to each group | |
groups.append("text") | |
.attr("x", function(d) | |
{ | |
return padding[3] + widthScale(d.Average_Household_Income) - | |
3; | |
}) | |
.attr("y", function(d) | |
{ | |
return heightScale(d.Geography) + 17; | |
}) | |
.text(function(d) | |
{ | |
return "Average household income" + " " + numFormat(d.Average_Household_Income); | |
}) | |
var weebox = group.append("circle") | |
.attr("r", 90) | |
.attr("cx", 100) | |
.attr("cy", 100) | |
.attr("fill", "#ffffff") | |
.transition() | |
.duration(10000) | |
.attr( | |
{ | |
fill: function(d) | |
{ | |
if (d.Average_STIR > 100) | |
{ | |
return "#FF0033"; | |
} | |
else | |
{ | |
return "#bdd684"; | |
} | |
} | |
}) | |
.transition() | |
.duration(5000) | |
.attr("cx", 200) | |
.transition() | |
.duration(5000) | |
.attr("cx", 100); | |
var rects2 = group.select("circle") | |
.on("click", function(d){ | |
window.alert("You clicked the circle and now it will vanish"); | |
}) | |
rects.transition() | |
.delay(function(d, i) | |
{ | |
return i * 50; | |
}) | |
.duration(1000) | |
.attr("width", function(d) | |
{ | |
return widthScale(d.Average_Household_Income); | |
}); | |
/* | |
This simply creates text inside the SVG - can be handy to place info/detail | |
svg.append("text") | |
.attr("id","babyText") | |
.attr("fill-opacity",1) | |
.attr("x",260) | |
.attr("y",215) | |
.attr("fill","steelblue") | |
.text("babies called Kevin") | |
.append("tspan") | |
.attr("x",260) | |
.attr("dy",20) | |
.text("born in Zurich"); | |
*/ | |
svg.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(" + padding[3] + "," + (h / 1.11 - | |
padding[2]) + ")") | |
.call(xAxis); | |
svg.append("g") | |
.attr("class", "y axis") | |
.attr("transform", "translate(" + padding[3] + ",0)") | |
.call(yAxis); | |
}); | |
</script> | |
<script type="text/javascript"> | |
var width = 800, //5000 | |
height =700, | |
centered; //2500 | |
//Define the map projection, scale etc | |
var projection = d3.geo.albers() | |
.center([-3.5, 46.4]) | |
.rotate([121,-11]) | |
.scale(2600) | |
.translate([w / 2, h / 2]); | |
//define path generator | |
var path = d3.geo.path() | |
.projection(projection); | |
var svg3 = d3.select("#mapBox") | |
.append("svg") | |
.attr("width", w) | |
.attr("height", h * 1.5); | |
d3.json(src="https://gist.githubusercontent.com/majomo/1beba4e212d12f3d6e29/raw/1bd280591bc4959449505395c90f7ffdd2e2ddbd/bcGeo.json", function(json) | |
{ | |
//Bind data and create one path per GeoJSON feature | |
svg3.selectAll("path") | |
.data(json.features) | |
.enter() | |
.append("path") | |
.attr("d", path) | |
// .on('click', function(d) { console.log(d.properties.CDNAME) | |
.on("mousemove", function(d) { | |
var xPosition = parseFloat(d3.select(this).attr("cx")); | |
var yPosition = parseFloat(d3.select(this).attr("cy")); | |
var currentState = this; | |
d3.select(this).style('fill-opacity', 1); | |
//Update the tooltip position and value | |
d3.select("#tooltip") | |
.style("left", (d3.event.pageX+20) + "px") | |
.style("top", (d3.event.pageY ) + "px") | |
.select("#NAME") | |
.text(d.properties.CDNAME); | |
// //Show the tooltip | |
d3.select("#tooltip").classed("hidden", false); | |
}) | |
.on("mouseout", function() { | |
d3.selectAll('path') | |
.style({ | |
'fill-opacity':10}); | |
//Hide the tooltip | |
d3.select("#tooltip").classed("hidden", true); | |
}); | |
}); | |
</script> | |
</body> | |
</html> |