clock

by Ryan

HTML

<script src="https://d3js.org/d3.v3.min.js"></script>
<center>
    <img style="width:350px; height:auto" src="http://asymmetrik.com/wp-content/uploads/2015/09/logo_stacked_dark.png"/>
    <div id="main"></div>
    <h1 id="time"></h1>
</center>

CSS

body { 
    background-color: #fcfcfc;
    font: 10px sans-serif;
}

rect.digit {
    stroke: #f5f5f5;
    fill: #fefefe;
}

.axis path {
    fill: none;
    stroke: none;
}
.axis line {
    fill: none;
    stroke: #aaa;
    shape-rendering: crispEdges;
}

line.connector {
    opacity: 0.15;
    stroke-width: 1;
    stroke: black;
    fill: none;
}

line.line {
    opacity: 0.5;
    stroke-width: 5;
    stroke: #f33;
    fill: none;
}

JavaScript

// Ranges for the digits in the clock
var clockRanges = [[0, 2], [0, 9], [0, 5], [0, 9], [0, 5], [0, 9]];

// How often to update the visualization
var epochTime = 500;

// Dimensions of the visualization
var margin = { top: 20, right: 10, bottom: 20, left: 10 };
var width = 400 - margin.right - margin.left, 
    height = 300 - margin.top - margin.bottom;

// Convenience variables for subcomponents of the visualization
var sectionWidth = (width/6);
var rectMargin = 0.3 * sectionWidth;
var rectWidth = sectionWidth - (rectMargin*2);

// Store axes for each digit
var axes = [];
for(var i=0; i<clockRanges.length; i++){
    var range = clockRanges[i];
    var scale = d3.scale.linear().range([height, 0]).domain(range);
    var axis = d3.svg.axis()
        .scale(scale).orient("left")
        .tickValues(d3.range(range[1] + 1))
        .tickFormat(d3.format(".0f"))
        .innerTickSize(-rectWidth)
        .outerTickSize(rectMargin);
    axes.push(axis);
}

// Build the base of the chart
var g = d3.select("div#main").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// Add rects for the digits
var digit = g.selectAll("rect").data(clockRanges);
digit.enter()
    .append("rect")
    .attr("class", "digit")
    .attr("x", function(d, i){ return sectionWidth*i + rectMargin; })
    .attr("y", 0)
    .attr("height", height)
    .attr("width", rectWidth);

// Append the axes
axes.forEach(function(e, i){
    g.append("g")
    .attr("class", "y axis")
    .attr("transform", "translate(" + (sectionWidth*i + rectMargin) + ",0)")
    .call(e);
});

// Redraws the visualization, updating it with the new data
var redraw = function(data){
    var lines = [
        [data[0], data[1]],
        [data[1], data[2]],
        [data[2], data[3]],
        [data[3], data[4]],
        [data[4], data[5]]
    ];
    
    //...