Skip to content

Instantly share code, notes, and snippets.

@comfysquirrel
Forked from mbostock/.block
Last active September 28, 2016 01:59
Show Gist options
  • Save comfysquirrel/978afcb0ec55f49d85b7e67f5c0f65ed to your computer and use it in GitHub Desktop.
Save comfysquirrel/978afcb0ec55f49d85b7e67f5c0f65ed to your computer and use it in GitHub Desktop.

Revisions

  1. Jonathan Herman revised this gist Sep 28, 2016. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,3 @@
    Forked from [Mike Bostock's Polar Clock III](http://bl.ocks.org/mbostock/c150b717e18d387e1b98) to auto adjust to screen size.
    Forked from [Mike Bostock's Polar Clock III](http://bl.ocks.org/mbostock/c150b717e18d387e1b98) to auto fit to screen size.

    This is so that it makes a great screensaver using [liquidx's webviewscreensaver](https://github.com/liquidx/webviewscreensaver).
    This is so it makes a great screensaver using [liquidx's webviewscreensaver](https://github.com/liquidx/webviewscreensaver).
  2. Jonathan Herman revised this gist Sep 28, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,3 @@
    Forked from [Mike Bostock's Polar Clock III](bl.ocks.org/mbostock/c150b717e18d387e1b98) to auto adjust to screen size.
    Forked from [Mike Bostock's Polar Clock III](http://bl.ocks.org/mbostock/c150b717e18d387e1b98) to auto adjust to screen size.

    This is so that it makes a great screensaver using [liquidx's webviewscreensaver](https://github.com/liquidx/webviewscreensaver).
  3. Jonathan Herman revised this gist Sep 28, 2016. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,3 @@
    Forked from [Mike Bostock's Polar Clock III](bl.ocks.org/mbostock/c150b717e18d387e1b98) to auto adjust to window size.
    Forked from [Mike Bostock's Polar Clock III](bl.ocks.org/mbostock/c150b717e18d387e1b98) to auto adjust to screen size.

    I am using this as a screensaver through [liquidx/webviewscreensaver](https://github.com/liquidx/webviewscreensaver)
    This is so that it makes a great screensaver using [liquidx's webviewscreensaver](https://github.com/liquidx/webviewscreensaver).
  4. Jonathan Herman revised this gist Sep 28, 2016. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,3 @@
    Forked from [Mike Bostock's Polar Clock III](bl.ocks.org/mbostock/c150b717e18d387e1b98) to auto adjust to window size.

    I am using this as a screensaver through [liquidx/webviewscreensaver](https://github.com/liquidx/webviewscreensaver)
  5. Jonathan Herman revised this gist Sep 27, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -5,7 +5,7 @@
    body {
    background: #222;
    margin: auto;
    position: absolute;
    overflow: hidden;
    }

    .field-track,
  6. Jonathan Herman revised this gist Sep 27, 2016. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -5,6 +5,7 @@
    body {
    background: #222;
    margin: auto;
    position: absolute;
    }

    .field-track,
  7. Jonathan Herman revised this gist Sep 27, 2016. 1 changed file with 6 additions and 3 deletions.
    9 changes: 6 additions & 3 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -5,7 +5,6 @@
    body {
    background: #222;
    margin: auto;
    width: 960px;
    }

    .field-track,
    @@ -48,12 +47,16 @@
    <script src="//d3js.org/d3.v4.0.0-alpha.28.min.js"></script>
    <script>

    var width = window.innerWidth
    var height = window.innerHeight

    var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height"),
    radius = Math.min(width, height) / 1.9,
    armRadius = radius / 22,
    dotRadius = armRadius - 6;

    svg.attr("width", width)
    svg.attr("height", height)

    var duration = 750,
    now = new Date(Date.now() + 2 * duration);
  8. Jonathan Herman revised this gist Sep 24, 2016. 3 changed files with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -1 +0,0 @@
    Another [variation](/mbostock/b89c89ec6b58435956a1) of a [polar clock](/mbostock/1096355), inspired by a [Flash screensaver by pixelbreaker](http://blog.pixelbreaker.com/polarclock).
    Binary file removed preview.png
    Binary file not shown.
    Binary file removed thumbnail.png
    Binary file not shown.
  9. @mbostock mbostock revised this gist Mar 11, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -45,7 +45,7 @@

    </style>
    <svg width="960" height="960"></svg>
    <script src="//d3js.org/d3.v4.0.0-alpha.27.min.js"></script>
    <script src="//d3js.org/d3.v4.0.0-alpha.28.min.js"></script>
    <script>

    var svg = d3.select("svg"),
  10. @mbostock mbostock revised this gist Mar 6, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -45,7 +45,7 @@

    </style>
    <svg width="960" height="960"></svg>
    <script src="//d3js.org/d3.v4.0.0-alpha.24.min.js"></script>
    <script src="//d3js.org/d3.v4.0.0-alpha.27.min.js"></script>
    <script>

    var svg = d3.select("svg"),
  11. @mbostock mbostock revised this gist Mar 1, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -45,7 +45,7 @@

    </style>
    <svg width="960" height="960"></svg>
    <script src="//d3js.org/d3.v4.0.0-alpha.21.min.js"></script>
    <script src="//d3js.org/d3.v4.0.0-alpha.24.min.js"></script>
    <script>

    var svg = d3.select("svg"),
  12. @mbostock mbostock revised this gist Feb 25, 2016. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -34,7 +34,8 @@

    .field-tick circle,
    .field-tick text {
    transition: fill 750ms linear;
    transition: fill 250ms linear;
    transition-delay: 400ms;
    }

    .field-tick text {
  13. @mbostock mbostock revised this gist Feb 24, 2016. 1 changed file with 7 additions and 2 deletions.
    9 changes: 7 additions & 2 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -123,7 +123,12 @@

    (function tick() {
    var now = new Date,
    then = new Date(+now + duration);
    then = new Date(+now + duration),
    next = d3.timeSecond.offset(d3.timeSecond(then), 1),
    delay = next - duration - now;

    // Skip ahead a second if there’s not time for this transition.
    if (delay < duration) delay += 1000, then = next;

    fieldArm.transition()
    .duration(duration)
    @@ -140,7 +145,7 @@
    .classed("field-tick--disabled", function(d, i) { return i >= d.field.activeLength; })
    .classed("field-tick--active", function(d, i) { return i === d.field.activeIndex; });

    setTimeout(tick, d3.timeSecond.offset(d3.timeSecond(then), 1) - now);
    setTimeout(tick, delay);
    })();

    </script>
  14. @mbostock mbostock revised this gist Feb 24, 2016. 1 changed file with 88 additions and 86 deletions.
    174 changes: 88 additions & 86 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -8,28 +8,38 @@
    width: 960px;
    }

    .dot {
    fill: #222;
    .field-track,
    .field-arm {
    fill: none;
    stroke: #000;
    stroke-width: 1.5px;
    }

    .dot--major {
    fill: #000;
    .field-tick {
    transition: opacity 750ms linear;
    }

    .track,
    .body {
    fill: none;
    stroke: #000;
    stroke-width: 1.5px;
    .field-tick:not(.field-tick--active) circle,
    .field-tick:not(.field-tick--active):first-of-type text {
    fill: #222 !important;
    }

    .dot text {
    fill: #000;
    font: 700 14px "Helvetica Neue";
    .field-tick:not(.field-tick--active):first-of-type circle {
    fill: #000 !important;
    }

    .dot--major text {
    fill: #222;
    .field-tick--disabled {
    opacity: 0;
    }

    .field-tick circle,
    .field-tick text {
    transition: fill 750ms linear;
    }

    .field-tick text {
    font: 700 14px "Helvetica Neue";
    text-anchor: middle;
    }

    </style>
    @@ -41,104 +51,96 @@
    width = +svg.attr("width"),
    height = +svg.attr("height"),
    radius = Math.min(width, height) / 1.9,
    bodyRadius = radius / 22,
    dotRadius = bodyRadius - 6;
    armRadius = radius / 22,
    dotRadius = armRadius - 6;

    var duration = 750,
    now = new Date(Date.now() + 2 * duration);

    var pi = Math.PI;
    var pi = Math.PI,
    tau = pi * 2;

    var fields = [
    {radius: 0.2 * radius, format: d3.timeFormat("%b"), interval: d3.timeYear, subinterval: d3.timeMonth},
    {radius: 0.3 * radius, format: d3.timeFormat("%-d"), interval: d3.timeMonth, subinterval: d3.timeDay},
    {radius: 0.4 * radius, format: d3.timeFormat("%a"), interval: d3.timeWeek, subinterval: d3.timeDay},
    {radius: 0.6 * radius, format: d3.timeFormat("%-H"), interval: d3.timeDay, subinterval: d3.timeHour},
    {radius: 0.7 * radius, format: d3.timeFormat("%-M"), interval: d3.timeHour, subinterval: d3.timeMinute},
    {radius: 0.8 * radius, format: d3.timeFormat("%-S"), interval: d3.timeMinute, subinterval: d3.timeSecond}
    {radius: 0.2 * radius, interval: d3.timeYear, subinterval: d3.timeMonth, format: d3.timeFormat("%b")},
    {radius: 0.3 * radius, interval: d3.timeMonth, subinterval: d3.timeDay, format: d3.timeFormat("%d")},
    {radius: 0.4 * radius, interval: d3.timeWeek, subinterval: d3.timeDay, format: d3.timeFormat("%a")},
    {radius: 0.6 * radius, interval: d3.timeDay, subinterval: d3.timeHour, format: d3.timeFormat("%H")},
    {radius: 0.7 * radius, interval: d3.timeHour, subinterval: d3.timeMinute, format: d3.timeFormat("%M")},
    {radius: 0.8 * radius, interval: d3.timeMinute, subinterval: d3.timeSecond, format: d3.timeFormat("%S")}
    ];

    var color = d3.scaleRainbow()
    .domain([0, 360]);
    .domain([0, tau]);

    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 arcArm = d3.arc()
    .startAngle(function(d) { return armRadius / d.radius; })
    .endAngle(function(d) { return -pi - armRadius / d.radius; })
    .innerRadius(function(d) { return d.radius - armRadius; })
    .outerRadius(function(d) { return d.radius + armRadius; })
    .cornerRadius(armRadius);

    var field = svg.append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
    .selectAll("g")
    .selectAll(".field")
    .data(fields)
    .enter().append("g");
    .enter().append("g")
    .attr("class", "field");

    field.append("circle")
    .attr("class", "track")
    .attr("class", "field-track")
    .attr("r", function(d) { return d.radius; });

    field.append("path")
    .attr("class", "body")
    var fieldTick = field.selectAll(".field-tick")
    .data(function(d) {
    var date = d.interval(new Date(2000, 0, 1));
    d.range = d.subinterval.range(date, d.interval.offset(date, 1));
    return d.range.map(function(t) { return {time: t, field: d}; });
    })
    .enter().append("g")
    .attr("class", "field-tick")
    .attr("transform", function(d, i) {
    var angle = i / d.field.range.length * tau - pi / 2;
    return "translate(" + Math.cos(angle) * d.field.radius + "," + Math.sin(angle) * d.field.radius + ")";
    });

    fieldTick.append("circle")
    .attr("r", dotRadius - 3)
    .style("fill", function(d, i) { return color(i / d.field.range.length * tau); });

    fieldTick.append("text")
    .attr("dy", "0.35em")
    .text(function(d) { return d.field.format(d.time).slice(0, 2); });

    var fieldArm = field.append("path")
    .attr("class", "field-arm")
    .attr("transform", "rotate(0)")
    .attr("d", function(d) {
    return arcBody(d)
    return arcArm(d)
    + "M0," + (dotRadius - d.radius)
    + "a" + dotRadius + "," + dotRadius + " 0 0,1 0," + -dotRadius * 2
    + "a" + dotRadius + "," + dotRadius + " 0 0,1 0," + dotRadius * 2;
    });

    field
    .each(function(d) { d.time = d.subinterval(now); })
    .each(tick)
    .select(".text")
    .text(function(d) { return d.format(now); });

    function tick(d) {
    var field = d3.select(this),
    start = d.interval(d.time),
    end = d.interval.offset(start, 1);

    d.angle = Math.round((d.time - start) / (end - start) * 360 * 100) / 100;

    var dot = field.selectAll(".dot")
    .data(d.subinterval.range(+d.time, +d.time + (end - start) * (0.5 + bodyRadius / d.radius / pi)).map(function(t) {
    var t0 = d.interval(t), t1 = d.interval.offset(t0, 1);
    return {time: +t, angle: (t - t0) / (t1 - t0) * 360};
    }), function(d) { return d.time; });

    var dotEnter = dot.enter().append("g", ".body")
    .attr("class", function(d) { return d.angle ? "dot" : "dot dot--major"; })
    .attr("transform", function(p) { var a = (p.angle - 90) / 180 * pi; return "translate(" + Math.cos(a) * d.radius + "," + Math.sin(a) * d.radius + ")"; });

    dotEnter.append("circle")
    .attr("r", dotRadius - 3);
    (function tick() {
    var now = new Date,
    then = new Date(+now + duration);

    dotEnter.append("text")
    .style("text-anchor", "middle")
    .attr("dy", "0.35em")
    .text(function(p) { return d.format(p.time).slice(0, 2); });

    var transition = field.transition()
    fieldArm.transition()
    .duration(duration)
    .on("end", posttick);

    transition.selectAll(".dot")
    .filter(function(p) { return +p.time === +d.time; })
    .attr("class", "dot dot--active")
    .style("fill", color(d.angle));

    transition.select(".body")
    .style("fill", color(d.angle))
    .attr("transform", "rotate(" + d.angle + ")");

    function posttick() {
    var now = Date.now();

    dot.exit().remove();

    setTimeout(function() { field.each(tick); }, (d.time = d.subinterval(now + 2 * duration)) - duration - now);
    }
    }
    .each(function(d) {
    var start = d.interval(then);
    d.activeLength = d.subinterval.count(start, d.interval.offset(start, 1));
    d.activeIndex = d.subinterval.count(start, then);
    d.angle = d.activeIndex / d.range.length * tau;
    })
    .attr("transform", function(d) { return "rotate(" + d.angle / pi * 180 + ")"; })
    .style("fill", function(d) { return color(d.angle); });

    fieldTick
    .classed("field-tick--disabled", function(d, i) { return i >= d.field.activeLength; })
    .classed("field-tick--active", function(d, i) { return i === d.field.activeIndex; });

    setTimeout(tick, d3.timeSecond.offset(d3.timeSecond(then), 1) - now);
    })();

    </script>
  15. @mbostock mbostock created this gist Feb 24, 2016.
    2 changes: 2 additions & 0 deletions .block
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,2 @@
    license: gpl-3.0
    height: 960
    1 change: 1 addition & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    Another [variation](/mbostock/b89c89ec6b58435956a1) of a [polar clock](/mbostock/1096355), inspired by a [Flash screensaver by pixelbreaker](http://blog.pixelbreaker.com/polarclock).
    144 changes: 144 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,144 @@
    <!DOCTYPE html>
    <meta charset="utf-8">
    <style>

    body {
    background: #222;
    margin: auto;
    width: 960px;
    }

    .dot {
    fill: #222;
    }

    .dot--major {
    fill: #000;
    }

    .track,
    .body {
    fill: none;
    stroke: #000;
    stroke-width: 1.5px;
    }

    .dot text {
    fill: #000;
    font: 700 14px "Helvetica Neue";
    }

    .dot--major text {
    fill: #222;
    }

    </style>
    <svg width="960" height="960"></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 / 22,
    dotRadius = bodyRadius - 6;

    var duration = 750,
    now = new Date(Date.now() + 2 * duration);

    var pi = Math.PI;

    var fields = [
    {radius: 0.2 * radius, format: d3.timeFormat("%b"), interval: d3.timeYear, subinterval: d3.timeMonth},
    {radius: 0.3 * radius, format: d3.timeFormat("%-d"), interval: d3.timeMonth, subinterval: d3.timeDay},
    {radius: 0.4 * radius, format: d3.timeFormat("%a"), interval: d3.timeWeek, subinterval: d3.timeDay},
    {radius: 0.6 * radius, format: d3.timeFormat("%-H"), interval: d3.timeDay, subinterval: d3.timeHour},
    {radius: 0.7 * radius, format: d3.timeFormat("%-M"), interval: d3.timeHour, subinterval: d3.timeMinute},
    {radius: 0.8 * radius, format: d3.timeFormat("%-S"), interval: d3.timeMinute, subinterval: d3.timeSecond}
    ];

    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 field = svg.append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
    .selectAll("g")
    .data(fields)
    .enter().append("g");

    field.append("circle")
    .attr("class", "track")
    .attr("r", function(d) { return d.radius; });

    field.append("path")
    .attr("class", "body")
    .attr("transform", "rotate(0)")
    .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;
    });

    field
    .each(function(d) { d.time = d.subinterval(now); })
    .each(tick)
    .select(".text")
    .text(function(d) { return d.format(now); });

    function tick(d) {
    var field = d3.select(this),
    start = d.interval(d.time),
    end = d.interval.offset(start, 1);

    d.angle = Math.round((d.time - start) / (end - start) * 360 * 100) / 100;

    var dot = field.selectAll(".dot")
    .data(d.subinterval.range(+d.time, +d.time + (end - start) * (0.5 + bodyRadius / d.radius / pi)).map(function(t) {
    var t0 = d.interval(t), t1 = d.interval.offset(t0, 1);
    return {time: +t, angle: (t - t0) / (t1 - t0) * 360};
    }), function(d) { return d.time; });

    var dotEnter = dot.enter().append("g", ".body")
    .attr("class", function(d) { return d.angle ? "dot" : "dot dot--major"; })
    .attr("transform", function(p) { var a = (p.angle - 90) / 180 * pi; return "translate(" + Math.cos(a) * d.radius + "," + Math.sin(a) * d.radius + ")"; });

    dotEnter.append("circle")
    .attr("r", dotRadius - 3);

    dotEnter.append("text")
    .style("text-anchor", "middle")
    .attr("dy", "0.35em")
    .text(function(p) { return d.format(p.time).slice(0, 2); });

    var transition = field.transition()
    .duration(duration)
    .on("end", posttick);

    transition.selectAll(".dot")
    .filter(function(p) { return +p.time === +d.time; })
    .attr("class", "dot dot--active")
    .style("fill", color(d.angle));

    transition.select(".body")
    .style("fill", color(d.angle))
    .attr("transform", "rotate(" + d.angle + ")");

    function posttick() {
    var now = Date.now();

    dot.exit().remove();

    setTimeout(function() { field.each(tick); }, (d.time = d.subinterval(now + 2 * duration)) - duration - now);
    }
    }

    </script>
    Binary file added preview.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    Binary file added thumbnail.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.