Skip to content

Instantly share code, notes, and snippets.

@karmadude
Last active October 13, 2015 03:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save karmadude/4132678 to your computer and use it in GitHub Desktop.
Save karmadude/4132678 to your computer and use it in GitHub Desktop.
India State Finances 2010-2011

A visualization of Indian state finances (revenues and expenditures) for 2010-2011

created for India60

<!DOCTYPE html>
<meta charset="utf-8">
<style>
body { position: relative; }
.chart { height: 500px; overflow: auto; }
.tooltip {
position: absolute;
top: 0;
left: 0;
width: 956px;
height: 121px;
padding: 0 0 16px 0;
background: #f5f5f5;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.15);
border: 1px solid #F7F7F7;
}
.tooltip.stick {
position: fixed;
top: 0;
z-index: 1000;
}
.tooltip hgroup {
margin-top: 0;
padding: 6px 16px;
background: #eee;
text-shadow: 1px 1px 1px #fff;
border-bottom: 1px solid #ddd;
border-right: 1px solid #ddd;
border-radius: 3px 3px 0 0;
float: left;
width: 200px;
}
.tooltip h1 {
margin: 0;
font-size: 18px;
text-transform: uppercase;
}
.tooltip h6 {
margin: 0;
line-height: 10px;
}
.tooltip-content {
padding: 0 16px 16px 16px;
}
.tooltip h2 {
font-size: 14px;
}
.revenue, .expenditure {
float: left;
margin-left: 60px;
}
</style>
<body>
<div class="chart"></div>
<p style="font-size: 12px; margin: 0;"><em>Source: <a href="http://saiindia.gov.in/english/home/Our_Products/Accounts/Combined_Finance/2010_11/2010_11.html">Comptroller and Auditor General of India</a></em></p>
<div class="tooltip">
<hgroup>
<h1>Legend</h1>
<h6>in billions of rupees</h6>
</hgroup>
<div class="tooltip-content">
<section class="revenue">
<h2>Revenue <span></span></h2>
<div class="chart-revenue"></div>
</section>
<section class="expenditure">
<h2>Expenditure <span></span></h2>
<div class="chart-expenditure"></div>
</section>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
d3.json("/d/4132655/india-state-finances-2011.json", function(error, data) {
data.shift(); //remove union data for now.
var formatter = d3.format(',d');
var rupee = formatter//function(v) { return '₹' + formatter(v); };
var midX = 480;
var contentPadding = 36;
var barHeight = 10;
var barPadding = 3;
var statePadding = 20;
var maxRevenue = d3.max(data, function(d) { return d3.sum(d.revenue, function(d) { return d.value; }); });
var maxExpenditure = d3.max(data, function(d) { return d3.sum(d.expenditure, function(d) { return d.value; }); });
var tooltip = d3.select('.tooltip');
var xRevenue = d3.scale.linear()
.domain([0, maxRevenue])
.rangeRound([0, 400]);
var xExpenditure = d3.scale.linear()
.domain([0, maxExpenditure])
.rangeRound([0, 400]);
var colorRevenue = d3.scale.ordinal()
.domain([0,1,2])
.range(['#8C510A', '#F6E8C3', '#5AB4AC']);
var colorExpenditure = d3.scale.ordinal()
.domain([0, 1, 2, 3])
.range(['#D73027', '#FC8D59', '#FEE08B', '#91CF60']);
var svg = d3.select('.chart').append('svg')
.attr('width', '960')
.attr('height', '1024')
.style('margin', '160px 0 0 0');
var state = svg.selectAll('g.state')
.data(data)
.enter().append('g')
.attr('class', 'state')
.on('mouseover', function(d) {
tooltip.select('h1').html(d.name);
var rmax = d3.max(d.revenue, function(r) { return r.value; });
var emax = d3.max(d.expenditure, function(r) { return r.value; });
var w = 268;
var x = d3.scale.linear()
.domain([0, d3.max([rmax, emax])])
.range([0, w - 100]);
var y = function(d1, i) { return (barHeight + barPadding) * i; };
tooltip.select('.revenue h2 span')
.html(' &ndash; ₹' + Math.round(d3.sum(d.revenue, function(d) { return d.value; })/100) + ' billion');
d3.select('.chart-revenue').html('');
var svgRevenue = d3.select('.chart-revenue').append('svg')
.attr('width', w)
.attr('height', (barHeight + barPadding) * d.revenue.length);
svgRevenue.selectAll('.label-name')
.data(d.revenue)
.enter().append('text')
.attr('class', 'label-name')
.attr('x', 0)
.attr('y', function(d2,i) { return y(d2, i) + 5; })
.attr("dy", ".35em")
.style("fill", '#6b6b6b')
.style("font-size", '12px')
.style("text-transform", 'capitalize')
.text(function(d) { return d.name; });
svgRevenue.selectAll('label-value')
.data(d.revenue)
.enter().append('text')
.attr('class', 'label-value')
.attr('x', 95)
.attr('y', function(d2,i) { return y(d2, i) + 5; })
.attr("dy", ".35em")
.attr("text-anchor", "end")
.style("fill", '#43403f')
.style("font-size", '12px')
.style("font-weight", 'bold')
.text(function(d) { return rupee(Math.round(d.value/100)); });
svgRevenue.selectAll('rect')
.data(d.revenue)
.enter().append('rect')
.attr('x', 100)
.attr('y', function(d2, i) { return y(d2, i); })
.attr('height', barHeight)
.attr('width', function(d1) { return x(d1.value); })
.style('fill', function(d1, i) { return colorRevenue(i); });
x = d3.scale.linear()
.domain([0, d3.max([rmax, emax])])
.range([0, w-100]);
tooltip.select('.expenditure h2 span')
.html(' &ndash; ₹' + Math.round(d3.sum(d.expenditure, function(d) { return d.value; })/100) + ' billion');
d3.select('.chart-expenditure').html('');
var svgExpenditure = d3.select('.chart-expenditure').append('svg')
.attr('width', w)
.attr('height', (barHeight + barPadding) * d.expenditure.length);
svgExpenditure.selectAll('text')
.data(d.expenditure)
.enter().append('text')
.attr('x', 0)
.attr('y', function(d2,i) { return y(d2, i) + 5; })
.attr("dy", ".35em")
.style("fill", '#6b6b6b')
.style("font-size", '12px')
.text(function(d) { return d.name.replace(/services|payments/gi, ''); });
svgExpenditure.selectAll('label-value')
.data(d.expenditure)
.enter().append('text')
.attr('class', 'label-value')
.attr('x', 95)
.attr('y', function(d2,i) { return y(d2, i) + 5; })
.attr("dy", ".35em")
.attr("text-anchor", "end")
.style("fill", '#43403f')
.style("font-size", '12px')
.style("font-weight", 'bold')
.text(function(d) { return rupee(Math.round(d.value/100)); });
svgExpenditure.selectAll('rect')
.data(d.expenditure)
.enter().append('rect')
.attr('x', 100)
.attr('y', function(d2, i) { return y(d2, i); })
.attr('height', barHeight)
.attr('width', function(d1) { return x(d1.value); })
.style('fill', function(d1, i) { return colorExpenditure(i); });
d3.event.stopPropagation();
});
var revenue = state.selectAll('rect.revenue')
.data(function(d, i) {
d.bottomX = 0;
d.bottomY = (barHeight * 2 + barPadding + statePadding/2) * (i + 1) + contentPadding;
var total = d3.sum(d.revenue, function(d1) { return d1.value; });
d.revenue.forEach(function(r, j) {
r.i = i;
r.total = total;
r.x0 = j === 0 ? midX - xRevenue(total)/2 : d.revenue[j-1].x0 + xRevenue(d.revenue[j-1].value);
d.bottomX = d.bottomX === 0 ? r.x0 : d3.min([d.bottomX, r.x0]);
});
return d.revenue;
})
.enter().append('rect')
.attr('class', 'revenue')
.attr('x', (function(d) {
return d.x0;
}))
.attr('y', function(d, i) {
return (barHeight + barPadding + statePadding) * d.i;
})
.attr('width', function(d) {
return xRevenue(d.value);
})
.attr('height', barHeight)
.style('fill', function(d, i) { return colorRevenue(i); });
state.append('text')
.attr('class', '.state-name')
.attr('x', function(d) { return d.revenue[0].x0 - 5; })
.attr('y', function(d,i) {
return (barHeight + barPadding + statePadding) * i + 5;
})
.attr("dy", ".35em")
.attr("text-anchor", "end")
.style('fill', '#6b6b6b')
.style("font-size", '10px')
.style("text-transform", 'uppercase')
.style("letter-spacing", "1px")
.text(function(d) { return d.name; });
var expenditure = state.selectAll('rect.expenditure')
.data(function(d, i) {
var total = d3.sum(d.expenditure, function(d1) { return d1.value; });
d.expenditure.forEach(function(r, j) {
r.i = i;
r.total = total;
r.x0 = j === 0 ? midX - xExpenditure(total)/2 : d.expenditure[j-1].x0 + xExpenditure(d.expenditure[j-1].value);
d.bottomX = d.bottomX === 0 ? r.x0 : d3.min([d.bottomX, r.x0]);
});
return d.expenditure;
})
.enter().append('rect')
.attr('class', 'expenditure')
.attr('x', (function(d) {
return d.x0;
}))
.attr('y', function(d, i) {
return (barHeight + barPadding + statePadding) * d.i + (barHeight + barPadding);
})
.attr('width', function(d) {
return xExpenditure(d.value);
})
.attr('height', barHeight)
.style('fill', function(d, i) { return colorExpenditure(i); });
});
var tooltip_relocate = function() {
var window_top = $(window).scrollTop();
var div_top = $('.chart').offset().top;
if (window_top > div_top)
$('.tooltip').addClass('stick')
else
$('.tooltip').removeClass('stick');
}
$(function() {
$(window).scroll(tooltip_relocate);
})
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment