<div id="sticky-wrapper">
<div id="heat-map"></div>
</div>
body {
font-family: "Courier New", Courier, monospace;
}
.sticky-wrapper {
overflow: auto;
position: relative;
width: 75%;
}
table {
width: 10px;
border-collapse: collapse;
margin-bottom: 1em;
margin: 0 auto;
}
caption {
caption-side: top;
font-weight: bold;
font-size: 1.1em;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
}
th {
background-color: white;
font-weight: normal;
}
thead tr:nth-child(1) th {
position: sticky;
top: 0;
z-index: 10;
}
tbody th {
position: sticky;
left: 0;
z-index: 10;
}
td,
th {
padding: 0.75em 1.5em;
text-align: left;
}
td {
min-width: 20px;
width: 20px;
max-width: 30px;
}
.legend {
margin: 0 auto;
width: 25%;
font-family: roboto, arial;
font-size: 0.75em;
}
.color-square {
float: left;
width: 9%;
margin-right: 1%;
height: 1.5em;
}
.align-left {
float: left;
}
.align-right {
float: right;
}
.fa-snowflake {
color: #3c2ea8;
}
.cold {
color: #7a2ea1;
}
.fa-sun {
color: #f06e1d;
}
.hot {
color: #e61717;
}
p {
margin: 0.5rem auto;
width: 400px;
}
let min;
let max;
let colorScale;
let temps;
let tempsArr;
let colors = [
"#7A2EA1",
"#3C2EA8",
"#5D2EE8",
"#2F9EEE",
"#2FC8EE",
"#2DD91A",
"#CBF22C",
"#F2CE2C",
"#F06E1D",
"#E61717",
];
let months = [
"",
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
];
let table;
let thead;
let tbody;
let rows;
let cells;
let data = d3.json("temperatures.json", (error, data) => {
temps = data.meanTemp;
tempsArr = createTempArr(temps);
initScale();
initTable();
addTopHeader();
addRows();
setColorTransition();
addLegend();
});
function initTable() {
table = d3.select("#heat-map").append("table");
table
.append("caption")
.html(
"<i class='fas fa-snowflake cold'></i> UK Average Tempatures 1910 - 2012 <i class='fas fa-sun hot'></i>"
);
thead = table.append("thead");
tbody = table.append("tbody");
}
function initScale() {
min = d3.min(d3.values(temps), (d) => d3.min(d));
max = d3.max(d3.values(temps), (d) => d3.max(d));
colorScale = d3.scaleQuantile().domain([min, max]).range(colors);
}
function addTopHeader() {
// make top heading
thead
.append("tr")
.selectAll("th")
.data(months)
.enter()
.append("th")
.text((d) => d);
}
function addRows() {
// create a row for each object in the data
rows = tbody.selectAll("tr").data(tempsArr).enter().append("tr");
// create vertical heading (first col of each row)
rows.append("th").text((d) => d.year);
// create a data cell for each monthly tempature
cells = rows
.selectAll("td")
.data((row, i) => row.temps)
.enter()
.append("td")
.text((d) => d)
.style("background-color", colors[0]);
}
function createTempArr() {
let tempsArr = [];
for (let k in temps) {
if (temps.hasOwnProperty(k)) {
tempsArr.push({ year: k, temps: temps[k] });
}
}
return tempsArr;
}
function setColorTransition() {
cells
.transition()
.duration(1000)
.style("background-color", (d) => colorScale(d));
}
function addLegend() {
let rangeValues = [min];
rangeValues = rangeValues.concat(colorScale.quantiles());
let legend = d3.select("caption").append("div");
legend.attr("class", "legend");
let colorSq = legend.append("div");
colorSq
.selectAll("div")
.data(rangeValues)
.enter()
.append("div")
.attr("class", "color-square")
.style("background-color", (d, i) => colors[i]);
// .text(function(d) { return "≥ " + Math.round(d); }); //add range
let labels = legend.append("div");
labels.append("div").attr("class", "align-left").text("colder");
labels.append("div").attr("class", "align-right").text("hotter");
}
A heatmap looking at the average temperature range in the UK from 1910 to 2012. Coloured cells shows the magnitude of the values – showing colder temperatures in a purplish-blue hue, and hotter temperatures in a orangeish-red hue. To make it easier for referencing the data on any screen, the headings on the top and side are sticky.
The data was taken from Met Office UK.