|
|
|
<!DOCTYPE html> |
|
|
|
<html lang="en"> |
|
<head> |
|
<meta charset="utf-8" /> |
|
<title>Aggregate Value Graduated Size and Color Hexbin</title> |
|
<style> |
|
|
|
svg { |
|
background: #3b7e77; |
|
} |
|
.node { |
|
stroke: #fff; |
|
stroke-width: 1.5px; |
|
} |
|
|
|
.link { |
|
fill: none; |
|
stroke: #000; |
|
stroke-width: 1.5px; |
|
opacity: 0.4; |
|
marker-end: url(#end-arrow); |
|
} |
|
|
|
.domain { |
|
fill: none; |
|
stroke: #5ba8b8; |
|
} |
|
|
|
.tick > line { |
|
stroke: #5ba8b8; |
|
} |
|
|
|
.tick > text { |
|
fill: #5ba8b8; |
|
} |
|
|
|
</style> |
|
</head> |
|
<body> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.16/d3.min.js" charset="utf-8" type="text/javascript"></script> |
|
<script src="d3.hexbin.js" charset="utf-8" type="text/javascript"></script> |
|
<script> |
|
|
|
var xAtt = "carat"; |
|
var yAtt = "depth"; |
|
var hexsize = 5; |
|
|
|
bgColors = d3.scale.threshold().domain([1,1000,100000,1000000,5000000]).range(["none","none","#0481ad","#39957c","#c18779"]); |
|
fgColors = d3.scale.threshold().domain([1,1000,100000,1000000,5000000]).range(["none","#1d3b3d","#035c94","#386b5c","#363b37"]); |
|
|
|
priceSizeScale = d3.scale.linear().domain([1,1000,1001,100000,100001,1000000,1000001,5000000]).range([0,hexsize,0,hexsize,0,hexsize,0,hexsize]); |
|
|
|
//These attributes could be derived from the data |
|
attributes = ["carat","depth","table","price","x","y","z"]; |
|
|
|
d3.csv("https://gist.githubusercontent.com/emeeks/613cd391ba7e9a3a4042/raw/5c3711f9e3f55bea40ce21f765dc373a28cf72de/diamonds.csv", hexbin); |
|
|
|
d3.select("body").append("svg").attr("height", 850).attr("width", 800) |
|
|
|
function hexbin(data) { |
|
|
|
//d3.csv pulls in data as strings so they need to be formatted as numbers |
|
data.forEach(function (d) { |
|
attributes.forEach(function (att) { |
|
d[att] = parseFloat(d[att]) |
|
}) |
|
}) |
|
|
|
xExtent = d3.extent(data, function (d) {return d[xAtt]}); |
|
xScale = d3.scale.linear(); |
|
xScale.domain(xExtent).range([20,995]); |
|
|
|
yExtent = d3.extent(data, function (d) {return d[yAtt]}); |
|
console.log(yExtent) |
|
yScale = d3.scale.linear(); |
|
yScale.domain(yExtent).range([995,20]); |
|
|
|
var hexbin = d3.hexbin() |
|
.size([1000,1000]) |
|
.x(function (d) {return xScale(d[xAtt])}) |
|
.y(function (d) {return yScale(d[yAtt])}) |
|
.radius(hexsize); |
|
|
|
//bind the matrix array to a grid of g elements |
|
d3.select("svg") |
|
.append("g") |
|
.attr("class", "hexbin") |
|
.attr("transform", function (d) {return "translate(30,-200)" }); |
|
|
|
d3.select("g") |
|
.selectAll("path.bg") |
|
.data(hexbin(data)) |
|
.enter() |
|
.append("path") |
|
.style("fill", function (d) {return bgColors(d3.sum(d, function (d) {return d.price}))}) |
|
.style("stroke", function (d) {return bgColors(d3.sum(d, function (d) {return d.price}))}) |
|
.attr("d", function(d) { return hexbin.hexagon(hexsize); }) |
|
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); |
|
|
|
d3.select("g") |
|
.selectAll("path.fg") |
|
.data(hexbin(data)) |
|
.enter() |
|
.append("path") |
|
.style("fill", function (d) {return fgColors(d3.sum(d, function (d) {return d.price}))}) |
|
.style("stroke", function (d) {return fgColors(d3.sum(d, function (d) {return d.price}))}) |
|
.attr("d", lastNumber) |
|
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); |
|
|
|
yAxis = d3.svg.axis() |
|
.scale(yScale) |
|
.orient("left") |
|
.ticks(10) |
|
.tickSize(0) |
|
.tickSubdivide(true); |
|
|
|
xAxis = d3.svg.axis() |
|
.scale(xScale) |
|
.orient("bottom") |
|
.ticks(10) |
|
.tickSize(0) |
|
.tickSubdivide(true); |
|
|
|
d3.select("g.hexbin").append("g").call(yAxis) |
|
|
|
d3.select("g.hexbin").append("g").attr("transform", "translate(0,1000)").call(xAxis) |
|
|
|
function lastNumber(d) { |
|
|
|
var sl = d3.sum(d, function (d) {return d.price}); |
|
|
|
return hexbin.hexagon(priceSizeScale(sl)); |
|
} |
|
|
|
} |
|
|
|
|
|
|
|
</script> |
|
</body> |
|
</html> |