paulo@62: <!DOCTYPE html> paulo@62: <meta charset="utf-8"> paulo@62: paulo@62: paulo@62: <style> paulo@62: paulo@62: body { paulo@62: background-color: #FFF; paulo@62: } paulo@62: paulo@62: text.digital { paulo@62: font-family: sans-serif; paulo@62: fill: #777; paulo@62: } paulo@62: paulo@62: .analog.seconds { paulo@62: fill: #CCC; paulo@62: } paulo@62: paulo@62: .analog.minutes { paulo@62: fill: #AAA; paulo@62: } paulo@62: paulo@62: .analog.hours { paulo@62: fill: #999; paulo@62: } paulo@62: paulo@62: .analog.past { paulo@62: fill: #EEE; paulo@62: } paulo@62: paulo@62: </style> paulo@62: paulo@62: paulo@62: <script src="d3.min.js"></script> paulo@62: paulo@62: paulo@62: <svg></svg> paulo@62: paulo@62: paulo@62: <script> paulo@62: paulo@62: var TAU = 2*Math.PI; paulo@63: var margin = {top: 10, right: 5, bottom: 5, left: 10}; paulo@62: paulo@62: var minutes_seconds_scale = d3.scale.linear() paulo@62: .domain([0, 60]) paulo@62: .range([0, TAU]); paulo@62: paulo@62: var hours_scale = d3.scale.linear() paulo@62: .domain([0, 24]) paulo@62: .range([0, TAU]); paulo@62: paulo@62: var tf = function(x) { return d3.format("02d")(Math.floor(x)) }; paulo@62: paulo@62: var render = function() { paulo@62: var ct = new Date(); paulo@62: var milliseconds = ct.getMilliseconds(); paulo@62: var seconds = ct.getSeconds() + (milliseconds/1000.0); paulo@62: var minutes = ct.getMinutes() + (seconds/60.0); paulo@62: var hours = ct.getHours() + (minutes/60.0); paulo@62: paulo@63: var svg_width = window.innerWidth - 20; paulo@63: var svg_height = window.innerHeight - 20; paulo@63: var c_x = (svg_width - margin.left - margin.right)/2; paulo@63: var c_y = (svg_height - margin.top - margin.bottom)/2; paulo@63: var r = Math.min(c_x, c_y); paulo@62: paulo@62: var or_seconds = r; paulo@62: var ir_seconds = r*0.75; paulo@62: paulo@62: var or_minutes = r*0.7; paulo@62: var ir_minutes = r*0.45; paulo@62: paulo@62: var or_hours = r*0.4; paulo@62: var ir_hours = r*0.15; paulo@62: paulo@62: var digital_text_scale = 0.75; paulo@62: paulo@62: var svg = d3.select("svg") paulo@63: .attr("width", svg_width) paulo@63: .attr("height", svg_height); paulo@62: paulo@65: svg = svg.selectAll("g").data([[margin.left, margin.top]]); paulo@65: svg.enter().append("g"); paulo@65: svg.attr("transform", function(d) { return "translate(" + d[0] + "," + d[1] + ")"; }); paulo@62: paulo@65: // DEBUG paulo@65: //var ts = svg.selectAll("text").data([ct]); paulo@65: //ts.enter().append("text") paulo@65: //ts.text(function(d) { return d3.time.format("%X")(d); }); paulo@62: paulo@65: var c = svg.selectAll("g").data([[c_x, c_y]]); paulo@65: c.enter().append("g"); paulo@65: c.attr("transform", function(d) { return "translate(" + d[0] + "," + d[1] + ")"; }); paulo@62: paulo@65: var cp = c.selectAll("path").data([ paulo@65: // class, outer radius, inner radius, start angle, end angle paulo@65: [ "analog seconds", or_seconds, ir_seconds, 0, minutes_seconds_scale(seconds) ], paulo@65: [ "analog seconds past", or_seconds, ir_seconds, minutes_seconds_scale(seconds), TAU ], paulo@65: [ "analog minutes", or_minutes, ir_minutes, 0, minutes_seconds_scale(minutes) ], paulo@65: [ "analog minutes past", or_minutes, ir_minutes, minutes_seconds_scale(minutes), TAU ], paulo@65: [ "analog hours", or_hours, ir_hours, 0, hours_scale(hours) ], paulo@65: [ "analog hours past", or_hours, ir_hours, hours_scale(hours), TAU ], paulo@65: ]); paulo@65: cp.enter().append("path") paulo@65: .attr("class", function(d) { return d[0]; }); paulo@65: cp paulo@65: .attr("d", d3.svg.arc() paulo@65: .outerRadius(function(d) { return d[1]; }) paulo@65: .innerRadius(function(d) { return d[2]; }) paulo@65: .startAngle(function(d) { return d[3]; }) paulo@65: .endAngle(function(d) { return d[4]; }) paulo@65: ); paulo@62: paulo@65: var ctxt = c.selectAll("text").data([ paulo@65: // class, x, size, val paulo@65: [ "digital seconds", ir_seconds, or_seconds - ir_seconds, seconds ], paulo@65: [ "digital minutes", ir_minutes, or_minutes - ir_minutes, minutes ], paulo@65: [ "digital hours", ir_hours, or_hours - ir_hours, hours ], paulo@65: ]); paulo@65: ctxt.enter().append("text") paulo@65: .attr("class", function(d) { return d[0]; }) paulo@65: ctxt paulo@65: .attr("x", function(d) { return d[1]; }) paulo@65: .attr("y", function(d) { return d[2]*digital_text_scale/3.0; }) paulo@65: .attr("font-size", function(d) { return d[2]*digital_text_scale + "px"; }) paulo@65: .text(function(d) { return tf(d[3]); }); paulo@62: paulo@62: } paulo@62: paulo@62: window.setInterval(render, 1000); paulo@62: paulo@62: paulo@62: </script>