xxxxxxxxxx
<html>
<head>
<meta charset="utf-8">
<title> Compare Countries</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.2/d3.min.js"></script>
<style>
#formPanel{
padding: 10px;
float:left;
width:150px;
height: 487px;
background:lightblue;
}
#svg{
float:left;
background:#c2b280;
}
</style>
</head>
<body>
<div id="svg"></div>
<div id="formPanel">
<form onsubmit="return addData()" class="my-form">
Country Name:<br>
<input type="text" id="country" value="Lala Land" required><br>
Carbon:<br>
<input type="text" id="carbon" value="300000000" required><br>
Fishing Grounds:<br>
<input type="text" id="fishingGround" value="600000000" required><br>
Crop Land:<br>
<input type="text" id="cropLand" value="500000000" required><br>
Built-up Land:<br>
<input type="text" id="builtupLand" value="800000000" required><br>
Forest Products:<br>
<input type="text" id="forestProduct" value="200000000" required><br>
Grazing Land:<br>
<input type="text" id="grazingLand" value="100000000" required><br>
<input type="submit" value="Add Country">
</form>
<button onclick="reorder()"> Reorder</button>
</div>
<script type="text/javascript">
let width = 700,
height = 500,
margin = {left: 100, bottom: 100, right: 50, top: 50 };
let svg = d3.select('#svg')
.append('svg')
.attr('width', width)
.attr('height', height)
let dataset, xScale, yScale, xAxis, yAxis, series, stack, groups, rects;
let colors = d3.scaleOrdinal(d3.schemeCategory10);
let createInitial = (data,keys)=>{
let obj = {},
array = [];
for(let i = 0 ; i<Object.keys(data).length; i++){
for(let j=0; j<keys.length; j++){
if(keys[j] == Object.keys(data)[i]){
array.push(data[keys[j]])
}
}
}
obj['country'] = data.countryName
obj['value'] = array;
obj['total'] = data.total;
return obj
}
let stackedData = (data,keys) => {
let mapData = [];
for(let i = 0; i<data.length; i++){
mapData.push(createInitial(data[i], keys))
}
return mapData.map(function(d){
let y0=0
return {
value:d.value.map(function(d){
return {
y0:y0,
y1: y0+=d
}
}),
total: d.total
}
})
}
let rowConvertor = (d,i) =>{
return {
total:+d['Total'],
countryName: d['Country Name'],
year:+d['year'],
builtupLand: +d['Built-up Land'],
carbon:+d['Carbon'],
cropLand: +d['Cropland'],
fishingGround:+d['Fishing Grounds'],
forestProduct:+d['Forest Products'],
grazingLand:+d['Grazing Land']
}
}
let sortOrder = false;
let keys = ['builtupLand', 'carbon', 'cropLand', 'fishingGround', 'forestProduct', 'grazingLand']
d3.csv('stacked_bar_data.csv', rowConvertor, (data)=>{
dataset = data
dataset.sort((a,b)=>{ return b.total - a.total});
//Set up scales
xScale = d3.scaleBand()
.domain(d3.range(data.length))
.range([margin.left, width])
.paddingInner(0.05)
yScale = d3.scaleLinear()
.domain([0,
d3.max(data, function(d) {
return d.builtupLand + d.carbon + d.cropLand + d.fishingGround + d.forestProduct + d.grazingLand;
})
])
.range([height-margin.bottom, margin.top]);
xAxis = d3.axisBottom()
.scale(xScale)
yAxis = d3.axisLeft()
.scale(yScale)
.ticks(10)
let groups = svg.selectAll('g')
.data(stackedData(data,keys))
.enter()
.append('g')
.attr('class', 'groups')
.attr('transform', (d,i)=>{
return 'translate(' + (margin.left+ (i * ((width-margin.left)/data.length))) + ',0)'
})
let rects = groups.selectAll("rect")
.data(function(d) {
return d.value;
})
.enter()
.append("rect")
.attr("y", function(d) {
return yScale(d.y1);
})
.attr("height", function(d) {
return yScale(d.y0) - yScale(d.y1);
})
.attr("width", xScale.bandwidth())
.style('fill', (d,i)=>{
return colors(i)
})
svg.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + (height-margin.bottom) + ')')
.call(xAxis)
.selectAll("text")
.text((d,i)=>{
return data[i].countryName
})
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-45)" );
svg.append('g')
.attr('class', 'y axis')
.attr("transform", "translate(" +margin.left + ", 0)")
.call(yAxis)
})
function reorder(){
sortOrder = !sortOrder //flips sorting order
if(sortOrder){
dataset.sort((a,b)=>{ return a.total - b.total})
}else{
dataset.sort((a,b)=>{ return b.total - a.total})
}
svg.selectAll('.groups')
.sort((a,b)=>{
if(sortOrder){
return d3.ascending(a.total, b.total);
}else{
return d3.ascending(b.total, a.total)
}
})
.transition()
.duration(1000)
.attr('transform', (d,i)=>{
return 'translate(' + (margin.left+ (i * ((width-margin.left)/dataset.length))) + ',0)'
})
svg.select('.x.axis')
.selectAll('text')
.transition()
.duration(500)
.text((d,i)=>{
return dataset[i].countryName
})
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-45)" );
/*
.attr('transform', (d,i)=>{
console.log(d,i)
return 'translate(0,0)'
})
*/
}
function addData(){
let entryData = {
total: 0,
countryName: document.getElementById('country').value,
builtupLand: +document.getElementById('builtupLand').value,
carbon: +document.getElementById('carbon').value,
cropLand: +document.getElementById('cropLand').value,
fishingGround: +document.getElementById('fishingGround').value,
forestProduct: +document.getElementById('forestProduct').value,
grazingLand: +document.getElementById('grazingLand').value
}
for(key in entryData){
if(key != 'countryName'){
entryData.total += +entryData[key]
}
}
dataset.push(entryData)
xScale.domain(d3.range(dataset.length));
yScale.domain([0,
d3.max(dataset, function(d) {
return d.builtupLand + d.carbon + d.cropLand + d.fishingGround + d.forestProduct + d.grazingLand;
})
])
svg.selectAll('.groups')
.attr('transform', (d,i)=>{
return 'translate(' + (margin.left+ (i * ((width-margin.left)/dataset.length))) + ',0)'
})
.selectAll("rect")
.attr("width", xScale.bandwidth())
groups = svg.selectAll('.groups')
.data(stackedData(dataset,keys))
groups.enter()
.append('g')
.attr('class', 'groups')
.attr('transform', (d,i)=>{
return 'translate(' + (margin.left+ (i * ((width-margin.left)/dataset.length))) + ',0)'
})
.selectAll('rect')
.data((d)=>
{
return d.value
})
.enter()
.append("rect")
.transition()
.duration(500)
.attr("y", function(d) {
return yScale(d.y1);
})
.attr("height", function(d) {
return yScale(d.y0) - yScale(d.y1);
})
.attr("width", xScale.bandwidth())
.style('fill', (d,i)=>{
return colors(i)
})
svg.select('.x.axis')
.transition()
.duration(500)
.call(xAxis)
.selectAll('text')
.text((d,i)=>{
return dataset[i].countryName
})
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-45)" );
svg.select('.y.axis')
.transition()
.duration(500)
.call(yAxis)
return false
}
</script>
</body>
</html>
https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.2/d3.min.js