|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<style> |
|
|
|
body { |
|
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; |
|
margin: auto; |
|
position: relative; |
|
width: 960px; |
|
} |
|
|
|
#tooltip { |
|
position: absolute; |
|
width: 90px; |
|
height: auto; |
|
padding: 5px; |
|
margin-bottom: 10px; |
|
background-color: white; |
|
-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: sans-serif; |
|
font-size: 16px; |
|
line-height: 20px; |
|
} |
|
</style> |
|
<script src="//d3js.org/d3.v3.min.js"></script> |
|
<body> |
|
<div id="tooltip" class='hidden'> |
|
<p><strong><span id="key"></span></strong></p> |
|
<p style="margin-top: 5px">Count: <span id="value"></span></p> |
|
</div> |
|
</body> |
|
<script> |
|
var draw = function(error, data) { |
|
if (error) throw error; |
|
|
|
// set margins according to Mike Bostock's margin conventions |
|
// http://bl.ocks.org/mbostock/3019563 |
|
var margin = {top: 25, right: 40, bottom: 50, left: 75}; |
|
|
|
// set height and width of chart |
|
var width = 960 - margin.left - margin.right, |
|
height = 500 - margin.top - margin.bottom; |
|
|
|
var radius = Math.min(width, height) / 2; |
|
var color = d3.scale.category20c(); |
|
|
|
// specify column we want to plot |
|
var field = 'count'; |
|
|
|
// append the SVG tag with height and width to accommodate for margins |
|
var svg = d3.select("body") |
|
.append("svg") |
|
.attr("width", width + margin.left + margin.right) |
|
.attr("height", height + margin.top + margin.bottom) |
|
.append('g') |
|
.attr('class','chart') |
|
.attr("transform", "translate(" + width / 2 + "," + height * .52 + ")"); |
|
|
|
|
|
var tree = d3.layout.tree() |
|
.children(function(d) { |
|
return d.values; |
|
}) |
|
.sort(null) |
|
.size([2 * Math.PI, radius * radius]) |
|
.value(function(d) { return d.value; }); |
|
|
|
var arc = d3.svg.arc() |
|
.startAngle(function(d) { return d.x; }) |
|
.endAngle(function(d) { return d.x + d.dx; }) |
|
.innerRadius(function(d) { return Math.sqrt(d.y); }) |
|
.outerRadius(function(d) { return Math.sqrt(d.y + d.dy); }); |
|
|
|
var dummy = { |
|
"key": "root", |
|
"values" : [ |
|
{ |
|
"key": "Entire", |
|
"values" : [ |
|
{"key": "5", "count": 7}, |
|
{"key": "4", "count": 4} |
|
] |
|
}, |
|
{ |
|
"key": "Shared", |
|
"values" : [ |
|
{"key": "5", "count": 3} |
|
] |
|
}, |
|
{ |
|
"key": "Single", |
|
"values" : [ |
|
{"key": "5", "count": 1}, |
|
{"key": "4", "count": 5}, |
|
{"key": "3", "count": 8}, |
|
{"key": "2", "count": 3} |
|
] |
|
} |
|
] |
|
}; |
|
|
|
var nested = d3.nest() |
|
.key(function (d) { |
|
// first group by neighborhood |
|
return d.neighbourhood_cleansed; |
|
}) |
|
.key(function (d) { |
|
// then group by listings type |
|
return d.room_type; |
|
}) |
|
.rollup(function(leaves) { |
|
var stars = {} |
|
|
|
leaves.forEach(function (d) { |
|
stars[d.stars] = stars[d.stars] ? stars[d.stars] + 1 : 1; |
|
}); |
|
|
|
// count leaves at end |
|
return d3.entries(stars); |
|
}).entries(data); |
|
|
|
console.log(nested); |
|
|
|
var path = svg.datum({ "key": "root", "values": nested }) |
|
.selectAll("path") |
|
.data(tree.links(nodes)) |
|
.enter().append("path") |
|
.attr("display", function(d) { return d.depth ? null : "none"; }) // hide inner ring |
|
.attr("d", d3.svg.diagonal()) |
|
.style("stroke", "#fff") |
|
.style("fill", function(d) { return color(d.key); }) |
|
.style("fill-rule", "evenodd"); |
|
|
|
path.on("mousemove", function(d) { |
|
// get current positions |
|
var pos = d3.mouse(this); |
|
var tool = d3.select("#tooltip"); |
|
var format = d3.format('$.2f'); |
|
|
|
//move the tooltip into position |
|
var xpos = pos[0] + margin.left + radius - parseFloat(tool.style('width')) / 2; |
|
|
|
var ypos = pos[1] + margin.top + radius - parseFloat(tool.style('height')) - 15; |
|
|
|
// move tooltip div |
|
tool.style("left", xpos + "px") |
|
.style("top", ypos + "px"); |
|
|
|
// set price display |
|
tool.select("#key") |
|
.text(d['key']); |
|
|
|
//set count value display |
|
tool.select("#value") |
|
.text(d['value']); |
|
|
|
// show the tooltip |
|
d3.select("#tooltip").classed("hidden", false); |
|
}) |
|
.on("mouseout", function() { |
|
// hide tooltip |
|
d3.select("#tooltip").classed("hidden", true); |
|
}); |
|
} |
|
d3.csv("airbnb_top_neigh.csv", draw); |
|
</script> |
|
|