Skip to content

Instantly share code, notes, and snippets.

@curran
Last active March 13, 2017 15:58
Show Gist options
  • Save curran/6a8c2817009a200e291707e4a1079bf0 to your computer and use it in GitHub Desktop.
Save curran/6a8c2817009a200e291707e4a1079bf0 to your computer and use it in GitHub Desktop.
[unlisted] Poorly Performing Clock
license: mit

A clock, constructed using nested components with d3-component.

Since we're not confined to physical limitations, why not have a "millisecond hand"?!

This is the first pass at implementing a clock, using d3-component "all the way down". This is not the most efficient way of doing it, because of the unnecessary garbage collection (visible using Chrome's "Allocation Timeline"). Take a look at this example - Clock - which is an optimized implementation of this one.

Built with blockbuilder.org

forked from curran's block: Clock

<!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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment