UNPKG

@ndbx/runtime

Version:

The `@ndbx/runtime` package provides a runtime environment to embed NodeBox visualizations directly into React applications. NodeBox is a powerful tool for creating interactive and generative visualizations, and this runtime allows you to integrate those

79 lines (68 loc) 2.48 kB
/** * Sort table data in ascending or descending order. * * - Natural mode: * - Numerical mode: * - Alphabethical mode: * * @category Table */ import { sort, group, ascending, descending } from "https://esm.sh/d3-array@3.2.4"; export default function (node) { const dataIn = node.tableIn({ name: "dataIn", label: "Data" }); const sortByIn = node.stringIn({ name: "sortBy", label: "Sort by attributename(s)" }); const groupByIn = node.stringIn({ name: "groupBy", label: "Group by attributename(s)" }); const orderIn = node.stringIn({ name: "order", label: "Order", value: "ascending", choices: ["ascending", "descending"], }); const modeIn = node.stringIn({ name: "mode", label: "Mode", value: "natural", choices: ["natural", "numerical", "alphabetical"], }); const dataOut = node.tableOut({ name: "dataOut", label: "Data" }); function sortData(data, sortBy = [], groupBy = [], order = "ascending", mode = "natural") { // Determine the sorting order const isAscending = order === "ascending"; // Define the comparison function based on the mode const getComparisonFunction = (mode) => { switch (mode) { case "numerical": return (a, b) => ascending(+a, +b); case "alphabetical": return (a, b) => ascending(String(a), String(b)); case "natural": default: return (a, b) => ascending(a, b); } }; const compare = getComparisonFunction(mode); const compareFunction = isAscending ? compare : (a, b) => -compare(a, b); // Group data by specified attributes const groupedData = group(data, (d) => groupBy.map((attr) => d[attr]).join("|")); // Sort each group const sortedData = []; for (const group of groupedData.values()) { group.sort((a, b) => { for (const attr of sortBy) { const comp = compareFunction(a[attr], b[attr]); if (comp !== 0) return comp; } return 0; }); sortedData.push(...group); } return sortedData; } node.onRender = () => { const data = dataIn.value ? structuredClone(dataIn.value) : []; const sortBy = sortByIn.value ? sortByIn.value.split(",").map((d) => d.trim()) : undefined; const groupBy = groupByIn.value ? groupByIn.value.split(",").map((d) => d.trim()) : undefined; const newData = sortData(data, sortBy, groupBy, orderIn.value, modeIn.value); dataOut.set(newData); }; }