Fix sort by values

This commit is contained in:
c-bata
2021-02-22 22:32:59 +09:00
parent 391d3eb9b5
commit aeef6ca5c5
2 changed files with 37 additions and 6 deletions
@@ -45,10 +45,10 @@ const useStyles = makeStyles((theme: Theme) =>
)
interface DataGridColumn<T> {
field: keyof T // TODO(c-bata): remove this or optional?
// TODO(c-bata): add comparator(or less function) field? see https://golang.org/pkg/sort/#Slice
field: keyof T
label: string
sortable?: boolean
less?: (i: number, j: number) => number
filterable?: boolean
toCellValue?: (rowIndex: number) => string | React.ReactNode
padding?: "default" | "checkbox" | "none"
@@ -132,7 +132,8 @@ function DataGrid<T>(props: {
setOrder(isAsc ? "desc" : "asc")
setOrderBy(columnId)
}
const sortedRows = stableSort<T>(filteredRows, getComparator(order, columns, orderBy))
const lessFunc = columns[orderBy].less
const sortedRows = stableSort<T>(filteredRows, getComparator(order, columns, orderBy), order, lessFunc)
const currentPageRows =
rowsPerPage > 0
? sortedRows.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
@@ -325,11 +326,21 @@ function descendingComparator<T>(
return 0
}
function stableSort<T>(array: T[], comparator: (a: T, b: T) => number) {
function stableSort<T>(
array: T[],
comparator: (a: T, b: T) => number,
order: Order,
less?: (i: number, j: number) => number
) {
const stabilizedThis = array.map((el, index) => [el, index] as [T, number])
stabilizedThis.sort((a, b) => {
const order = comparator(a[0], b[0])
if (order !== 0) return order
if (less) {
const result = order == "asc" ? -less(a[1], b[1]) : less(a[1], b[1])
if (result !== 0) return result
} else {
const result = comparator(a[0], b[0])
if (result !== 0) return result
}
return a[1] - b[1]
})
return stabilizedThis.map((el) => el[0])
@@ -225,6 +225,16 @@ const TrialTable: FC<{ studyDetail: StudyDetail | null }> = ({
field: "values",
label: "Value",
sortable: true,
less: (i, j): number => {
if (trials[i].values?.[0] === trials[j].values?.[0]) {
return 0
} else if (trials[i].values === undefined) {
return -1
} else if (trials[j].values === undefined) {
return 1
}
return trials[i].values![0] < trials[j].values![0] ? 1 : -1
},
toCellValue: (i) => trials[i].values?.[0] || null,
})
} else {
@@ -234,6 +244,16 @@ const TrialTable: FC<{ studyDetail: StudyDetail | null }> = ({
field: "values",
label: `Objective ${objectiveId}`,
sortable: true,
less: (i, j): number => {
if (trials[i].values?.[objectiveId] === trials[j].values?.[objectiveId]) {
return 0
} else if (trials[i].values === undefined) {
return -1
} else if (trials[j].values === undefined) {
return 1
}
return trials[i].values![objectiveId] < trials[j].values![objectiveId] ? 1 : -1
},
toCellValue: (i) => trials[i].values?.[objectiveId] || null,
}))
columns.push(...objectiveColumns)