Representation of the different speed of the Gregorian and Hijri calendars.
The date conversion is taken from this StackOverflow question
Representation of the different speed of the Gregorian and Hijri calendars.
The date conversion is taken from this StackOverflow question
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> | |
<style> | |
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; | |
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; | |
} | |
svg { width:100%; height: 100% } | |
</style> | |
</head> | |
<body> | |
<div id="graph"></div> | |
The Islamic Calendar (or Hijri Calendar) started at 622 AD. Its years are based on the lunar calendar, shorter than the solar calendar, so it will catch the Gregorian Calendar. | |
<script> | |
var duration = 3000; | |
var delay = 1500; | |
var width = 600; | |
var margin = 30; | |
var GregorianYear = (new Date()).getFullYear(); | |
var HijriYear = Math.round((GregorianYear - 622) * (33 / 32)); | |
var colors = ["#faa", "#afa"]; | |
var scaleToday = d3.scale.linear() | |
.domain([0, GregorianYear]) | |
.range([0, width]); | |
var endDate = 20526; | |
var scaleEnd = d3.scale.linear() | |
.domain([0, endDate]) | |
.range([0, width]); | |
var data = [{"name":"Gregorian","startDate": 691, "today": GregorianYear, "endDate": endDate}, | |
{"name":"Hijri","startDate": 0, "today": HijriYear, "endDate": endDate}]; | |
var canvas = d3.select("#graph").append("canvas") | |
.attr("width", 1000) | |
.attr("height", 400); | |
var context = canvas.node().getContext("2d"); | |
d3.transition() | |
.duration(duration) | |
.ease("linear") | |
.tween("zoom", function() { | |
return function(t) { | |
draw_graph(t, scaleToday, scaleToday, "startDate", "today"); | |
} | |
}) | |
.each("end", function() { | |
d3.transition() | |
.delay(delay) | |
.duration(duration) | |
.ease("linear") | |
.tween("zoom", function() { | |
return function(t) { | |
draw_graph(t, scaleToday, scaleEnd, "today", "today"); | |
} | |
}) | |
.each("end", function() { | |
d3.transition() | |
.delay(delay) | |
.duration(duration) | |
.ease("linear") | |
.tween("zoom", function() { | |
return function(t) { | |
draw_graph(t, scaleEnd, scaleEnd, "today", "endDate"); | |
} | |
}); | |
}); | |
}); | |
function draw_graph(progress, scaleIni, scaleEnd, ini, end){ | |
context.clearRect(0, 0, 1000, 400); | |
data.forEach(function(d, i){ | |
var curr_year = d[ini]*(1-progress) + progress*d[end]; | |
var curr_width = scaleIni(curr_year)*(1-progress) + progress * scaleEnd(curr_year); | |
context.fillStyle = colors[i]; | |
context.fillRect(margin, | |
margin + i*(30 + margin), | |
curr_width, | |
30); | |
context.fillStyle = "#000"; | |
context.font="15px Helvetica"; | |
context.fillText(Math.round(curr_year), | |
margin + 10 + curr_width, | |
50 + i*(30 + margin)); | |
}); | |
} | |
/* | |
var svg = d3.select("#graph").append("svg"); | |
var bars = svg.selectAll(".calbar") | |
.data(data) | |
.enter() | |
.append("rect") | |
.attr("class","calbar") | |
.attr("fill", function(d,i){return colors[i];}) | |
.attr("x", margin) | |
.attr("y", function(d,i){return margin + i*(30 + margin);}) | |
.attr("height", 30) | |
.attr("width", function(d){return scaleToday(d.startDate);}) | |
.transition() | |
.delay(delay) | |
.duration(duration) | |
.attr("width", function(d){return scaleToday(d.today);}) | |
.transition() | |
.delay(2*delay + duration) | |
.duration(duration) | |
.attr("width", function(d){return scaleEnd(d.today);}) | |
.transition() | |
.delay(3*delay + 2*duration) | |
.duration(duration) | |
.attr("width", function(d){return scaleEnd(endDate);}); | |
var labels = svg.selectAll(".label") | |
.data(data) | |
.enter() | |
.append("text") | |
.attr("class","label") | |
.attr("x", function(d){return margin + 10 + scaleToday(d.startDate);}) | |
.attr("y", function(d,i){return 50 + i*(30 + margin);}) | |
.attr("text-anchor","start") | |
.text(function(d){return d.startDate;}) | |
.transition() | |
.delay(delay) | |
.duration(duration) | |
.attr("x", function(d){return margin + 10 + scaleToday(d.today);}) | |
.tween("text", function(d) { | |
var i = d3.interpolate(this.textContent, d.today), | |
prec = (d + "").split("."), | |
round = (prec.length > 1) ? Math.pow(10, prec[1].length) : 1; | |
return function(t) { | |
this.textContent = Math.round(i(t) * round) / round; | |
}; | |
}) | |
.transition() | |
.delay(2*delay + duration) | |
.duration(duration) | |
.attr("x", function(d){return margin + 10 + scaleEnd(d.today);}) | |
.transition() | |
.delay(3*delay + 2*duration) | |
.duration(duration) | |
.attr("x", function(d){return margin + 10 + scaleEnd(endDate);}) | |
.tween("text", function(d) { | |
var i = d3.interpolate(this.textContent, endDate), | |
prec = (d + "").split("."), | |
round = (prec.length > 1) ? Math.pow(10, prec[1].length) : 1; | |
return function(t) { | |
this.textContent = Math.round(i(t) * round) / round; | |
}; | |
}); | |
var names = svg.selectAll(".name") | |
.data(data) | |
.enter() | |
.append("text") | |
.attr("class","label") | |
.attr("x", 2*margin) | |
.attr("y", function(d,i){return 30 + i*(30 + margin);}) | |
.attr("text-anchor","start") | |
.text(function(d){return d.name;}); */ | |
</script> | |
</body> |