Skip to content

Instantly share code, notes, and snippets.

@timproDev
Last active October 24, 2017 14:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timproDev/4e267b524557b1e83341dcd3ef2e492e to your computer and use it in GitHub Desktop.
Save timproDev/4e267b524557b1e83341dcd3ef2e492e to your computer and use it in GitHub Desktop.
Top Values Horizontal Bar Chart

I am using jetpack as the standard lib. Here is a barchart that manipulates data and allows for user controls and dynamic rendering.

  • I am still learning and aim to document my process :)
Country JAZZ ROCKSTEADY TROPICALIA
United Arab Emirates 2 20 16
Albania 16 24 19
Armenia 29 25 15
Argentina 14 28 20
Austria 12 26 14
Australia 2 21 12
Azerbaijan 12 15 7
Bosnia and Herzegovina 12 19 27
Bangladesh 19 24 19
Belgium 17 22 19
Bulgaria 27 20 10
Bahrain 4 23 18
Burundi 26 11 23
Benin 28 10 23
Brunei Darussalam 13 17 88
Brazil 16 20 16
Bhutan 23 4 19
Botswana 14 27 18
* {
box-sizing: border-box;
padding:0;
margin:0;
/*font-family: 'Raleway', sans-serif; */
font-family: 'Josefin Slab', sans-serif;
}
body {
background-color:#ececec;
padding:0 0 2rem 0;
}
header, .dv-wrap, .footer {
width:100%;
padding:5% 10%;
border-bottom: 2px dashed #ffffff;
float: left;
}
h1 {
text-align: center;
padding: 10px;
text-decoration: underline;
}
/* //////////////// UI controls //////////////// */
.btn-wrap {
padding: 2rem 0 2rem 0;
text-align: center;
}
/* //////////////// Axis and Ticks //////////////// */
.y-axis .tick text {
text-anchor: start;
}
.y-axis .tick line {
stroke-width:1;
stroke-dasharray: 2;
stroke: #45555f;
stroke-opacity:.5;
}
.y-axis .tick.zilch line {
stroke-width:1;
stroke-dasharray: 0;
}
.x-axis .tick line {
stroke-width:1;
stroke: #45555f;
}
.domain {
display:none;
}
/* //////////////// Chart Elements //////////////// */
.comp-rect {
stroke-width:1;
stroke:#45555f;
fill: #ffffff;
}
/* IE HACK CANVAS */
.cov-div {
position: relative;
}
.cov-div canvas {
display: block;
height: 100%;
visibility: hidden;
}
.cov-div svg {
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
.dv-wrap .header-section {
text-align: center;
}
.dv-wrap .header-section .disclaimer {
font-size: .75rem;
}
.g-chart-container-top-bar .y-axis .tick text {
font-size: 1rem;
text-anchor:end;
fill: #45555f;
}
.g-chart-container-top-bar .top-five-wrap {
text-align: center;
padding:1rem 0 2rem 0;
}
.g-chart-container-top-bar .top-five-wrap p {
display: inline-block;
margin:0 2rem;
font-weight: bold;
font-size: 1.25rem;
}
.g-chart-container-top-bar select {
font-size: 1.25rem;
height:45px;
}
.g-chart-container-top-bar .comp-rect {
stroke-width: 0;
fill: #45555f;
}
function topBar() {
// Nested Single Bars and Lines
var settings = {
chartContainerClass: ".g-chart-container-top-bar",
dataPointFocus: "Jazz",
tickCount : "8",
transSpeed: 700
};
var optionsArray = [
"Jazz",
"Rocksteady",
"Tropicalia"
]
var chartContainer = d3.select(settings.chartContainerClass).html("");
var margin = {
top:0,
left:100,
right:120,
bottom:80
};
var w = chartContainer.node().clientWidth - margin.left - margin.right,
h = 600 - margin.top - margin.bottom;
d3.queue()
.defer(d3.csv, "block-data.csv")
.await(ready);
// user control
var viewByUI = d3.select("div.view-by-ui").selectAll("button");
value = "By Risk";
viewByUI.on("click", function(){
var value = d3.select(this).html();
});
if (value == "By Risk") {
} else if (value == "By Country") {
console.log("hey hey");
}
function ready(error, topriskdata) {
if (error) throw "error: not loading data, bro";
// type of chart
var headers = d3.keys(topriskdata[0]);
topriskdata.forEach(function(d){
d["Jazz"] = +d.JAZZ;
d["Rocksteady"] = +d.ROCKSTEADY;
d["Tropicalia"] = +d.TROPICALIA;
});
var optWrap = chartContainer.append("div.btn-wrap");
var select = optWrap // data join for buttons
.append('select')
.attr('class','select')
.on('change',onchange);
var options = select
.selectAll('option')
.data(optionsArray).enter()
.append('option')
.text(function (d) { return d; });
function onchange() {
selectValue = d3.select('select').property('value');
updateChart(selectValue);
};
topriskdata.sort(function(a,b){
return d3.descending(+a[settings.dataPointFocus], +b[settings.dataPointFocus])
});
var topFive = topriskdata.filter(function(d, i) {
return i == 0 || i == 1 || i == 2 || i == 3 || i == 4;
});
var topFiveWrap = chartContainer.append("div.top-five-wrap");
topFiveWrap.selectAll("p")
.data(topFive)
.enter()
.append("p")
.html(function(d){
return d.Country;
});
// scales
var yscale = d3.scaleBand()
.rangeRound([0,h])
.domain(topriskdata.map(function(d) { return d.Country; }))
.paddingInner(0.15);
var yaxis = d3.axisLeft(yscale);
var xscale = d3.scaleLinear()
.domain([0, 30])
.range([margin.left,w]);
var xaxis = d3.axisBottom()
.scale(xscale);
// svg
var svg = chartContainer
.append("svg")
.style("width", (w + margin.left + margin.right) + "px")
.style("height", (h + margin.top + margin.bottom) + "px")
.append("g.wrap")
.translate([margin.left,margin.top]);
svg.insert("canvas");
svg.append("g.x-axis")
.call(xaxis)
.attr("transform","translate(0," + h + ")");
var gRects = svg.selectAll(".g-comp-rect")
.data(topriskdata)
.enter()
.append("g.g-comp-rect");
gRects
.append("rect.comp-rect")
.attr("y",function(d){
return yscale(d.Country);
})
.attr("x",margin.left)
.attr("height",yscale.bandwidth())
.attr("width", function(d){
return xscale(d[settings.dataPointFocus]);
})
.on("mouseover", function(){
d3.select(this).style("fill", "#ff4747");
})
.on("mouseout", function(){
d3.select(this).style("fill", "#45555f");
});
svg.append("g.y-axis").call(yaxis).attr("transform","translate(" + margin.left + ",0)");
gRects.append("text.bar-label")
.attr("y", function(d) { return yscale(d.Country) + yscale.bandwidth()/2; })
.attr("x", function(d) { return (xscale(d[settings.dataPointFocus]) + 15 + margin.left); })
.attr("dy", "4px")
.text(function(d) { return d[settings.dataPointFocus]; });
function updateChart(updatedData) {
topriskdata.sort(function(a,b){
return d3.descending(+a[updatedData], +b[updatedData])
});
var uptopFive = topriskdata.filter(function(d, i){
return i == 0 || i == 1 || i == 2 || i == 3 || i == 4;
});
topFiveWrap.selectAll("p")
.data(uptopFive)
.html(function(d){
return d.Country;
});
yscale
.domain(topriskdata.map(function(d) { return d.Country; }))
yaxis.scale(yscale);
svg.select(".y-axis")
.transition().duration(settings.transSpeed)
.call(yaxis);
var upgRects = svg.selectAll(".g-comp-rect")
.data(topriskdata);
upgRects
.selectAll("rect.comp-rect")
.transition().duration(settings.transSpeed)
.attr("y",function(d){
return yscale(d.Country);
})
.attr("x",margin.left)
.attr("height",yscale.bandwidth())
.attr("width", function(d){
return xscale(d[updatedData]);
});
upgRects
.selectAll("text.bar-label")
.transition().duration(settings.transSpeed)
.attr("y", function(d) { return yscale(d.Country) + yscale.bandwidth()/2; })
.attr("x", function(d) { return (xscale(d[updatedData]) + 15 + margin.left); })
.attr("dy", "4px")
.text(function(d) { return d[updatedData]; });
}
// update end
}
}
$( window ).resize(fireAll);
function fireAll() {topBar();}
;(function(){topBar();})();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3 .•*•* Magic *•*•. JS</title>
<link href="https://fonts.googleapis.com/css?family=Josefin+Slab" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="d3-style-top-bar.css">
<script src="https://code.jquery.com/jquery-3.2.1.js" integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE=" crossorigin="anonymous"></script>
</head>
<body>
<main>
<section class="dv-wrap">
<div class="header-section">
<h1>Top Music By Country</h1>
<span class="disclaimer">* This data is hogwash.</span>
</div>
<div class="g-chart-container-top-bar"></div>
</section>
</main>
</body>
<script src="https://rawgit.com/timproDev/d3-first-timer/master/js/d3v4-473-jetpack.js"></script>
<script type="text/javascript" src="dyn-horiz-barchart.js"></script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment