Built with blockbuilder.org
This example summarizes a data table using Datalib.
This data is from Kaggle - World Happiness Report.
This dataset is described as "The World Happiness Report is a landmark survey of the state of global happiness."
It goes on to state "The World Happiness 2017, which ranks 155 countries by their happiness levels, was released at the United Nations at an event celebrating International Day of Happiness on March 20th."
For the data visualization assignments, I chose to build the charts from scratch instead of copying a block as a starting point to help me better understand how to use D3. I looked at a number of examples and have used the book "Interactive Data Visualization for the Web" by Scott Murray.
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; }
svg { background-color: #ffffff; }
.label { font-size: 18pt; font-family:Helvetica; }
</style>
</head>
<body>
<script>
// variables
let w = 960;
let h = 500;
let margin = { top: 20, right: 20, left: 150, bottom: 120 };
let innerWidth = w - margin.right - margin.left;
let innerHeight = h - margin.top - margin.bottom;
let happy = [];
let fieldStats = [];
let xLinear;
let yLinear = d3.scaleLinear();
let svg = d3.select("body").append("svg")
.attr("width", w)
.attr("height", h);
// Create dynamic scales based on columns passed
const createScales=(xField,yField)=>{
xLinear = d3.scaleLinear()
.domain([d3.min(happy,(d,i)=>{ return d[xField]; }), d3.max(happy,(d,i)=>{ return d[xField]; })])
.range([0 + margin.left, w - margin.right])
.nice();
yLinear = d3.scaleLinear()
.domain([0,d3.max(happy,(d,i)=>{ return d[yField]; })])
.range([innerHeight,0 + margin.bottom])
.nice();
}
// Create dynamic axis based on columns passed
const createAxis=(xField,yField)=>{
let xAxis = d3.svg.axis();
}
// Create Scatter plot based on columns passed (happy)
const createScatterPlot=(xField,yField,rField)=>{
svg.selectAll("circle")
.data(happy)
.enter()
.append("circle")
.attr("cx", (d,i)=>{ return xLinear(d[xField]); })
.attr("cy", (d,i)=>{ return yLinear(d[yField]); })
.attr("r", (d,i)=>{ return d[rField] * 10; });
svg.append("g")
.attr("transform", "translate(0," + innerHeight + ")")
.call(d3.axisBottom(xLinear));
svg.append("text")
.attr("class","label")
.attr("y", 425)
.attr("x", w /2)
.style("text-anchor", "middle")
.text("Happiness Ranking");
svg.append("g")
.attr("transform", "translate(" + 150 + "," + 0 + ")")
.call(d3.axisLeft(yLinear));
svg.append("text")
.attr("class","label")
.attr("transform", "rotate(-90)")
.attr("y", 100)
.attr("x", -(h / 2))
.style("text-anchor", "middle")
.text("GDP Per Capita");
svg.append("text")
.attr("class","label")
.attr("y", 50)
.attr("x", w /2)
.style("text-anchor", "middle")
.text("World Happiness Ranking");
}
// Convert header to JSON friendly header (Columns)
const processHappy=(d)=>{
return {
country: d["Country"],
happinessRank: +d["Happiness_Rank"],
happinessScore: +d["Happiness_Score"],
whiskerHigh: +d["Whisker_high"],
whiskerLow: +d["Whisker_low"],
gdpPerCapita: +d["Economy__GDP_per_Capita_"],
family: +d["Family"],
lifeExpectancy: +d["Health__Life_Expectancy_"],
freedom: +d["Freedom"],
generosity: +d["Generosity"],
governmentCorruption: +d["Trust__Government_Corruption_"],
dystopiaResidual: +d["Dystopia_Residual"]
};
}
// Load world happiness data
const happyFile=()=>{
d3.csv("data1.csv",processHappy,data=>{
happy = data;
// For each column calculate basic statistics
fieldStats.push(fieldProfile("happinessRank"));
fieldStats.push(fieldProfile("happinessScore"));
fieldStats.push(fieldProfile("whiskerHigh"));
fieldStats.push(fieldProfile("whiskerLow"));
fieldStats.push(fieldProfile("gdpPerCapita"));
fieldStats.push(fieldProfile("family"));
fieldStats.push(fieldProfile("lifeExpectancy"));
fieldStats.push(fieldProfile("freedom"));
fieldStats.push(fieldProfile("generosity"));
fieldStats.push(fieldProfile("governmentCorruption"));
fieldStats.push(fieldProfile("dystopiaResidual"));
// Write out all the statistics
fieldStats.forEach((row,index)=>{
console.log(JSON.stringify(row));
});
// World Happyiness Rank
createScales("happinessScore","gdpPerCapita");
createScatterPlot("happinessScore","gdpPerCapita","lifeExpectancy");
});
};
// Calculate basic statistics on a field
const fieldProfile=(fieldname)=>{
const avg = d3.nest().rollup((v)=>{ return d3.mean(v, (d)=>{ return d[fieldname]; }); }).entries(happy);
const med = d3.nest().rollup((v)=>{ return d3.median(v, (d)=>{ return d[fieldname]; }); }).entries(happy);
const min = d3.nest().rollup((v)=>{ return d3.min(v, (d)=>{ return d[fieldname]; }); }).entries(happy);
const max = d3.nest().rollup((v)=>{ return d3.max(v, (d)=>{ return d[fieldname]; }); }).entries(happy);
happy.sort((a,b)=>{ return a[fieldname] - b[fieldname]; });
const p25 = Math.round(happy.length * .25);
const v25 = happy[p25][fieldname];
const v75 = happy[happy.length - p25];
const stats = {};
stats["fieldname"] = fieldname;
stats["average"] = avg;
stats["median"] = med;
stats["min"] = min;
stats["max"] = max;
stats["p25"] = v25;
stats["p75"] = v75[fieldname];
return stats;
}
document.addEventListener("DOMContentLoaded", (event)=>{
// World Happyiness Rank
happyFile();
});
</script>
</body>
https://d3js.org/d3.v4.min.js