Skip to content

Instantly share code, notes, and snippets.

@timproDev
Last active February 28, 2018 17:15
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/8945f76517d1648d100169e066bfd6f0 to your computer and use it in GitHub Desktop.
Save timproDev/8945f76517d1648d100169e066bfd6f0 to your computer and use it in GitHub Desktop.
Simple Barchart for Presentation
document.addEventListener("DOMContentLoaded", function(){
var options = {
window: window,
path:"",
css: "d3-presentation.css",
js: "d3-presentation.js",
dataFile: "nat-cat.csv",
element: document.querySelector("#presBarchart"),
functionName: "presBarchart",
dataY: "Total losses",
dataX: "Catastrophe"
};
function d3Init() {
var linkElem = document.createElement('link');
document.getElementsByTagName('head')[0].appendChild(linkElem);
linkElem.rel = 'stylesheet';
linkElem.type = 'text/css';
linkElem.href = (options.path + options.css);
var resizeTimer;
window.addEventListener('resize', function(e) {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(function() {
window[options.functionName].init(options);
}, 300);
});
d3.csv((options.path + "nat-cat.csv"), function(data){
data.forEach(function(d){
d["Total losses"] = +d["Total losses"];
d["Events"] = +d["Events"];
d["Fatalities"] = +d["Fatalities"];
d["Total losses"] = +d["Total losses"];
d["Insured losses"] = +d["Insured losses"];
});
options.data = data;
window[options.functionName].init(options);
});
};
var span = document.querySelector('.data-event');
var buttons = document.getElementsByTagName('button');
for (var i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', function(){
span.innerHTML = this.innerHTML;
});
}
function userEvents(){
document.querySelector('#dataChange').addEventListener('click', function(){
d3.csv((options.path + "nat-cat-2.csv"), function(data){
data.forEach(function(d){
d["Total losses"] = +d["Total losses"];
d["Events"] = +d["Events"];
d["Fatalities"] = +d["Fatalities"];
d["Total losses"] = +d["Total losses"];
d["Insured losses"] = +d["Insured losses"];
});
window[options.functionName].setColor("#000000");
options.data = data;
window[options.functionName].init(options);
});
});
document.querySelector('#dataReset').addEventListener('click', function(){
d3.csv((options.path + "nat-cat.csv"), function(data){
data.forEach(function(d){
d["Total losses"] = +d["Total losses"];
d["Events"] = +d["Events"];
d["Fatalities"] = +d["Fatalities"];
d["Total losses"] = +d["Total losses"];
d["Insured losses"] = +d["Insured losses"];
});
window[options.functionName].setColor("#ffffff");
options.data = data;
window[options.functionName].init(options);
});
});
};
d3Init();
userEvents();
});
* {
font-family: arial, verdana, sans-serif;
color:#808080;
}
text.bar-label {
font-size: 1rem;
}
.y-axis .tick text {
font-weight: bold;
font-size: .65rem;
text-transform: uppercase;
color:#bdbdbd;
font-style: italic;
}
.button-container {
padding:2rem 0 1rem 0;
}
.chart-premise {
font-size: .75rem;
line-height: 1.5;
}
button {
border:none;
width: 19.5%;
background: #efefef;
padding: .75rem .5rem;
border-radius: 3px;
border: 2px solid #f5f5f5;
outline:none;
display: inline-block;
cursor: pointer;
font-weight: bold;
font-size: .65rem;
text-transform: uppercase;
color:#bdbdbd;
}
button:hover {
background: #c6eae4;
border: 2px solid #e0f9f4;
color:#0b9c8a;
}
.data-event {
color:#000000;
}
.tooltip {
box-shadow: 0 2px 4px 0px rgba(0, 0, 0, 0.5);
border-radius: 2px;
background-color: #fff;
top: -1000px;
position: fixed;
padding: .65rem;
pointer-events: none;
max-width: 25%;
z-index: 500;
}
.tooltip-info {
padding: 0;
margin: 0;
display: block;
width: 100%;
}
.tooltip-hidden {
opacity: 0;
transition: all .3s;
transition-delay: .1s;
}
body {
background-color: #F8A021;
font-family: 'Raleway', sans-serif; }
.d3-presentation-container {
width: 400px;
margin: 5% auto 10% auto; }
.d3-presentation-container .chart-title {
font-size: 1.5rem;
margin: 1rem 0 2rem 10px;
color: #9a5900; }
.d3-presentation-container .chart-title span {
color: #ffffff;
display: block;
width: 100%; }
.d3-presentation-container button {
font-family: 'Raleway', sans-serif;
border: none;
padding: .75rem 1rem;
border-radius: 26px;
outline: none;
display: inline-block;
cursor: pointer;
font-weight: bold;
font-size: .85rem;
background-color: transparent;
border: 1px solid #d27f11;
color: #653b00;
box-shadow: 0 3px 10px -3px transparent;
transition: background-color 250ms ease-out, border 250ms ease-out, box-shadow 250ms ease-out;
margin: 0 0 2rem 10px; }
.d3-presentation-container button:hover {
background-color: #ffffff;
border: 1px solid #ffffff;
box-shadow: 0 3px 10px -3px #a96708; }
var presBarchart = {
init: function(opts){
this.data = opts.data;
this.dataX = this.dataX || opts.dataX;
this.dataY = this.dataY || opts.dataY;
this.element = opts.element;
this.spacing = -25;
this.draw();
},
draw: function(){
this.width = this.element.offsetWidth;
this.height = this.data.length * 60;
this.margin = {
top:40,
left:40,
right:40,
bottom:40
};
this.element.innerHTML = '';
var svg = d3.select(this.element).append('svg');
svg.attr('width', (this.width + this.margin.left + this.margin.right));
svg.attr('height', (this.height + this.margin.top + this.margin.bottom));
this.plot = svg.append('g')
.attr('transform',`translate(${this.margin.left},${this.margin.top})`);
this.createScales()
this.addAxes()
this.addRect()
this.addLabels()
},
createScales: function() {
var self = this
var yscaleDomain = this.data.map(function(d) { return d[self.dataY]; });
var xscaleDomain = this.data.map(function(d){ return d[self.dataX]; });
this.xscale = d3.scaleBand()
.rangeRound([0,this.width])
.domain(xscaleDomain)
.paddingInner(0.35);
this.yscale = d3.scaleLinear()
.domain([0, d3.max(yscaleDomain)])
.range([this.height,0]);
},
addAxes: function(){
var self = this
var yaxis = d3.axisLeft(this.yscale);
var xaxis = d3.axisBottom()
.scale(this.xscale);
// .tickSize(this.height);
this.plot.append('g.y-axis').call(yaxis).attr("transform","translate(-15,0)");
this.plot.append('g.x-axis').call(xaxis).attr("transform","translate(0," + this.height + ")");
},
addRect: function() {
var self = this;
this.gRects = this.plot.selectAll('.g-comp-rect')
.data(this.data)
.enter()
.append('g.g-comp-rect')
.append('rect.comp-rect')
.style('fill', this.lineColor || '#ffffff')
.attr('x',function(d){
return self.xscale(d[self.dataX]);
})
.attr('y', this.height)
.transition().delay(function(d, i) { return i * 120; })
.attr('y', function(d){
return self.yscale(d[self.dataY]);
})
.attr('width',self.xscale.bandwidth())
.attr('height', function(d){
return self.height - self.yscale(d[self.dataY]);
});
},
addLabels: function(){
var self = this;
this.plot.selectAll('.g-comp-rect')
.append('text.bar-label')
.attr('x', function(d) { return self.xscale(d[self.dataX]) + self.xscale.bandwidth()/2;})
.style('fill', this.lineColor || '#ffffff')
.attr('y', this.height)
.transition().delay(function(d, i) { return i * 120; })
.attr('y', function(d) {
return (self.yscale(d[self.dataY]) - 15);
})
.attr('dy', '5px')
.style('text-anchor',"middle")
.text(function(d) {
return d[self.dataY] + "%";
});
this.plot.selectAll('.domain').style('display','none');
this.plot
.append("line.fake-xdomain")
.attr("x1",this.spacing)
.attr("y1", this.height)
.attr("x2", this.width)
.attr("y2", this.height)
.attr("stroke-width","4")
.attr("stroke",this.lineColor || '#ffffff');
this.plot
.append("line.fake-ydomain")
.attr("x1",this.spacing)
.attr("y1", this.spacing)
.attr("x2", this.spacing)
.attr("y2", this.height)
.attr("stroke-width","4")
.attr("stroke",this.lineColor || '#ffffff');
yText = this.plot.selectAll('.y-axis .tick text'),
xText = this.plot.selectAll('.x-axis .tick text'),
yTick = this.plot.selectAll('.y-axis .tick'),
xTick = this.plot.selectAll('.x-axis .tick'),
yLine = this.plot.selectAll('.y-axis .tick line'),
xLine = this.plot.selectAll('.x-axis .tick line');
yTick
.style('display','none');
xTick
.style('display','none');
},
// the following are 'public methods'
// which can be used by code outside of this file
setColor:function(newColor) {
this.plot.selectAll('rect.comp-rect')
.style('fill', newColor);
// store for use when redrawing
this.lineColor = newColor;
},
setDataX:function(val) {
this.dataX = val;
this.draw();
},
setDataY:function(val) {
this.dataY = val;
this.draw();
},
setData: function(newData) {
this.data = newData;
this.draw();
}
}
<!doctype html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bar Chart Example</title>
<link href="https://fonts.googleapis.com/css?family=Raleway" rel="stylesheet">
</head>
<body>
<section class="d3-presentation-container">
<div class="mx-dv-container">
<h3 class="chart-title"><span class="data-event">White chart data</span></h3>
<div class="plot-wrap w-svg" id="presBarchart"></div>
<div class="button-container">
<button id="dataChange">Black chart data</button>
<button id="dataReset">White chart data</button>
</div>
</div>
</section>
<script src="d3-presentation.js"></script>
<script src="d3-presentation-init.js"></script>
<script src="https://rawgit.com/timproDev/d3-first-timer/master/js/d3v4-473-jetpack.js"></script>
</body>
</html>
Catastrophe Events Fatalities Total losses Insured losses
Really Bad Storm 43 40 2.0 14
Tidal Wave 19 83 4.0 4.3
Fire 18 32 8.2 1.0
Blizzard 7 55 12.7 1.0
Anything from the movie Twister 2 52 16.0 3.5
Catastrophe Events Fatalities Total losses Insured losses
Really Bad Storm 43 80 19.0 14
Tidal Wave 19 83 15.0 4.3
Fire 18 62 11.2 1.0
Blizzard 7 55 9.7 1.0
Anything from the movie Twister 2 52 7.0 3.5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment