Skip to content

Instantly share code, notes, and snippets.

@akrusz
Created August 16, 2012 17:01
Show Gist options
  • Save akrusz/3371690 to your computer and use it in GitHub Desktop.
Save akrusz/3371690 to your computer and use it in GitHub Desktop.
d3 graph
<html>
<head>
<title>D3 Demo: Making a bar chart with value labels!</title>
<meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8" />
<script type="text/javascript" src="d3.js"></script>
<style type="text/css">
/* No style rules here yet */
</style>
</head>
<body>
<script type="text/javascript">
//Width and height
var w = 800;
var h = 550;
var barPadding = 1;
var bottomMargin = 42;
var verticalDataPixels = h - bottomMargin;
var dataset = [ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13,
11, 12, 15, 20, 18, 17, 16, 18, 23, 25 ];
var stdDevs = [ 1, 2, 3, 3, 4, 3, 6, 2, 1.5, 2,
5, 5.5, 5, 4.5, 4, 3.5, 3, 2.5, 2, 1.5];
var maxDisplayValue = -Infinity;
var minDisplayValue = Infinity;
// At 3.33 standard deviations away from the mean, the probability
// density is less than 1/256 of that at the peak. We can round it
// down to zero as there are 256 shades of web-safe gray.
var sizeOfCurveInStdDevs = 3.33;
for(var index = 0; index < dataset.length; index++){
if(dataset[index] + sizeOfCurveInStdDevs*stdDevs[index] > maxDisplayValue){
maxDisplayValue = dataset[index] + sizeOfCurveInStdDevs*stdDevs[index];
}
if(dataset[index] - sizeOfCurveInStdDevs*stdDevs[index] < minDisplayValue){
minDisplayValue = dataset[index] - sizeOfCurveInStdDevs*stdDevs[index];
}
}
// This is the vertical size of the display area, in terms of data value.
var dataRange = maxDisplayValue - minDisplayValue;
var maxValue = Math.max.apply(Math, dataset);
// This is so we can scale the opacity down for data points with large
// standard deviations, so total color is the same for each data point.
// In the case that the lowest stddev is super small, this will cause
// the large ones to be too pale, so we can specify a minimum stddev
// for the purposes of scaling down opacity.
var minStdDev = Math.max(2, Math.min.apply(Math, stdDevs));
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
// We'll replace this with a smarter, algorithmic way to get a smoother
// bell curve or other probability density function.
var gradient = svg.append("svg:defs")
.append("svg:linearGradient")
.attr("id", "gradient")
.attr("x1", "0%")
.attr("y1", "0%")
.attr("x2", "0%")
.attr("y2", "100%")
.attr("spreadMethod", "pad");
gradient.append("svg:stop")
.attr("offset", "0%")
.attr("stop-opacity", 0)
.attr("stop-color", "#049");
gradient.append("svg:stop")
.attr("offset", "17%")
.attr("stop-opacity", .15)
.attr("stop-color", "#049");
gradient.append("svg:stop")
.attr("offset", "42%")
.attr("stop-opacity", .85)
.attr("stop-color", "#049");
gradient.append("svg:stop")
.attr("offset", "50%")
.attr("stop-opacity", 1)
.attr("stop-color", "#049");
gradient.append("svg:stop")
.attr("offset", "58%")
.attr("stop-opacity", .85)
.attr("stop-color", "#049");
gradient.append("svg:stop")
.attr("offset", "83%")
.attr("stop-opacity", .15)
.attr("stop-color", "#049");
gradient.append("svg:stop")
.attr("offset", "100%")
.attr("stop-opacity", 0)
.attr("stop-color", "#049");
// for(var i = 0; i < 101; i++){
// gradient.append("svg:stop")
// .attr("offset", i + "%")
// .attr("stop-color", "#049")
// .attr("stop-opacity", circletop(i * .02 - 1));
// }
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", function(d, i) {
return i * (w / dataset.length);
})
.attr("y", function(d, i) {
return verticalPositionOfDatum(
d + sizeOfCurveInStdDevs*stdDevs[i], minDisplayValue, maxDisplayValue, verticalDataPixels);
})
.attr("width", w / dataset.length - barPadding)
.attr("height", function(d, i) {
return verticalPositionOfDatum(
d - sizeOfCurveInStdDevs*stdDevs[i], minDisplayValue, maxDisplayValue, verticalDataPixels)
- verticalPositionOfDatum(
d + sizeOfCurveInStdDevs*stdDevs[i], minDisplayValue, maxDisplayValue, verticalDataPixels);
})
.style("fill", "url(#gradient)")
.style("opacity", function(d, i) {
return Math.min(1, minStdDev / stdDevs[i]);
});
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text(function(d, i) {
return i + 1990;
})
.attr("text-anchor", "middle")
.attr("x", function(d, i) {
return i * (w / dataset.length) + (w / dataset.length - barPadding) / 2;
})
.attr("y", function(d) {
return h - 30;
})
.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("fill", "black");
svg.selectAll("text")
.append('tspan')
.attr("x", function(d, i) {
return i * (w / dataset.length) + 15;
})
.attr("y", function(d, i) {
return h - 10;
})
.text(function(d, i) {
return "σ: " + stdDevs[i];
})
.append('tspan')
.attr("x", function(d, i) {
return i * (w / dataset.length) + 15;
})
.attr("y", function(d, i) {
return h - 20;
})
.text(function(d) {
return "μ: " + d;
});
function verticalPositionOfDatum(dataValue, windowMin, windowMax, verticalPixels){
return verticalPixels * (windowMax - dataValue) / (windowMax - windowMin);
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment