Skip to content

Instantly share code, notes, and snippets.

@rfprod
Last active April 22, 2017 15:49
Show Gist options
  • Save rfprod/0da99e5b689c665322e4 to your computer and use it in GitHub Desktop.
Save rfprod/0da99e5b689c665322e4 to your computer and use it in GitHub Desktop.
Data Visualization with Multi-Bar Chart

Data Visualization with Multi-Bar Chart

User can view a heat map with data represented both on the Y and X axis. Each cell is colored based its relationship to other data. User can mouseover a cell in the heat map to get more exact information.

A Pen by V on CodePen.

License.

<div class="container-fluid nopadding">
<nav class="navbar navbar-inverse navbar-fixed-top topnav" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#toggle-nav" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand font-effect-neon" target=_blank href="http://codepen.io/rfprod"><span class="glyphicon glyphicon-wrench"></span> RFProd</a>
</div>
<div class="collapse navbar-collapse" id="toggle-nav">
<div class="container-fluid">
<ul class="nav navbar-nav navbar-right font-effect-emboss">
<li class="nav-tabs"><a href="#approot"><span class="glyphicon glyphicon-stats"></span> Data Visualization with Multi-Bar Chart</a></li>
<li class="nav-tabs"><a href="https://gist.github.com/rfprod/0da99e5b689c665322e4" target=_blank><span class="glyphicon glyphicon-download-alt" ></span> GIST</a></li>
</ul>
</div>
</div>
</nav>
<a name="approot"></a>
<div class="home sect">
<div class="container-fluid">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<h2 class="hidden-sm hidden-md hidden-xl"><span class="glyphicon glyphicon-stats"></span> Data Visualization with Multi-Bar Chart</h2>
<div id="output">
Output
</div>
<span class="credits">info <a href="https://d3js.org/" target=_blank>D3.js</a> | <a href="https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/global-temperature.json" target=_blank>data</a> <br/>licence <a href="http://www.gnu.org/licenses/gpl-3.0.en.html" target=_blank>GPL 3.0</a></span>
</div>
</div>
</div>
</div>
$(document).on('ready',function(){
(function (){
var UserInstructionsAndGDPChart = React.createClass({
render: function(){
return (
<span>
<p id="user-instructions">Monthly Global Land-Surface Temperature visualization using D3.js.</p>
<div id="temp"></div>
</span>
);
}
});
ReactDOM.render(<UserInstructionsAndGDPChart />,document.getElementById('output'));
var chartContainerObj = d3.select('#temp');
var monthNames = ['January','February','March','April','May','June','July','August','September','October','November','December'];
$.getJSON('https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/global-temperature.json', function(json){
var years = [], months = [], uniqueYearsCounter = 0;
var baseTemp = json['baseTemperature'];
var monthlyVar = json['monthlyVariance'];
for (var i=0;i<monthlyVar.length;i++){
if (years.indexOf(monthlyVar[i].year) == -1) uniqueYearsCounter++;
years.push(monthlyVar[i].year);
months.push(monthlyVar[i].month);
}
var minYr = d3.min(years,function(val,i){return val;});
var maxYr = d3.max(years,function(val,i){return val;});
chartContainerObj.append('p').attr('id','user-instructions').html('Temperature values are presented in &deg;C<br>Year range: '+minYr+' - '+maxYr);
//console.log('years: '+years);
//console.log('months: '+months);
var k = 0, windowWidth = $(window).width();
if (windowWidth < 1000) k = windowWidth/500;
else k = windowWidth/500;
var width = $('#temp').width()-75*k, height = 400;
var rectHeight = height/monthNames.length, rectWidth = width/uniqueYearsCounter;
chartContainerObj.append('svg').attr('class','chart');
chartContainerObj.append('svg').attr('class','legend');
var chartObj = d3.select('.chart').attr("width", width).attr("height", height);
var legendObj = d3.select('.legend').attr("width", width).attr("height", rectHeight*2);
var legendVarData = [{'v':'t<'+(baseTemp-2),'variance':-2.1},{'v':(baseTemp-2)+'<=t<'+(baseTemp-1),'variance':-1.5},{'v':(baseTemp-1)+'<=t<'+(baseTemp),'variance':-0.5},{'v':'t='+baseTemp,'variance':0},{'v':baseTemp+'<=t<'+(baseTemp+1),'variance':0.5},{'v':(baseTemp+1)+'<=t<'+(baseTemp+2),'variance':1.5},{'v':'t>='+(baseTemp+2),'variance':2.1}];
var y = d3.scale.ordinal().domain(monthNames).rangeRoundBands([height,10*k]);
var x = d3.scale.linear().domain([d3.min(years, function(val) {return val;}), d3.max(years, function(val) {return val;})]).range([0,width]);
var div = d3.select("body").append("div").attr("class", "tooltip").style("opacity", 0);
var tooltip = d3.select('.tooltip');
var xCursorPosition = 0, yCursorPosition = 0;
var legend = legendObj.selectAll('g').data(legendVarData).enter()
.append('g')
.attr("transform", function(val, i) {return "translate("+(width*i/7)+",0)";});
legend.append('rect')
.attr('id', function(val,i){
console.log('val: '+JSON.stringify(val));
if (val.variance < -2) return 'var-0';
if (val.variance >= -2 && val.variance < -1) return 'var-1';
if (val.variance >= -1 && val.variance < 0) return 'var-2';
if (val.variance > 0 && val.variance < 1) return 'var-3';
if (val.variance >= 1 && val.variance < 2) return 'var-4';
if (val.variance >= 2) return 'var-5';
return "var-null";
})
.attr("class", function(val,i){return "rect-marker";})
.attr("x", 60)
.attr("y", 0)
.attr("width", width/7)
.attr("height", rectHeight);
legend.append("text")
.attr("x", 60)
.attr("y", rectHeight * 1.5)
.attr("dy", ".35em")
.text(function(val) {return val.v;});
var rect = chartObj.selectAll('g').data(monthlyVar).enter()
.append('g')
.attr('class','animated fadeIn')
.attr("transform", function(val, i) {return "translate(60,0)";});
rect.append("rect")
.attr('id', function(val,i){
if (val.variance < -2) return 'var-0';
if (val.variance >= -2 && val.variance < -1) return 'var-1';
if (val.variance >= -1 && val.variance < 0) return 'var-2';
if (val.variance > 0 && val.variance < 1) return 'var-3';
if (val.variance >= 1 && val.variance < 2) return 'var-4';
if (val.variance >= 2) return 'var-5';
return "var-null";
})
.attr("class", function(val,i){return "rect-marker "+i;})
.attr("x",function(val){return x(val.year);})
.attr("y",function(val){return y(monthNames[val.month-1]);})
.attr("width", rectWidth)
.attr("height", rectHeight)
.on("mouseover", function(){
document.onmousemove = function(e){
xCursorPosition = e.pageX;
yCursorPosition = e.pageY;
}
d3.select(this).transition()
.duration(100)
.style("opacity", .3);
div.transition()
.duration(100)
.style("opacity", .9);
console.log(d3.select(this).attr('id'));
})
.on("mousemove", function(){
tooltip.style("left",xCursorPosition+"px");
tooltip.style("top",yCursorPosition-30+"px");
var index = d3.select(this).attr('class').substr(12,d3.select(this).attr('class').length-1);
var dataObj = monthlyVar[index];
tooltip.html('Year: '+dataObj.year+'<br>Month: '+dataObj.month+'<br>Base Temperature: '+baseTemp+'<br>Variance: '+dataObj.variance+'<br>Final Temperature: '+(Math.floor((baseTemp+dataObj.variance)*1000)/1000));
})
.on("mouseout", function(){
document.onmousemove = null;
d3.select(this).transition()
.duration(400)
.style("opacity", 1);
div.transition()
.duration(400)
.style("opacity", 0);
});
var margin = {top: 10, right: 20, bottom: 30, left: 60};
chartObj
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + "0)");
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(10,'yr');
chartObj.append("g")
.attr("class", "x axis")
.attr("transform", "translate("+margin.left+"," + height + ")")
.call(xAxis)
.append("text")
.attr('class','axis-label')
.attr("text-anchor", "middle")
.attr("transform", "translate("+ (width/2) +","+margin.bottom+")")
.text("Years");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
chartObj.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + margin.left + ",0)")
.call(yAxis);
});
})();
});
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://d3js.org/d3.v3.min.js"></script>
$black: #000000
$white: #ffffff
$grey: #bfbfbf
$blue: #3366cc
$green: #33cc33
$darkblue1: #000066
$darkblue2: #0000ff
$lightyellow: #ffff99
$yellow: #ffff00
$orange: #ff6600
$red: #ff3300
body
color: $black
font-family: 'Play', sans-serif
font-size: 2.2em
overflow-x:hidden
.tooltip
position: absolute
text-align: center
width: auto !important
height: auto !important
padding: 2px
font: 12px sans-serif
background: lightsteelblue
border: 0px
border-radius: 8px
pointer-events: none
.nopadding
padding: 0
.navbar-brand
font-size: 1em
.home
min-height: 100vh
height: auto !important
.sect
padding-top: 8vh
.githublogo
height: 1em
h2
text-align: center
font-weight: bold
#output
text-align: center
width: 100%
height: auto !important
#user-instructions
text-align: center
font-size: 0.75em
margin-top: 1em
#temp
display: block
background-color: $grey
padding-top: 1em
padding-left: 1em
.legend
width: 97%
font: 10px sans-serif
.rect
display: inline-block
#var-null
fill: $lightyellow
#var-0
fill: $darkblue1
#var-1
fill: $darkblue2
#var-2
fill: $blue
#var-3
fill: $yellow
#var-4
fill: $orange
#var-5
fill: $red
text
fill: $black
.chart
width: 97%
.rect-marker
display: inline-block
rect
fill: $blue
#var-null
fill: $lightyellow
#var-0
fill: $darkblue1
#var-1
fill: $darkblue2
#var-2
fill: $blue
#var-3
fill: $yellow
#var-4
fill: $orange
#var-5
fill: $red
text
fill: $black
.axis
text
font: 9px sans-serif
path, line
fill: none
stroke: $black
shape-rendering: crispEdges
.axis-label
font: 15px sans-serif
.hidden
display: none
a
text-decoration: none
.credits
display: block
text-align: center
font-size: 0.75em
a:hover
text-decoration: none
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<link href="//cdnjs.cloudflare.com/ajax/libs/animate.css/3.2.3/animate.min.css" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css?family=Play&effect=neon" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment