forked from mbostock's block: Heatmap (2D Histogram, CSV)
xxxxxxxxxx
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.label {
font-weight: bold;
}
.tile {
shape-rendering: crispEdges;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
function adjustTextLabels(selection) {
selection.selectAll('.axis text')
.attr("font-size","2em");
}
var margin = {top: 40, right: 90, bottom: 30, left: 50},
width = 400 - margin.top - margin.bottom,
height = 768 - margin.left - margin.right;
var parseDate = d3.time.format("%m/%d/%Y").parse,
formatDate = d3.time.format("%d");
//d3.scale.ordinal().rangeRoundBands([0, height], .05)
var y = d3.time.scale().range([0,height]),
x = d3.scale.linear().range([0, width]),
z = d3.scale.linear().range(["#fee0d2", "#de2d26"]);
// The size of the buckets in the CSV data file.
// This could be inferred from the data if it weren't sparse.
var yStep = 864e5,
xStep = 1;
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.csv("data_heatmap.csv", function(error, buckets) {
if (error) throw error;
// Coerce the CSV data to the appropriate types.
buckets.forEach(function(d) {
d.date = parseDate(d.date);
d.time_hour = +d.time_hour;
d.count = +d.count;
});
// Compute the scale domains.
y.domain(d3.extent(buckets, function(d) { return d.date; }));
x.domain(d3.extent(buckets, function(d) { return d.time_hour; }));
z.domain([0, d3.max(buckets, function(d) { return d.count; })]);
// Extend the y- and x-domain to fit the last bucket.
// For example, the x-bucket 3200 corresponds to values [3200, 3300].
y.domain([y.domain()[0], +y.domain()[1] + yStep]);
x.domain([x.domain()[0], x.domain()[1] + xStep]);
// Display the tiles for each non-zero bucket.
// See https://bl.ocks.org/3074470 for an alternative implementation.
svg.selectAll(".tile")
.data(buckets)
.enter().append("rect")
.attr("class", "tile")
.attr("y", function(d) { return y(d.date); })
.attr("x", function(d) { return x(d.time_hour); })
.attr("width", x(xStep) - x(0))
.attr("height", -(y(0) - y(yStep)))
.style("fill", function(d) { return z(d.count); });
// Add a legend for the color values.
var legend = svg.selectAll(".legend")
.data(z.ticks(14).slice(1).reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(" + (width + 25) + "," + (10-6 + i * 25) + ")"; });
legend.append("rect")
.attr("width", 25)
.attr("height", 25)
.style("fill", z);
legend.append("text")
.attr("x", 26)
.attr("y", 10)
.attr("dy", ".8em")
.text(String);
svg.append("text")
.attr("class", "label")
.attr("x", width + 25)
.attr("y", -7)
.attr("dy", ".8em")
.text("Count");
// Add an x-axis with label.
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + 0 + ")")
.call(d3.svg.axis().scale(x).orient("top").ticks(5)
.tickFormat(function(d,i) {
return"";
})
);
// remove the tick labels and add custom label later
// Add a y-axis with label.
svg.append("g")
.attr("class", "y axis")
.call(d3.svg.axis()
.scale(y)
.ticks(d3.time.days)
.tickFormat(formatDate)
.orient("left"));
// On y axis, Adjust tick marks
svg.selectAll(".y text")
.attr("transform","translate(0,10)");
// On y axis, Remove the extra 01 tick
// The index for that tick is 37
// Careful this index changes easily!!
svg.selectAll(".tick")
.filter(function (d,i) { return i === 37; })
.remove();
// Add label for y axis
svg.append("text")
.attr("class", "label")
.attr("y", 6)
.attr("dy", "-32")
.attr("dx", "-298")
.attr("font-size", "16px")
.attr("text-anchor", "middle")
.attr("transform", "rotate(-90)")
.text("Day of month (Dec 2016)");
// Add Dec 2016 - remove because seem weird
// svg.append("text")
// .attr("dy","-21px")
// .attr("dx","-40px")
// .attr("font-size", "13px")
// .attr("font-weight","800")
// .text("Dec");
// svg.append("text")
// .attr("dy","-8px")
// .attr("dx","-40px")
// .attr("font-size", "13px")
// .attr("font-weight","800")
// .text("2016");
//Add label for x axis
svg.append("text")
.attr("font-size", "14px")
.attr("class", "label")
.attr("x", width/2)
.attr("y", "-28")
.attr("text-anchor", "middle")
.text("Call Receive Time");
xLabels = svg.selectAll(".x");
hour1 = xLabels.append("g");
hour1.append("text")
.attr("transform","translate(25,-15)")
.text("00:00AM -");
hour1.append("text")
.attr("transform","translate(25,-5)")
.text("00:59AM");
hour1.attr("transform","translate(-15,0)")
.attr("class","hours");
hour2 = xLabels.append("g");
hour2.append("text")
.attr("transform","translate(109,-15)")
.text("01:00AM -");
hour2.append("text")
.attr("transform","translate(109,-5)")
.text("01:59AM");
hour2.attr("transform","translate(-32,0)")
.attr("class","hours");
hour3 = xLabels.append("g");
hour3.append("text")
.attr("transform","translate(194,-15)")
.text("02:00AM -");
hour3.append("text")
.attr("transform","translate(194,-5)")
.text("02:59AM");
hour3.attr("transform","translate(-51,0)")
.attr("class","hours");
hour4 = xLabels.append("g");
hour4.append("text")
.attr("transform","translate(281,-15)")
.text("03:00AM -");
hour4.append("text")
.attr("transform","translate(281,-5)")
.text("03:59AM");
hour4.attr("transform","translate(-71,0)")
.attr("class","hours");
hour5 = xLabels.append("g");
hour5.append("text")
.attr("transform","translate(368,-15)")
.text("04:00AM -");
hour5.append("text")
.attr("transform","translate(368,-5)")
.text("04:59AM");
hour5.attr("transform","translate(-93,0)")
.attr("class","hours");
});
</script>
https://d3js.org/d3.v3.min.js