Skip to content

Instantly share code, notes, and snippets.

@FilipIlievski
Last active July 14, 2020 15:17
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 FilipIlievski/3afda30c5d9585b868047c1305faef06 to your computer and use it in GitHub Desktop.
Save FilipIlievski/3afda30c5d9585b868047c1305faef06 to your computer and use it in GitHub Desktop.
import React from "react";
import {
createTableMultiSort,
Column,
Table,
SortDirection,
} from "react-virtualized";
import "./styles.css";
import { orderBy, sortBy } from "lodash";
// NOTE: Based on https://github.com/bvaughn/react-virtualized/blob/master/docs/multiColumnSortTable.md
const rows = [
{
id: "200880",
names: { de: "B Weg ", en: "B Weg " },
},
{
id: "200878",
names: { de: "A", en: "A" },
},
{
id: "200881",
names: { de: "C", en: "C" },
},
{
id: "200882",
names: { de: "D", en: "D" },
},
{
id: "200883",
names: { de: "E", en: "E" },
},
];
const columns = [
{
dataKey: "stopName",
label: "stopName",
width: 200,
cellRenderer: ({
rowData: {
id,
names: { de: stopName },
},
dataKey,
}) => (
<div style={{ border: "1px solid black" }} id={id}>
<p>{stopName}</p>
</div>
),
},
{
dataKey: "stopId",
label: "stopId",
width: 200,
cellRenderer: ({ rowData: { id }, dataKey }) => (
<div style={{ border: "1px solid black" }} id={id}>
<p>{id}</p>
</div>
),
},
{
dataKey: "avgWalkingDist",
label: "avgWalkingDist",
width: 200,
cellRenderer: ({ rowData: { id, combinedWalkingDistance }, dataKey }) => (
<div style={{ border: "1px solid black" }} id={id}>
<p>{combinedWalkingDistance}</p>
</div>
),
},
];
const DataTableSortIcon = ({ active, order, ...props }) => {
const activeColor = "#00f";
const defaultColor = "#000";
const upperArrow = active && order === "desc" ? activeColor : defaultColor;
const lowerArrow = active && order === "asc" ? activeColor : defaultColor;
return (
<svg width={12} height={13} fill="none" {...props}>
<path d="M1 8L6 13L11 8H1Z" fill={upperArrow} />
<path d="M11 5L6 0L1 5L11 5Z" fill={lowerArrow} />
</svg>
);
};
export const SortIndicator = ({ active, sortDirection }) => {
return (
<DataTableSortIcon
active={active}
order={
sortDirection === SortDirection.ASC
? "asc"
: sortDirection === SortDirection.DESC
? "desc"
: null
}
/>
);
};
const defaultSortState = {
defaultSortBy: ["stopId", "avgWalkingDist"],
defaultSortDirection: {
stopId: "DESC",
avgWalkingDist: "ASC",
},
};
const VirtualizedMultiSortingTable = (tableProps) => {
// sort function
const sortFunc = ({ row, sortBy }) => {
return sortBy.map((sortField) => {
switch (sortField) {
case "stopId":
return +row.id;
case "stopName":
return row?.names?.de;
case "avgWalkingDist":
return row.combinedWalkingDistance || 0;
default:
return +row.id;
}
});
};
// sorting the provided list
const sortList = ({ sortBy, sortDirection }) => {
return orderBy(
rows,
(row) => sortFunc({ row, sortBy }),
Object.values(sortDirection).map((val) => val.toLowerCase())
);
};
// **start** local state
const [sortByState, setSortByState] = React.useState(
defaultSortState.defaultSortBy
);
const [sortDirectionState, setSortDirectionState] = React.useState(
defaultSortState.defaultSortDirection
);
const [sortListState, setsortListState] = React.useState(null);
// ** end ** local state
// callback for the createTableMultiSort()
const sort = ({ sortBy, sortDirection }) => {
const sortedList = sortList({
sortBy: sortByState,
sortDirection: sortDirectionState,
});
setsortListState(sortedList);
setSortByState(Array.from(new Set([sortByState, sortBy].flat(Infinity))));
setSortDirectionState({ ...sortDirectionState, ...sortDirection });
return sortedList;
};
const sortState = createTableMultiSort(sort);
//
// 🤔
sortState.sortBy = sortByState;
sortState.sortDirection = sortDirectionState;
console.log(sortState);
const headerRenderer = ({ dataKey, label }) => {
const showSortIndicator = sortByState?.includes(dataKey);
return (
<div
style={{ display: "flex", background: "skyblue", marginRight: "5px" }}
>
<span title={label}>{label}</span>
{showSortIndicator && (
<SortIndicator
active={showSortIndicator}
sortDirection={sortDirectionState[dataKey]}
/>
)}
</div>
);
};
return (
<div
style={{ display: "flex", flexDirection: "column", marginTop: "30px" }}
>
<Table
{...tableProps}
sort={sortState.sort}
// sortBy={undefined}
// sortDirection={undefined}
sortBy={sortByState}
sortDirection={sortDirectionState}
// sortBy={sortState.sortBy}
// sortDirection={sortState.sortDirection}
width={600}
height={600}
headerHeight={30}
rowHeight={50}
rowCount={rows.length}
rowGetter={({ index }) => rows[index]}
>
{columns.map((column) => {
return (
<Column
// style={{ ...headerColumn }}
{...column}
key={column.dataKey}
width={300}
headerRenderer={headerRenderer}
/>
);
})}
</Table>
<pre>{JSON.stringify(sortState)}</pre>
</div>
);
};
export default VirtualizedMultiSortingTable;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment