|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<script src="https://d3js.org/d3.v4.min.js"></script> |
|
<style type="text/css"> |
|
html, body, |
|
.wrapper { |
|
margin: 10px; |
|
} |
|
table { |
|
border: 1px #E3E3E3 solid; |
|
border-collapse: collapse; |
|
border-spacing: 0; |
|
} |
|
table th { |
|
padding: 5px; |
|
border: #E3E3E3 solid; |
|
border-width: 0 0 1px 1px; |
|
background: #F5F5F5; |
|
font-weight: bold; |
|
line-height: 120%; |
|
text-align: center; |
|
} |
|
table td { |
|
padding: 5px; |
|
border: 1px #E3E3E3 solid; |
|
border-width: 0 0 1px 1px; |
|
text-align: center; |
|
} |
|
.__selected { |
|
color: red; |
|
} |
|
.__checked { |
|
color: red; |
|
} |
|
.btn-group__item { |
|
position: relative; |
|
display: inline-block; |
|
font-weight: bold; |
|
padding: 8px 10px 5px 10px; |
|
text-decoration: none; |
|
color: #222222; |
|
background: #EEEEEE; |
|
border-bottom: solid 4px #AAAAAA; |
|
border-radius: 5px 5px 0 0; |
|
transition: .4s; |
|
font-size: 14px; |
|
} |
|
|
|
.btn-group__item:hover { |
|
background: #BBBBBB; |
|
color: #FFF; |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<div class="wrapper"> |
|
<div class="btn-group"> |
|
<button class="btn-group__item" value="job">職種別</button> |
|
<button class="btn-group__item" value="ind">業種別</button> |
|
</div> |
|
<div class="switchable-table"></div> |
|
<script type="text/javascript"> |
|
|
|
d3.queue() |
|
.defer(d3.tsv, 'job_category.tsv') |
|
.defer(d3.tsv, 'ind_category.tsv') |
|
.await(function(error, job, ind) { |
|
|
|
drawTable('2018年5月', job); |
|
var selectedTable = "job"; |
|
|
|
d3.selectAll('.btn-group__item').on('click', function(){ |
|
if(selectedTable !== this.value){ |
|
d3.select(".switchable-table").select("table").remove(); |
|
|
|
var thisData = ("job"===this.value) ? job : ind; |
|
drawTable('2018年5月', thisData); |
|
selectedTable = this.value; |
|
} |
|
}); |
|
|
|
function drawTable(sortTarget, inputData) { |
|
// クラス一覧 |
|
const tableClassName = 'switchable-table'; |
|
const tableClass = '.'+tableClassName; |
|
const headerClassName = tableClassName + '__header'; |
|
const headerClass = tableClass + '__header'; |
|
const sortedData = returnSortedData(sortTarget, inputData); |
|
|
|
const table = d3.select(tableClass).append('table'); |
|
|
|
const headers = ['2018年5月', '2018年4月', '2018年3月', '2018年2月', '2018年1月']; |
|
const theadText = '<tr><th></th><th class='+headerClassName+'>' + headers.join('</th><th class='+headerClassName+'>') + '</tr>'; |
|
|
|
table.append('thead').html(theadText); |
|
|
|
const tbody = table.append('tbody'); |
|
const selectedTrs = tbody.selectAll("tr").exit().remove().data(sortedData); |
|
const newTrs = selectedTrs.enter().append("tr"); |
|
const trs = selectedTrs.merge(newTrs); |
|
|
|
trs.selectAll('td') |
|
.data(function(d){ return [d.index, d['2018年5月'], d['2018年4月'], d['2018年3月'], d['2018年2月'], d['2018年1月']]; }) |
|
.enter() |
|
.append('td') |
|
.text(function(d){ |
|
return d; |
|
}); |
|
|
|
updateSlected(headers.indexOf(sortTarget)); |
|
|
|
d3.selectAll(headerClass) |
|
.on('click', function(_, i){ |
|
const that = this; |
|
clearTable(tableClass); |
|
drawTable(that.textContent, sortedData); |
|
updateSlected(i); |
|
}); |
|
|
|
// ソート中のヘッダーに付与するクラスを更新する関数 |
|
function updateSlected(i){ |
|
const selector = d3.selectAll(headerClass); |
|
selector.classed('__selected', false); // 古いクラスをクリア |
|
selector.classed('__selected', function(_,j){ if(i===j) return true; }); |
|
} |
|
|
|
// 入力されたデータを指定のヘッダーを基準にソートして返す関数 |
|
function returnSortedData(sortTarget, sortedData){ |
|
sortedData.sort(function(a, b) { return (a[sortTarget] > b[sortTarget]) ? -1 : 1; }); |
|
return sortedData; |
|
} |
|
|
|
// クリア機能 |
|
function clearTable(tableClass){ |
|
d3.select(tableClass).select("table").remove(); |
|
} |
|
} |
|
}) |
|
|
|
</script> |
|
</div> |
|
</body> |
|
</html> |