Last active
August 29, 2015 14:26
-
-
Save amb26/fd84508ae2446d62ad75 to your computer and use it in GitHub Desktop.
This file contains hidden or 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