Skip to content

Instantly share code, notes, and snippets.

@fraserxu
Created December 18, 2014 06:35
Show Gist options
  • Save fraserxu/fc1217314735bf608df3 to your computer and use it in GitHub Desktop.
Save fraserxu/fc1217314735bf608df3 to your computer and use it in GitHub Desktop.
china population choropleth
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.
var formatNumber = d3.format(",f")
var bodyNode = d3.select('body').node()
var Choropleth = function(json, options) {
var container = options.container || 'body'
var projection = options.projection
var w = options.width || 960
var h = options.height || 600
var colorScale = options.colorScale
var colors = options.colors
var path = options.path
var tooltip
var svg = d3.select(container)
.append('svg')
.attr('width', w)
.attr('height', h)
svg.selectAll('path')
.attr('class', 'province')
.data(json.features)
.enter()
.append('path')
.attr('d', path)
.style('fill', function(d) {
var total = d.properties.total
if (total) {
return colorScale(total)
} else {
return '#ccc'
}
})
.on('mouseover', function(d) {
d3.select('body').selectAll('div.tooltip').remove()
tooltip = d3.select('body').append('div')
.attr('class', 'tooltip')
.style('opacity', 0)
})
.on('mousemove', function(d) {
d3.select(this).transition().duration(300).style('opacity', 1)
tooltip.transition().duration(300)
.style('opacity', 1)
var absoluteMousePos = d3.mouse(bodyNode)
tooltip.text(d.properties.name + ' : ' + d.properties.total)
.style('left', (absoluteMousePos[0] + 10) + 'px')
.style('top', (absoluteMousePos[1] - 25) + 'px')
})
.on('mouseout', function() {
d3.select(this)
.transition().duration(300)
.style('opacity', 0.8)
tooltip.transition().duration(300)
.remove()
})
// legend
var legend = svg.selectAll('g.legend')
.data(colors)
.enter()
.append('g')
.attr('class', 'legend')
var ls_w = 20, ls_h = 20
legend.append('rect')
.attr('x', 20)
.attr('y', function(d, i) { return h - (i*ls_h) - 2*ls_h })
.attr('width', ls_w)
.attr('height', ls_h)
.style('fill', function(d) {
return d
})
legend.append('text')
.attr('x', 50)
.attr('y', function(d, i){ return h - (i*ls_h) - ls_h - 4})
.text(function(d, i){
return formatNumber(colorScale.invertExtent(d)[0]) + ' - ' + formatNumber(colorScale.invertExtent(d)[1])
})
}
var w = 960
var h = 600
var colors = ['rgb(237,248,233)', 'rgb(186,228,179)', 'rgb(116,196,118)', 'rgb(49,163,84)','rgb(0,109,44)']
var projection = d3.geo.mercator().center([105, 38]).scale(750).translate([w/2, h/2])
var path = d3.geo.path().projection(projection)
var colorScale = d3.scale.quantize().range(colors)
d3.csv('population.csv', function(data) {
colorScale.domain([ d3.min(data, function(d) { return d.total }), d3.max(data, function(d) { return d.total })])
d3.json('china_provinces.json', function(json) {
for (var i = 0; i < data.length; i++) {
var dataProvince = data[i].name
var total = parseInt(data[i].total)
var male = parseInt(data[i].male)
var female = parseInt(data[i].female)
for (var j = 0; j < json.features.length; j++) {
var jsonProvince = json.features[j].properties.name
if (jsonProvince == dataProvince) {
json.features[j].properties.total = total
json.features[j].properties.male = male
json.features[j].properties.female = female
break
}
}
}
// draw the choropleth
Choropleth(json, {
container: 'body',
colorScale: colorScale,
width: w,
height: h,
path: path,
colors: colors
})
})
})
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>China population choropleth</title>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="choropleth.js"></script>
</body>
</html>
name total male female
北京 1849475 941325 908150
天津 1127589 581562 546027
河北 7037620 3554766 3482854
山西 3477805 1771808 1705997
内蒙古 2310941 1186071 1124870
辽宁 4252076 2138602 2113474
吉林 2551123 1287411 1263712
黑龙江 3465051 1749344 1715707
上海 2253525 1151331 1102194
江苏 7577122 3792269 3784853
浙江 5400348 2761136 2639212
安徽 5312628 2678455 2634173
福建 3477491 1773098 1704393
江西 4251692 2188051 2063641
山东 9272503 4663609 4608894
河南 9224288 4650716 4573572
湖北 5226904 2658892 2568012
湖南 6096586 3114294 2982292
广东 9676589 5023631 4652958
广西 4362551 2249997 2112554
海南 826560 432579 393981
重庆 2609882 1310663 1299219
四川 8161604 4120256 4041348
贵州 3332265 1714400 1617865
云南 4467537 2300361 2167176
西藏 265904 134009 131895
陕西 3614887 1848641 1766246
甘肃 2623094 1330609 1292485
青海 535412 273891 261521
宁夏 611957 311355 300602
新疆 2086576 1061322 1025254
香港 723480 334270 389210
澳门 62400 30720 31680
台湾 2322491 1164567 1157923
.province {
fill: none;
stroke: #aaa;
stroke-width: 0.2px;
stroke-linejoin: round;
}
div.tooltip {
position: absolute;
text-align: center;
width: 100px;
height: 18px;
padding: 2px;
font-size: 10px;
background: #FFFFE0;
border: 1px;
border-radius: 2px;
pointer-events: none;
}
.axis path, .axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
}
@vincentjiang777
Copy link

returns error Uncaught TypeError: Cannot read property 'features' of null(…)

@jessicachinafile
Copy link

I was having the same error message. Just go to the top of the .json file and erase the two commented-out lines at the top.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment