Skip to content

Instantly share code, notes, and snippets.

@SubSide
Created October 20, 2019 21:58
Show Gist options
  • Save SubSide/a919931049ee73efd0b15079ec7b9ccd to your computer and use it in GitHub Desktop.
Save SubSide/a919931049ee73efd0b15079ec7b9ccd to your computer and use it in GitHub Desktop.
<canvas id="buienradar" width="453" height="120"></canvas>
<script type="text/javascript">
function request() {
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
doDraw(xmlHttp.responseText);
}
xmlHttp.open("GET", "https://graphdata.buienradar.nl/forecast/json/?lat=52.16&lon=4.49", true); // true for asynchronous
xmlHttp.send(null);
}
function doDraw(text) {
let data = JSON.parse(text);
console.debug(data);
var canvas = document.getElementById("buienradar");
var ctx = canvas.getContext("2d");
ctx.font = "15px Arial";
ctx.fillStyle = data.color;
ctx.save();
ctx.translate(0, -20);
drawGraph(canvas, ctx, data.forecasts);
ctx.restore();
}
function drawGraph(canvas, ctx, forecasts) {
const partSize = canvas.width / (Math.floor(forecasts.length / 2) * 2);
// Save the state so we don't screw up later
ctx.save();
// Translate and scale so we can draw with the bottom-left being the origin
ctx.translate(0, canvas.height);
ctx.scale(1, -1);
//We start at 0,0
ctx.beginPath();
ctx.moveTo(0, 0);
// And then for each line we move to the corresponding value
var x = 0;
forecasts.forEach(function(item) {
ctx.lineTo(x++ * partSize, item.value);
});
// Then we make a line to the start and fill it
ctx.lineTo((x-1) * partSize, 0);
ctx.fill();
const verticals = forecasts.length/2;
// Vertical lines
for(var i = 1; i < verticals; i++) {
// Every non%3 line we want dim
if (i % 3 != 0) {
ctx.strokeStyle = "#e7e7e7"
} else {
ctx.strokeStyle = "#c4c4c4"
}
ctx.beginPath();
ctx.moveTo(i * partSize * 2, 0);
ctx.lineTo(i * partSize * 2, 100);
ctx.stroke();
}
ctx.strokeStyle = "#c4c4c4"
// Horizontal lines
ctx.beginPath();
ctx.moveTo(0, 40);
ctx.lineTo(canvas.width, 40);
ctx.moveTo(0, 70);
ctx.lineTo(canvas.width, 70);
ctx.stroke();
// Border around the field
ctx.beginPath();
ctx.lineTo(0, 0);
ctx.lineTo(0, 100);
ctx.lineTo(canvas.width, 100);
ctx.lineTo(canvas.width, 0);
ctx.lineTo(0, 0);
ctx.stroke();
// Draw the time text
drawTimeText(canvas, ctx, forecasts, partSize);
// Draw the light, heavy text
drawLightHeavyText(canvas, ctx);
// And restore the state
ctx.restore();
}
function drawTimeText(canvas, ctx, forecasts, partSize) {
ctx.save();
// We position ourselves
ctx.translate(0, -18);
ctx.textAlign = "left";
drawText(ctx, "Nu", 0)
ctx.textAlign = "center";
for (var i = 1; i < forecasts.length/6-1; i++) {
// We set all the times at the bottom except the last one
drawText(ctx, timeFromString(forecasts[i * 6].datetime), partSize * i * 6);
}
// If the last one is a %3 then we want to align the text to the right of the border
if (Math.floor(forecasts.length/2)%3 == 0) {
ctx.textAlign = "right";
drawText(ctx, timeFromString(forecasts[forecasts.length-1].datetime), canvas.width);
} else {
// Otherwise we want to center it under the last vertical lign
ctx.textAlign = "center";
drawText(ctx, timeFromString(forecasts[Math.floor(forecasts.length/6)*6].datetime), partSize * 6 * Math.floor(forecasts.length/6));
}
ctx.restore();
}
function drawLightHeavyText(canvas, ctx) {
ctx.save();
ctx.translate(canvas.width - 8, 7);
ctx.textAlign = "right";
ctx.shadowBlur=7;
// Here we draw light and heavy
drawText(ctx, "Licht", 0);
ctx.translate(0, 74);
drawText(ctx, "Zwaar", 0);
ctx.shadowBlur=0;
ctx.restore();
}
function drawText(ctx, text, x) {
ctx.save();
ctx.translate(x, 0);
ctx.scale(1, -1);
ctx.fillStyle = "black";
ctx.fillText(text, 0, 0);
ctx.restore();
}
function timeFromString(text) {
let date = new Date(text);
return date.getHours().pad()+":"+date.getMinutes().pad();
}
Number.prototype.pad = function(size) {
var s = String(this);
while (s.length < (size || 2)) {s = "0" + s;}
return s;
}
request();
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment