Last active
May 8, 2017 16:15
-
-
Save Ewiseman/53c81c7916159f25a216e6d1913b697c to your computer and use it in GitHub Desktop.
Sortable Bar Chart
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
$(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