123 строки
3.0 KiB
HTML
123 строки
3.0 KiB
HTML
<!DOCTYPE html>
|
|
<meta charset="utf-8">
|
|
<title>Polar Clock</title>
|
|
<style>
|
|
|
|
body {
|
|
position: relative;
|
|
background: #222;
|
|
width: 960px;
|
|
height: 700px;
|
|
}
|
|
|
|
div {
|
|
position: absolute;
|
|
right: 4px;
|
|
bottom: 4px;
|
|
color: #ddd;
|
|
font: 10px sans-serif;
|
|
}
|
|
|
|
a {
|
|
color: #fff;
|
|
font-weight: bold;
|
|
}
|
|
|
|
text {
|
|
font: bold 13px sans-serif;
|
|
}
|
|
|
|
</style>
|
|
<script src="../../d3.js"></script>
|
|
<div>Inspired by <a href="http://blog.pixelbreaker.com/polarclock/">pixelbreaker</a>.</div>
|
|
<script>
|
|
|
|
// Based on http://vis.stanford.edu/protovis/ex/clock.html
|
|
// Based on http://blog.pixelbreaker.com/polarclock
|
|
|
|
var width = 960,
|
|
height = 700,
|
|
radius = Math.min(width, height) / 1.8,
|
|
sectorWidth = .09,
|
|
fsec = d3.time.format("%S s"),
|
|
fmin = d3.time.format("%M m"),
|
|
fhou = d3.time.format("%H h"),
|
|
fwee = d3.time.format("%a"),
|
|
fdat = d3.time.format("%d d"),
|
|
fmon = d3.time.format("%b");
|
|
|
|
var fill = d3.scale.linear()
|
|
.range(["hsl(-180, 50%, 50%)", "hsl(180, 50%, 50%)"])
|
|
.interpolate(d3.interpolateString);
|
|
|
|
var arc = d3.svg.arc()
|
|
.startAngle(0)
|
|
.endAngle(function(d) { return d.value * 2 * Math.PI; })
|
|
.innerRadius(function(d) { return d.index * radius; })
|
|
.outerRadius(function(d) { return (d.index + sectorWidth) * radius; });
|
|
|
|
var svg = d3.select("body").append("svg")
|
|
.attr("width", width)
|
|
.attr("height", height)
|
|
.append("g")
|
|
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
|
|
|
|
var g = svg.selectAll("g")
|
|
.data(fields)
|
|
.enter().append("g");
|
|
|
|
g.append("path")
|
|
.style("fill", function(d) { return fill(d.value); })
|
|
.attr("d", arc);
|
|
|
|
g.append("text")
|
|
.attr("text-anchor", "middle")
|
|
.attr("dy", "1em")
|
|
.text(function(d) { return d.text; });
|
|
|
|
// Update arcs.
|
|
d3.timer(function() {
|
|
var g = svg.selectAll("g")
|
|
.data(fields);
|
|
|
|
g.select("path")
|
|
.style("fill", function(d) { return fill(d.value); })
|
|
.attr("d", arc);
|
|
|
|
g.select("text")
|
|
.attr("dy", function(d) { return d.value < .5 ? "-.5em" : "1em"; })
|
|
.attr("transform", function(d) {
|
|
return "rotate(" + 360 * d.value + ")"
|
|
+ "translate(0," + -(d.index + sectorWidth / 2) * radius + ")"
|
|
+ "rotate(" + (d.value < .5 ? -90 : 90) + ")"
|
|
})
|
|
.text(function(d) { return d.text; });
|
|
});
|
|
|
|
// Generate the fields for the current date/time.
|
|
function fields() {
|
|
var d = new Date;
|
|
|
|
function days() {
|
|
return 32 - new Date(d.getYear(), d.getMonth(), 32).getDate();
|
|
}
|
|
|
|
var second = (d.getSeconds() + d.getMilliseconds() / 1000) / 60,
|
|
minute = (d.getMinutes() + second) / 60,
|
|
hour = (d.getHours() + minute) / 24,
|
|
weekday = (d.getDay() + hour) / 7,
|
|
date = (d.getDate() - 1 + hour) / days(),
|
|
month = (d.getMonth() + date) / 12;
|
|
|
|
return [
|
|
{value: second, index: .7, text: fsec(d)},
|
|
{value: minute, index: .6, text: fmin(d)},
|
|
{value: hour, index: .5, text: fhou(d)},
|
|
{value: weekday, index: .3, text: fwee(d)},
|
|
{value: date, index: .2, text: fdat(d)},
|
|
{value: month, index: .1, text: fmon(d)},
|
|
];
|
|
}
|
|
|
|
</script>
|