[英]How can I use d3.js to sort a table by different variables?
data = [ { "name": "Dave", "dept": "Marketing", "region": "South", "items": 28 }, { "name": "Amy", "dept": "IT", "region": "West", "items": 46 }, { "name": "John", "dept": "Sales", "region": "North", "items": 35 }, { "name": "Sarah", "dept": "Communications", "region": "North", "items": 13 } ] drawTable(data) sortTable(data) function drawTable(data) { // not working // when redrawing table, trying to re-initialize sort function sortTable(data) d3.select('#data-table').remove() let table = d3.select('#table').append('div').attr('id', 'data-table') let row = table.selectAll('.row') .data(data) .enter() .append('div') .attr('class', 'row') let grid = row .append('div') .attr('class', 'grid') let name = grid.append('div') .attr('class', 'box') .html(d => d.name) let dept = grid.append('div') .attr('class', 'box') .html(d => d.dept) let region = grid.append('div') .attr('class', 'box') .html(d => d.region) let items = grid.append('div') .attr('class', 'box') .html(d => d.items) } function sortTable(data) { d3.selectAll(".name,.dept,.region,.items").on('click', function () { let sortWhich = d3.select(this).attr("class") console.log('sortWhich', sortWhich) let tableSort if (sortWhich == "name") { tableSort = data.sort((a, b) => d3.ascending(a.name, b.name)) } else if (sortWhich == "dept") { tableSort = data.sort((a, b) => d3.ascending(a.dept, b.dept)) } else if (sortWhich == 'region') { tableSort = data.sort((a, b) => d3.ascending(a.region, b.region)) } else { tableSort = data.sort((a, b) => d3.ascending(a.items, b.items)) } // Can I combine the above and pass a variable to a sort function? This is not working: // let tableSort = data.sort((a, b) => a.sortWhich - b.sortWhich) drawTable(tableSort) }) }
html, body { height: 100%; margin: 0; } .grid { display: flex; flex-wrap: wrap; flex-direction: row; } .grid>div { display: flex; flex-basis: calc(100%/4 - 28px); justify-content: center; flex-direction: column; padding: 10px; } .box { margin: 0; } .box { color: #000; border: .5px solid #ccc; } .hrbox { background-color: #333; color: #fff; }
<!DOCTYPE html> <html lang="en"> <head> <script src="https://d3js.org/d3.v6.min.js"></script> </head> <body> <div id="table"> <div class="grid"> <div class="box hrbox name"> <div>name</div> </div> <div class="box hrbox dept"> <div>dept</div> </div> <div class="box hrbox region"> <div>region</div> </div> <div class="box hrbox items"> <div>items</div> </div> </div> <div id="data-table"></div> </div> </body>
I created a flexbox table using d3.js that pulls json data to populate it.我使用 d3.js 创建了一个 flexbox 表,它拉取 json 数据来填充它。 I want to be able to sort each column by its header row, and I wrote a sort function for that.
我希望能够按标题行对每一列进行排序,为此我编写了一个排序函数。 However, I'm only able to sort one column at a time right now.
但是,我现在一次只能对一列进行排序。 Then if I refresh the page, I can sort a different column.
然后,如果我刷新页面,就可以对不同的列进行排序。 I want to be able to switch without needing to refresh the page.
我希望能够在不需要刷新页面的情况下进行切换。 So- sort by name, then decide to sort by items, then region, to see different views of the data.
因此,按名称排序,然后决定按项目排序,然后按区域排序,以查看数据的不同视图。 What am I missing?
我错过了什么?
I'd appreciate any feedback.我很感激任何反馈。
[I'd also like to just have one sort function that I pass a variable to instead of having all those conditionals. [我也希望只有一个排序函数,我将一个变量传递给它,而不是拥有所有这些条件。 I'm not sure if it's possible.
我不确定这是否可能。 (Definitely not my main concern.) But putting it out there]
(绝对不是我主要关心的问题。)但是把它放在那里]
Thanks!谢谢!
If you look at the console you'll see that sortWhich
is always something like "box hrbox whatever"
, and because of that all conditions will fail and the code will go to the else
at the bottom.如果您查看控制台,您会看到
sortWhich
总是类似于"box hrbox whatever"
,因此所有条件都将失败,代码将转到底部的else
。
A simplest solution is using includes()
:最简单的解决方案是使用
includes()
:
if (sortWhich.includes("name")) etc...
Here is your code with that change:这是带有该更改的代码:
data = [{ "name": "Dave", "dept": "Marketing", "region": "South", "items": 28 }, { "name": "Amy", "dept": "IT", "region": "West", "items": 46 }, { "name": "John", "dept": "Sales", "region": "North", "items": 35 }, { "name": "Sarah", "dept": "Communications", "region": "North", "items": 13 } ] drawTable(data) sortTable(data) function drawTable(data) { // not working // when redrawing table, trying to re-initialize sort function sortTable(data) d3.select('#data-table').remove() let table = d3.select('#table').append('div').attr('id', 'data-table') let row = table.selectAll('.row') .data(data) .enter() .append('div') .attr('class', 'row') let grid = row .append('div') .attr('class', 'grid') let name = grid.append('div') .attr('class', 'box') .html(d => d.name) let dept = grid.append('div') .attr('class', 'box') .html(d => d.dept) let region = grid.append('div') .attr('class', 'box') .html(d => d.region) let items = grid.append('div') .attr('class', 'box') .html(d => d.items) } function sortTable(data) { d3.selectAll(".name,.dept,.region,.items").on('click', function() { let sortWhich = d3.select(this).attr("class") console.log('sortWhich', sortWhich) let tableSort if (sortWhich.includes("name")) { tableSort = data.sort((a, b) => d3.ascending(a.name, b.name)) } else if (sortWhich.includes("dept")) { tableSort = data.sort((a, b) => d3.ascending(a.dept, b.dept)) } else if (sortWhich.includes('region')) { tableSort = data.sort((a, b) => d3.ascending(a.region, b.region)) } else { tableSort = data.sort((a, b) => d3.ascending(a.items, b.items)) } // Can I combine the above and pass a variable to a sort function? This is not working: // let tableSort = data.sort((a, b) => a.sortWhich - b.sortWhich) drawTable(tableSort) }) }
html, body { height: 100%; margin: 0; } .grid { display: flex; flex-wrap: wrap; flex-direction: row; } .grid>div { display: flex; flex-basis: calc(100%/4 - 28px); justify-content: center; flex-direction: column; padding: 10px; } .box { margin: 0; } .box { color: #000; border: .5px solid #ccc; } .hrbox { background-color: #333; color: #fff; }
<!DOCTYPE html> <html lang="en"> <head> <script src="https://d3js.org/d3.v6.min.js"></script> </head> <body> <div id="table"> <div class="grid"> <div class="box hrbox name"> <div>name</div> </div> <div class="box hrbox dept"> <div>dept</div> </div> <div class="box hrbox region"> <div>region</div> </div> <div class="box hrbox items"> <div>items</div> </div> </div> <div id="data-table"></div> </div> </body>
There are some problems here:这里有一些问题:
sort()
sorts the array in place, no need for that tableSort
variable sort()
对数组进行原地排序,不需要tableSort
变量 Regarding your secondary question, if you had the proper variable names you could just use bracket notation, removing all that if...else
section:关于你的第二个问题,如果你有正确的变量名称,你可以使用括号表示法,删除所有
if...else
部分:
data.sort((a, b) => d3.ascending(a[sortWhich], b[sortWhich]))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.