Built with blockbuilder.org
Created
December 9, 2017 13:13
-
-
Save dharwadravi/35d0d8abf67e78e602aa3d430160258f to your computer and use it in GitHub Desktop.
bar chart from json array
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
license: mit |
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
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<style> | |
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } | |
#card_analytics__requests_by_period { | |
max-width: 100%; | |
background: #f7f7f7; | |
height: 300px; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
overflow-x: auto; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="card_analytics__requests_by_period"></div> | |
<script> | |
// DATA | |
var data = [ | |
{ | |
data_month: "2017-01-31", | |
label: "January", | |
requests_submitted: { | |
current: 21, | |
prior: 16, | |
during:236 | |
} | |
}, { | |
data_month: "2017-02-28", | |
label: "February", | |
requests_submitted: { | |
current: 16, | |
prior: 43 | |
} | |
}, { | |
data_month: "2017-03-31", | |
label: "March", | |
requests_submitted: { | |
current: 36, | |
prior: 20 | |
} | |
}, { | |
data_month: "2017-04-30", | |
label: "April", | |
requests_submitted: { | |
current: 230, | |
prior: 310 | |
} | |
}, { | |
data_month: "2017-05-31", | |
label: "May", | |
requests_submitted: { | |
current: 50, | |
prior: 14 | |
} | |
}, { | |
data_month: "2017-06-30", | |
label: "June", | |
requests_submitted: { | |
current: 39, | |
prior: 47 | |
} | |
}, { | |
data_month: "2017-07-31", | |
label: "July", | |
requests_submitted: { | |
current: 72, | |
prior: 68 | |
} | |
}, { | |
data_month: "2017-08-31", | |
label: "August", | |
requests_submitted: { | |
current: 31, | |
prior: 97 | |
} | |
}, { | |
data_month: "2017-09-30", | |
label: "September", | |
requests_submitted: { | |
current: 57, | |
prior: 25 | |
} | |
}, { | |
data_month: "2017-10-31", | |
label: "October", | |
requests_submitted: { | |
current: 71, | |
prior: 45 | |
} | |
}, { | |
data_month: "2017-11-30", | |
label: "November", | |
requests_submitted: { | |
current: 25, | |
prior: 32 | |
} | |
}, { | |
data_month: "2017-12-31", | |
label: "December", | |
requests_submitted: { | |
current: 41, | |
prior: 21 | |
} | |
}] | |
// VARS | |
/* margin object for parent container */ | |
var margin = {top: 20, right: 20, bottom: 20, left: 40}; | |
/* parent container id */ | |
var container = '#card_analytics__requests_by_period' | |
/* width of parent container that will by dynamic in ReloQuest app. For now it is static */ | |
var parentWidth = 900 | |
var parentHeight = 300 | |
/* width and height of the chart area. This is defined so that margins aren't needed in later calculations */ | |
var width = parentWidth - margin.left - margin.right | |
var height = parentHeight - margin.top - margin.bottom | |
/* Will be used to separate each month's data into current and prior periods */ | |
var keys = Object.keys(data[0].requests_submitted) | |
// SVG | |
/* the svg element's width and height is identical to the parent width and height. Instead of just using the `width` | |
and `height` variables declared earlier, we are basically setting some padding on the entire svg element so calculations | |
don't need to take it into account */ | |
var svg = d3.select(container).append('svg') | |
.attr('width', width + margin.left + margin.right) | |
.attr('height', height + margin.top + margin.bottom) | |
/* The g element will be where the chart actually lives */ | |
var g = svg.append('g') | |
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); | |
// Scales | |
/* Scales the months */ | |
var x0 = d3.scaleBand() | |
.domain(data.map( d => d.label)) | |
.range([0, width]) | |
.padding(0.2) | |
/* Scales the current and prior periods in each month */ | |
var x1 = d3.scaleBand() | |
.domain(keys) | |
.range([0, x0.bandwidth()]) | |
.padding(0.1) | |
/* Scales the y axis based on request values */ | |
var y = d3.scaleLinear() | |
.domain([0, getRequestMax()]) | |
.range([height, 0]) | |
function _buildChart() { | |
var chart = g.append('g') | |
.classed('chart', true) | |
// Adds a `g` element for every month, | |
// which will contain 2 `rects` for data of each period | |
var months = chart.selectAll('g') | |
.data(data) | |
.enter().append('g') | |
.attr('transform', function(d) { | |
return 'translate(' + x0(d.label) + ', 0)'; | |
}) | |
.selectAll('rect') | |
.data(function(d) { | |
var datum = keys.map(function(key, i) { | |
return { | |
key: key, | |
fill: getFill(i), | |
val: d.requests_submitted[key] | |
} | |
}); | |
return datum | |
}) | |
.enter().append('rect') | |
.attr('x', d => x1(d.key)) | |
.attr('y', d => y(d.val)) | |
.attr('width', x1.bandwidth()) | |
.attr('height', d => height - y(d.val)) | |
.attr('fill', d => d.fill) | |
} | |
function _buildAxes() { | |
var xAxis = d3.axisBottom(x0) | |
var yAxis = d3.axisLeft(y) | |
g.append('g') | |
.classed('axis', true) | |
.attr('transform', 'translate(0,' + height +')') | |
.call(xAxis) | |
g.append('g') | |
.classed('axis', true) | |
.attr('transform', 'translate(0, 0)') | |
.call(yAxis) | |
} | |
function init() { | |
_buildChart() | |
_buildAxes() | |
} | |
init() | |
// HELPERS | |
/* | |
* Takes an index of 0 or 1 returns a color depending on the index | |
* @returns {string} - A color string | |
*/ | |
function getFill(i) { | |
return i ? 'lightblue' : 'lightgreen' | |
} | |
/* | |
* A wrapper around the d3.max method that returns the highest request submission | |
* total for a given month from 2 separate years | |
* --- | |
* @returns {num} | |
*/ | |
function getRequestMax() { | |
return d3.max(getAllRequests(data)) | |
} | |
/* | |
* Combines all request submission values into an array | |
* --- | |
* @param {Array} `data` - An array of objects for each month | |
* @returns {Array} | |
*/ | |
function getAllRequests(data) { | |
return data.reduce(function(collection, d) { | |
return collection.concat( | |
keys.map(function(key) { | |
return d.requests_submitted[key] | |
}) | |
) | |
}, []) | |
} | |
</script> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment