3

Using d3.js - I would like to create this kind of clock interface.

Ideally if there is a way to incorporate a 12 clock data driven way into this pie chart.

enter image description here

https://jsfiddle.net/qkHK6/2191/

var w = 400;
var h = 400;
var r = h / 2;
var color = d3.scale.category20c();

var data = [{
  "label": "Category B",
  "value": 70
}, {
  "label": "Category A",
  "value": 30
}];


var vis = d3.select('#chart').append("svg:svg").data([data]).attr("width", w).attr("height", h).append("svg:g").attr("transform", "translate(" + r + "," + r + ")");
var pie = d3.layout.pie().value(function(d) {
  return d.value;
});

// declare an arc generator function
var arc = d3.svg.arc().outerRadius(r);

// select paths, use arc generator to draw
var arcs = vis.selectAll("g.slice").data(pie).enter().append("svg:g").attr("class", "slice");
arcs.append("svg:path")
  .attr("fill", function(d, i) {
    return color(i);
  })
  .attr("d", function(d) {
    // log the result of the arc generator to show how cool it is :)
    console.log(arc(d));
    return arc(d);
  });
The Old County
  • 89
  • 13
  • 59
  • 129

1 Answers1

5

I think there is no magic bullet for this case. But, you can accomplish the goal with some mathematics.

jsfiddle is here in advance.

Ticks

Ticks can be drawn based on trigonometric functions. If you are scared about tons of formulas, just take a look at this and use them. He described it very neatly as pseudo-code (I guess).

var radius = 80;
var tickLength = 10;
var circleDegree = 360;

clockGroup.append('g')
  .attr('class', 'ticks')
  .selectAll('path')
  .data(splitDegrees(12))
  .enter()
  .append('path')
  .attr('d', function(d) {
    var coord = {
      outer: getCoordFromCircle(d, 0, 0, radius),
      inner: getCoordFromCircle(d, 0, 0, radius - tickLength)
    };
    return 'M' + coord.outer[0] + ' ' + coord.outer[1] + 'L' + coord.inner[0] + ' ' + coord.inner[1] + 'Z';
  });

function degToRad(degrees) {
  return degrees * Math.PI / 180;
}

// it'll give you xy-coord by degree from 12(or 0) o'clock 
function getCoordFromCircle(deg, cx, cy, r) {
  var rad = degToRad(deg);
  var x = cx + r * Math.cos(rad);
  var y = cy + r * Math.sin(rad);
  return [x, y];
}

function splitDegrees(num) {
  var angle = circleDegree / num;
  var degrees = [];

  for (var ang = 0; ang < circleDegree; ang += angle) {
    degrees.push(ang);
  }

  return degrees;
}

Arc range

In this case, you can draw it via simple d3 methods.

var fromClock = 9;
var toClock = 6;

var arc = d3.svg.arc()
  .innerRadius(0)
  .outerRadius(radius)
  .startAngle(clockToRad(fromClock, -1))
  .endAngle(clockToRad(toClock, 1));

clockGroup.append('path')
  .attr('d', arc)
  .style('fill', 'orange');

function clockToRad(clock, direction) {
  var unit = circleDegree / 12;
  var degree = direction > 0 ? unit * clock : unit * clock - circleDegree;
  return degToRad(degree);
}
Community
  • 1
  • 1
Jinyoung Kim
  • 1,885
  • 3
  • 14
  • 23
  • that is great man. I've tweaked it to make it look more like their designs. http://jsfiddle.net/3uz3nzpx/3/ -- I don't know if they would anticipate it to be an actual clock -- but thought this was a start. Is there a way to LOCK the clock to the start time? – The Old County Jul 03 '16 at 00:48
  • @TheOldCounty you don't want the clock to be animated? – Jinyoung Kim Jul 03 '16 at 11:41
  • 1
    @TheOldCounty If it was right, you just turn off `setInterval` function and change `startAngle` and `endAngle` of `minuteArc` and `hourArc` to what you want. http://jsfiddle.net/jkiimm/3uz3nzpx/4/ – Jinyoung Kim Jul 03 '16 at 11:57
  • Well not too sure - was looking for options -- what is the start and end time are not bang on 9, 6 -- what if the start time was 9:20 – The Old County Jul 03 '16 at 21:47
  • I've added a fraction element to the time -- so you can add a time and have it be 1/2 an hour. http://jsfiddle.net/3uz3nzpx/5/ – The Old County Jul 04 '16 at 22:05
  • @TheOldCounty great update. it is working about any time. – Jinyoung Kim Jul 05 '16 at 02:58
  • Actually I noticed the minute hand is broken -- when its 9:30 --- the minute hand is still stuck at 0. http://jsfiddle.net/3uz3nzpx/7/ – The Old County Jul 16 '16 at 04:18
  • were you able to fix the clock? – The Old County Jul 27 '16 at 21:23
  • @TheOldCounty I haven't enough time to fix it recently but, I made time a little bit. I've updated your fiddle and tried to reuse some functions instead of huge refactoring. `scale` functions are already made and you could expand usage of them. http://jsfiddle.net/3uz3nzpx/8/ – Jinyoung Kim Jul 29 '16 at 14:30
  • Where is the wrong? Isn't it right the orange arc area is drawn on between 9:15 - 18:00? – Jinyoung Kim Aug 02 '16 at 08:53