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>
我使用 d3.js 創建了一個 flexbox 表,它拉取 json 資料來填充它。我希望能夠按標題行對每一列進行排序,為此我撰寫了一個排序函式。但是,我現在一次只能對一列進行排序。然后,如果我重繪 頁面,就可以對不同的列進行排序。我希望能夠在不需要重繪 頁面的情況下進行切換。因此,按名稱排序,然后決定按專案排序,然后按區域排序,以查看資料的不同視圖。我錯過了什么?
我很感激任何反饋。
[我也希望只有一個排序函式,我將一個變數傳遞給它,而不是擁有所有這些條件。我不確定這是否可能。(絕對不是我主要關心的問題。)但是把它放在那里]
謝謝!
uj5u.com熱心網友回復:
如果您查看控制臺,您會看到它sortWhich總是類似于"box hrbox whatever",因此所有條件都將失敗,代碼將轉到else底部。
一個最簡單的解決方案是使用includes():
if (sortWhich.includes("name")) etc...
這是帶有該更改的代碼:
顯示代碼片段
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>
這里有一些問題:
sort()對陣列進行排序,不需要該tableSort變數- 洗掉用于再次繪制表格的元素不是慣用的 D3,只需使用輸入/更新/退出選擇。
關于您的次要問題,如果您有正確的變數名稱,您可以使用括號表示法,洗掉所有該if...else部分:
data.sort((a, b) => d3.ascending(a[sortWhich], b[sortWhich]))
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/339864.html
標籤:javascript 排序 d3.js
