Skip to content

Instantly share code, notes, and snippets.

@mourner
Last active October 7, 2019 13:28
Show Gist options
  • Save mourner/4946049 to your computer and use it in GitHub Desktop.
Save mourner/4946049 to your computer and use it in GitHub Desktop.
D3 Sun Heatmap example

This is a D3.js Heatmap example showing how the highest sun position of the day (which directly correlates with average temperature) changes over the year depending on the latitude of the place. The actual temperature chart would be shifted to the right a bit beacuse of thermal lag.

The data for the chart is calculated using SunCalc.

<!doctype html>
<meta charset="utf-8">
<style>
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
</style>
<body>
<script src="https://rawgit.com/mourner/suncalc/master/suncalc.js"></script>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script>
var margin = {top: 20, right: 20, bottom: 30, left: 30},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var now = new Date(),
start = d3.time.year.floor(now),
end = d3.time.year.ceil(now);
var x = d3.time.scale()
.range([0, width])
.domain([start, end]);
var y = d3.scale.linear()
.range([height, 0])
.domain([-90, 90]);
var color = d3.scale.linear()
.domain([90, 60, 30, 0])
.range(['#D7191C', '#FDAE61', '#ABD9E9', '#2C7BB6']);
var xAxis = d3.svg.axis()
.scale(x)
.orient('bottom');
var yAxis = d3.svg.axis()
.scale(y)
.orient('left');
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 + ')');
var data = [],
latitudes = y.ticks(90),
days = d3.range(0, 365, 2).map(function (i) { return d3.time.day.offset(start, i); });
for (var i = 0, len = latitudes.length - 1; i < len; i++) {
for (var j = 0, len2 = days.length - 1; j < len2; j++) {
var day1 = days[j],
day2 = days[j + 1],
lat1 = latitudes[i],
lat2 = latitudes[i + 1],
day = new Date((day1.valueOf() + day2.valueOf()) / 2),
lat = (lat1 + lat2) / 2;
var solarNoon = SunCalc.getTimes(day, lat, 0).solarNoon;
var altitude = SunCalc.getPosition(solarNoon, lat, 0).altitude * 180 / Math.PI;
data.push({
day1: day1,
day2: day2,
lat1: lat1,
lat2: lat2,
altitude: altitude
});
}
}
svg.selectAll('.cell')
.data(data)
.enter().append('rect')
.attr('x', function (d) { return x(d.day1); })
.attr('y', function (d) { return y(d.lat2); })
.attr('width', function (d) { return x(d.day2) - x(d.day1); })
.attr('height', function (d) { return y(d.lat1) - y(d.lat2); })
.attr('fill', function (d) { return color(d.altitude); });
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
</script>
@bojanvidanovic
Copy link

bojanvidanovic commented Feb 1, 2017

The path of Suncalc.js is wrong (404).

@sainanky
Copy link

is there any way to how to render json format data on that chart
i have json data of such type :
"HeatChartData": [
"Mar",
"Apr",
"May",
"34.87",
"0.00",
"26.00"
]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment