D3 - 2 Quadrant Bar Chart
D3 fiddle exploring how to create a bar chart with the following requirements:
* x axis should use an ordinal scale and be labelled along the bottom
* y axis should use a linear scale and rendered along left side of the chart
* series bars should have a linear gradient
* colors used in the gradient should be defined in a separate css file
* the width and height of the chart should be based on the dimension of the window
* the dimensions of the chart should refresh on window resize
* the y axis should use a custom scale based on the values proximity to a fixed value (aka tolerance)
* the chart should have two quadrant for plotting positive and negative y values
by brady houseknecht
April 12, 2016
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.16/d3.js"></script>
CSS
body {
font-family: "Courier New";
font-size: small;
text-align: center;
background-color: black;
}
.axis path,
.axis line {
fill: none;
stroke: white;
shape-rendering: crispEdges;
}
.axis text {
font: 10px sans-serif;
stroke: white;
}
.axis .h-grid-line {
stroke: white;
shape-rendering: crispEdges;
stroke-opacity: 1;
stroke-width: 2;
}
.axis .v-grid-line {
stroke: turquoise;
shape-rendering: crispEdges;
stroke-opacity: .2;
}
stop.yellow {
stop-color: #E9F90B;
}
stop.red {
stop-color: #F91B0B;
}
stop.lightblue {
stop-color: #0BC1F9;
}
stop.blue {
stop-color: #0B0BF9;
}
JavaScript
(function(app, $, undefined) {
"use strict";
let metadata = {
fiddleHeader: 'D3 - 2 Quadrant Bar Chart',
urls: {
github: 'https://github.com/bradyhouse/house/tree/master/fiddles/d3/fiddle-0025-TwoQuadrantBarChart'
},
consoleTag: 'H O U S E ~ f i d d l e s'
};
function barChart() {
let _chart = {},
_duration = 1000,
_margins = {
top: 30,
left: 40,
right: 0,
bottom: 30
},
_width = window.innerWidth - _margins.left - _margins.right,
_height = window.innerHeight - _margins.top - _margins.bottom,
_xAxis, _yAxis,
_forceY = [0],
_data = [],
_svg,
_bodyG,
_snapshot = false,
getX = function(d) {
return d.x
},
getY = function(d) {
return d.y
},
x = d3.scale.ordinal(),
y = d3.scale.linear(),
x0, y0;
function constrain(number, min, max) {
let x = parseFloat(number);
if (min === null) {
min = number;
}
if (max === null) {
max = number;
}
return (x < min) ? min : ((x > max) ? max : x);
}
function defineAxesAndScales() {
/*_xScale = d3.scale.ordinal()
.domain(_data.map(function (d) {
return d.label;
}))
.rangeRoundBands([0, quadrantWidth(), 0.05]);*/
x.domain(_data.map(function(d) {
return d.label;
}))
.rangeBands([0, quadrantWidth()], .1);
_xAxis = d3.svg.axis().scale(x).orient("bottom");
y.domain(d3.extent(_data.map(function(d) {
return d.y
}).concat(_forceY)));
y.range([quadrantHeight() - (y.domain()[0] < 0 ? 12 : 0), y.domain()[1] > 0 ? 12 : 0]);
/*_yScale = d3.scale.linear()
.domain([
d3.min(_data, function (d) {
let scale = Math.floor(d.y / 3),
ret = (scale < 0) ? constrain(scale, -20, -0.05) : 0;
return ret;
...