xxxxxxxxxx
<html>
<head>
<meta charset="utf-8">
<title>Layer Cake </title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.2/d3.min.js"></script>
<style type="text/css">
h1 {
font-family: Helvetica, sans-serif;
font-size: 14px;
font-weight: bold;
}
.area {
stroke: none;
}
.area:hover {
fill: yellow;
}
#backButton {
cursor: pointer;
}
#backButton rect {
fill: #ccc;
}
#backButton text {
font-family: Helvetica, sans-serif;
font-weight: bold;
font-size: 14px;
fill: black;
}
#backButton:hover rect {
fill: red;
}
.unclickable {
pointer-events: none;
}
</style>
</head>
<body>
<script>
let width = 800,
height = 400,
margin = {top: 50, right:50, left:100, bottom:50};
let dataset, xScale, yScale, xAxis, yAxis, area, svg;
let stack = d3.stack()
.order(d3.stackOrderDescending);
let rowConvertor = (d,i)=>{
return {
total:+d['value'],
year:+d['year'],
countryName: d['countryName'],
builtupLand: +d['builtupLand'],
carbon:+d['carbon'],
cropLand: +d['cropLand'],
fishingGround:+d['fishingGround'],
forestProduct:+d['forestLand'],
grazingLand:+d['grazingLand']
}
}
let keys = ['builtupLand','carbon','cropLand','fishingGround','forestProduct','grazingLand']
let key = (d)=>{
return d.key
}
let viewState = 0;
svg = d3.select('body')
.append('svg')
.attr('width', width)
.attr('height', height)
d3.csv('analyze_trends_Data.csv', rowConvertor, (data)=>{
stack.keys(keys)
let series = stack(data)
xScale = d3.scaleTime()
.domain([
d3.min(data, (d)=> {return d.year}),
d3.max(data, (d)=>{ return d.year})
])
.range([margin.left, width-margin.right * 2])
yScale = d3.scaleLinear()
.domain([
0,
d3.max(data, (d)=>{
let sum = 0
for(let i=0; i<keys.length; i++){
sum += d[keys[i]];
}
return sum
})
])
.range([height - margin.left, margin.left/2])
.nice()
xAxis = d3.axisBottom()
.scale(xScale)
.ticks(10)
.tickFormat(d3.format('d'))
yAxis = d3.axisLeft()
.scale(yScale)
.ticks(5)
area = d3.area()
.x((d)=> { return xScale(d.data.year) })
.y0((d)=>{ return yScale(d[0]); })
.y1((d)=>{ return yScale(d[1]); })
svg.append('g')
.attr('id', 'types')
.selectAll('path')
.data(series,key)
.enter()
.append('path')
.attr('class', 'area')
.attr('d', area)
.attr('fill', (d,i)=>{
let color;
switch(d.key){
case "builtupLand":
color = d3.schemeCategory20[0];
break;
case "carbon":
color = d3.schemeCategory20[1];
break
case "cropLand":
color = d3.schemeCategory20[2];
break;
case "fishingGround":
color = d3.schemeCategory20[3];
break;
case "forestProduct":
color = d3.schemeCategory20[4];
break;
case "grazingLand":
color = d3.schemeCategory20[5];
break;
}
return color;
})
.on('click', (d)=>{
viewState++
let type = d.key
var thisTypeDataset = [];
for (var i = 0; i < data.length; i++) {
thisTypeDataset[i] = {
year:data[i].year,
builtupLand:0,
carbon:0,
cropLand:0,
fishingGround:0,
forestProduct:0,
grazingLand:0,
[type]:data[i][type]
}
}
let typeStack = d3.stack()
.order(d3.stackOrderDescending);
typeStack.keys(keys)
let thisTypeSeries = typeStack(thisTypeDataset);
console.log(series,thisTypeSeries)
var paths = d3.selectAll("#types path")
.data(thisTypeSeries, key);
var areaTransitions = paths.transition()
.duration(1000)
.attr('d', area )
//Update scale
yScale.domain([
0,
d3.max(thisTypeDataset, function(d) {
var sum = 0;
sum += d[type];
return sum;
})
]);
areaTransitions.transition()
.delay(200)
.on("start", function() {
d3.select("g.y.axis")
.transition()
.duration(1000)
.call(yAxis);
})
.duration(1000)
.attr("d", area);
})
.append("title")
.text(function(d,i) {
return d.key;
});
let backButton = svg.append('g')
.attr("opacity", 1)
.attr('id', 'backButton')
.attr("transform", "translate(" + xScale.range()[0] + "," + yScale.range()[1] + ")");
backButton.append('rect')
.attr('x', 0)
.attr('x', 0)
.attr('width', 70)
.attr('height', 30)
backButton.append('text')
.attr('x', 7)
.attr('y', 20)
.html('← Back')
svg.append('g')
.attr('class', 'x axis')
.attr("transform", "translate(0," + (height - margin.left) + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + (margin.left) + ",0)")
.call(yAxis);
backButton.on('click', ()=>{
if(viewState > 0){
//Re-bind type data and fade in types
var typeAreaTransitions = d3.selectAll("g#types path")
.data(series, key)
.transition()
.duration(250)
.attr("opacity", 1)
yScale.domain([
0,
d3.max(data, (d)=>{
let sum = 0
for(let i=0; i<keys.length; i++){
sum += d[keys[i]];
}
return sum
})
])
typeAreaTransitions.transition()
.duration(1000)
.on("start", function() {
d3.select("g.axis.y")
.transition()
.duration(1000)
.call(yAxis);
})
.attr("d", area)
}
})
})
</script>
</body>
</html>
https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.2/d3.min.js