/* global d3 queue */
const 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;
const columns = [
{
head: 'State',
cl: 'state',
html(row) {
const sfLetter = stateface[row.state_abbrev];
const icon = `${sfLetter}`;
const text = `${row.state}`;
return icon + text;
},
},
{
head: 'Employment (millions)',
cl: 'emp',
html(row) {
const scale = d3.scaleThreshold()
.domain([1, 2, 4, 6])
.range([1, 2, 3, 4, 5]);
const icon = '';
const value = d3.format(',.1f')(row.emp / 1000000);
const nIcons = scale(value);
const text = `${value}`;
return text + d3.range(nIcons)
.map(() => icon).join('');
},
},
{
head: 'Change in Employment',
cl: 'emp_pc',
html(row) {
const scale = d3.scaleThreshold()
.domain([0, 0.045])
.range(['down', 'right', 'up']);
const icon = ``;
const value = d3.format(',.0%')(row.emp_pc);
const text = `${value}`;
return text + icon;
},
},
{
head: 'Wage (weekly)',
cl: 'wage',
html(row) {
const scale = d3.scaleThreshold()
.domain([850, 1000])
.range([1, 2, 3]);
const icon = '';
const nIcons = scale(row.wage);
const value = d3.format('$,')(row.wage);
const text = `${value}`;
return text + d3.range(nIcons)
.map(() => icon).join('');
},
},
{
head: 'Change in Wage',
cl: 'wage_pc',
html(row) {
const scale = d3.scaleThreshold()
.domain([0, 0.07])
.range(['down', 'right', 'up']);
const icon = ``;
const value = d3.format(',.0%')(row.wage_pc);
const text = `${value}`;
return text + icon;
},
},
];
table.call(renderTable);
function renderTable(table) {
const tableUpdate = table.select('thead')
.selectAll('th')
.data(columns);
const tableEnter = tableUpdate
.enter().append('th')
.attr('class', d => d.cl)
.text(d => d.head)
.on('click', (d) => {
let ascending;
if (d.ascending) {
ascending = false;
} else {
ascending = true;
}
d.ascending = ascending;
qcew.sort((a, b) => {
if (ascending) {
return d3.ascending(a[d.cl], b[d.cl]);
}
return d3.descending(a[d.cl], b[d.cl]);
});
table.call(renderTable);
});
const trUpdate = table.select('tbody').selectAll('tr')
.data(qcew);
const trEnter = trUpdate.enter().append('tr');
const trMerge = trUpdate.merge(trEnter)
.on('mouseenter', mouseenter)
.on('mouseleave', mouseleave);
const tdUpdate = trMerge.selectAll('td')
.data((row, i) => columns.map((c) => {
const cell = {};
d3.keys(c).forEach((k) => {
cell[k] = typeof c[k] === 'function' ? c[k](row, i) : c[k];
});
return cell;
}));
const tdEnter = tdUpdate.enter().append('td');
tdEnter
.attr('class', d => d.cl)
.style('background-color', '#fff')
.style('border-bottom', '.5px solid white');
tdEnter.merge(tdUpdate).html(d => 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');
}