-
-
Save waharnum/e9e8d710bcc55304a380 to your computer and use it in GitHub Desktop.
Pie chart + table example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>D3: Pie layout</title> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> | |
<style type="text/css"> | |
svg text { | |
font-family: sans-serif; | |
font-size: 12px; | |
fill: white; | |
} | |
svg g:focus, | |
svg g:hover | |
{ | |
outline:none; | |
} | |
svg g:hover path, | |
svg g:focus path, | |
svg g.matched path | |
{ | |
fill: black; | |
} | |
table tr:hover td, | |
table tr:focus td, | |
table tr.matched td { | |
background-color:black; | |
color: white; | |
} | |
</style> | |
</head> | |
<body> | |
<p id="add"> | |
Click to add. | |
</p> | |
<p id="subtract"> | |
Click to subtract. | |
</p> | |
<script type="text/javascript"> | |
var randomInteger = function(min, max) { | |
return Math.floor(Math.random() * (max - min)) + min; | |
} | |
//Width and height | |
var w = 500; | |
var h = 500; | |
var dataset = [ | |
{label: "iPhone", value: 400}, | |
{label: "Android", value: 370}, | |
{label: "Windows Phone", value: 25}, | |
{label: "Blackberry", value:87} | |
]; | |
// Label-based key function | |
var key = function(d) { | |
return d.label; | |
}; | |
var findMatchingSliceByLabel = function(matchLabel, selector) { | |
de = d3.selectAll(selector).filter(function (d) { | |
if(matchLabel == d.data.label) return true; | |
}); | |
return de; | |
} | |
var findMatchingRowByLabel = function(matchLabel, selector) { | |
de = d3.selectAll(selector).filter(function (d) { | |
if(matchLabel == d.label) return true; | |
}); | |
return de; | |
} | |
var outerRadius = w / 2; | |
var innerRadius = 0; | |
var arc = d3.svg.arc() | |
.innerRadius(innerRadius) | |
.outerRadius(outerRadius); | |
var pie = d3.layout.pie() | |
.value(function(d) { return d.value }); | |
//Easy colors accessible via a 20-step ordinal scale | |
var color = d3.scale.category20(); | |
//Create SVG element | |
var svg = d3.select("body") | |
.append("svg") | |
.attr("width", w) | |
.attr("height", h); | |
//Create table element | |
var table = d3.select("body") | |
.append("table") | |
.append("tbody"); | |
//Set up groups | |
var arcs = svg.selectAll("g.arc") | |
.data(pie(dataset, key)) | |
.enter() | |
.append("g") | |
.on("mouseover", function(d,i) { | |
elem = findMatchingRowByLabel(d3.select(this).data()[0].data.label, "table tbody tr") | |
.classed("matched",true); | |
}) | |
.on("mouseout", function(d,i) { | |
elem = findMatchingRowByLabel(d3.select(this).data()[0].data.label, "table tbody tr") | |
.classed("matched",false); | |
}) | |
.attr("tabindex", function(d,i) { | |
return i; | |
}) | |
.attr("class", "arc") | |
.attr("transform", "translate(" + outerRadius + "," + outerRadius + ")"); | |
//Set up table | |
var rows = table.selectAll("tbody tr") | |
.data(dataset, key) | |
.enter() | |
.append("tr") | |
.on("mouseover", function(d,i) { | |
findMatchingSliceByLabel(d3.select(this).data()[0].label, "svg g.arc") | |
.classed("matched", true); | |
}) | |
.on("mouseout", function(d,i) { | |
findMatchingSliceByLabel(d3.select(this).data()[0].label, "svg g.arc") | |
.classed("matched", false); | |
}) | |
.html(function(d, i) { | |
return "<td>"+d.label+"</td>"+ | |
"<td>"+d.value+"</td>"+ | |
"<td style='background-color:"+color(i)+";'> </td>"; | |
}); | |
//Draw arc paths | |
arcs.append("path") | |
.attr("fill", function(d, i) { | |
return color(i); | |
}) | |
.attr("d", arc); | |
//Labels | |
arcs.append("text") | |
.attr("transform", function(d) { | |
return "translate(" + arc.centroid(d) + ")"; | |
}) | |
.attr("text-anchor", "middle") | |
.text(function(d) { | |
// return d.data.label; | |
return d.value; | |
}); | |
d3.selectAll("p") | |
.on("click", function() { | |
paragraphId = this.id; | |
if(paragraphId == "add") { | |
newValue = {label: "Random Phone Brand #"+randomInteger(1000,50000), value: randomInteger(50,600)}; | |
// newValue = randomInteger(0,30); | |
dataset.push(newValue); | |
} else if(paragraphId == "subtract") { | |
dataset.pop(); | |
} | |
var arcs = svg.selectAll("g.arc") | |
.data(pie(dataset, key)); | |
arcs.select("path") | |
.attr("d", arc); | |
arcs.select("text") | |
.attr("transform", function(d) { | |
return "translate(" + arc.centroid(d) + ")"; | |
}) | |
var newArcs = arcs.enter() | |
.append("g") | |
.attr("tabindex", function(d,i) { | |
return i; | |
}) | |
.on("mouseover", function(d,i) { | |
elem = findMatchingRowByLabel(d3.select(this).data()[0].data.label, "table tbody tr") | |
.classed("matched",true); | |
}) | |
.on("mouseout", function(d,i) { | |
elem = findMatchingRowByLabel(d3.select(this).data()[0].data.label, "table tbody tr") | |
.classed("matched",false); | |
}) | |
.attr("class", "arc") | |
.attr("transform", "translate(" + outerRadius + "," + outerRadius + ")"); | |
newArcs.append("path") | |
.attr("fill", function(d, i) { | |
return color(i); | |
}) | |
.attr("d", arc) | |
newArcs.append("text") | |
.attr("transform", function(d) { | |
return "translate(" + arc.centroid(d) + ")"; | |
}) | |
.attr("text-anchor", "middle") | |
.text(function(d) { | |
// return d.data.label; | |
return d.value; | |
}); | |
var removedArcs = arcs.exit() | |
.remove("g"); | |
var rows = table.selectAll("tbody tr") | |
.data(dataset,key); | |
var newRows = rows.enter() | |
.append("tr") | |
.on("mouseover", function(d,i) { | |
findMatchingSliceByLabel(d3.select(this).data()[0].label, "svg g.arc") | |
.classed("matched", true); | |
}) | |
.on("mouseout", function(d,i) { | |
findMatchingSliceByLabel(d3.select(this).data()[0].label, "svg g.arc") | |
.classed("matched", false); | |
}) | |
.html(function(d, i) { | |
return "<td>"+d.label+"</td>"+ | |
"<td>"+d.value+"</td>"+ | |
"<td style='background-color:"+color(i)+";'> </td>"; | |
}); | |
var removedRows = rows.exit() | |
.remove("tr"); | |
}); | |
// Returns an attrTween for translating along the specified path element. | |
function translateAlong(path) { | |
var l = path.getTotalLength(); | |
return function(d, i, a) { | |
return function(t) { | |
var p = path.getPointAtLength(t * l); | |
return "translate(" + (p.y+outerRadius) + "," + (p.x+outerRadius) + ")"; | |
}; | |
}; | |
} | |
// Draw circular path around pie chart, for player-positioning purposes | |
var radians = 2 * Math.PI; | |
var points = 50; | |
var angle = d3.scale.linear() | |
.domain([0, points-1]) | |
.range([0, radians]); | |
var line = d3.svg.line.radial() | |
.interpolate("cardinal-closed") | |
.tension(1) | |
.radius(outerRadius) | |
.angle(function(d, i) { return angle(i); }); | |
var path = svg.append("path").datum(d3.range(points)) | |
.attr("class", "line") | |
.attr("d", line) | |
.attr("stroke", "black") | |
.attr("stroke-width", 5) | |
.attr("fill-opacity", 0) | |
.attr("transform", "translate(" + (outerRadius) + ", " + (outerRadius) + ")") | |
; | |
var circle = svg.append("circle") | |
.attr("r", 13) | |
.attr("fill", "red") | |
.attr("transform", "translate(0,250)"); | |
function transition() { | |
circle.transition() | |
.delay(500) | |
.duration(15000) | |
.attrTween("transform", translateAlong(path.node())) | |
.each("end", transition); | |
} | |
transition(); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment