Skip to content

Instantly share code, notes, and snippets.

@erikhazzard
Created August 14, 2013 18:20
Show Gist options
  • Save erikhazzard/6233914 to your computer and use it in GitHub Desktop.
Save erikhazzard/6233914 to your computer and use it in GitHub Desktop.
simple negative bar chart pt1
{"description":"simple negative bar chart pt1","endpoint":"","display":"svg","public":true,"require":[],"fileconfigs":{"inlet.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"style.css":{"default":true,"vim":false,"emacs":false,"fontSize":12},"_.md":{"default":true,"vim":false,"emacs":false,"fontSize":12},"config.json":{"default":true,"vim":false,"emacs":false,"fontSize":12}},"fullscreen":false,"play":false,"loop":false,"restart":false,"autoinit":true,"pause":true,"loop_type":"period","bv":false,"nclones":15,"clone_opacity":0.4,"duration":3000,"ease":"linear","dt":0.01,"thumbnail":"http://i.imgur.com/vzMWBvU.png"}
var DURATION = 500;
var margin = {top: 30, right: 10, bottom: 10, left: 10};
var width = 800 - margin.left - margin.right;
var height = 400 - margin.top - margin.bottom;
// Setup chart
var chart = d3.select('svg')
.attr({
viewBox: "0 0 800 400",
preserveAspectRatio: 'xMinYMin',
width: width + (margin.left + margin.right),
height: height + (margin.top + margin.bottom)
})
.append("g")
.attr({
transform: "translate(" + margin.left + "," + margin.top + ")"
});
// setup scales
// --------------------------------------
// create x scale, using the max value to center the zero line
var xScale = d3.scale.linear()
.range([0, width])
.nice();
//// for non centered chart
//xScale.domain(d3.extent(data, function(d) { return d.value; })).nice();
var yScale = d3.scale.ordinal()
.rangeRoundBands([0, height], .4);
// Setup axes
// --------------------------------------
var xAxis = d3.svg.axis()
.scale(xScale)
.tickSize(-height)
.orient("top");
// draw axes
var xAxisGroup = chart.append("g")
.attr({
"class": "x axis"
})
.call(xAxis);
// Draw zero line
var zeroLine = chart.append("g")
.attr({
"class": "y axis zeroLine"
})
.append("line")
.attr({
x1: xScale(0),
x2: xScale(0),
y1: 0,
y2: height
});
// Draw bars
// --------------------------------------
var genData = function(){
var data = [
{title: "Q1", value: -400 + Math.random() * 800 | 0},
{title: "Q2", value: -400 + Math.random() * 800 | 0},
{title: "Q3", value: -400 + Math.random() * 800 | 0},
{title: "Q4", value: -400 + Math.random() * 800 | 0}
];
return data;
}
var updateChart = function(data){
// get the max data value
// Add some padding to it s othe domain extens just a bit past
// (1.1 = 10% extra padding)
var maxX = Math.max(
d3.min(data, function(d){ return d.value; }) * -1,
d3.max(data, function(d){ return d.value; })
) * 1.1;
// update scales
xScale.domain([maxX * -1, maxX])
yScale.domain(data.map(function(d) { return d.title; }));
// update axis
xAxisGroup.transition().duration(DURATION)
.call(xAxis);
//update zero line
zeroLine.transition().duration(DURATION)
.attr({
x1: xScale(0),
x2: xScale(0)
});
// Update chart
var bars = chart.selectAll(".bar")
.data(data);
bars.enter()
.append("rect")
.attr({
x: xScale(0),
y: function(d) {
return yScale(d.title);
},
width: 0,
height: yScale.rangeBand()
});
bars.transition().duration(DURATION).attr({
"class": function(d) {
var name = 'bar ';
if(d.value < 0)
name += "negative";
else {
name += "positive";
}
return name;
},
x: function(d) {
// the starting x position will be either the xScale position for a
// negative value OR the x location of the zero line
return xScale(Math.min(0, d.value));
},
y: function(d) {
return yScale(d.title);
},
width: function(d) {
// width is just the absolute value of the
// location of the x value minus where the zero line is
return Math.abs(xScale(d.value) - xScale(0));
},
height: yScale.rangeBand()
});
bars.exit().transition().remove();
return bars;
};
// update the chart
updateChart(genData());
// call it a lot
setInterval(function(){
updateChart(genData());
}, 2000);
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.tick line {
stroke: #d0d0d0;
}
.zeroLine {
stroke-width: 1px;
}
.negative {
fill: #dd4444;
stroke: #bb2222;
}
.positive {
fill: #44dd44;
stroke: #22bb22;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment