Skip to content

Instantly share code, notes, and snippets.

@davo

davo/README.md

Forked from jazzido/README.md
Last active Aug 29, 2015
Embed
What would you like to do?
Diferencia porcentual votos positivos al FPV entre PASO 2011 y 2015 — Por provincia
Provincia 2011 2015 Diferencia
Santa Cruz 65.54 44.35 -21.19
Neuquen 55.29 35.63 -19.66
Cordoba 34.25 14.66 -19.6
Salta 62.68 43.8 -18.89
Jujuy 58.01 41.68 -16.33
Rio Negro 60.08 44.62 -15.46
Tierra del Fgo. 61.66 47.02 -14.64
San Luis 34.15 19.58 -14.58
Sgo. del Estero 80.45 66.03 -14.42
Buenos Aires 53.35 39.49 -13.86
Mendoza 46.94 33.2 -13.74
Corrientes 63.42 50.24 -13.17
Catamarca 63.43 51.59 -11.85
San Juan 65.26 54.48 -10.78
La Rioja 50.52 40.58 -9.95
Formosa 69.68 60.14 -9.54
La Pampa 47.93 39.84 -8.1
Tucuman 65.15 57.14 -8.01
CABA 30.17 23.25 -6.93
Misiones 64.1 57.44 -6.66
Entre Rios 45.85 39.45 -6.4
Chaco 60.35 54.65 -5.7
Santa Fe 37.91 32.95 -4.96
Chubut 51.56 47.32 -4.25
<!DOCTYPE html>
<html>
<head>
<title>Diferencia votos positivos al FPV entre PASO 2011 y 2015</title>
<script src="http://mbostock.github.com/d3/d3.v2.min.js?2.8.1"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
body { color: #444; background: #f3f3f3; font: normal 12px "Adobe Garamond Pro", "Palatino", serif; margin: 2em; }
header { margin: 0 0 20px 220px; border-bottom: 1px solid #6c6c6c; width: 360px; position: relative; }
h1 { font-size: 28px; font-weight: normal; text-shadow: #fff 0 1px 0; margin: 0 0 0 0; padding: 0; }
small { color: #a3a3a3; font-size: 12px; position: absolute; bottom: -2.8em; left: 0;}
a { color: #a3a3a3; }
span.label_year:hover { cursor: ew-resize; }
text.label { fill: #444; }
text.label.start { text-anchor: end; }
line.slope { stroke: #444; stroke-width: 1; }
.missing text.label { display: none; }
.missing line.slope { display: none; }
.over text.label { fill: #bb2629; }
.over line.slope { stroke: #bb2629; stroke-width: 2; }
</style>
</head>
<body>
<header>
<h1>
Diferencia votos positivos al FPV entre PASO 2011 y 2015
</h1>
<small>Datos del artículo <a href="http://www.lanacion.com.ar/1820011-como-variaron-los-resultados-del-fpv-entre-las-paso-de-2011-y-las-de-2015">Cómo variaron los resultados del FPV entre las PASO de 2011 y las de 2015</a></small>
</header>
<div id="chart"></div>
</body>
<script>
d3.csv("elecciones.csv", function(csv) {
//var csv = cs.slice(1,50);
data = csv;
// console.log("CSV", csv);
var
// Extract years from the dataset
years = d3.keys(csv[0]).filter( function(d) { return d.match(/^\d/) }), // Return numerical keys
// Extract names of countries from the dataset
countries = csv.map( function(d) { return d["Provincia"] }),
// Return true for countries without start/end values
missing = function(d) { return !d.start || !d.end; },
font_size = 12,
margin = 20,
width = 800,
height = 5 * countries.length * font_size + margin,
chart = d3.select("#chart").append("svg")
.attr("width", width)
.attr("height", height);
//Ignore this code ... makes bl.ocks.org show this in an acceptable-sized iframe.
var styleElement = parent.document.getElementById('styles_js'); if (!styleElement) {styleElement = parent.document.createElement('style'); styleElement.type = 'text/css'; styleElement.id = 'styles_js'; parent.document.getElementsByTagName('head')[0].appendChild(styleElement); } styleElement.appendChild(document.createTextNode('iframe{height:'+height+'px;}'));
// Scales
var slope = d3.scale.linear()
.domain( [83, 29] )
.range([margin, height]);
var year_scale = d3.scale.linear()
.domain([ parseInt(d3.first(years)), parseInt(d3.last(years)) ])
.clamp(true);
// Update the chart graphics based on new data for selected year
var update = function() {
var
// Extract country names and start/end values from the dataset
data = csv
.map( function(d, i) {
var r = {
label: d["Provincia"],
start: d3.round(parseFloat(d['2011']),3),
end: d3.round(parseFloat(d['2015']),3)
};
// console.log(r);
return r;
})
// Sort in descending order
.sort( function(a,b) {
return d3.max([a.start, a.end]) > d3.max([b.start, b.end]) ?
-1 :
d3.max([a.start, a.end]) < d3.max([b.start, b.end]) ?
1 : 0;
} ),
// Compute the minimum and maximum value in the dataset
extent = [ csv.map(function(d) {
return d3.entries(d)
.filter(function(d) { return d.key.match(/^\d/) })
.map(function(d) { return d.value })
}) ];
//Go through the list of countries in order, adding additional space as necessary.
var min_h_spacing = 1.2 * font_size, // 1.2 is standard font height:line space ratio
previousY = 0,
thisY,
additionalSpacing;
//Preset the Y positions (necessary only for the lower side)
//These are used as suggested positions.
data.forEach(function(d) {
d.startY = slope(d.start);
d.endY = slope(d.end);
});
//Loop over the higher side (right) values, adding space to both sides if there's a collision
data
.sort(function(a,b) {
if (a.end == b.end) return 0;
return (a.end < b.end) ? -1 : +1;
})
.forEach(function(d) {
thisY = d.endY; //position "suggestion"
additionalSpacing = d3.max([0, d3.min([(min_h_spacing - (thisY - previousY)), min_h_spacing])]);
//Adjust all Y positions lower than this end's original Y position by the delta offset to preserve slopes:
data.forEach(function(dd) {
if (dd.startY >= d.endY) dd.startY += additionalSpacing;
if (dd.endY >= d.endY) dd.endY += additionalSpacing;
});
previousY = thisY;
});
//Loop over the lower side (left) values, adding space to both sides if there's a collision
previousY = 0;
data
.sort(function(a,b) {
if (a.startY == b.startY) return 0;
return (a.startY < b.startY) ? -1 : +1;
})
.forEach(function(d) {
thisY = d.startY; //position "suggestion"
additionalSpacing = d3.max([0, d3.min([(min_h_spacing - (thisY - previousY)), min_h_spacing])]);
//Adjust all Y positions lower than this start's original Y position by the delta offset to preserve slopes:
data.forEach(function(dd) {
if (dd.endY >= d.startY) dd.endY += additionalSpacing;
if (dd.startY >= d.startY) dd.startY += additionalSpacing;
});
previousY = thisY;
});
// Countries
var country = chart.selectAll("g.country")
.data( data );
country
.enter()
.append("g")
.attr("class", "country");
country
.classed("missing", function(d) { return missing(d); });
country
.on("mouseover", function(d,i) { return d3.select(this).classed("over", true); })
.on("mouseout", function(d,i) { return d3.select(this).classed("over", false); });
// ** Left column
var left_column = country
.selectAll("text.label.start")
.data( function(d) { return [d]; } );
left_column
.enter()
.append("text")
.classed("label start", true)
.attr("xml:space", "preserve")
.style("font-size", font_size)
.attr("x", 200)
.attr("y", 0);
left_column
.attr("y", function(d,i) { return d.startY; })
.text(function(d) { return d.label+ " " + d3.round(d.start, 2) + "%"; });
// ** Right column
var right_column = country
.selectAll("text.label.end")
.data( function(d) { return [d]; } );
right_column
.enter()
.append("text")
.classed("label end", true)
.attr("xml:space", "preserve")
.style("font-size", font_size)
.attr("x", width-200)
.attr("y", 0);
right_column
.attr("y", function(d,i) { return d.endY; })
.text(function(d) { return d3.round(d.end, 2) + "% " + d.label; });
// ** Slope lines
var line = country
.selectAll("line.slope")
.data( function(d) { return [d]; } );
line
.enter()
.append("line")
.attr("x1", 210)
.attr("x2", width-210)
.attr("opacity", 0)
.attr("y1", 0)
.attr("y2", 0);
line
.classed("slope", function(d) { return d.start || d.end; })
.attr("opacity", 1)
.attr("y1", function(d,i) { return d.start && d.end ? Math.round( d.startY - font_size/2 + 2) : null; })
.attr("y2", function(d,i) { return d.start && d.end ? Math.round( d.endY - font_size/2 + 2) : null; });
return chart;
};
return update( d3.first(years), d3.last(years) );
}, {});
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment