D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
LSLink
Full window
Github gist
calendar
Built with
blockbuilder.org
<!DOCTYPE html> <meta charset="utf-8"> <style> body { background: #222; margin: auto; width: 960px; } .tracks { fill: none; stroke: #000; stroke-width: 1.5px; } .bodies path { stroke: #000; stroke-width: 1.5px; } .bodies .text-path { stroke: none; } .bodies text { fill: #000; font: 500 16px "Helvetica Neue"; } </style> <svg width="500" height="500"></svg> <script src="//d3js.org/d3.v4.0.0-alpha.21.min.js"></script> <script> var svg = d3.select("svg"), width = +svg.attr("width"), height = +svg.attr("height"), radius = Math.min(width, height) / 1.9, bodyRadius = radius / 23, dotRadius = bodyRadius - 8; var pi = Math.PI; var fields = [ {radius: 0.2 * radius, format: d3.timeFormat("%B"), interval: d3.timeYear}, {radius: 0.3 * radius, format: formatDate, interval: d3.timeMonth}, {radius: 0.4 * radius, format: d3.timeFormat("%A"), interval: d3.timeWeek}, {radius: 0.6 * radius, format: d3.timeFormat("%-H hours"), interval: d3.timeDay}, {radius: 0.7 * radius, format: d3.timeFormat("%-M minutes"), interval: d3.timeHour}, {radius: 0.8 * radius, format: d3.timeFormat("%-S seconds"), interval: d3.timeMinute} ]; var color = d3.scaleRainbow() .domain([0, 360]); var arcBody = d3.arc() .startAngle(function(d) { return bodyRadius / d.radius; }) .endAngle(function(d) { return -pi - bodyRadius / d.radius; }) .innerRadius(function(d) { return d.radius - bodyRadius; }) .outerRadius(function(d) { return d.radius + bodyRadius; }) .cornerRadius(bodyRadius); var arcTextPath = d3.arc() .startAngle(function(d) { return -bodyRadius / d.radius; }) .endAngle(-pi) .innerRadius(function(d) { return d.radius; }) .outerRadius(function(d) { return d.radius; }); var g = svg.append("g") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); g.append("g") .attr("class", "tracks") .selectAll("circle") .data(fields) .enter().append("circle") .attr("r", function(d) { return d.radius; }); var body = g.append("g") .attr("class", "bodies") .selectAll("g") .data(fields) .enter().append("g"); body.append("path") .attr("d", function(d) { return arcBody(d) + "M0," + (dotRadius - d.radius) + "a" + dotRadius + "," + dotRadius + " 0 0,1 0," + -dotRadius * 2 + "a" + dotRadius + "," + dotRadius + " 0 0,1 0," + dotRadius * 2; }); body.append("path") .attr("class", "text-path") .attr("id", function(d, i) { return "body-text-path-" + i; }) .attr("d", arcTextPath); var bodyText = body.append("text") .attr("dy", ".35em") .append("textPath") .attr("xlink:href", function(d, i) { return "#body-text-path-" + i; }); tick(); d3.timer(tick); function tick() { var now = Date.now(); fields.forEach(function(d) { var start = d.interval(now), end = d.interval.offset(start, 1); d.angle = Math.round((now - start) / (end - start) * 360 * 100) / 100; }); body .style("fill", function(d) { return color(d.angle); }) .attr("transform", function(d) { return "rotate(" + d.angle + ")"; }); bodyText .attr("startOffset", function(d, i) { return d.angle <= 90 || d.angle > 270 ? "100%" : "0%"; }) .attr("text-anchor", function(d, i) { return d.angle <= 90 || d.angle > 270 ? "end" : "start"; }) .text(function(d) { return d.format(now); }); } function formatDate(d) { d = new Date(d).getDate(); switch (10 <= d && d <= 19 ? 10 : d % 10) { case 1: d += "st"; break; case 2: d += "nd"; break; case 3: d += "rd"; break; default: d += "th"; break; } return d; } </script>
https://d3js.org/d3.v4.0.0-alpha.21.min.js