Built with blockbuilder.org
xxxxxxxxxx
<meta charset="utf-8">
<html>
<head>
<style>
rect.bordered {
stroke: #ffffff;
stroke-width:2px;
}
text.mono {
font-size: 7pt;
font-family: Consolas, courier;
fill: #aaa;
}
text.axis-workweek {
fill: #000;
}
text.axis-worktime {
fill: #000;
}
</style>
<script src="https://d3js.org/d3.v4.js"></script>
</head>
<body>
<div id="chart">
</div>
<div id="dataset-picker">
<script type="text/javascript">
const margin = { top: 50, right: 0, bottom: 100, left: 320 },
width = 1300 - margin.left - margin.right,
height = 1900 - margin.top - margin.bottom,
gridSize = Math.floor(width / 7),
legendElementWidth = gridSize*0.5,
buckets = 8,
colors = ["#bae6d9","#98cfd2","#77bfcb","#5ea9c0","#4195b7","#2988a8","#2e6e9a","#2b598a"], // alternatively colorbrewer.YlGnBu[9]
tiername = ["Four-year/For-profit","Highly selective/private","Highly selective/public","Ivy Plus","Less than two-year schools of any type","Nonselective four-year private/not-for-profit","Nonselective four-year/public","Other elite schools/(public and private)","Selective/private","Selective/public","Two-year/(public and private not-for-profit)","Two-year/for-profit"],
fieldname = ["Child_Married","Parent_Income_Mean","Parent_Income_Median","Parent_Income_Rank","Child_Earning_Rank","Child_Earning_Mean","Child_Earning_Median"];
const svg = d3.select("#chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("text")
.attr("x", -300)
.attr("y", -40 )
.attr("dy", "0.35em")
.attr("text-anchor", "left")
.attr("font-family", "sans-serif")
.attr("font-size", "30px")
.attr("font-weight", "bold")
.attr("fill", "black")
.text("Information about children and parents with different types of University");
const tienameLabels = svg.selectAll(".tienameLabel")
.data(tiername)
.enter().append("text")
.text(function (d) { return d; })
.attr("x", 0)
.attr("y", (d, i) => i * gridSize)
.style("text-anchor", "end")
.attr("transform", "translate(-6," + gridSize / 1.5 + ")")
.attr("class","tienameLabel mono axis axis-workweek" );
const fieldnameLabels = svg.selectAll(".fieldnameLabel")
.data(fieldname)
.enter().append("text")
.text((d) => d)
.attr("x", (d, i) => i * gridSize)
.attr("y", 0)
.style("text-anchor", "middle")
.attr("transform", "translate(" + gridSize / 2 + ", -6)")
.attr("class", "fieldnameLabel mono axis axis-worktime");
const type = (d) => {
return {
tier_name: +d.tier_name,
field_name: +d.field_name,
value: +d.value
};
};
const heatmapChart = function() {
var dic = new Array();
dic["Four-year for-profit"] = 1;//"Four-year for-profit","Highly selective private","Highly selective public","Ivy Plus","Less than two-year schools of any type","Nonselective four-year private not-for-profit","Nonselective four-year public","Other elite schools (public and private)","Selective private","Selective public","Two-year (public and private not-for-profit)","Two-year for-profit"
dic["Highly selective private"] = 2;
dic["Highly selective public"] = 3;
dic["Ivy Plus"] = 4;
dic["Less than two-year schools of any type"] = 5;
dic["Nonselective four-year private not-for-profit"] = 6;
dic["Nonselective four-year public"] = 7;
dic["Other elite schools (public and private)"] = 8;
dic["Selective private"] = 9;
dic["Selective public"] = 10;
dic["Two-year (public and private not-for-profit)"] = 11;
dic["Two-year for-profit"] = 12;
var dics = new Array();
dics["married"] = 1;
dics["par_mean"] = 2;
dics["par_median"] = 3;
dics["par_rank"] = 4;
dics["k_mean"] = 5;
dics["k_median"] = 6;
dics["k_rank"] = 7;
d3.csv("s4.csv", function(error, data) {
var dic = new Array();
dic["Four-year for-profit"] = 1;
dic["Highly selective private"] = 2;
dic["Highly selective public"] = 3;
dic["Ivy Plus"] = 4;
dic["Less than two-year schools of any type"] = 5;
dic["Nonselective four-year private not-for-profit"] = 6;
dic["Nonselective four-year public"] = 7;
dic["Other elite schools (public and private)"] = 8;
dic["Selective private"] = 9;
dic["Selective public"] = 10;
dic["Two-year (public and private not-for-profit)"] = 11;
dic["Two-year for-profit"] = 12;
var dics = new Array();
dics["Married"] = 1;
dics["Par Mean"] = 2;
dics["Par Median"] = 3;
dics["Par Rank"] = 4;
dics["K Mean"] = 5;
dics["K Median"] = 6;
dics["K Rank"] = 7;
//console.log(data);
data.forEach(function(d) {
d.tier_name = parseInt(dic[d.tier_name]);
d.field_name = parseInt(dics[d.field_name]);
d.value = parseFloat(d.value);
});
console.log(data);
const colorScale = d3.scaleQuantile()
.domain([0, d3.max(data, (d) => d.value)])
.range(colors);
console.log(d3.max(data, (d) => d.value));
console.log(colorScale);
const cards = svg.selectAll(".field_name")
.data(data, (d) => d.tier_name+':'+d.field_name);
cards.append("title");
cards.enter().append("rect")
.attr("x", function(d) {return (d.field_name - 1) * gridSize; })
.attr("y", (d) => (d.tier_name - 1) * gridSize)
.attr("rx", 4)
.attr("ry", 4)
.attr("class", "field_name bordered")
.attr("width", gridSize)
.attr("height", gridSize)
.style("fill", colors[0])
.merge(cards)
.transition()
.duration(1000)
.style("fill", (d) => colorScale(d.value));
cards.select("title").text((d) => d.value);
cards.exit().remove();
const legend = svg.selectAll(".legend")
.data([0].concat(colorScale.quantiles()), (d) => d);
console.log(colorScale.quantiles());
const legend_g = legend.enter().append("g")
.attr("class", "legend");
legend_g.append("rect")
.attr("x", (d, i) => legendElementWidth * i*1.7)
.attr("y", height)
.attr("width", legendElementWidth*1.7)
.attr("height", gridSize / 2)
.style("fill", (d, i) => colors[i]);
legend_g.append("text")
.attr("class", "mono")
.text((d) => "≥" + d.toFixed(4))
.attr("x", (d, i) => legendElementWidth * i*1.7)
.attr("y", height );
legend.exit().remove();
});
};
heatmapChart();
function wrap(text, width,left) {
text.each(function() {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 3, // ems
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null).append("tspan").attr("x",left).attr("y", y).attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan").attr("x",left).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
}
}
});
}
</script>
</div>
<div>
<p>About Data: I use the rescaling method in python that is discussed in Freature Scaling article in wikipeadia page. I rescale the data in seven colums and normalized these data from 0 to 1. In order to creat the normalized heatmap, I also apply the pivot function so that this data file could be used in Tableau-Lan Yu
</p>
<p>This visualization shows the information about children's conditions and parents' conditions in different types of universities. Color here represents the percentage of each column occupies in a specific type of universities. -Lan Yu
</p>
<p>From this visualization, it's clear that the highest rate of marriage and the highest parents' income ouucrs when the tier_name is Two-year public, private and not-for-profit. -Lan Yu
</p>
</div>
</body>
</html>
Modified http://d3js.org/d3.v4.js to a secure url
https://d3js.org/d3.v4.js