<head>
	<meta charset="utf-8">
	<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
  <link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>

</head>
<script src="https://cdn.rawgit.com/bm-w/d3/master/d3.js"></script>
html{
  height: 100%;
}
body {
  min-height: 100%;
  background: #000000;
  padding:0;
  margin:0;

}
.icon{
  font-family:fontawesome;
  font-weight:bold;
  font-size:30px;

}
.goal,.completed{
  font-family: 'Roboto','Myriad Set Pro', 'Lucida Grande', 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;
  fill:white;
  text-anchor:middle;
}
.goal{
  font-size: 30px;


}
.completed{
  font-size: 95px;
}
	//based on https://bl.ocks.org/mbostock/1096355
	//apple design:https://images.apple.com/watch/features/images/fitness_large.jpg
	"use strict";

	(function(){
		var gap = 2;

		var ranDataset = function () {
			var ran = Math.random();

			return    [
				{index: 0, name: 'move', icon: "\uF105", percentage: ran * 60 + 30},
				{index: 1, name: 'exercise', icon: "\uF101", percentage: ran * 60 + 30},
				{index: 2, name: 'stand', icon: "\uF106", percentage: ran * 60 + 30}
			];

		};

		var ranDataset2 = function () {
			var ran = Math.random();

			return    [
				{index: 0, name: 'move', icon: "\uF105", percentage: ran * 60 + 30}
			];

		};
		var colors = ["#e90b3a", "#a0ff03", "#1ad5de"];
		var width = 500,
				height = 500,
				τ = 2 * Math.PI;

		function build(dataset,singleArcView){

			var arc = d3.svg.arc()
					.startAngle(0)
					.endAngle(function (d) {
						return d.percentage / 100 * τ;
					})
					.innerRadius(function (d) {
						return 140 - d.index * (40 + gap)
					})
					.outerRadius(function (d) {
						return 180 - d.index * (40 + gap)
					})
					.cornerRadius(20);//modified d3 api only

			var background = d3.svg.arc()
					.startAngle(0)
					.endAngle(τ)
					.innerRadius(function (d, i) {
						return 140 - d.index * (40 + gap)
					})
					.outerRadius(function (d, i) {
						return 180 - d.index * (40 + gap)
					});

			var svg = d3.select("body").append("svg")
					.attr("width", width)
					.attr("height", height)
					.append("g")
					.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

			//add linear gradient, notice apple uses gradient alone the arc..
			//meh, close enough...


			var gradient = svg.append("svg:defs")
					.append("svg:linearGradient")
					.attr("id", "gradient")
					.attr("x1", "0%")
					.attr("y1", "100%")
					.attr("x2", "50%")
					.attr("y2", "0%")
					.attr("spreadMethod", "pad");

			gradient.append("svg:stop")
					.attr("offset", "0%")
					.attr("stop-color", "#fe08b5")
					.attr("stop-opacity", 1);

			gradient.append("svg:stop")
					.attr("offset", "100%")
					.attr("stop-color", "#ff1410")
					.attr("stop-opacity", 1);


			//add some shadows
			var defs = svg.append("defs");

			var filter = defs.append("filter")
					.attr("id", "dropshadow")

			filter.append("feGaussianBlur")
					.attr("in", "SourceAlpha")
					.attr("stdDeviation", 4)
					.attr("result", "blur");
			filter.append("feOffset")
					.attr("in", "blur")
					.attr("dx", 1)
					.attr("dy", 1)
					.attr("result", "offsetBlur");

			var feMerge = filter.append("feMerge");

			feMerge.append("feMergeNode")
					.attr("in", "offsetBlur");
			feMerge.append("feMergeNode")
					.attr("in", "SourceGraphic");

			var field = svg.selectAll("g")
					.data(dataset)
					.enter().append("g");

			field.append("path").attr("class", "progress").attr("filter", "url(#dropshadow)");

			field.append("path").attr("class", "bg")
					.style("fill", function (d) {
						return colors[d.index];
					})
					.style("opacity", 0.2)
					.attr("d", background);

			field.append("text").attr('class','icon');


			if(singleArcView){

				field.append("text").attr('class','goal').text("OF 600 CALS").attr("transform","translate(0,50)");
				field.append("text").attr('class','completed').attr("transform","translate(0,0)");

			}

			d3.transition().duration(1750).each(update);

			function update() {
				field = field
						.each(function (d) {
							this._value = d.percentage;
						})
						.data(dataset)
						.each(function (d) {
							d.previousValue = this._value;
						});

				field.select("path.progress").transition().duration(1750).delay(function (d, i) {
					return i * 200
				})
						.ease("elastic")
						.attrTween("d", arcTween)
						.style("fill", function (d) {
							if(d.index===0){
								return "url(#gradient)"
							}
							return colors[d.index];
						});

				field.select("text.icon").text(function (d) {
					return d.icon;
				}).attr("transform", function (d) {
							return "translate(10," + -(150 - d.index * (40 + gap)) + ")"

						});

				field.select("text.completed").text(function (d) {
					return Math.round(d.percentage /100 * 600);
				});

				setTimeout(update, 2000);

			}

			function arcTween(d) {
				var i = d3.interpolateNumber(d.previousValue, d.percentage);
				return function (t) {
					d.percentage = i(t);
					return arc(d);
				};
			}


		}


		build(ranDataset);
		build(ranDataset2,true);


	})()

Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.