Skip to content

Instantly share code, notes, and snippets.

@timproDev
Last active January 25, 2018 16:37
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/5bfe578051bcd65f93d500910f297ce0 to your computer and use it in GitHub Desktop.
Save timproDev/5bfe578051bcd65f93d500910f297ce0 to your computer and use it in GitHub Desktop.
Barchart Null to Data Values
function barChart(dataPath, elem, opts) {
var settings = {
premise: opts.premise,
title: opts.title,
axisCategory: opts.axisCategory,
axisValue: opts.axisValue,
orientationVal: opts.orientationVal,
rangeMax: opts.rangeMax,
sortDescending: opts.sortDescending,
chartHeight: opts.chartHeight,
transSpeed: 700,
dataPath: dataPath,
chartContainerClass: "." + elem
};
var chartContainer = d3.select(settings.chartContainerClass).html("");
if (settings.orientationVal == "vertical") {
// vertical bar margins
var margin = {
top:10,
left:20,
right:20,
bottom:40
};
} else {
// horizontal bar margins
var margin = {
top:30,
left:20,
right:20,
bottom:20
};
}
var w = chartContainer.node().clientWidth - margin.left - margin.right,
h = settings.chartHeight - margin.top - margin.bottom;
// svg and non-data elements
// if title
if (settings.title !== "") {
chartContainer.insert("h3").html(settings.title).classed("chart-title", true);
}
// if premise
if (settings.title !== "") {
chartContainer.insert("p").html(settings.premise).classed("chart-premise", true);
}
// if range
if (settings.rangeMax == true) {
var fullRange = d3.max(valArray);
} else {
var fullRange = 100;
}
// create inner div
var div = chartContainer
.append("div.svg-container")
.style("width", (w + margin.left + margin.right) + "px")
.style("height", (h + margin.top + margin.bottom) + "px");
// insert canvas inner div
div.insert("canvas");
// append svg in inner div
var svg = div
.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]);
d3.queue()
.defer(d3.csv, settings.dataPath)
.await(ready);
function ready(error, data) {
if (error) throw "error: not loading data, bro";
// manipulate data
var valArray = data.map(function(d){
return d[settings.axisValue];
});
// if sort
if (settings.sortDescending) {
data.sort(function(a,b){
return d3.descending(+a.value, +b.value)
});
}
// bind data
var gRects = svg.selectAll(".g-comp-rect")
.data(data)
.enter()
.append("g.g-comp-rect");
// if orientation
if (settings.orientationVal == "vertical") {
createVertScales(fullRange);
fireScales();
createVertElements(fullRange);
} else {
createHorizScales(fullRange);
fireScales();
createHorizElements(fullRange);
}
function createHorizScales(rangeOpt) {
yscale = d3.scaleBand()
.rangeRound([0,h])
.domain(data.map(function(d) { return d[settings.axisCategory]; }))
.paddingInner(0.5);
xscale = d3.scaleLinear()
.domain([0, rangeOpt])
.range([0,w]);
}
function createVertScales(rangeOpt) {
yscale = d3.scaleLinear()
.domain([0, rangeOpt])
.range([h,0]);
xscale = d3.scaleBand()
.rangeRound([0,w])
.domain(data.map(function(d) { return d[settings.axisCategory]; }))
.paddingInner(0.15);
}
function createHorizElements(rangeOpt) {
gRects
// append grey background
.append("rect.bg-bar")
.attr("y",function(d){
return yscale(d[settings.axisCategory]);
})
.attr("x",0)
.attr("height",yscale.bandwidth())
.attr("width", function(d){
return xscale(rangeOpt);
});
gRects
// append bars
.append("rect.comp-rect")
.attr("y",function(d){
return yscale(d[settings.axisCategory]);
})
.attr("x",0)
.attr("height",yscale.bandwidth())
.attr("width",0)
.transition().delay(function(d, i) { return i * 120; })
.attr("width", function(d){
return xscale(d[settings.axisValue]);
});
gRects.append("text.bar-label")
// append labels
.attr("y", function(d) { return yscale(d[settings.axisCategory]) + yscale.bandwidth()/2; })
.attr("x", function(d) {
if (d[settings.axisValue] < 5) {
return (xscale(d[settings.axisValue]) + 10);
} else {
return (xscale(d[settings.axisValue]) - 10);
}
})
.attr("dy", "4px")
.style("text-anchor",function(d){
if (d[settings.axisValue] < 5) {
return "start";
} else {
return "end";
}
})
.style("fill",function(d){
if (d[settings.axisValue] < 5) {
return "#45555f";
} else {
return "#ffffff";
}
})
.style("opacity",0)
.transition().delay(function(d, i) { return i * 120; })
.style("opacity",1)
.text(function(d) { return d[settings.axisValue] + "%"; });
// tick text line
yText
.style("text-anchor","start")
.attr("x",0)
.attr("y", function(d) { return -yscale.bandwidth() + (yscale.bandwidth()/6); })
.classed("axis-category-text", true);
yLine
.style("display","none");
xTick
.style("display","none");
}
function createVertElements(rangeOpt) {
gRects
// append grey background
.append("rect.bg-bar")
.attr("y",0)
.attr("x",function(d){
return xscale(d[settings.axisCategory]);
})
.attr("width",xscale.bandwidth())
.attr("height",h);
gRects
// append bars
.append("rect.comp-rect")
.attr("x",function(d){
return xscale(d[settings.axisCategory]);
})
.attr("y",h)
.transition().delay(function(d, i) { return i * 120; })
.attr("y",function(d){
return yscale(d[settings.axisValue]);
})
.attr("width",xscale.bandwidth())
.attr("height",function(d){
return h - yscale(d[settings.axisValue]);
});
gRects.append("text.bar-label")
.attr("x", function(d) { return xscale(d[settings.axisCategory]) + xscale.bandwidth()/2; })
.attr("y", function(d) {
if (d[settings.axisValue] < 5) {
return yscale(d[settings.axisValue]) - 10;
} else {
return yscale(d[settings.axisValue]) + 20;
}
})
.attr("dy", "0")
.attr("text-anchor","middle")
.style("fill",function(d){
if (d[settings.axisValue] < 5) {
return "#45555f";
} else {
return "#ffffff";
}
})
.style("opacity",0)
.transition().delay(function(d, i) { return i * 120; })
.style("opacity",1)
.text(function(d) { return d[settings.axisValue] + "%"; });
// tick text line
xText
.style("text-anchor","middle")
.attr("y",h + 10)
.attr("x", function(d) { return -xscale.bandwidth() + (xscale.bandwidth()); })
.classed("axis-category-text", true);
yTick
.style("display","none");
xLine
.style("display","none");
}
function fireScales(){
// create axis element variables
var yaxis = d3.axisLeft(yscale);
var xaxis = d3.axisBottom()
.scale(xscale)
.tickSize(h);
svg.append("g.y-axis").call(yaxis);
svg.append("g.x-axis").call(xaxis);
// tick presentation | fire after axis appended
yText = svg.selectAll(".y-axis .tick text"),
xText = svg.selectAll(".x-axis .tick text"),
yTick = svg.selectAll(".y-axis .tick"),
xTick = svg.selectAll(".x-axis .tick"),
yLine = svg.selectAll(".y-axis .tick line"),
xLine = svg.selectAll(".x-axis .tick line");
}
//////////////////
function updateVertChart(newdata, rangeOpt){
var upyscale = d3.scaleLinear()
.domain([0, rangeOpt])
.range([h,0]);
var upxscale = d3.scaleBand()
.rangeRound([0,w])
.domain(newdata.map(function(d) { return d[settings.axisCategory]; }))
.paddingInner(0.15);
// create axis element variables
var upyaxis = d3.axisLeft(upyscale);
var upxaxis = d3.axisBottom()
.scale(upxscale)
.tickSize(h);
svg.selectAll("g.y-axis").transition().duration(600).call(upyaxis);
svg.selectAll("g.x-axis").transition().duration(600).call(upxaxis);
// add new data to parent
var upgRects = svg.selectAll(".g-comp-rect")
.data(newdata);
// grey bars
svg.selectAll("rect.bg-bar")
.transition().duration(600)
.attr("x",function(d){
return upxscale(d[settings.axisCategory]);
});
// through parent, selectAll children
upgRects.selectAll(".comp-rect")
.transition().duration(600)
.attr("y",function(d){
return upyscale(d[settings.axisValue]);
})
.attr("x",function(d){
// console.log(upxscale);
return upxscale(d[settings.axisCategory]);
});
upgRects.selectAll("text.bar-label")
.transition().duration(600)
.attr("x", function(d) { return upxscale(d[settings.axisCategory]) + upxscale.bandwidth()/2; });
} // end updateChart
} // end ready
}
var d3Comp = d3Comp || {};
d3Comp.init = function(settings) {
d3Comp.linkStyle(settings);
if (typeof settings.win.d3 === "undefined") {
console.log("library undefined");
d3Comp.loadLib(settings);
}
if (typeof settings.win.d3 !== "undefined") {
console.log("library defined");
d3Comp.loadComp(settings);
}
}
d3Comp.linkStyle = function(params){
var linkElem = document.createElement('link');
document.getElementsByTagName('head')[0].appendChild(linkElem);
linkElem.rel = 'stylesheet';
linkElem.type = 'text/css';
linkElem.href = (params.path + params.css);
}
d3Comp.loadLib = function(params){
$.when(
$.getScript((params.path + params.lib)),
$.Deferred(function( deferred ){
$( deferred.resolve );
})
).done(function(){
d3Comp.loadComp(params);
});
}
d3Comp.loadComp = function(params){
$.when(
$.getScript((params.path + params.comp)),
$.Deferred(function( deferred ){
$( deferred.resolve );
})
).done(function(){
params.win[params.func]((params.path + params.data), params.elem, params.options);
d3Comp.chartRefire(params);
});
}
d3Comp.chartRefire = function(params){
$(params.win).resize(function(){
params.win[params.func]((params.path + params.data), params.elem, params.options);
});
}
* {
font-family: 'Comfortaa', arial, verdana, sans-serif;
color:cadetblue;
}
/* line 7, ../../scss/components/d3/barchart.scss */
.dv-wrap {
text-align: center;
background-color: #fff;
width:80%;
margin:2rem auto;
}
/* line 27, ../../scss/components/d3/barchart.scss */
.chart-container-barchart {
border: 1px solid #ececec;
font-weight: normal;
font-size: 1rem;
}
/* line 32, ../../scss/components/d3/barchart.scss */
.chart-container-barchart .svg-container {
position: relative;
}
/* line 35, ../../scss/components/d3/barchart.scss */
.chart-container-barchart .svg-container canvas {
display: block;
height: 100%;
visibility: hidden;
}
/* line 40, ../../scss/components/d3/barchart.scss */
.chart-container-barchart .svg-container svg {
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
/* line 47, ../../scss/components/d3/barchart.scss */
.chart-container-barchart .domain {
display: none;
}
/* line 50, ../../scss/components/d3/barchart.scss */
.chart-container-barchart .comp-rect {
stroke-width: 0;
fill: cadetblue;
}
/* line 54, ../../scss/components/d3/barchart.scss */
.chart-container-barchart .chart-title {
padding: 1.25rem;
border-bottom: 1px solid #ececec;
margin: 0;
text-align: left;
}
/* line 60, ../../scss/components/d3/barchart.scss */
.chart-container-barchart .chart-premise {
padding: 1.25rem;
margin: 0;
text-align: left;
}
/* line 65, ../../scss/components/d3/barchart.scss */
.chart-container-barchart .bg-bar {
fill: #ececec;
}
/* line 68, ../../scss/components/d3/barchart.scss */
.chart-container-barchart .bar-label {
font-weight: normal;
font-size: 0.6875rem;
font-size: 1rem;
}
/* line 72, ../../scss/components/d3/barchart.scss */
.chart-container-barchart .axis-category-text {
font-weight: normal;
font-size: 0.6875rem;
fill: #404040;
font-size: 1rem;
text-anchor: end;
}
/* line 81, ../../scss/components/d3/barchart.scss */
.chart-container-barchart .x-axis .tick line {
stroke-width: 1;
stroke: #45555f;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Bar Chart with Configuration</title>
<link href="https://fonts.googleapis.com/css?family=Comfortaa" rel="stylesheet">
<!-- this element is hard-coded to mimic the module functionality -->
<link rel="stylesheet" type="text/css" href="d3-style-barchart-config.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="chart-container-barchart"></div>
</section>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function(){
var d3settings = {
win: window,
path:"", // i.e. "d3-bundles/d3-components/barchart/"
css: "d3-style-barchart-config.css",
lib: "d3v4-473-jetpack.js",
comp: "barchart.js",
data: "music-data-barchart.csv",
elem: "chart-container-barchart",
func: "barChart",
options:{
title:"How many people like Jazz?",
premise:"I think that more people like Jazz over Classical. But the data presented below suggests that I am wrong.",
axisCategory:"genre",
axisValue:"value",
orientationVal:"vertical", // vertical, ""
rangeMax:false,
sortDescending:false,
chartHeight:550
}
};
d3Comp.init(d3settings);
});
</script>
</main>
</body>
<script src="https://rawgit.com/timproDev/d3-first-timer/master/js/d3v4-473-jetpack.js"></script>
<script src="d3-platform-init.js"></script>
</html>
genre value
jazz 2
classical 16
rock 29
reggae 14
samba 88
blues 54
bossa nova 21
hip hop 35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment