D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
dharwadravi
Full window
Github gist
bar chart from json array
Built with
blockbuilder.org
<!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>
https://d3js.org/d3.v4.min.js