A sort button example taken from Scott Murray's excellent tutorials and tweaked a little.
- divs for buttons
- sort data dynamically by changing order of 's based on data values
A sort button example taken from Scott Murray's excellent tutorials and tweaked a little.
| <!DOCTYPE html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> | |
| <title>D3: Ascending and descending sorts</title> | |
| <style type="text/css"> | |
| body { | |
| background-color: gray; | |
| } | |
| /* New rules for styling buttons */ | |
| #buttonContainer { | |
| margin-bottom: 10px; | |
| } | |
| button { | |
| padding: 15px; | |
| } | |
| svg { | |
| background-color: white; | |
| } | |
| g.bar text { | |
| font-family: sans-serif; | |
| font-size: 11px; | |
| fill: white; | |
| font-style: bold; | |
| text-anchor: middle; | |
| opacity: 0; | |
| } | |
| g.bar.highlight text { | |
| opacity: 1; | |
| } | |
| g.bar.highlight rect { | |
| fill: Maroon; | |
| } | |
| .axis path, | |
| .axis line { | |
| fill: none; | |
| stroke: black; | |
| shape-rendering: crispEdges; | |
| } | |
| .axis text { | |
| font-family: sans-serif; | |
| font-size: 11px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- New buttons to trigger sorting! | |
| use divs to setup buttons --> | |
| <div id="buttonContainer"> | |
| <button id="sortAscending">Sort Ascending</button> | |
| <button id="sortDescending">Sort Descending</button> | |
| </div> | |
| <script type="text/javascript"> | |
| //Width, height, padding | |
| var w = 800; | |
| var h = 500; | |
| var padding = 25; | |
| //Array of dummy data values | |
| var dataset = [ 5, 8, 13, 19, 21, 22, 31, 26, 25, 23, | |
| 16, 17, 15, 14, 11, 3, 6, 8, 3, 5 ]; | |
| //Configure x and y scale functions | |
| var xScale = d3.scale.ordinal() | |
| .domain(d3.range(dataset.length)) | |
| .rangeRoundBands([ padding, w - padding ], 0.1); | |
| var yScale = d3.scale.linear() | |
| .domain([ 0, d3.max(dataset) ]) | |
| .rangeRound([ h - padding, padding ]); | |
| //Configure y axis generator | |
| var yAxis = d3.svg.axis() | |
| .scale(yScale) | |
| .orient("left") | |
| .ticks(5); | |
| //Create SVG element | |
| var svg = d3.select("body") | |
| .append("svg") | |
| .attr("width", w) | |
| .attr("height", h); | |
| //Create groups | |
| var groups = svg.selectAll("g") | |
| .data(dataset) | |
| .enter() | |
| .append("g") | |
| .attr("class", "bar") | |
| .attr("transform", function(d, i) { | |
| return "translate(" + xScale(i) + ",0)"; | |
| }) | |
| .on("mouseover", function() { | |
| d3.select(this) | |
| .classed("highlight", true); | |
| }) | |
| .on("mouseout", function() { | |
| d3.select(this) | |
| .classed("highlight", false); | |
| }); | |
| //Add bar to each group | |
| var rects = groups.append("rect") | |
| .attr("x", 0) | |
| .attr("y", function(d) { | |
| return h - padding; | |
| }) | |
| .attr("width", xScale.rangeBand()) | |
| .attr("height", 0) | |
| .attr("fill", "#ff89fd"); | |
| //Add label to each group | |
| groups.append("text") | |
| .attr("x", xScale.rangeBand() / 2) | |
| .attr("y", function(d) { | |
| return yScale(d) + 14; | |
| }) | |
| .text(function(d) { | |
| return d; | |
| }) | |
| //Transition rects into place | |
| rects.transition() | |
| .delay(function(d, i) { | |
| return i * 100; | |
| }) | |
| .duration(1500) | |
| .attr("y", function(d) { | |
| return yScale(d); | |
| }) | |
| .attr("height", function(d) { | |
| return h - padding - yScale(d); | |
| }) | |
| .filter(function(d) { | |
| if (d < 12) { | |
| return true; | |
| } | |
| return false; | |
| }) | |
| .attr("fill", "#00e0f4"); | |
| //Create y axis | |
| svg.append("g") | |
| .attr("class", "axis") | |
| .attr("transform", "translate(" + padding + ",0)") | |
| .attr("opacity", 0) | |
| .call(yAxis) | |
| .transition() | |
| .delay(2000) | |
| .duration(1500) | |
| .attr("opacity", 1.0); | |
| //Sorting logic | |
| d3.select("#sortAscending") | |
| .on("click", function() { | |
| groups.sort(function(a, b) { | |
| return d3.ascending(a, b); | |
| }) | |
| .transition() | |
| .delay(function(d, i) { | |
| return i * 50; // gives it a smoother effect | |
| }) | |
| .duration(1000) | |
| .attr("transform", function(d, i) { | |
| return "translate(" + xScale(i) + ",0)"; | |
| }); | |
| }); | |
| //This is EXACTLY the same as above, except for: | |
| d3.select("#sortDescending") //DEscending | |
| .on("click", function() { | |
| groups.sort(function(a, b) { | |
| return d3.descending(a, b); //DEscending | |
| }) | |
| .transition() | |
| .delay(function(d, i) { | |
| return i * 50; | |
| }) | |
| .duration(1000) | |
| .attr("transform", function(d, i) { | |
| return "translate(" + xScale(i) + ",0)"; | |
| }); | |
| }); | |
| </script> | |
| </body> | |
| </html> |