JSFiddle - React, Tailwind, and code Playground

by RodrigoSC

HTML

<script src="http://d3js.org/d3.v3.min.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css">
<body>
	<div id='donut' class='wheelMenu'>
	</div>
	<div>
		Show this text: <input id="innerText" type="text" value="Type something here!" onkeyup="menu.setText($('#innerText').val());"/>
	</div>
	<div>
		<input id="turns" value="50" style="width: 20px;"/> turns and stop on <input id="slice" value="2" style="width: 20px;"/>
		<button onclick="menu.spin(parseInt($('#turns').val()), parseInt($('#slice').val()));">Spin!</button>
	</div>
	<div id="console" style="float:clear;">
		I'll write clever stuff here
	</div>
	<div id='donut2' class='wheelMenu'>
	</div>
</body>

CSS

.wheelMenu {
	max-width:400px;
	width: 100%;
}

body {
	font-family: arial;
}

svg.pie { max-height: 100%; }

svg.pie path {
	stroke-width: 0;
}

svg.pie .slice0 {
	fill: #c4b891;
}

svg.pie .slice1 {
	fill: #D44C5C;	
}

svg.pie .slice2 {
	fill: #f09156;	
}

svg.pie .slice3 {
	fill: #45B09A;
}

svg.pie .slice4 {
	fill: #80ad61;
}

svg.pie .slice5 {
	fill: #abd3d9;
}

svg.pie text {
	font-family: arial;
	fill: white;
	text-shadow: 1px 1px 1px #888;
}

svg.pie text.centerText {
	font-size: 1.3em;
}

svg.pie text.icon {
	font-family: FontAwesome;
}

svg.pie .selected text.icon {
	font-size: 1.3em;
}

JavaScript

window.wheelMenu = function(divid, selectedSlice, text, icons){

var dOrig, dChanged;
var iconPos = {x: 0, y: -68};
var minHeight = 100;
var maxHeight = 115;
var midPoint = maxHeight + 5;
var centerRadius = 40;
var animationDuration = 50;
var that = this;

that.canvas = {};

var init = function (divid, selectedSlice, text, icons) { 
	dOrig = buildPath(minHeight);
	dChanged = buildPath(maxHeight);
	that.canvas = d3.select(divid).append('svg')
		.attr('viewBox', '0 0 ' + midPoint*2 + ' ' + midPoint*2)
		.attr('preserveAspectRatio','xMinYMin meet')
		.classed('pie', true);
	for (var i = 0; i < 6; i++) {
		var tOrig = 'translate(' + midPoint + ',' + midPoint + ') rotate(' + (i*60) + ')';
		var g = that.canvas.append('g')
			.datum({slice: i})
			.classed('slice' + i, true)
			/* jshint -W083 */
			.on('mouseout', function(d) {that.updatePath(d.slice, dOrig);})
			.on('mouseover', function(d) {that.updatePath(d.slice, dChanged);})
			.on('click', function(d) {that.selectSlice(d.slice);})
			/* jshint +W083 */
			.attr('transform', tOrig);
		g.append('path')
			.attr('d', dOrig);
		g.append('text')
			.classed('icon', true)
			.text(icons[i])
			.datum({slice: i});
	}
	that.canvas.append('circle')
		.classed('center', true)
		.attr('cx', midPoint)
		.attr('cy', midPoint)
		.attr('r', centerRadius);
	that.canvas.append('text')
		.classed('centerText', true)
		.text('Hello');
	that.setText(text);
	centerText(that.canvas.selectAll('text.icon'), iconPos.x, iconPos.y);
	that.canvas.selectAll('text.icon').attr('transform', function(d) {return 'rotate(-'+ (d.slice *60) + ', '+ iconPos.x +', ' + iconPos.y + ')';});
	that.selectSlice(selectedSlice);
};

that.updatePath = function (i, path) {
	var pelem = that.canvas.select('g.slice'+i);
	if (!pelem.classed('selected'))
		pelem.select('path')
			.transition()
			.duration(animationDuration)
			.attr('d', path);
};

that.selectSlice = function (slice)...