d3.unconf(2016)
Last active
September 24, 2016 10:33
-
-
Save denjn5/dc1b70dc31d149ddb96d864ea699e03c to your computer and use it in GitHub Desktop.
d3 unconf badge
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
| license: gpl-3.0 | |
| height: 1000 | |
| border: no |
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> | |
| <meta charset="utf-8"> | |
| <style> | |
| @import url('https://fonts.googleapis.com/css?family=PT+Sans+Narrow'); | |
| body { | |
| font-family: "PT Sans Narrow", "Arial Narrow", "Helvetica Neue", Helvetica, Arial, sans-serif; | |
| } | |
| #gameboard { | |
| height: 1000px; | |
| width: 1000px; | |
| } | |
| path { | |
| stroke: #fff; | |
| } | |
| text { | |
| pointer-events: none; | |
| } | |
| </style> | |
| <body> | |
| <svg id="gameboard"></svg><br /> | |
| <label><input class="mode" type="radio" name="mode" value="linear" checked> Linear</label> | |
| <label><input class="mode" type="radio" name="mode" value="grouped"> Grouped</label> | |
| </body> | |
| <script src="https://d3js.org/d3.v4.min.js"></script> | |
| <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> | |
| <script> | |
| $(function () { | |
| // helpful: https://bl.ocks.org/kerryrodden/477c1bfb081b783f80ad | |
| // palettes: https://designschool.canva.com/blog/website-color-schemes/ | |
| // Global Variables | |
| var gWidth = $('#gameboard').width(), // Width of the svg palette | |
| gHeight = $('#gameboard').height(), // Height of the svg palette | |
| radius = (Math.min(gWidth, gHeight) / 2) - 10, | |
| quote = ["John 3:16-17", "For[g1063] God[g2316] so[g3779] loved[g25] the world[g2889], that[g5620] he gave[g1325] his[g846] only begotten[g3439] Son[g5207], that[g2443] whosoever[g3956] believeth[g4100] in[g1519] him[g846] should[g622] not[g3361] perish[g622], but[g235] have[g2192] everlasting[g166] life[g2222]. For[g1063] God[g2316] sent[g649] not[g3756] his[g846] Son[g5207] into[g1519] the world[g2889] to[g2443] condemn[g2919] the world[g2889]; but[g235] that[g2443] the world[g2889] through[g1223] him[g846] might be saved[g4982]."], | |
| mode = $('.mode:checked').val(), // Linear or grouped, based on radio buttons | |
| svg = d3.select("svg").append("g").attr("transform", "translate(" + gWidth / 2 + "," + (gHeight / 2) + ")"), | |
| color_palettes = [ ['#062f4f', '#813772', '#b82601']]; | |
| // D3 Global Variables | |
| var root = textToHierarchy(quote[0], quote[1]), | |
| node = root, // Save root for tweening | |
| x = d3.scaleLinear().range([0, 2 * Math.PI]), | |
| y = d3.scaleSqrt().range([0, radius]), | |
| color = d3.scaleLinear().domain([0, 0.5, 1]).range(color_palettes[~~(Math.random() * 1)]), // ~~(Math.random() * 6) | |
| partition = d3.partition(); | |
| // Calculate the d path for each slice. | |
| var arc = d3.arc() | |
| .startAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x0))); }) | |
| .endAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x1))); }) | |
| .innerRadius(function(d) { return Math.max(0, y(d.y0)); }) | |
| .outerRadius(function(d) { return Math.max(0, y(d.y1)); }); | |
| // Build the sunburst. | |
| var first_build = true; | |
| function update() { | |
| // Determine how to size the slices. | |
| if (mode == "linear") { | |
| root.sum(function (d) { return d.size; }); | |
| } else { | |
| root.sum(function (d) { return d.grpSize; }); | |
| } | |
| if (first_build) { | |
| // Add a <path d="[shape]" style="fill: [color];"><title>[popup text]</title></path> | |
| // to each <g> element; add click handler; save slice widths for tweening | |
| svg.selectAll("path").data(partition(root).descendants()).enter().append("path") | |
| .style("fill", function (d) { return d.parent ? color(d.x0) : "white"; }) // Return white for root. | |
| .on("click", click); | |
| svg.selectAll("path").append("title").text(function (d) { return d.data.word; }) | |
| first_build = false; | |
| //setTimeout(alert("hey"), 1000); | |
| } else { | |
| svg.selectAll("path").data(partition(root).descendants()); | |
| } | |
| svg.selectAll("path").transition().duration(1000).attrTween("d", arcTweenData); | |
| } | |
| update(); // GO! | |
| // Respond to radio click. | |
| $('.mode').on("change", function change() { | |
| mode = $('.mode:checked').val(); | |
| update(); | |
| }); | |
| // Respond to slice click. | |
| function click(d) { | |
| node = d; | |
| svg.selectAll("path").transition().duration(1000).attrTween("d", arcTweenZoom(d)); | |
| } | |
| // When switching data: interpolate the arcs in data space. | |
| function arcTweenData(a, i) { | |
| // (a.x0s ? a.x0s : 0) -- grab the prev saved x0 or set to 0 (for 1st time through) | |
| // avoids the stash() and allows the sunburst to grow into being | |
| var oi = d3.interpolate({ x0: (a.x0s ? a.x0s : 0), x1: (a.x1s ? a.x1s : 0) }, a); | |
| function tween(t) { | |
| var b = oi(t); | |
| a.x0s = b.x0; | |
| a.x1s = b.x1; | |
| return arc(b); | |
| } | |
| if (i == 0) { | |
| // If we are on the first arc, adjust the x domain to match the root node | |
| // at the current zoom level. (We only need to do this once.) | |
| var xd = d3.interpolate(x.domain(), [node.x0, node.x1]); | |
| return function (t) { | |
| x.domain(xd(t)); | |
| return tween(t); | |
| }; | |
| } else { | |
| return tween; | |
| } | |
| } | |
| // When zooming: interpolate the scales. | |
| function arcTweenZoom(d) { | |
| var xd = d3.interpolate(x.domain(), [d.x0, d.x1]), | |
| yd = d3.interpolate(y.domain(), [d.y0, 1]), // [d.y0, 1] | |
| yr = d3.interpolate(y.range(), [d.y0 ? 40 : 0, radius]); | |
| return function (d, i) { | |
| return i | |
| ? function (t) { return arc(d); } | |
| : function (t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t)); return arc(d); }; | |
| }; | |
| } | |
| // Take text from Strong's and format as hierarchy with root. | |
| function textToHierarchy(rootNode, quote) { | |
| var vsWords = quote.replace(/[^A-Za-z0-9 /[]/g, "").replace(/[/[]/g, "|").split(" "); | |
| var sbWords = [{ "name": rootNode, "parent": "" }]; | |
| for (i = 0; i < vsWords.length ; i++) { | |
| //sbWords.filter(function (value) { return value == vsWords[i]; }).length; | |
| word = vsWords[i].split("|"); | |
| if (word.length == 1) { | |
| sbWords.push({ "name": i, "word": word[0], "parent": rootNode, "size": 1, "grpSize": 0 }); | |
| } else { | |
| // If this combo of English:Greek word exists, then add a | |
| filtered = sbWords.filter(function (value) { return value.word == word[1] && value.eWord == word[0]; }); | |
| var newGrpSize = 1; | |
| if (filtered.length > 0) { | |
| filtered[0].grpSize += 1; | |
| newGrpSize = 0; | |
| } | |
| sbWords.push({ "name": word[1], "parent": i, "word": word[1], "size": 1, "grpSize": newGrpSize, "eWord": word[0] }); | |
| sbWords.push({ "name": i, "word": word[0], "parent": rootNode, "size": 0, "grpSize": 0 }); | |
| } | |
| } | |
| var root = d3.stratify().id(function (d) { return d.name; }) | |
| .parentId(function (d) { return d.parent; })(sbWords); | |
| return root; | |
| } | |
| }); | |
| </script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment