Skip to content

Instantly share code, notes, and snippets.

@nyem69
Last active July 9, 2022 10:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nyem69/c01ee022fb28093ed74a92727aeb9e03 to your computer and use it in GitHub Desktop.
Save nyem69/c01ee022fb28093ed74a92727aeb9e03 to your computer and use it in GitHub Desktop.
d3.js table
license: mit

d3.js table

  • load data from json
  • render html table with selectable and sortable columns
{
"rows": [
{
"alpha3": "BRN",
"name": "Brunei",
"alpha2": "BN",
"numeric": 99
},
{
"alpha3": "KHM",
"name": "Cambodia",
"alpha2": "KH",
"numeric": 116
},
{
"alpha3": "IDN",
"name": "Indonesia",
"alpha2": "ID",
"numeric": 360
},
{
"alpha3": "LAO",
"name": "Laos",
"alpha2": "LA",
"numeric": 418
},
{
"alpha3": "MYS",
"name": "Malaysia",
"alpha2": "MY",
"numeric": 458
},
{
"alpha3": "MMR",
"name": "Myanmar",
"alpha2": "MM",
"numeric": 458
},
{
"alpha3": "PHL",
"name": "Phillippines",
"alpha2": "PH",
"numeric": 608
},
{
"alpha3": "SGP",
"name": "Singapore",
"alpha2": "SG",
"numeric": 702
},
{
"alpha3": "THA",
"name": "Thailand",
"alpha2": "TH",
"numeric": 764
},
{
"alpha3": "TIL",
"name": "Timor Leste",
"alpha2": "TL",
"numeric": 603
},
{
"alpha3": "VNM",
"name": "Vietnam",
"alpha2": "VN",
"numeric": 704
}
]
}
<!DOCTYPE html>
<meta charset="utf-8">
<html>
<head>
<title>d3.js table</title>
<script type="text/javascript" src="//d3js.org/d3.v7.min.js"></script>
<style>
body {
font-family:sans-serif;
}
table {
margin:12px;
}
</style>
</head>
<body>
<script>
d3.json('data.json')
.then((json)=>{
console.log('json', json);
d3.select('body')
.selectAll('.root').data([json])
.join('div').attr('class','root')
.call(sel=>{
sel.selectAll('h1').data(d=>[d])
.join('h1')
.html('select & sort columns')
sel.selectAll('form').data(d=>[d])
.join('form')
.selectAll('.inputs').data(d=>Object.entries(d.rows[0]).map(d=>d[0]))
.join('div').attr('class','inputs')
.call(sel=>{
sel.selectAll('input').data(d=>[d])
.join('input')
.attr('type','checkbox')
.attr('checked', 'checked')
.on('input', function(e,d){
d3.select('.root').call(renderTable);
})
.html(d=>d)
sel.selectAll('span').data(d=>[d])
.join('span')
.html(d=>d)
});
sel.call(renderTable)
function renderTable(sel) {
sel.selectAll('table').data(d=>[d])
.join('table')
.call(sel=>{
sel.selectAll('thead').data(d=>[d])
.join('thead')
.selectAll('tr').data(d=>[d])
.join('tr')
.selectAll('th').data(d=>{
return Object.entries(d.rows[0])
.filter(d=>d3.selectAll('input:checked').data().includes(d[0]))
.map(d=>d[0])
})
.join('th')
.style('cursor','pointer')
.on('click', function(e,d){
let sel = d3.select(this),
order_descending = !sel.classed('order_descending');
sel.classed('order_descending', order_descending);
d3.select(this.closest('table'))
.select('tbody')
.selectAll('tr')
.sort((a,b)=>order_descending
? d3.descending(a[d],b[d])
: d3.ascending(a[d],b[d])
)
})
.html(d=>d)
sel.selectAll('tbody').data(d=>[d]).join('tbody')
.selectAll('tr').data(d=>d.rows).join('tr')
.selectAll('td').data(d=>{
return Object.entries(d)
.filter(d=>d3.selectAll('input:checked').data().includes(d[0]))
.map(d=>d[1])
}).join('td')
.html(d=>d)
});
}
});
});
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment