| <!DOCTYPE html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> | |
| </head> | |
| <body> | |
| <div id="container"> | |
| </div> | |
| <script> | |
| var data = [ | |
| { | |
| "name": "Jeb Bush", | |
| "total_receipts": 11429897.64, | |
| "total_from_individuals": 10983577.49, | |
| "total_from_pacs": 57600, | |
| "total_contributions": 0, | |
| "total_disbursements": 3078087.31 | |
| }, | |
| { | |
| "name": "Ted Cruz", | |
| "total_receipts": 14349160.55, | |
| "total_from_individuals": 14078316.37, | |
| "total_from_pacs": 20207.25, | |
| "total_contributions": 0, | |
| "total_disbursements": 5821564.62 | |
| }, | |
| { | |
| "name": "Hillary Clinton", | |
| "total_receipts": 47549949.64, | |
| "total_from_individuals": 46938582.3, | |
| "total_from_pacs": 332396.25, | |
| "total_contributions": 0, | |
| "total_disbursements": 18699814.02 | |
| } | |
| ] | |
| var keys = [ | |
| "total_from_pacs", | |
| "total_from_individuals" | |
| ] | |
| var subcategories = keys.map(function(key, i) { | |
| var results = data.map(function(candidate) { | |
| return candidate[key]; | |
| }); | |
| var accumulative = data.map(function(candidate) { | |
| var memo = 0; | |
| for(var j = 0; j <= i; j++) { | |
| memo += candidate[keys[j]]; | |
| } | |
| return memo; | |
| }); | |
| return { | |
| key: key, | |
| results: results, | |
| accumulative: accumulative | |
| }; | |
| }); | |
| var STATIC = { | |
| width: 960, | |
| height: 500, | |
| margin: 20, | |
| bar: { | |
| thickness: 30, | |
| gap: 60 | |
| }, | |
| text: { | |
| columnWidth: 250 | |
| } | |
| } | |
| var totalReceiptMax = d3.max(data, function(d) { | |
| return d.total_receipts; | |
| }); | |
| var barLengthScale = d3.scale.linear() | |
| .domain([0, totalReceiptMax]) | |
| .range([0, STATIC.width * 0.7 - STATIC.margin * 2]); | |
| var svg = d3.select("#container").append("svg") | |
| .attr("width", STATIC.width) | |
| .attr("height", STATIC.height); | |
| var drawBars = function(d, i) { | |
| var layer = d3.select(this); | |
| layer.attr("transform", "translate(" + (STATIC.margin + STATIC.text.columnWidth) + ", " + (STATIC.margin + i * (STATIC.bar.thickness + STATIC.bar.gap)) + ")"); | |
| layer.append("text") | |
| .attr("x", -10) | |
| .attr("y", STATIC.bar.thickness - 9) | |
| .attr("text-anchor", "end") | |
| .text(function(d) { | |
| return d.name; | |
| }) | |
| layer.append("rect") | |
| .attr("fill", "none") | |
| .attr("stroke", "#00aaff") | |
| .attr("width", function(d) { | |
| return barLengthScale(d.total_receipts); | |
| }) | |
| .attr("height", STATIC.bar.thickness); | |
| } | |
| svg.selectAll(".bars") | |
| .data(data) | |
| .enter() | |
| .append("g").attr("class", "bars") | |
| .each(drawBars); | |
| var drawCategoryPaths = function(d, i) { | |
| var layer = d3.select(this); | |
| layer.attr("transform", "translate(" + (STATIC.margin + STATIC.text.columnWidth) + ", " + STATIC.margin + ")"); | |
| var pathString = "M"; | |
| d.accumulative.map(function(datum, i) { | |
| console.log(datum, i); | |
| var x = barLengthScale(datum); | |
| var y = i * (STATIC.bar.thickness + STATIC.bar.gap); | |
| if (i > 0) { pathString += "L"; } | |
| pathString += x + "," + y + "L" + x + "," + (y + STATIC.bar.thickness); | |
| }); | |
| layer.append("path") | |
| .attr("stroke", "#000") | |
| .attr("fill", "none") | |
| .attr("stroke-width", 1) | |
| .attr("d", pathString); | |
| } | |
| var subCategoryLayer = svg.append("g").attr("id", "paths"); | |
| subCategoryLayer.selectAll(".category") | |
| .data(subcategories) | |
| .enter() | |
| .append("g").attr("class", "category") | |
| .each(drawCategoryPaths); | |
| </script> | |
| </body> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment