Skip to content

Instantly share code, notes, and snippets.

Created January 10, 2014 06:24
Show Gist options
  • Save anonymous/8347776 to your computer and use it in GitHub Desktop.
Save anonymous/8347776 to your computer and use it in GitHub Desktop.
A Pen by Liji Jinaraj.
<div class="chart">
</div>
/**
* ref http://en.wikipedia.org/wiki/User_talk:Slashme/parliament.py
*/
function parliamentCharts(el, parliament) {
var margin = {top: 10, right: 0, bottom: 0, left: 10},
width = 500 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var totalSpots = [3, 15, 33, 61, 95, 138, 189, 247, 313, 388, 469, 559, 657, 762, 876, 997, 1126, 1263, 1408, 1560, 1722, 1889, 2066, 2250, 2442, 2641, 2850, 3064, 3289, 3519, 3759, 4005, 4261, 4522, 4794, 5071, 5358, 5652, 5953, 6263, 6581, 6906, 7239, 7581, 7929, 8287, 8650, 9024, 9404];
var formatNumber = d3.format("n");
var partyColors = {
"d":{name:"Democrats", color:"#0A5F90"}
, "r":{name:"Republicans", color:"#CC5B2E"}
, "i":{name:"Independents", color:"#333"}
, "vacant":{name:"Vacant", color:"#fff"}
};
var svg = el.append("svg")
.attr("class", "parliament usa")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
draw(svg, parliament[0].houses[0], 0, 10, {x:5, y:5});
draw(svg, parliament[0].houses[1], 180, 5, {x:5, y:15});
drawLegend(svg);
function draw(svgEl, pData, pOffsetAngle, pRows, centerOffset) {
var dcols = [];
var baseRow = 0;
var n = pData.totalMembers;
var maxRadius = 0.2/8;
var partyIndex = 0;
var partyStartIndex = 0;
var dataRef = [];
var direction = pOffsetAngle === 180 ? 1 : 0;
function initDataRef() {
pOffsetAngle *= Math.PI/180;
function calcCol(drow, dcol, dn, dr) {
var da = dcol*(Math.PI-2.0*Math.sin(maxRadius/dr))/(dn-1.0)+Math.sin(maxRadius/dr) + pOffsetAngle;
var dx = Math.cos(da) * dr + 1.75;
var dy = Math.sin(da) * dr;
dataRef.push({
id: dataRef.length,
row: drow,
col: dcol,
a: da,
x: dx,
y: dy
});
}
d3.range(1, pRows).forEach(function(drow) {
var dr = (3.0*pRows+4.0*drow-2.0)/(4.0*pRows);
var dn = Math.floor(n/totalSpots[pRows-1]*Math.PI/(2*Math.asin(2.0/(3.0*pRows+4.0*drow-2.0))));
d3.range(dn).forEach(function(dcol) {
calcCol(drow, dcol, dn, dr);
});
});
var dn = n - dataRef.length;
var dr =(7.0*pRows-2.0)/(4.0*pRows);
d3.range(dn).forEach(function(dcol) {
calcCol(0, dcol, dn, dr);
})
}
initDataRef();
dataRef = dataRef.sort(function(a,b) {
return a.a - b.a;
}).reverse();
var gHouse = svgEl.select(".house " + pData.id);
if(gHouse.empty()) {
gHouse = svgEl.append("g")
.attr("class", "house " + pData.id);
}
var gTitle = gHouse.append("g")
.attr("class", "house-heading");
var center = {
x: Math.cos(90 * Math.PI/180 + pOffsetAngle) * 0.2 + 1.75,
y: Math.sin(90 * Math.PI/180 + pOffsetAngle) * 0.2
};
gTitle.append("text")
.attr("class", "house-members")
.attr("text-anchor", "middle")
.attr("x", center.x * 100 + centerOffset.x)
.attr("y", (1.75 - center.y) * 100 + centerOffset.y + (direction * 28))
.style("fill", "#333")
.text(pData.totalMembers);
center = {
x: Math.cos(90 * Math.PI/180 + pOffsetAngle) * 0.05 + 1.75,
y: Math.sin(90 * Math.PI/180 + pOffsetAngle) * 0.05
};
gTitle.append("text")
.attr("class", "house-name")
.attr("text-anchor", "middle")
.attr("x", center.x * 100 + centerOffset.x)
.attr("y", (1.75 - center.y) * 100 + centerOffset.y + (direction * 12))
.style("fill", "#333")
.text(pData.name);
var spot = -1;
pData.parties.forEach(function(party) {
var gParty = gHouse.select(".party .party-" + party.id);
if(gParty.empty()) {
gParty = gHouse.append("g")
.datum(party)
.attr("class", "party party-" + party.id);
}
var circles = gParty.selectAll(".node." + pData.id)
.data(d3.range(spot+1, spot+party.totalMembers+1));
circles.enter().append("circle")
.attr("class", function(d) {
var dref = dataRef[d];
return "node " + dref.id + " node" + dref.row;
})
.attr("r", maxRadius * 100);
circles
.attr("cx", function(d) {
var dref = dataRef[d];
return dref.x * 100 + centerOffset.x;
})
.attr("cy", function(d) {
var dref = dataRef[d];
return (1.75 - dref.y) * 100 + centerOffset.y;
})
.style("fill", partyColors[party.id].color || "#333");
circles.exit().remove();
spot = spot + party.totalMembers;
});
}
function drawLegend(svg) {
var legend = svg.selectAll(".legend")
.data(d3.map(partyColors).values())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + (i * 20 + 50) + ")"; });
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", function(d) { return d.color; });
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.style("fill", "#666")
.text(function(d) { return d.name; });
}
}
var data = [{
"id": "usa",
"country": "USA",
"code": "US",
"houses": [{
"id": "house",
"name": "House",
"totalMembers": 435,
"parties": [
{
"id": "d",
"name": "Democrats",
"totalMembers": 200
},
{
"id": "r",
"name": "Republicans",
"totalMembers": 233
},
{
"id": "vacant",
"name": "Vacant",
"totalMembers": 2
}
]
},
{
"id": "senate",
"name": "Senate",
"totalMembers": 100,
"parties": [
{
"id": "d",
"name": "Democrats",
"totalMembers": 53
},
{
"id": "r",
"name": "Republicans",
"totalMembers": 45
},
{
"id": "i",
"name": "Independent",
"totalMembers": 2
}
]
}]
}];
parliamentCharts(d3.select(".chart"), data);
body {
background: #C1BBB8;
}
.chart {
border: none;
background: none;
}
.chart h3 {
padding: 0 12px;
}
.house .house-members {
font-size: 32px;
font-weight: 500;
}
.house .house-name {
font-size: 12px;
font-weight: 100;
text-transform: uppercase;
letter-spacing: 1px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment