Built with blockbuilder.org
forked from RobertDelgado's block: Project Prototype round 3
forked from RobertDelgado's block: Project Prototype round 3 v2
forked from RobertDelgado's block: Project Prototype round 3 v3
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
.xAxisText, .yAxisText{font-size: 30}
.popObj {}
.outerGroup {}
.popObj1990 {}
.popObj1991 {}
.popObj1992 {}
.popObj1993 {}
.popObj1994 {}
.popObj1995 {}
.popObj1996 {}
.popObj1997 {}
.popObj1998 {}
.popObj1999 {}
.popObj2000 {}
.popObj2001 {}
.popObj2002 {}
.popObj2003 {}
.popObj2004 {}
.popObj2005 {}
.popObj2006 {}
.popObj2007 {}
.popObj2008 {}
.popObj2009 {}
.popObj2010 {}
.popObj2011 {}
.popObj2012 {}
.popObj2013 {}
.popGroup {}
.stem1990 {}
.stem1991 {}
.stem1992 {}
.stem1993 {}
.stem1994 {}
.stem1995 {}
.stem1996 {}
.stem1997 {}
.stem1998 {}
.stem1999 {}
.stem2001 {}
.stem2002 {}
.stem2003 {}
.stem2004 {}
.stem2005 {}
.stem2006 {}
.stem2007 {}
.stem2008 {}
.stem2009 {}
.stem2010 {}
.stem2011 {}
.stem2012 {}
.stem2013 {}
.floatingLabel {}
.Year {}
.textMarker{}
.tooltip{
position: absolute;
text-align: center;
width: 60px;
height: 28px;
padding: 2px;
font: 12px sans-serif;
background: lightsteelblue;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
</style>
</head>
<body>
<p>
<label for="Year" style="display: inline-block; width: 160px; text-align: right">
Year = <span id="Year-value" style="width:400px">…</span>
</label>
<input type="range" min="1990" max="2013" id="Year">
</p>
<script>
var height = 500;
var width = 960;
var margin = {top: 50, bottom: 40, left:20, right:20};
var innerHeight = height - margin['top'] - margin['bottom'];
var innerWidth = height - margin['left'] - margin['right'];
function generalUpdate(obj, elt, data)
{
var className = ((elt.hasOwnProperty('cl'))? elt.class: elt.obj);
var output = obj.selectAll(className)
.data(data);
return(output)
};
function generalEnter(obj, elt)
{
var output = obj.enter().append(elt.obj);
if(elt.hasOwnProperty('cl'))
output = output.attr('class', elt.cl);
return(output)
};
function attributes(obj, attributes)
{
var output = obj;
for(var name in attributes)
{
if( attributes.hasOwnProperty(name))
{
output = output.attr(name, attributes[name]);
};
};
return(output);
}
function render(data, year, countryNum)
{
data = data.filter(function(d){return(d.Year <= Math.ceil(year));});
data = data.filter(function(d){return(d.Final_Rank <= countryNum)});
data = data.sort(function(a,b){return(a.Final_Rank - b.Final_Rank);})
var xValue = d => d.Country;//function(d){return d.Country;}
var xScale = d3.scaleBand().padding(.80);
xScale.domain(data.map(xValue))
.range([0,innerWidth]);
var yScale = d3.scaleLinear().domain([0,200000])
.range([innerHeight,0]);
var yValueBottom = d => d.GHG_Cum - d.GHG;
var yValueTop = d => d.GHG_Cum
var body = d3.select('body');
var svg = generalUpdate(body, {obj:'svg'}, [null]);
svg = attributes(svg,{height:height,width:width} );
svg = generalEnter(svg, {obj: 'svg'} ); //Why do I need this here and not after svg declaration?
svg = attributes(svg,{height:innerHeight,width:innerWidth} );
var outerGroup = generalUpdate(svg, {obj: 'g'}, [null]);
outerGroup = generalEnter(outerGroup, {obj: 'g', cl:'.outerGroup'});
outerGroup = attributes(outerGroup, {height: innerHeight
, width: innerWidth
, transform: `translate(${margin['left']}, ${margin['top'] -100})`});
outerGroup = outerGroup.merge(outerGroup);
var topYear = Math.max(Math.min(2013, Math.ceil(year)), 1990);
var linkData = data.filter(function(d){return(d.Year == topYear);})
//console.log(linkData);
var fYearData = data.filter(function(d){return(d.Year == Math.ceil(year));})
//console.log(fYearData)
var factor = 1 - (Math.ceil(year) - year);
//console.log(factor)
var popObj = generalUpdate(outerGroup, {obj:"g", cl:".popObj"}, fYearData);
popObj = generalEnter(popObj, {obj:"g", cl:".popObj"})
popObj = popObj.merge(popObj);
popObj = attributes(popObj,{transform: function(d){return(
'translate('+ (xScale(d.Country)+ xScale.bandwidth()/2) + ',' + yScale(d.GHG_Cum - d.GHG + factor * d.GHG) + ')');}
, stroke: "black"
, 'stroke-dasharray': '5,5'}
);
popCircle = popObj.append('circle')
.attr("r",d => Math.sqrt(d.Population/(1000000)))
.attr("fill", "rgba(10,10,10,.1)")
popObj.on('mouseover', function(d){
d3.select(this).select('circle').attr('fill', 'rgba(0,0,255,.2)');
d3.select(this).select('text')
.text(d => "Pop: " + Math.round(d.Population/1000000) + "M , Cum GHG: " + Math.round(d.GHG_Cum/1000) + 'K tonnes')
.attr('y',-40)
.attr('x', 50)
.style('display',null);
//var thisYear = d3.select(this).attr('cx');
console.log(d3.select(this).data()[0]);
})
.on('mouseout', function(d){
d3.select(this).select('circle').attr('fill', 'rgba(10, 10, 10, .1)');
d3.select(this).select('text').style('display','none');
})
;
popObj = popObj.append('text')
.text('Hello')
.style('display','none');
popObj.exit().remove();
var floatingLabel = generalUpdate(outerGroup, {obj:'g', cl:'.floatingLabel'}, [null]);
floatingLabel = generalEnter(floatingLabel, {obj:'g', cl:'.floatingLabel'});
floatingLabel = floatingLabel.merge(floatingLabel)
floatingLabel = floatingLabel.attr('transform', 'translate(100, 2000)')
//floatingLabel = floatingLabel.style("display", "none");
/*floatingLabel.append('rect')
.attr("width",60)
.attr("height", 20)
.attr("fill", "blue")
.attr("opacity", .5);*/
var floatingText = floatingLabel.append("text")
//.attr("x", 30)
//.attr("dy", "1.2em")
//.style("text-anchor", "middle")
//.attr("font-size", "12px")
//.attr("font-weight", "bold");
floatingLabel.exit().remove();
var bandwidthFactor = 1.08
var stemObjBottom = {};
for(var yr = 1990; yr < year; yr++)
{
stemObjBottom[yr] = outerGroup.selectAll('.stem' + yr).data([null]);
stemObjBottom[yr] = stemObjBottom[yr].enter().append('g')
.attr('class','stem' + yr);
stemObjBottom[yr].merge(stemObjBottom[yr]);
stemObjBottom[yr].exit().remove();
}
for(var yr = 1990; yr < year; yr++)
{
yearData = data.filter(function(d){return(d.Year == yr);})
var circleObjs = stemObjBottom[yr].selectAll('circle').data(yearData);
circleObjs =circleObjs.enter().append('circle')
.attr('r',4)
.attr('fill','rgba(0,0,0,.2)')
.attr('cx',d => xScale(xValue(d)) + xScale.bandwidth()/2)
.attr('cy', d =>{return yScale(d.GHG_Cum);});
var linkObj = stemObjBottom[yr].selectAll('.link').data(yearData);
linkObj = linkObj.enter()
.append('line')
.attr('x1',function(d){return(xScale(d.Country) + xScale.bandwidth()/2);})
.attr('x2',function(d){return(xScale(d.Country) + xScale.bandwidth()/2);})
.attr('y1', function(d){return(yScale(d.GHG_Cum));})
.attr('y2', function(d){return(yScale(d.GHG_Cum - d.GHG));})
.attr('stroke-dasharray', '5,4')
.attr('stroke', 'black')
.attr('stroke-width', 1)
stemObjBottom[yr].on('mouseover',function(d){
var className = "stem" + yr
d3.select(this).selectAll('circle')
.attr("fill", "blue")
.attr('r',6);
d3.select(this).selectAll('line')
.attr('stroke-width', 3)
.attr('stroke', 'blue')
.attr('stroke-dasharray','none');
//.attr('r',d=>{return(Math.sqrt(d.Population/(1000000)));})
})
.on('mouseout',function(d){
var className = "stem" + yr
d3.select(this).selectAll('circle')
.attr("fill", 'rgba(0,0,0,.2)')
.attr('r',4);
d3.select(this).selectAll('line')
.attr('stroke-width', 1)
.attr('stroke', 'black')
.attr('stroke-dasharray', '5,4');
var tempData = d3.select(this).selectAll('circle').data()
var floatingTSpan = floatingText.selectAll('tspan').data(tempData);
floatingTSpan = floatingTSpan.enter().append('tspan')
.text(function(d){
return('Year: ' + d.Year + ', Country: ' + d.Country + ', GHG: ' + d.GHG + ', Cumulative GHG: ' + d.GHG_Cum );})
.attr('stroke', 'black')
.attr('stroke-width', 2)
.attr('fill', 'black')
.attr('font-size', '2em');
//floatingLabel.style('display',null);
})
stemObjBottom[yr].exit().remove();
};
/*var stemObjTop = generalUpdate(outerGroup,{obj:"rect", cl:".stem" + Math.ceil(year)}, fYearData);
stemObjTop = generalEnter(stemObjTop, {obj:"rect", cl:".stem" + Math.ceil(year)});
stemObjTop = stemObjTop.merge(stemObjTop);
stemObjTop = attributes(stemObjTop, {width: xScale.bandwidth() * bandwidthFactor
, height:function(d){return(yScale( (1-factor) * d.GHG));}
, x: d=>xScale(xValue(d))
, y: function(d){return(yScale((d.GHG_Cum - d.GHG) + factor * d.GHG ));}
, stroke: "black"
, fill: "none"});
stemObjTop.exit().remove();*/
/*var popObj = generalUpdate(outerGroup, {obj:"g", cl:".popObj"}, fYearData);
popObj = generalEnter(popObj, {obj:"g", cl:".popObj"})
popObj = popObj.merge(popObj);
popObj = attributes(popObj,{transform: function(d){return(
'translate('+ (xScale(d.Country)+ xScale.bandwidth()/2) + ',' + yScale(d.GHG_Cum - d.GHG + factor * d.GHG) + ')');}
, stroke: "black"
, 'stroke-dasharray': '5,5'}
);*/
}
var rows = function(d){
d.Country = d.Country;
d.Year = +d.Year;
d.GHG = +d.GHG;
d.GHG_Cum = +d.GHG_Cum;
d.Population = +d.Population;
d.Final_Rank = +d.Final_Rank;
return(d);};
d3.csv("Data3.csv", rows , function(data){return(render(data, 2013, 10))})
/*var update = function(Year){
console.log(Year);
d3.csv("Data3.csv", rows , function(data){return(render(data, Year, 5))});
};
//d3.csv("Data3.csv", rows , function(data){return(render(data, 2013, 2))})
update(1990)
d3.select("#Year").on("input", function()
{
update(+this.value);
});*/
</script>
</body>
https://d3js.org/d3.v4.min.js