|
<!DOCTYPE html> |
|
<head> |
|
<meta charset="utf-8"> |
|
<script src="https://unpkg.com/d3@4"></script> |
|
<script src="https://unpkg.com/d3-component@2"></script> |
|
<style> |
|
body { |
|
margin: 0px; |
|
} |
|
</style> |
|
</head> |
|
|
|
<body> |
|
<script> |
|
var width = 960, |
|
height = 500; |
|
|
|
var clock = (function (){ |
|
var outerRing = d3.component("circle") |
|
.render(function (d){ |
|
var strokeWidth = d.width * 0.01; |
|
d3.select(this) |
|
.attr("cx", d.width / 2) |
|
.attr("cy", d.height / 2) |
|
.attr("r", d.height / 2 - strokeWidth) |
|
.attr("fill", "none") |
|
.attr("stroke", "black") |
|
.attr("stroke-width", strokeWidth); |
|
}); |
|
|
|
var centralCircle = d3.component("circle") |
|
.render(function (d){ |
|
var radius = d.height * 0.04; |
|
d3.select(this) |
|
.attr("cx", d.width / 2) |
|
.attr("cy", d.height / 2) |
|
.attr("r", radius); |
|
}); |
|
|
|
var handLine = d3.component("line") |
|
.render(function (d){ |
|
var strokeWidth = d.height * d.handWidth; |
|
d3.select(this) |
|
.attr("x1", 0) |
|
.attr("y1", 0) |
|
.attr("x2", d.height / 2 * d.handLength) |
|
.attr("y2", 0) |
|
.attr("stroke", d.color || "black") |
|
.attr("stroke-width", strokeWidth); |
|
}); |
|
|
|
var hand = d3.component("g") |
|
.render(function (d){ |
|
d3.select(this) |
|
.attr("transform", "translate(" + [ |
|
d.width / 2, |
|
d.height / 2 |
|
] + ") rotate(" + d.handAngle + ")") |
|
.call(handLine, d); |
|
}); |
|
|
|
var hourHand = (function (){ |
|
function hourAngle(date){ |
|
//var midnight = d3.utcDay(date), |
|
var midnight = d3.timeDay(date), |
|
day = 1000 * 60 * 60 * 12, |
|
percent = (date.getTime() - midnight.getTime()) / day; |
|
return percent * 360 - 90; |
|
} |
|
return d3.component("g").render(function (d){ |
|
var angle = hourAngle(d.date); |
|
d3.select(this) |
|
.call(hand, d, { |
|
handLength: 0.7, |
|
handWidth: 0.03, |
|
handAngle: angle |
|
}); |
|
}); |
|
}()); |
|
|
|
var minuteHand = (function (){ |
|
function minuteAngle(date){ |
|
var topOtheHour = d3.timeHour(date), |
|
hour = 1000 * 60 * 60, |
|
percent = (date.getTime() - topOtheHour.getTime()) / hour; |
|
return percent * 360 - 90; |
|
} |
|
return d3.component("g").render(function (d){ |
|
var angle = minuteAngle(d.date); |
|
d3.select(this) |
|
.call(hand, d, { |
|
handLength: 0.85, |
|
handWidth: 0.015, |
|
handAngle: angle |
|
}); |
|
}); |
|
}()); |
|
|
|
var secondHand = (function (){ |
|
function secondAngle(date){ |
|
var topOtheMinute = d3.timeMinute(date), |
|
minute = 1000 * 60, |
|
percent = (date.getTime() - topOtheMinute.getTime()) / minute; |
|
return percent * 360 - 90; |
|
} |
|
return d3.component("g").render(function (d){ |
|
var angle = secondAngle(d.date); |
|
d3.select(this) |
|
.call(hand, d, { |
|
handLength: 0.9, |
|
handWidth: 0.005, |
|
handAngle: angle |
|
}); |
|
}); |
|
}()); |
|
|
|
// A new invention! |
|
var millisecondHand = (function (){ |
|
function millisecondAngle(date){ |
|
var topOtheSecond = d3.timeSecond(date), |
|
second = 1000, |
|
percent = (date.getTime() - topOtheSecond.getTime()) / second; |
|
return percent * 360 - 90; |
|
} |
|
return d3.component("g").render(function (d){ |
|
var angle = millisecondAngle(d.date); |
|
d3.select(this) |
|
.call(hand, d, { |
|
handLength: 0.08, |
|
handWidth: 0.004, |
|
handAngle: angle, |
|
color: "white" |
|
}); |
|
}); |
|
}()); |
|
|
|
return d3.component("svg") |
|
.render(function (d){ |
|
// d = Object.assign({}, d, { |
|
// date: d3.timeMinute.offset(d.date, d.timeZoneOffset * 60) |
|
// }); |
|
d3.select(this) |
|
.attr("width", d.width) |
|
.attr("height", d.height) |
|
.call(outerRing, d) |
|
.call(centralCircle, d) |
|
.call(hourHand, d) |
|
.call(minuteHand, d) |
|
.call(secondHand, d) |
|
.call(millisecondHand, d); |
|
}); |
|
}()); |
|
|
|
d3.timer(function (){ |
|
d3.select("body") |
|
.call(clock, { |
|
width: width, |
|
height: height, |
|
date: new Date(), |
|
//timeZoneOffset: 5.5 // India Standard Time |
|
}); |
|
}); |
|
|
|
</script> |
|
</body> |