xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.25.6/d3-legend.js"></script>
<script src=textAnimate_.js></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
.total_text {
text-anchor: middle;
font-family: sans-serif;
fill: blue;
}
.rev_exp_title {
text-anchor: middle;
font-family: sans-serif;
fill: black;
text-decoration: underline;
}
</style>
</head>
<body>
<div id = "select_box_div">
<select id = "year">
<option value = "2013">2013</option>
<option value = "2014">2014</option>
<option value = "2015">2015</option>
<option value = "2016">2016</option>
<option value = "2017">2017</option>
<option value = "2018">2018</option>
<option value = "2019">2019</option>
<option value = "2020">2020</option>
</select>
<div>
<script>
d3.csv('Revenue_Exp_.csv', function(Revenue_Exp){
var Rev = Revenue_Exp.filter(d => (d.Type == 'Revenues'));
var Exp = Revenue_Exp.filter(d => (d.Type == 'Expenditures'));
var Bal = Revenue_Exp.filter(d => (d.Type == 'Balance'));
// dimensions of the chart
var width = 620;
var height = 380;
var innerRad_ratio = 0.75;
// pie is used to generate angles and a dataset ready for arc (which generates paths using that data)
years = ['2013', '2014', '2015', '2016', '2017', '2018', '2019', '2020'];
sum_rev_exps = [];
// combining all revenue and expenses numbers and finding the max
for (var i = 0; i < years.length; i++){
var rev_point = Rev.map(d => +d[years[i]]).reduce(function(a,b){ return a+b });
var exp_point = Exp.map(d => +d[years[i]]).reduce(function(a,b){ return a+b });
sum_rev_exps.push(rev_point);
sum_rev_exps.push(exp_point);
}
// max of all revenue and expenses
max_all = d3.max(sum_rev_exps);
year = '2013';
var pie = d3.pie()
.value(d => d[year])
.sort(null)
.padAngle(0.005);
var colorScale = d3.scaleOrdinal(d3.schemeCategory20)
var max_r = 110;
var transition_time = 750;
var svg = d3.select('body')
.append('svg')
.attr('width', width)
.attr('height', height)
var rev_pie_g = svg.append('g')
.attr('transform', 'translate('+ width/4 + ',' + height/2 +')')
.classed('rev_pie_g', true);
var exp_pie_g = svg.append('g')
.attr('transform', 'translate('+ (3*width)/4 + ',' + height/2 +')')
.classed('rev_pie_g', true);
var sum_rev = pie(Rev).map(d => +d.data[year]).reduce(function(a,b){ return a+b });
var sum_exp = pie(Exp).map(d => +d.data[year]).reduce(function(a,b){ return a+b });
rev_pie_g.append('text')
.attr('class', 'total_text')
.attr('id', 'total_rev_text')
.text(sum_rev);
exp_pie_g.append('text')
.attr('class', 'total_text')
.attr('id', 'total_exp_text')
.text(sum_exp);
// find the maximum o
max_rev_exp = d3.max([sum_rev, sum_exp]);
var max_rev_scale = d3.scaleSqrt()
//.domain([0, d3.max([sum_rev, sum_exp])])
.domain([0, max_rev_exp])
.range([0, 1]);
var arc = d3.arc()
.innerRadius(innerRad_ratio * max_r * max_rev_scale(sum_rev))
.outerRadius(max_r * max_rev_scale(sum_rev));
//.innerRadius(0)
var arc_exp = d3.arc()
.innerRadius(innerRad_ratio * max_r * max_rev_scale(sum_exp))
.outerRadius(max_r * max_rev_scale(sum_exp));
//console.log(max_rev);
var Rev_pie = pie(Rev);
var sum_year = d3.sum(Rev, x => x[year]);
var outerRad = max_r * max_rev_scale(sum_year);
var innerRad = innerRad_ratio * outerRad;
Rev_pie.forEach(function(d){
d.outerRadius = outerRad;
})
Rev_pie.forEach(function(d){
d.innerRadius = innerRad;
})
var Exp_pie = pie(Exp);
var sum_yearE = d3.sum(Exp, x => x[year]);
var outerRadE = max_r * max_rev_scale(sum_yearE);
var innerRadE = innerRad_ratio * outerRadE;
Exp_pie.forEach(function(d){
d.outerRadius = outerRadE;
})
Exp_pie.forEach(function(d){
d.innerRadius = innerRadE;
})
//console.log("This is ", Rev_pie);
var gRevArcs = rev_pie_g.selectAll(".arc_Rev")
.data(Rev_pie)
.enter().append("g")
.attr("class", "arc_Rev");
gRevArcs.append("path")
.attr("d", arc)
.style("fill", function(d) { return colorScale(d.data.Head); });
var gExpArcs = exp_pie_g.selectAll(".arc_Exp")
.data(Exp_pie)
.enter().append("g")
.attr("class", "arc_Exp");
gExpArcs.append("path")
.attr("d", arc_exp)
.style("fill", function(d) { return colorScale(d.data.Head); });
balance_cash = Revenue_Exp.filter(function(d){
return d.Type != 'Revenues' && d.Type != 'Expenditures';
})
balance = +balance_cash.filter(function(d){ return d.Type == 'Balance' })[0][year];
cash_reserves = balance_cash.filter(function(d){ return d.Type == 'Cash' })[0][year];
text_balance = svg.append('g')
.classed('balance_text_hold', true)
.attr('transform', 'translate('+ width/2 + ',' + (height - 28) +')')
.append('text')
.style('text-anchor', 'middle')
//.text('Fiscal Balance: ' + balance + ' billion PKR')
.style('font-size', '12px')
.style('font-family', 'sans-serif')
text_cash_res = svg.append('g')
.classed('cash_res_text_hold', true)
.attr('transform', 'translate('+ width/2 + ',' + (height - 10) +')')
.append('text')
.style('text-anchor', 'middle')
//.text('Fiscal Balance: ' + balance + ' billion PKR')
.style('font-size', '12px')
.style('font-family', 'sans-serif')
text_balance.append("svg:tspan").style("fill", "black").text('Fiscal Balance: ').classed('desc', true);
text_balance.append("svg:tspan").style("fill", (d) => (balance > 0) ? "blue" : "red" ).text("0").classed('amount', true);
text_balance.append("svg:tspan").style("fill", "black").text(' billion PKR').classed('currency', true);
text_cash_res.append("svg:tspan").style("fill", "black").text('Cash Reserves: ').classed('desc', true);
text_cash_res.append("svg:tspan").style("fill", (d) => (cash_reserves > 0) ? "blue" : "red" ).text("0").classed('amount', true);
text_cash_res.append("svg:tspan").style("fill", "black").text(' billion PKR').classed('currency', true);
interp_text_transit(".balance_text_hold .amount", 1500, balance);
interp_text_transit(".cash_res_text_hold .amount", 1500, cash_reserves);
rev_pie_g.append('text')
.classed('rev_exp_title', true)
.text('Revenue (in billion PKR)')
.attr('transform', 'translate(0, -150)');
exp_pie_g.append('text')
.classed('rev_exp_title', true)
.text('Expenditure (in billion PKR)')
.attr('transform', 'translate(0, -150)');
d3.select('#year').on('input', function(){
var old_pie_data = d3.selectAll('.arc_Rev').select('path').data();
var old_pie_dataE = d3.selectAll('.arc_Exp').select('path').data();
year_selected = this.value;
var pie = d3.pie()
.value(d => d[this.value])
.sort(null)
.padAngle(0.005);
var new_pie_data = pie(Rev);
var new_pie_dataE = pie(Exp);
sum_Rev = d3.sum(Rev, x => x[this.value]);
sum_Exp = d3.sum(Exp, x => x[this.value]);
max_rev_exp = d3.max([sum_Rev, sum_Exp]);
max_rev_scale.domain([0, max_rev_exp])
var outerRad = max_r * max_rev_scale(sum_Rev);
var innerRad = innerRad_ratio * outerRad;
var outerRadE = max_r * max_rev_scale(sum_Exp);
var innerRadE = innerRad_ratio * outerRadE;
new_pie_data.forEach(function(d){
d.outerRadius = outerRad;
})
new_pie_data.forEach(function(d){
d.innerRadius = innerRad;
})
new_pie_dataE.forEach(function(d){
d.outerRadius = outerRadE;
})
new_pie_dataE.forEach(function(d){
d.innerRadius = innerRadE;
})
console.log(sum_Rev);
console.log(sum_Exp);
interp_text_transit("#total_rev_text", 1000, sum_Rev);
interp_text_transit("#total_exp_text", 1000, sum_Exp);
console.log(old_pie_dataE);
console.log(new_pie_dataE);
var Rev_arcs = d3.selectAll('.arc_Rev')
Rev_arcs.data(new_pie_data)
Rev_arcs.select('path').data(new_pie_data);
// update_pies(old_pie_data, new_pie_data);
Rev_arcs.select('path').transition('rev_trans')
.duration(transition_time)
//.ease(d3.easeElastic)
.attrTween('d', arcTween(old_pie_data, "Revenue"));
var Exp_arcs = d3.selectAll('.arc_Exp')
Exp_arcs.data(new_pie_dataE)
Exp_arcs.select('path').data(new_pie_dataE);
Exp_arcs.select('path').transition('exp_trans')
.duration(transition_time)
//.ease(d3.easeElastic)
.attrTween('d', arcTween(old_pie_dataE, "Expenditure"));
balance = +balance_cash.filter(function(d){ return d.Type == 'Balance' })[0][this.value];
cash_reserves = balance_cash.filter(function(d){ return d.Type == 'Cash' })[0][this.value];
//console.log(balance);
interp_text_transit(".balance_text_hold .amount", 1500, balance);
interp_text_transit(".cash_res_text_hold .amount", 1500, cash_reserves);
})
// function for tweening the arcs for groups
function arcTween(prev_data, type){
return function(d, i) {
return function(t) {
arc_interp = d3.interpolate(prev_data[i], d);
if (type == "Revenue"){
arc.innerRadius(arc_interp(t).innerRadius)
.outerRadius(arc_interp(t).outerRadius);
return arc(arc_interp(t));
}
else {
arc_exp.innerRadius(arc_interp(t).innerRadius)
.outerRadius(arc_interp(t).outerRadius);
return arc_exp(arc_interp(t));
}
}
}
};
})
</script>
</body>
https://d3js.org/d3.v4.min.js
https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.25.6/d3-legend.js