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>