Skip to content

Instantly share code, notes, and snippets.

@AbnormalDistribution-2020
Created January 16, 2020 09:34
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 AbnormalDistribution-2020/d565ad5f4d8415bab411a2aed42d17b2 to your computer and use it in GitHub Desktop.
Save AbnormalDistribution-2020/d565ad5f4d8415bab411a2aed42d17b2 to your computer and use it in GitHub Desktop.
World Data Visualization Prize - Interactive Submission
<!DOCTYPE html>
<meta charset="utf-8">
<style type="text/css">
</style>
<body>
</body>
<div id="map"></div>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://unpkg.com/topojson@3.0.2/dist/topojson.js"></script>
<script>
var margins = {top:20, bottom:300, left:30, right:600};
var height = 600;
var width = 900;
var totalWidth = width+margins.left+margins.right;
var totalHeight = height+margins.top+margins.bottom;
var projection = d3.geoMercator();
var path = d3.geoPath().projection(projection);
var svg = d3.select("body")
.append('svg')
.attr('width', totalWidth)
.attr('height', totalHeight);
var topoData = d3.json("wdvp-countries.json");
topoData.then(function(data){
//var country = topojson.feature(data, data.features);
/*
var b, s, t;
projection.scale(1).translate([0, 0]);
var b = path.bounds(country);
console.log(d3.geoBounds(country))
var s = .9 / Math.max((b[1][0] - b[0][0]) / width, (b[1][1] - b[0][1]) / height);
var t = [(width - s * (b[1][0] + b[0][0])) / 2, (height - s * (b[1][1] + b[0][1])) / 2];
projection.scale(s).translate(t);
*/
var map = svg.append('g').attr('class', 'boundary');
var world = map.selectAll('path').data(data.features.filter(d => d.id !== "ATA"));
var color = d3.scaleLinear()
.range(["#0ba4d4","#0b77a8"])
.domain([50,80]);
world.enter()
.append('path')
.attr('d', path)
.attr('fill', function(d) {return color(d.properties.gov)})
.on('click.second', function(d) {return progressText(d); })
.on('click.third', function(d) {return lineUpdate(d); })
.on('click', function(d) {return progressDonut(d); })
.on('click.fourth', function(d) {return progressDonut3(d); })
.on('click.fifth', function(d) {return circUpdate(d); });
var gradient = svg.append('defs')
.append('linearGradient')
.attr('id', 'gradient')
.attr('x1', '0%')
.attr('y1', '0%')
.attr('x2', '0%')
.attr('y2', '100%')
.attr('spreadMethod', 'pad');
gradient.append('stop')
.attr('offset', '0%')
.attr('stop-color', '#0ba4d4')
.attr('stop-opacity', 1);
gradient.append('stop')
.attr('offset', '100%')
.attr('stop-color', '#0b77a8')
.attr('stop-opacity', 1);
svg.append('rect')
.attr('width', 30)
.attr('height', (452))
.attr('transform', 'translate(' + (margins.left+975) + ',' + (3+0) + ')')
.style('fill','url(#gradient)');
var legendScale = d3.scaleLinear()
.domain([0,100]).nice()
.range([451, 0]);
var legendAxis = d3.axisRight(legendScale).tickValues([10,20,30,40,50,60,70,80,90,100]);
var graphGroup = svg.append('g')
.attr('transform', "translate("+ margins.left+","+3+")");
graphGroup.append('g')
.attr('class', 'axis')
.attr('transform', "translate(1010,"+00+")")
.call(legendAxis);
var marker = graphGroup.append('line')
.attr('y1',legendScale(51))
.attr('y2',legendScale(51))
.attr('x1',975)
.attr('x2',1005)
.style('stroke','#fff')
.style('stroke-width','4px');
var triangle = graphGroup.append('path')
.attr("transform", function(d) { return "translate(" + 965 + "," + legendScale(51) + ")rotate(90)"; })
.attr("d", d3.symbol().type(d3.symbolTriangle))
.style('fill',"#0b77a8");
function lineUpdate(datum) {
marker.transition()
.attr('y1', legendScale(datum.properties.gov))
.attr('y2', legendScale(datum.properties.gov))
.duration(1000);
triangle.transition()
.attr("transform", function(d) { return "translate(" + 965 + "," + legendScale(datum.properties.gov) + ")rotate(90)"; })
.duration(1000);
}
//donut start
var percentage = 51;
var pData = d3.range(16).map(function(d) {
return { value: d*6.25, interval: 6.25 };
})
var pWidth = 200,
pHeight = 200,
radius = Math.min(pWidth, pHeight) / 2;
var color = d3.scaleLinear()
.range(["#0b77a8","#0ba4d4"]).domain([0,75]);
var explode = function(x,index) {
var offset = (index==5) ? 80:0;
var angle = (x.startAngle + x.endAngle)/2;
var xOff = Math.sin(angle)*offset;
var yOff = -Math.cos(angle)*offset;
return "translate(" +xOff+","+yOff+ ")";
}
var arc = d3.arc()
.outerRadius(radius - 50)
.innerRadius(radius - 70);
var pie = d3.pie()
.padAngle(.05)
.sort(null)
.value(function(d) { return d.interval; });
var g = graphGroup.selectAll(".arc")
.data(pie(pData))
.enter().append("g")
.attr('transform', "translate("+200+","+(height+100)+")")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
//.attr('transform', explode)
.style('stroke','none')
.style("fill", function(d) {return color(d.data.value); });
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.text(function(d) { return d.data.age; });
var coverArc = g.append("path")
.attr("fill","white")
.attr("d", d3.arc()
.endAngle(Math.PI*2)
.startAngle(percentage * Math.PI*2)
.outerRadius(radius - 50)
.innerRadius(radius - 70));
var label = g.append('text')
.text(percentage) // magic number
.style('font-family','TW Cen MT')
.attr('text-anchor','middle')
.attr('x',0)
.attr('y',5);
var province = g.append('text')
.attr('x',100)
.attr('y',-200)
.text('Afghanistan')
.style('font-size', '52px');
var h2G = g.append('g');
h2G.append('rect')
.attr('x',-100)
.attr('y',-150)
.attr('width',200)
.attr('height',100)
.style('fill',"#fff");
h2G.append('text')
.text("Government Index") // magic number
.style('font-family','TW Cen MT')
.style("font-size", "18px")
.attr('text-anchor','middle')
.attr('x',0)
.attr('y',-70);
function progressDonut(datum) {
// progress one chart
var percentage = datum.properties.gov;
console.log(percentage)
label.text(percentage);
function transition() {
coverArc
.transition()
.tween("d", function(d) {
var that = d3.select(this),
i = d3.interpolateNumber(0, percentage);
return function(t) {
that.attr("d", d3.arc()
.endAngle(Math.PI*2)
.startAngle(i(t)/100 * Math.PI*2)
.outerRadius(radius - 10)
.innerRadius(radius - 70)
)
label.text(Math.round(i(t)));
};
})
.duration(1000);
}
transition();
province
.transition()
.duration(750)
.tween("text", function() {
var self = this;
var newText = datum.properties.name;
var textLength = newText.length;
return function(t) {
self.textContent = newText.slice(0, Math.round(t * textLength));
};
});
}
//donut2 start
var percentage2 = 1919;
var arc2 = d3.arc()
.outerRadius(radius - 50)
.innerRadius(radius - 70);
var pie2 = d3.pie()
.padAngle(.05)
.sort(null)
.value(function(d) { return d.interval; });
var g2 = graphGroup.selectAll(".arc2")
.data(pie2(pData))
.enter().append("g")
.attr('transform', "translate("+400+","+(height+100)+")")
.attr("class", "arc2");
g2.append("path")
.attr("d", arc2)
//.attr('transform', explode)
.style('stroke','none')
.style("fill", function(d) {return color(d.data.value); });
g2.append("text")
.attr("transform", function(d) { return "translate(" + arc2.centroid(d) + ")"; })
.attr("dy", ".35em")
.text(function(d) { return d.data.age; });
var coverArc2 = g2.append("path")
.attr("fill","white")
.attr("d", d3.arc()
.endAngle(Math.PI*2)
.startAngle(percentage2 * Math.PI*2)
.outerRadius(radius - 50)
.innerRadius(radius - 70));
var label2 = g2.append('text')
.text(percentage2) // magic number
.style('font-family','TW Cen MT')
.attr('text-anchor','middle')
.attr('font-size',48)
.attr('x',0)
.attr('y',5);
var h2G2 = g2.append('g');
h2G2.append('rect')
.attr('x',-100)
.attr('y',-150)
.attr('width',200)
.attr('height',100)
.style('fill',"#fff");
h2G2.append('text')
.text("GDP per Capita") // magic number
.style('font-family','TW Cen MT')
.style("font-size", "18px")
.attr('text-anchor','middle')
.attr('x',0)
.attr('y',-70);
function progressText(datum) {
// progress one chart
var percentage2 = datum.properties.gdp;
console.log(percentage2)
label2.text(percentage2);
function transition() {
coverArc2
.transition()
.tween("d", function(d) {
var that = d3.select(this),
i = d3.interpolateNumber(0, percentage2);
return function(t) {
label2.text(Math.round(i(t)));
};
})
.duration(1000);
}
transition();
}
//donut3 start
var percentage3 = 20;
var pData3 = d3.range(16).map(function(d) {
return { value: d*3.125, interval: 3.125 };
})
var arc3 = d3.arc()
.outerRadius(radius - 50)
.innerRadius(radius - 70);
var pie3 = d3.pie()
.padAngle(.05)
.sort(null)
.value(function(d) { return d.interval; });
var g3 = graphGroup.selectAll(".arc3")
.data(pie3(pData3))
.enter().append("g")
.attr('transform', "translate("+600+","+(height+100)+")")
.attr("class", "arc3");
g3.append("path")
.attr("d", arc3)
//.attr('transform', explode)
.style('stroke','none')
.style("fill", function(d) {return color(d.data.value); });
g3.append("text")
.attr("transform", function(d) { return "translate(" + arc3.centroid(d) + ")"; })
.attr("dy", ".35em")
.text(function(d) { return d.data.age; });
var coverArc3 = g3.append("path")
.attr("fill","white")
.attr("d", d3.arc()
.endAngle(Math.PI*2)
.startAngle(percentage3 * Math.PI*2)
.outerRadius(radius - 50)
.innerRadius(radius - 70));
var label3 = g3.append('text')
.text(percentage3) // magic number
.style('font-family','TW Cen MT')
.attr('text-anchor','middle')
.attr('x',0)
.attr('y',5);
var h2G3 = g3.append('g');
h2G3.append('rect')
.attr('x',-100)
.attr('y',-150)
.attr('width',200)
.attr('height',100)
.style('fill',"#fff");
h2G3.append('text')
.text("Happiness Index") // magic number
.style('font-family','TW Cen MT')
.style("font-size", "18px")
.attr('text-anchor','middle')
.attr('x',0)
.attr('y',-70);
function progressDonut3(datum) {
// progress one chart
var percentage = datum.properties.happy;
console.log(percentage)
label3.text(percentage);
function transition() {
coverArc3
.transition()
.tween("d", function(d) {
var that = d3.select(this),
i = d3.interpolateNumber(0, percentage);
return function(t) {
that.attr("d", d3.arc()
.endAngle(Math.PI*2)
.startAngle(i(t)/50 * Math.PI*2)
.outerRadius(radius - 10)
.innerRadius(radius - 70)
)
label3.text(Math.round(i(t)));
};
})
.duration(1000);
}
transition();
}
//scatterplot start
var xScale = d3.scaleLinear()
.range([1010,1450])
.domain([0, 50]);
graphGroup.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate("+0+","+ 451 + ")")
.call(d3.axisBottom(xScale));
graphGroup.selectAll('circle')
.data(data.features.filter(function(d) {return d.properties.happy!==""}))
.enter()
.append('circle')
.style('fill', function(d) { return color(d.properties.gov)})
.attr('cx', function(d) {return xScale(d.properties.happy)})
.attr('cy', function(d) {return legendScale(d.properties.gov)})
.attr('r', 4);
function circUpdate(datum) {
var allCircles = graphGroup.selectAll('circle');
var thisCircle = graphGroup.selectAll('circle').filter(function(d) {return d==datum});
allCircles
.transition()
.attr('r', 4)
.duration(1000);
thisCircle
.transition()
.attr('r',20)
.duration(1000);
}
})
</script>
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment