Skip to content

Instantly share code, notes, and snippets.

@bhvaleri
Last active August 29, 2015 14:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bhvaleri/11103877 to your computer and use it in GitHub Desktop.
Save bhvaleri/11103877 to your computer and use it in GitHub Desktop.
Pie Chart v1
<!doctype html>
<html>
<style>
line {
cursor: -webkit-grab;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script>
var myData = [
{ id: 'a', count: 33, colour: 'steelblue' },
{ id: 'b', count: 33, colour: 'tomato' },
{ id: 'c', count: 34, colour: 'teal' },
];
for (var i = 0; i < myData.length; i++) {
myData[i].neighbour = myData[(i+1) % myData.length];
}
var width = 960,
height = 500,
size = Math.min(width, height) / 2,
radius = size - 10
var arc = d3.svg.arc()
.outerRadius(radius)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.count; });
var pieData = pie(myData);
var svg = d3.select('body').append('svg')
.attr('width', width)
.attr('height', height);
var stuff = svg.append('g')
.attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');
var arcsLayer = stuff.append('g').attr('id', 'frederick-d-orcslayer');
var linesLayer = stuff.append('g').attr('id', 'buffy-t-lineslayer');
// MOUSE STUFF
var currentSelected = null;
var mouseDown = function () {
currentSelected = this;
d3.select(window)
.on('mousemove', mouseMove)
.on('mouseup', mouseUp);
};
var mouseUp = function () {
console.log('mouseup');
d3.select(window)
.on('mousemove', null)
.on('mouseup', null);
currentSelected = null;
};
var normalize = function (angle) {
return (2 * Math.PI + angle ) % (2 * Math.PI)
};
var mouseMove = function () {
if (currentSelected) {
var line = d3.select(currentSelected);
var firstArc = line.datum();
var neighbour = firstArc.data.neighbour;
var secondArc = pieData[myData.indexOf(neighbour)];
var point = d3.mouse(stuff.node());
var newAngle = normalize(Math.atan2(point[1], point[0]) + Math.PI / 2);
// there must be a better way
if (firstArc.startAngle > secondArc.endAngle) {
if (newAngle > secondArc.endAngle && newAngle < firstArc.startAngle) {
return;
}
}
else if (newAngle < firstArc.startAngle || newAngle > secondArc.endAngle) {
return;
}
firstArc.endAngle = newAngle;
secondArc.startAngle = newAngle;
if (firstArc.endAngle < firstArc.startAngle) {
firstArc.endAngle += Math.PI * 2;
}
if (secondArc.startAngle >= secondArc.endAngle) {
secondArc.startAngle -= Math.PI * 2;
}
refresh();
}
};
var refresh = function () {
var arcs = arcsLayer.selectAll('.arc')
.data(pieData);
arcs.enter().append('path')
.attr('class', 'arc')
.style('fill', function (d) { return d.data.colour; })
.style('opacity', 0.5);
arcs.attr('d', arc);
var lines = linesLayer.selectAll('line')
.data(pieData);
lines.enter().append('line')
.style('stroke', 'darkslategray')
.style('stroke-width', '3px')
.attr('x1', 0)
.attr('y1', 0)
.on('mousedown', mouseDown);
lines
.attr('x2', function (d) { return (radius ) * Math.sin( Math.PI - d.endAngle);})
.attr('y2', function (d) { return (radius ) * Math.cos( Math.PI - d.endAngle);});
}
refresh();
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment