d3.compose Heatmap
xxxxxxxxxx
<link rel="stylesheet" type="text/css" href="https://npmcdn.com/d3.compose@0.15.13/dist/d3.compose.css">
<style>
.chart {width: 940px; height: 480px; margin: 10px; font-family: sans-serif;}
.chart-axis .domain, .chart-axis .tick line {visibility: hidden;}
.chart-axis .tick text {font-family: Consolas, courier; fill: #aaa, font-size: 10px;}
.chart-heatmap rect {stroke: #e6e6e6; stroke-width: 2px;}
</style>
<div id="heatmap" class="chart"></div>
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3.chart/0.2.1/d3.chart.min.js"></script>
<script src="https://npmcdn.com/d3.compose@0.15.13/dist/d3.compose-all.js"></script>
<script>
var helpers = d3c.helpers;
var di = helpers.di;
var mixins = d3c.mixins;
// Heatmap Chart
// -------------
var Mixed = helpers.mixin(d3c.Chart, mixins.XY, mixins.XYValues, mixins.StandardLayer);
Mixed.extend('Heatmap', {
initialize: function() {
Mixed.prototype.initialize.apply(this, arguments);
this.standardLayer('Heatmap', this.base.append('g').classed('chart-heatmap', true));
},
zScale: helpers.property(),
onDataBind: function(selection, data) {
return selection.selectAll('rect')
.data(data, function(d) { return d.x + '-' + d.y; });
},
onInsert: function(selection) {
return selection.append('rect')
.attr('rx', 4)
.attr('ry', 4);
},
onEnter: function(selection) {
selection
.attr('fill', '#fff');
},
onMerge: function(selection) {
selection
.attr('x', this.barX)
.attr('y', this.barY)
.attr('width', this.barWidth)
.attr('height', this.barHeight);
},
onMergeTransition: function(selection) {
selection
.attr('fill', this.barFill);
},
itemHeight: function() {
var scale = this.yScale();
if (scale && scale.width) {
return scale.width();
} else if (scale && scale.rangeBand) {
return scale.rangeBand() || 0;
} else {
return 0;
}
},
barX: di(function(chart, d, i, j) {
return chart.x.call(this, d, i, j) - (chart.itemWidth() / 2);
}),
barY: di(function(chart, d, i, j) {
return chart.y.call(this, d, i, j) - (chart.itemHeight() / 2);
}),
barWidth: di(function(chart, d, i, j) {
return chart.itemWidth();
}),
barHeight: di(function(chart, d, i, j) {
return chart.itemHeight();
}),
barFill: di(function(chart, d, i, j) {
return chart.zScale()(d.z);
})
});
// Create chart
// ------------
// (from https://bl.ocks.org/tjdecke/5558084)
var config = {
colors: ["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#253494","#081d58"],
days: ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
times: ["1a", "2a", "3a", "4a", "5a", "6a", "7a", "8a", "9a", "10a", "11a", "12a", "1p", "2p", "3p", "4p", "5p", "6p", "7p", "8p", "9p", "10p", "11p", "12p"],
buckets: 9
};
var chart = d3.select('#heatmap').chart('Compose', function(data) {
var xScale = {type: 'ordinal', domain: config.times, padding: 0};
var yScale = {type: 'ordinal', domain: config.days.reverse(), padding: 0};
var zScale = d3.scale.quantile()
.domain([0, config.buckets - 1, d3.max(data, function(d) { return d.value; })])
.range(config.colors);
var charts = [
{type: 'Heatmap', id: 'heatmap', data: data, xScale: xScale, yScale: yScale, zScale: zScale}
];
var xAxis = d3c.axis({scale: xScale});
var yAxis = d3c.axis({scale: yScale});
return [
xAxis,
[yAxis, d3c.layered(charts)],
];
}).width(940).height(300);
// Draw chart
// ----------
d3.tsv('data.tsv', function(d) {
return {
hour: +d.hour,
day: +d.day,
value: +d.value,
x: config.times[+d.hour - 1],
y: config.days[+d.day - 1],
z: +d.value
};
}, function(err, data) {
chart.draw(data);
});
</script>
https://d3js.org/d3.v3.min.js
https://cdnjs.cloudflare.com/ajax/libs/d3.chart/0.2.1/d3.chart.min.js
https://npmcdn.com/d3.compose@0.15.13/dist/d3.compose-all.js