Skip to content

Instantly share code, notes, and snippets.

@Ewiseman
Last active May 8, 2017 16:15
Show Gist options
  • Save Ewiseman/53c81c7916159f25a216e6d1913b697c to your computer and use it in GitHub Desktop.
Save Ewiseman/53c81c7916159f25a216e6d1913b697c to your computer and use it in GitHub Desktop.
Sortable Bar Chart
$(document).ready(function() {
var acreageThreshold = 0 ; //not greater than 4000
var margin = {top: 20, right: 50, bottom: 50, left: 200},
width = $("#horizontal-tool").width() - margin.left - margin.right,
height = ((4000 - acreageThreshold)- 250),
stateHeight = 2000,
barPadding = 8;
var yAxisMargin = height - margin.bottom
var svg = d3.select("#horizontal-tool").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom )
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var x = d3.scale.linear().range([0, width]);
var y = d3.scale.ordinal().rangeRoundBands([0, height]);
var avg = d3.scale.linear().range([0, width]);
var med = d3.scale.linear().range([0, width]);
var count = d3.scale.linear().range([0, width]);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10);
d3.csv("/ski_resort_acres_three.csv", function(error, data) {
data = jQuery.grep(data, function(d, index) {
var is_viewable = d.acres >= acreageThreshold;
return is_viewable;
});
data.forEach(function(d) {
d.resort_name = d.resort_name;
d.acres = +d.acres;
});
var resortBars = function(d) { return y(d.resort_name); }
var resortLabels = function(d) { return y(d.resort_name) + 5; }
x.domain([0, d3.max(data, function(d) { return d.acres; })]);
y.domain(data.map(function(d) { return d.resort_name; }));
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.style("font-size", "10px")
.attr("transform", "translate(0,-5)")
.attr("opacity", 1);
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", 0)
.attr("fill", "steelblue")
.attr("height", height / data.length - barPadding)
.attr("y", resortBars)
.attr("width", function(d) { return x(d.acres); })
.attr("opacity", 1);
svg.selectAll(".bartext")
.data(data)
.enter().append("text")
.attr("class", "bartext")
.attr("text-anchor", "middle")
.attr("fill", "black")
.attr("x", function(d) { return x(d.acres) + 20 })
.attr("y", resortLabels)
.attr("font-size", "11px")
.attr("text-anchor", "middle")
.text(function(d){
return addCommas(d.acres);
});
// Summed by State //
var stateSum = d3.nest()
.key(function(d) { return d.state; })
.rollup(function(v) { return {
count: v.length,
total: d3.sum(v, function(d) { return d.acres; }),
avg: d3.mean(v, function(d) { return d.acres; }),
med: d3.median(v, function(d) { return d.acres; })
}; })
.entries(data);
x.domain([0, d3.max(stateSum, function(d) { return d.values.total; })]);
y.domain(stateSum.map(function(d) { return d.key; }));
avg.domain([0, d3.max(stateSum, function(d) { return d.values.avg; })]);
med.domain([0, d3.max(stateSum, function(d) { return d.values.med; })]);
count.domain([0, d3.max(stateSum, function(d) { return d.values.count; })]);
var xAxisState = d3.svg.axis()
.scale(x)
.orient("bottom")
var yAxisState = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10);
svg.append("g")
.attr("class", "y axis state")
.call(yAxisState)
.style("font-size", "10px")
.attr("opacity", 0);
svg.selectAll(".barsum")
.data(stateSum)
.enter().append("rect")
.attr("class", "barsum")
.attr("x", 0)
.attr("fill", "steelblue")
.attr("height", stateHeight / stateSum.length - (barPadding))
.attr("y", function(d) { return y(d.key); })
.attr("width", function(d) { return x(d.values.total); })
.attr("transform", "translate(0,22)")
.attr("opacity", 0);
svg.selectAll(".bartextsum")
.data(stateSum)
.enter().append("text")
.attr("class", "bartextsum")
.attr("text-anchor", "bottom")
.attr("fill", "black")
.attr("y", function(d) { return y(d.key); })
.attr("x", function(d) { return x(d.values.total) + 25 })
.attr("font-size", "11px")
.attr("text-anchor", "middle")
.attr("transform", "translate(0,25)")
.attr("opacity", 0)
.text(function(d){
return addCommas(d.values.total);
});
///// Sort Buttons /////
// Sort by Resort Name //
d3.selectAll("#resort-name")
.on("click", function () {
var sortFunction = function(a, b) { return d3.descending(b.resort_name, a.resort_name); };
var resortNames = data.sort(sortFunction).map(function(d) { return d.resort_name; });
y.domain(resortNames);
var transition = svg.transition().duration(750),
delay = function(d, i) { return i * 3 ; };
transition.selectAll(".bar")
.delay(delay)
.attr("y", resortBars)
.attr("opacity", 1);
transition.selectAll(".bartext")
.delay(delay)
.attr("y", resortLabels)
.attr("opacity", 1);
transition.select(".y.axis")
.call(yAxis)
.selectAll("g")
.delay(delay);
transition.selectAll(".barsum")
.delay(delay)
.attr("opacity", 0);
transition.selectAll(".bartextsum")
.delay(delay)
.attr("opacity", 0);
});
// Sort by Ascending Acres //
d3.selectAll("#ascend")
.on("click", function () {
var sortFunction = function(a, b) { return d3.descending(b.acres, a.acres) || d3.descending(a.resort_name, b.resort_name); };
var resortNames = data.sort(sortFunction).map(function(d) { return d.resort_name; });
y.domain(resortNames);
var transition = svg.transition().duration(750),
delay = function(d, i) { return i * 3; };
transition.selectAll(".bar")
.delay(delay)
.attr("y", resortBars)
.attr("opacity", 1);
transition.selectAll(".bartext")
.delay(delay)
.attr("y", resortLabels)
.attr("opacity", 1);
transition.select(".y.axis")
.call(yAxis)
.selectAll("g")
.delay(delay);
transition.selectAll(".barsum")
.delay(delay)
.attr("opacity", 0);
transition.selectAll(".bartextsum")
.delay(delay)
.attr("opacity", 0);
});
// Sort by Descending Acres //
d3.selectAll("#descend")
.on("click", function () {
var sortFunction = function(a, b) { return d3.descending(a.acres, b.acres)|| d3.descending(a.resort_name, b.resort_name); };
var resortNames = data.sort(sortFunction).map(function(d) { return d.resort_name; });
y.domain(resortNames);
var transition = svg.transition().duration(750),
delay = function(d, i) { return i * 3; };
transition.selectAll(".bar")
.delay(delay)
.attr("y", resortBars)
.attr("opacity", 1);
transition.selectAll(".bartext")
.delay(delay)
.attr("y", resortLabels)
.attr("opacity", 1);
transition.select(".y.axis")
.call(yAxis)
.selectAll("g")
.delay(delay);
transition.selectAll(".barsum")
.delay(delay)
.attr("opacity", 0);
transition.selectAll(".bartextsum")
.delay(delay)
.attr("opacity", 0);
});
// Group By State //
d3.selectAll("#state")
.on("click", function () {
var sortFunction = function(a, b) { return d3.descending(b.state, a.state)|| d3.descending(a.acres, b.acres); };
var resortNames = data.sort(sortFunction).map(function(d) { return d.resort_name; });
y.domain(resortNames);
var transition = svg.transition().duration(750),
delay = function(d, i) { return i * 3; };
transition.selectAll(".bar")
.delay(delay)
.attr("y", resortBars)
.attr("opacity", 1);
transition.selectAll(".bartext")
.delay(delay)
.attr("y", resortLabels)
.attr("opacity", 1);
transition.select(".y.axis")
.call(yAxisState)
.selectAll("g")
.delay(delay);
transition.selectAll(".barsum")
.delay(delay)
.attr("opacity", 0);
transition.selectAll(".bartextsum")
.delay(delay)
.attr("opacity", 0);
});
// Sum States //
d3.selectAll("#state-totals")
.on("click", function () {
var sortFunction = function(a, b) { return d3.descending(a.acres, b.acres); };
var stateNames = data.sort(sortFunction).map(function(d) { return d.state; });
y.domain(stateNames);
var sortStateFunction = function(a, b) { return d3.ascending(b.values.total, a.values.total) || d3.descending(a.key, b.key) };
var stateSumNames = stateSum.sort(sortStateFunction).map(function(d) { return d.key; });
var dataSum = y.domain(stateSumNames);
var transition = svg.transition().duration(750),
delay = function(d, i) { return i * 3 ; };
transition.selectAll(".bar")
.delay(delay)
.attr("y", function(d) { return y(d.state); })
.attr("opacity", 0);
transition.selectAll(".bartext")
.delay(delay)
.attr("opacity", 0);
transition.selectAll(".barsum")
.delay(delay)
.attr("y", function(d) { return dataSum(d.key); })
.attr("width", function(d) { return x(d.values.total)})
.attr("opacity", 1);
transition.selectAll(".bartextsum")
.delay(delay)
.attr("y", function(d) { return dataSum(d.key) + 22; })
.attr("x", function(d) { return x(d.values.total) + 25 })
.attr("opacity", 1)
.text(function(d){
return addCommas(d3.round(d.values.total));
});
transition.select(".y.axis.state")
.call(yAxisState)
.selectAll("g")
.attr("opacity", 1);
transition.select(".y.axis")
.call(yAxis)
.selectAll("g")
.attr("opacity", 0);
});
// Average by State //
d3.selectAll("#state-avg")
.on("click", function () {
var sortFunction = function(a, b) { return d3.descending(a.acres, b.acres); };
var stateNames = data.sort(sortFunction).map(function(d) { return d.state; });
y.domain(stateNames);
var sortStateFunction = function(a, b) { return d3.ascending(b.values.avg, a.values.avg) || d3.descending(a.key, b.key) };
var stateSumNames = stateSum.sort(sortStateFunction).map(function(d) { return d.key; });
var dataSum = y.domain(stateSumNames);
var transition = svg.transition().duration(750),
delay = function(d, i) { return i * 3 ; };
transition.selectAll(".bar")
.delay(delay)
.attr("y", function(d) { return y(d.state); })
.attr("opacity", 0);
transition.selectAll(".bartext")
.delay(delay)
.attr("opacity", 0);
transition.selectAll(".barsum")
.delay(delay)
.attr("y", function(d) { return dataSum(d.key); })
.attr("width", function(d) { return avg(d.values.avg); })
.attr("opacity", 1);
transition.selectAll(".bartextsum")
.delay(delay)
.attr("y", function(d) { return dataSum(d.key) + 22; })
.attr("x", function(d) { return avg(d.values.avg) + 20 })
.attr("opacity", 1)
.text(function(d){
return addCommas(d3.round(d.values.avg));
});
transition.select(".y.axis.state")
.call(yAxisState)
.selectAll("g")
.attr("opacity", 1);
transition.select(".y.axis")
.call(yAxis)
.selectAll("g")
.attr("opacity", 0);
});
// Med by State //
d3.selectAll("#state-med")
.on("click", function () {
var sortFunction = function(a, b) { return d3.descending(a.acres, b.acres); };
var stateNames = data.sort(sortFunction).map(function(d) { return d.state; });
y.domain(stateNames);
var sortStateFunction = function(a, b) { return d3.ascending(b.values.med, a.values.med) || d3.descending(a.key, b.key) };
var stateSumNames = stateSum.sort(sortStateFunction).map(function(d) { return d.key; });
var dataSum = y.domain(stateSumNames);
var transition = svg.transition().duration(750),
delay = function(d, i) { return i * 3 ; };
transition.selectAll(".bar")
.delay(delay)
.attr("y", function(d) { return y(d.state); })
.attr("opacity", 0);
transition.selectAll(".bartext")
.delay(delay)
.attr("opacity", 0);
transition.selectAll(".barsum")
.delay(delay)
.attr("y", function(d) { return dataSum(d.key); })
.attr("width", function(d) { return med(d.values.med); })
.attr("opacity", 1);
transition.selectAll(".bartextsum")
.delay(delay)
.attr("y", function(d) { return dataSum(d.key) + 22; })
.attr("x", function(d) { return med(d.values.med) + 20 })
.attr("opacity", 1)
.text(function(d){
return addCommas(d3.round(d.values.med));
});
transition.select(".y.axis.state")
.call(yAxisState)
.selectAll("g")
.attr("opacity", 1);
transition.select(".y.axis")
.call(yAxis)
.selectAll("g")
.attr("opacity", 0);
});
// Count by State //
d3.selectAll("#state-count")
.on("click", function () {
var sortFunction = function(a, b) { return d3.descending(a.acres, b.acres); };
var stateNames = data.sort(sortFunction).map(function(d) { return d.state; });
y.domain(stateNames);
var sortStateFunction = function(a, b) { return d3.ascending(b.values.count, a.values.count) || d3.descending(a.key, b.key) };
var stateSumNames = stateSum.sort(sortStateFunction).map(function(d) { return d.key; });
var dataSum = y.domain(stateSumNames);
var transition = svg.transition().duration(750),
delay = function(d, i) { return i * 3 ; };
transition.selectAll(".bar")
.delay(delay)
.attr("y", function(d) { return y(d.state); })
.attr("opacity", 0);
transition.selectAll(".bartext")
.delay(delay)
.attr("opacity", 0);
transition.selectAll(".barsum")
.delay(delay)
.attr("y", function(d) { return dataSum(d.key); })
.attr("width", function(d) { return count(d.values.count); })
.attr("opacity", 1);
transition.selectAll(".bartextsum")
.delay(delay)
.attr("y", function(d) { return dataSum(d.key) + 22; })
.attr("x", function(d) { return count(d.values.count) + 15 })
.attr("opacity", 1)
.text(function(d){
return addCommas(d3.round(d.values.count));
});
transition.select(".y.axis.state")
.call(yAxisState)
.selectAll("g")
.attr("opacity", 1);
transition.select(".y.axis")
.call(yAxis)
.selectAll("g")
.attr("opacity", 0);
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment