Skip to content

Instantly share code, notes, and snippets.

@armollica
Last active May 28, 2019 03:06
Show Gist options
  • Save armollica/e4fbd694c02629251b6f to your computer and use it in GitHub Desktop.
Save armollica/e4fbd694c02629251b6f to your computer and use it in GitHub Desktop.
Pictogram Table
height: 900

Using pictograms within a table. Click headers to sort.

Notes: Uses technique from this blog post to implement HTML tables with D3 in a nice way. Growth rates are from Q2-2012 to Q2-2015. Data from BLS. State icons from ProPublica's StateFace project. Other icons from Font Awesome.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="table-container">
</div>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/queue-async/1.0.7/queue.min.js"></script>
<script>
var table = d3.select(".table-container").append("table");
table.append("thead");
table.append("tbody");
queue()
.defer(d3.json, "qcew.json")
.defer(d3.json, "stateface.json")
.await(ready);
function ready(error, qcew, stateface) {
if (error) throw error;
var columns = [
{
head: "State",
cl: "state",
html: function(row) {
var sf_letter = stateface[row.state_abbrev];
var icon = '<span class="stateface">' + sf_letter + '</span>';
var text = '<span class="title">' + row.state + '</span>';
return icon + text;
}
},
{
head: "Employment (millions)",
cl: "emp",
html: function(row) {
var scale = scale = d3.scale.threshold()
.domain([1, 2, 4, 6])
.range([1, 2, 3, 4, 5]);
var icon = '<span class="fa fa-male"></span>';
var value = d3.format(",.1f")(row.emp/1000000);
var nIcons = scale(value);
var text = '<span class="text">' + value + '</span>';
return text + d3.range(nIcons)
.map(function() { return icon; }).join("");
}
},
{
head: "Change in Employment",
cl: "emp_pc",
html: function(row) {
var scale = d3.scale.threshold()
.domain([0, .045])
.range(["down", "right", "up"]);
var icon = '<span class="fa fa-arrow-' + scale(row.emp_pc) +'"></span>';
var value = d3.format(",.0%")(row.emp_pc);
var text = '<span class="text">' + value + '</span>';
return text + icon;
}
},
{
head: "Wage (weekly)",
cl: "wage",
html: function(row) {
var scale = d3.scale.threshold()
.domain([850, 1000])
.range([1, 2, 3]);
var icon = '<span class="fa fa-money fa-rotate-90"></span>';
var nIcons = scale(row.wage);
var value = d3.format("$,")(row.wage);
var text = '<span class="text">' + value + '</span>';
return text + d3.range(nIcons)
.map(function() { return icon; }).join("");
}
},
{
head: "Change in Wage",
cl: "wage_pc",
html: function(row) {
var scale = d3.scale.threshold()
.domain([0, .07])
.range(["down", "right", "up"]);
var icon = '<span class="fa fa-arrow-' + scale(row.wage_pc) +'"></span>';
var value = d3.format(",.0%")(row.wage_pc);
var text = '<span class="text">' + value + '</span>';
return text + icon;
}
}
];
table.call(renderTable);
function renderTable(table) {
table.select("thead")
.selectAll("th")
.data(columns)
.enter().append("th")
.attr("class", function(d) { return d.cl; })
.text(function(d) { return d.head; })
.on("click", function(d) {
var ascending = d.ascending ? false : true;
d.ascending = ascending;
qcew.sort(function(a, b) {
return ascending ?
d3.ascending(a[d.cl], b[d.cl]) :
d3.descending(a[d.cl], b[d.cl]);
});
table.call(renderTable);
});
var tr = table.select("tbody").selectAll("tr").data(qcew);
tr.enter().append("tr")
.on("mouseenter", mouseenter)
.on("mouseleave", mouseleave);
var td = tr.selectAll("td")
.data(function(row, i) {
return columns.map(function(c) {
var cell = {};
d3.keys(c).forEach(function(k) {
cell[k] = typeof c[k] == 'function' ? c[k](row,i) : c[k];
});
return cell;
})
})
td.enter().append("td")
.attr("class", function(d) { return d.cl; })
.style("background-color", "#fff")
.style("border-bottom", ".5px solid white");
td.html(function(d) { return d.html; });
}
}
function mouseenter() {
d3.select(this).selectAll("td")
.style("background-color", "#f0f0f0")
.style("border-bottom", ".5px solid slategrey");
}
function mouseleave() {
d3.select(this).selectAll("td")
.style("background-color", "#fff")
.style("border-bottom", ".5px solid white");
}
</script>
</body>
</html>
[{"fips":"01","state":"Alabama","state_abbrev":"AL","emp":1894247,"emp_pc":0.0312,"wage":819,"wage_pc":0.046,"estabs":118496,"estabs_pc":0.0268},{"fips":"02","state":"Alaska","state_abbrev":"AK","emp":338078,"emp_pc":0.0192,"wage":1028,"wage_pc":0.0764,"estabs":22338,"estabs_pc":0.0315},{"fips":"04","state":"Arizona","state_abbrev":"AZ","emp":2585850.6667,"emp_pc":0.0687,"wage":904,"wage_pc":0.0487,"estabs":151145,"estabs_pc":0.0317},{"fips":"05","state":"Arkansas","state_abbrev":"AR","emp":1183673,"emp_pc":0.021,"wage":762,"wage_pc":0.0628,"estabs":88603,"estabs_pc":0.0414},{"fips":"06","state":"California","state_abbrev":"CA","emp":16272726,"emp_pc":0.0863,"wage":1131,"wage_pc":0.1013,"estabs":1420008,"estabs_pc":0.0027},{"fips":"08","state":"Colorado","state_abbrev":"CO","emp":2489827.6667,"emp_pc":0.1003,"wage":989,"wage_pc":0.0773,"estabs":185399,"estabs_pc":0.0817},{"fips":"09","state":"Connecticut","state_abbrev":"CT","emp":1678711.6667,"emp_pc":0.0255,"wage":1177,"wage_pc":0.0594,"estabs":115445,"estabs_pc":0.039},{"fips":"10","state":"Delaware","state_abbrev":"DE","emp":433342,"emp_pc":0.0654,"wage":991,"wage_pc":0.0465,"estabs":30521,"estabs_pc":0.0961},{"fips":"11","state":"District Of Columbia","state_abbrev":"DC","emp":743073,"emp_pc":0.0399,"wage":1599,"wage_pc":0.0363,"estabs":37199,"estabs_pc":0.0468},{"fips":"12","state":"Florida","state_abbrev":"FL","emp":8003431.3333,"emp_pc":0.0909,"wage":861,"wage_pc":0.0682,"estabs":658263,"estabs_pc":0.0896},{"fips":"13","state":"Georgia","state_abbrev":"GA","emp":4154506.3333,"emp_pc":0.0776,"wage":903,"wage_pc":0.0649,"estabs":289226,"estabs_pc":0.079},{"fips":"15","state":"Hawaii","state_abbrev":"HI","emp":635094.3333,"emp_pc":0.0499,"wage":876,"wage_pc":0.0815,"estabs":39508,"estabs_pc":0.0476},{"fips":"16","state":"Idaho","state_abbrev":"ID","emp":668081,"emp_pc":0.0854,"wage":713,"wage_pc":0.0642,"estabs":55412,"estabs_pc":0.0466},{"fips":"17","state":"Illinois","state_abbrev":"IL","emp":5876319.6667,"emp_pc":0.0378,"wage":1015,"wage_pc":0.0651,"estabs":428328,"estabs_pc":0.0944},{"fips":"18","state":"Indiana","state_abbrev":"IN","emp":2952937,"emp_pc":0.0453,"wage":811,"wage_pc":0.0629,"estabs":159694,"estabs_pc":-0.0046},{"fips":"19","state":"Iowa","state_abbrev":"IA","emp":1545515.3333,"emp_pc":0.038,"wage":802,"wage_pc":0.0809,"estabs":100605,"estabs_pc":0.0575},{"fips":"20","state":"Kansas","state_abbrev":"KS","emp":1376710,"emp_pc":0.035,"wage":819,"wage_pc":0.0734,"estabs":86812,"estabs_pc":0.0367},{"fips":"21","state":"Kentucky","state_abbrev":"KY","emp":1843882.6667,"emp_pc":0.0394,"wage":822,"wage_pc":0.0648,"estabs":121697,"estabs_pc":0.1017},{"fips":"22","state":"Louisiana","state_abbrev":"LA","emp":1935351.6667,"emp_pc":0.0283,"wage":850,"wage_pc":0.0559,"estabs":126513,"estabs_pc":0.0031},{"fips":"23","state":"Maine","state_abbrev":"ME","emp":598530,"emp_pc":0.0205,"wage":768,"wage_pc":0.0682,"estabs":50631,"estabs_pc":0.0229},{"fips":"24","state":"Maryland","state_abbrev":"MD","emp":2609762,"emp_pc":0.0328,"wage":1046,"wage_pc":0.0555,"estabs":167250,"estabs_pc":0.0048},{"fips":"25","state":"Massachusetts","state_abbrev":"MA","emp":3441869,"emp_pc":0.0555,"wage":1211,"wage_pc":0.092,"estabs":239474,"estabs_pc":0.0826},{"fips":"26","state":"Michigan","state_abbrev":"MI","emp":4182290.6667,"emp_pc":0.0572,"wage":916,"wage_pc":0.0676,"estabs":237670,"estabs_pc":-0.0093},{"fips":"27","state":"Minnesota","state_abbrev":"MN","emp":2798098.6667,"emp_pc":0.0505,"wage":977,"wage_pc":0.0772,"estabs":164087,"estabs_pc":-0.0114},{"fips":"28","state":"Mississippi","state_abbrev":"MS","emp":1116829.3333,"emp_pc":0.025,"wage":709,"wage_pc":0.0411,"estabs":71906,"estabs_pc":0.0532},{"fips":"29","state":"Missouri","state_abbrev":"MO","emp":2739022,"emp_pc":0.0415,"wage":842,"wage_pc":0.0658,"estabs":191050,"estabs_pc":0.0821},{"fips":"30","state":"Montana","state_abbrev":"MT","emp":454126,"emp_pc":0.0452,"wage":754,"wage_pc":0.0771,"estabs":45380,"estabs_pc":0.0737},{"fips":"31","state":"Nebraska","state_abbrev":"NE","emp":962499.3333,"emp_pc":0.0401,"wage":787,"wage_pc":0.0961,"estabs":71548,"estabs_pc":0.0723},{"fips":"32","state":"Nevada","state_abbrev":"NV","emp":1243926.6667,"emp_pc":0.0961,"wage":855,"wage_pc":0.0491,"estabs":78447,"estabs_pc":0.0809},{"fips":"33","state":"New Hampshire","state_abbrev":"NH","emp":638569.3333,"emp_pc":0.0392,"wage":967,"wage_pc":0.0865,"estabs":50742,"estabs_pc":0.0436},{"fips":"34","state":"New Jersey","state_abbrev":"NJ","emp":3941282.6667,"emp_pc":0.0333,"wage":1126,"wage_pc":0.0653,"estabs":266867,"estabs_pc":0.0404},{"fips":"35","state":"New Mexico","state_abbrev":"NM","emp":808459,"emp_pc":0.027,"wage":805,"wage_pc":0.0281,"estabs":56059,"estabs_pc":0.0148},{"fips":"36","state":"New York","state_abbrev":"NY","emp":9062160.3333,"emp_pc":0.0508,"wage":1180,"wage_pc":0.0766,"estabs":636614,"estabs_pc":0.0601},{"fips":"37","state":"North Carolina","state_abbrev":"NC","emp":4171099.3333,"emp_pc":0.0643,"wage":850,"wage_pc":0.0787,"estabs":266026,"estabs_pc":0.0275},{"fips":"38","state":"North Dakota","state_abbrev":"ND","emp":442512.6667,"emp_pc":0.0693,"wage":939,"wage_pc":0.0982,"estabs":32132,"estabs_pc":0.1009},{"fips":"39","state":"Ohio","state_abbrev":"OH","emp":5282683,"emp_pc":0.0409,"wage":865,"wage_pc":0.06,"estabs":290156,"estabs_pc":0.0073},{"fips":"40","state":"Oklahoma","state_abbrev":"OK","emp":1598213.6667,"emp_pc":0.0334,"wage":818,"wage_pc":0.0665,"estabs":108844,"estabs_pc":0.0423},{"fips":"41","state":"Oregon","state_abbrev":"OR","emp":1786037.6667,"emp_pc":0.0847,"wage":899,"wage_pc":0.0741,"estabs":143057,"estabs_pc":0.0961},{"fips":"42","state":"Pennsylvania","state_abbrev":"PA","emp":5726758,"emp_pc":0.0192,"wage":958,"wage_pc":0.0728,"estabs":354050,"estabs_pc":0.0152},{"fips":"44","state":"Rhode Island","state_abbrev":"RI","emp":474281.6667,"emp_pc":0.0427,"wage":925,"wage_pc":0.0756,"estabs":36360,"estabs_pc":0.0335},{"fips":"45","state":"South Carolina","state_abbrev":"SC","emp":1954333.6667,"emp_pc":0.0719,"wage":782,"wage_pc":0.0625,"estabs":121168,"estabs_pc":0.0857},{"fips":"46","state":"South Dakota","state_abbrev":"SD","emp":421137.3333,"emp_pc":0.0388,"wage":740,"wage_pc":0.0931,"estabs":32363,"estabs_pc":0.0334},{"fips":"47","state":"Tennessee","state_abbrev":"TN","emp":2820220.6667,"emp_pc":0.059,"wage":863,"wage_pc":0.0576,"estabs":149702,"estabs_pc":0.0659},{"fips":"48","state":"Texas","state_abbrev":"TX","emp":11651792.6667,"emp_pc":0.0861,"wage":988,"wage_pc":0.0716,"estabs":634983,"estabs_pc":0.0679},{"fips":"49","state":"Utah","state_abbrev":"UT","emp":1338293,"emp_pc":0.0994,"wage":821,"wage_pc":0.0718,"estabs":92945,"estabs_pc":0.0994},{"fips":"50","state":"Vermont","state_abbrev":"VT","emp":306212,"emp_pc":0.0271,"wage":831,"wage_pc":0.0559,"estabs":24657,"estabs_pc":0.0125},{"fips":"51","state":"Virginia","state_abbrev":"VA","emp":3739379.6667,"emp_pc":0.0295,"wage":1000,"wage_pc":0.0504,"estabs":247583,"estabs_pc":0.0442},{"fips":"53","state":"Washington","state_abbrev":"WA","emp":3137354.3333,"emp_pc":0.0838,"wage":1026,"wage_pc":0.0846,"estabs":235511,"estabs_pc":0.0027},{"fips":"54","state":"West Virginia","state_abbrev":"WV","emp":704558.6667,"emp_pc":-0.0126,"wage":803,"wage_pc":0.0348,"estabs":50066,"estabs_pc":0.0144},{"fips":"55","state":"Wisconsin","state_abbrev":"WI","emp":2806129.3333,"emp_pc":0.0331,"wage":836,"wage_pc":0.0746,"estabs":166660,"estabs_pc":0.045},{"fips":"56","state":"Wyoming","state_abbrev":"WY","emp":284545.3333,"emp_pc":0.0119,"wage":869,"wage_pc":0.0333,"estabs":26050,"estabs_pc":0.0238}]
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
{
"AL": "B",
"AK": "A",
"AZ": "D",
"AR": "C",
"CA": "E",
"CO": "F",
"CT": "G",
"DE": "H",
"DC": "y",
"FL": "I",
"GA": "J",
"HI": "K",
"ID": "M",
"IL": "N",
"IN": "O",
"IA": "L",
"KS": "P",
"KY": "Q",
"LA": "R",
"ME": "U",
"MD": "T",
"MA": "S",
"MI": "V",
"MN": "W",
"MS": "Y",
"MO": "X",
"MT": "Z",
"NE": "c",
"NV": "g",
"NH": "d",
"NJ": "e",
"NM": "f",
"NY": "h",
"NC": "a",
"ND": "b",
"OH": "i",
"OK": "j",
"OR": "k",
"PA": "l",
"RI": "m",
"SC": "n",
"SD": "o",
"TN": "p",
"TX": "q",
"UT": "r",
"VT": "t",
"VA": "s",
"WA": "u",
"WV": "w",
"WI": "v",
"WY": "x",
"US": "z"
}
@font-face {
font-family: 'StateFaceRegular';
src: url('stateface-regular-webfont.eot');
src: url('stateface-regular-webfont.eot?#iefix') format('embedded-opentype'),
url('stateface-regular-webfont.woff') format('woff'),
url('stateface-regular-webfont.ttf') format('truetype'),
url('stateface-regular-webfont.svg#StateFaceRegular') format('svg');
font-weight: normal;
font-style: normal;
}
.stateface {
font-family: "StateFaceRegular";
}
body {
font: 12px monospace;
}
table-container {
width: 960px;
overflow: auto;
}
table {
border-collapse: collapse;
position: relative;
left: 160px;
}
th {
border-bottom: 1px solid black;
cursor: pointer;
}
td, th {
padding-left: 10px;
padding-right: 10px;
}
span.stateface,
span.fa {
display: inline-block;
}
span.stateface {
width: 25px;
line-height: 14px;
text-align: center;
}
td > span {
float: left;
}
span.text {
width: 40px;
text-align: right;
padding-right: 10px;
}
th.emp, td.emp
th.wage, td.wage {
width: 100px;
}
th.emp_pc, td.emp_pc
th.wage_pc, td.wage_pc {
width: 90px;
}
.emp span.fa {
width: 8px;
}
.fa-arrow-up {
color: darkgreen;
}
.fa-arrow-right {
color: slategrey;
}
.fa-arrow-down {
color: red;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment