UNPKG

@czi-sds/data-viz

Version:
1,256 lines (1,204 loc) 996 kB
"use client"; 'use strict'; var jsxRuntime = require('react/jsx-runtime'); var echarts = require('echarts'); var React = require('react'); var lodash = require('lodash'); var styled = require('@emotion/styled'); var _styled = require('@emotion/styled/base'); var react = require('@emotion/react'); var material = require('@mui/material'); require('@mui/icons-material'); var css$1 = require('@emotion/css'); var Button$2 = require('@mui/material/Button'); var styles = require('@mui/material/styles'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var React__namespace = /*#__PURE__*/_interopNamespace(React); var styled__default = /*#__PURE__*/_interopDefault(styled); var _styled__default = /*#__PURE__*/_interopDefault(_styled); var Button$2__default = /*#__PURE__*/_interopDefault(Button$2); /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */ var __assign$1 = function() { __assign$1 = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign$1.apply(this, arguments); }; function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } function __spreadArray(to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); } function __makeTemplateObject(cooked, raw) { if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; } typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; var EMPTY_OBJECT$1 = {}; var DEFAULT_ITEM_STYLE = { color: function () { return "rgb(0, 0, 0)"; }, }; function createChartOptions(props) { var axisPointer = props.axisPointer, camera = props.camera, data = props.data, dataZoom = props.dataZoom, emphasis = props.emphasis, encode = props.encode, gridProp = props.grid, _a = props.itemStyle, itemStyle = _a === void 0 ? DEFAULT_ITEM_STYLE : _a, options = props.options, symbolSize = props.symbolSize, _b = props.symbol, symbol = _b === void 0 ? "rect" : _b; var _c = generateDefaultValues(props), defaultAxisPointer = _c.defaultAxisPointer, defaultDataZoom = _c.defaultDataZoom, defaultEmphasis = _c.defaultEmphasis, defaultGrid = _c.defaultGrid, defaultXAxis = _c.defaultXAxis, defaultYAxis = _c.defaultYAxis; var customGrid = typeof gridProp === "function" ? gridProp(defaultGrid) : gridProp; var _d = options || {}, optionsAxisPointer = _d.axisPointer, optionsDataZoom = _d.dataZoom, optionsSeries = _d.series, optionsXAxis = _d.xAxis, optionsYAxis = _d.yAxis, optionsRest = __rest(_d, ["axisPointer", "dataZoom", "series", "xAxis", "yAxis"]); return __assign$1({ animation: false, axisPointer: mergeAxisPointer(defaultAxisPointer, axisPointer, optionsAxisPointer), dataZoom: (camera === null || camera === void 0 ? void 0 : camera.active) ? mergeDataZoom(defaultDataZoom, dataZoom, optionsDataZoom) : [], dataset: { source: data, }, grid: customGrid || defaultGrid, series: [ Object.assign({ emphasis: Object.assign(defaultEmphasis, emphasis), encode: encode, itemStyle: itemStyle, legendHoverLink: false, symbol: symbol, symbolSize: symbolSize, }, optionsSeries ? Array.isArray(optionsSeries) ? optionsSeries[0] : optionsSeries : [], { symbol: symbol, type: "scatter" }), ], xAxis: [ Object.assign(defaultXAxis, optionsXAxis ? Array.isArray(optionsXAxis) ? optionsXAxis[0] : optionsXAxis : {}), ], yAxis: [ Object.assign(defaultYAxis, optionsYAxis ? Array.isArray(optionsYAxis) ? optionsYAxis[0] : optionsYAxis : {}), ] }, optionsRest); } function mergeAxisPointer(defaultAxisPointer, axisPointer, optionsAxisPointer) { var finalAxisPointer = Array.isArray(axisPointer) ? axisPointer // if it's an array, assume that the user has [{...propsToChangeOnX}] OR [ , {...propsToChangeOnY}] OR [{...propsToChangeOnX}, {...propsToChangeOnY}] : [axisPointer, axisPointer]; // else if the user only supplies one AxisPointer object, we assume they want the props to apply to both x and y axisPointer objects var finalOptionsAxisPointer = Array.isArray(optionsAxisPointer) ? optionsAxisPointer : [optionsAxisPointer, optionsAxisPointer]; // merge x axisPointer options var x = __assign$1(__assign$1(__assign$1({}, defaultAxisPointer), finalAxisPointer[0]), finalOptionsAxisPointer === null || finalOptionsAxisPointer === void 0 ? void 0 : finalOptionsAxisPointer[0]); // merge y axisPointer options var y = __assign$1(__assign$1(__assign$1({}, defaultAxisPointer), finalAxisPointer[1]), finalOptionsAxisPointer[1]); return [x, y]; } function mergeDataZoom(defaultDataZoom, dataZoom, optionsDataZoom) { var finalDataZoom = Array.isArray(dataZoom) ? dataZoom // if it's an array, assume that the user has [{...propsToChangeOnX}] OR [ , {...propsToChangeOnY}] OR [{...propsToChangeOnX}, {...propsToChangeOnY}] : [dataZoom, dataZoom]; // else if the user only supplies one dataZoom object, we assume they want the props to apply to both x and y zoom objects var finalOptionsDataZoom = Array.isArray(optionsDataZoom) ? optionsDataZoom : [optionsDataZoom, optionsDataZoom]; // merge x dataZoom options var x = __assign$1(__assign$1(__assign$1({}, defaultDataZoom[0]), finalDataZoom[0]), finalOptionsDataZoom === null || finalOptionsDataZoom === void 0 ? void 0 : finalOptionsDataZoom[0]); // merge y dataZoom options var y = __assign$1(__assign$1(__assign$1({}, defaultDataZoom[1]), finalDataZoom[1]), finalOptionsDataZoom[1]); return [x, y]; } function generateDefaultValues(props) { var camera = props.camera, height = props.height, symbol = props.symbol, width = props.width, xAxisData = props.xAxisData, yAxisData = props.yAxisData; var defaultGrid = { height: "".concat(height, "px"), left: 0, top: 0, // (atarashansky): this is the key change to align x and y axis // labels to fixed spaces width: "".concat(width, "px"), }; var defaultAxisPointer = { label: { show: false }, show: false, triggerOn: "mousemove", }; var defaultXAxis = { axisLabel: { fontSize: 0, rotate: 90 }, axisLine: { show: false, }, axisTick: { show: false, }, boundaryGap: true, data: xAxisData, splitLine: { show: false, }, type: "category", }; var defaultYAxis = { axisLabel: { fontSize: 0 }, axisLine: { show: false, }, axisTick: { show: false, }, boundaryGap: true, data: yAxisData, splitLine: { show: false, }, }; var defaultEmphasis = { itemStyle: { borderColor: symbol === "circle" ? "black" : "white", borderType: "solid", borderWidth: symbol === "circle" ? 2 : 4, opacity: 1, }, scale: false, }; var defaultCamera = { height: camera && camera.height ? camera.height : 20, width: camera && camera.width ? camera.width : 40, }; var defaultDataZoom = [ { // end index of the x axis window endValue: defaultCamera.width - 1, filterMode: "filter", moveOnMouseMove: true, // There's a PR to allow touchpad panning // https://github.com/apache/echarts/pull/19352 moveOnMouseWheel: false, orient: "horizontal", preventDefaultMouseMove: true, // start index of the x axis window startValue: 0, throttle: 0, type: "inside", xAxisIndex: 0, zoomOnMouseWheel: false, }, { // end index of the y axis window endValue: defaultCamera.height - 1, filterMode: "filter", moveOnMouseMove: true, moveOnMouseWheel: true, orient: "vertical", preventDefaultMouseMove: true, // start index of the y axis window startValue: 0, throttle: 0, type: "inside", yAxisIndex: 0, zoomOnMouseWheel: false, }, ]; return { defaultAxisPointer: defaultAxisPointer, defaultDataZoom: defaultDataZoom, defaultEmphasis: defaultEmphasis, defaultGrid: defaultGrid, defaultXAxis: defaultXAxis, defaultYAxis: defaultYAxis, }; } var UPDATE_THROTTLE_MS = 1 * 100; function useUpdateChart(_a) { var axisPointer = _a.axisPointer, camera = _a.camera, chart = _a.chart, data = _a.data, emphasis = _a.emphasis, xAxisData = _a.xAxisData, yAxisData = _a.yAxisData, width = _a.width, height = _a.height, encode = _a.encode, itemStyle = _a.itemStyle, symbol = _a.symbol, symbolSize = _a.symbolSize, grid = _a.grid, options = _a.options, onEvents = _a.onEvents; var throttledUpdateChart = React.useMemo(function () { return lodash.throttle(function () { if (!chart || !data || !xAxisData || !yAxisData) { return; } // (thuang): resize() needs to be called before setOption() to prevent // TypeError: Cannot read properties of undefined (reading 'shouldBePainted') chart.resize(); var chartOptions = createChartOptions({ axisPointer: axisPointer, camera: camera, data: data, emphasis: emphasis, encode: encode, grid: grid, height: height, itemStyle: itemStyle, options: options, symbol: symbol, symbolSize: symbolSize, width: width, xAxisData: xAxisData, yAxisData: yAxisData, }); chart.setOption(chartOptions, { replaceMerge: ["dataZoom", "tooltip"], }); /** * We need to remove old event listeners and bind new ones to * make sure that the event listeners are updated when the props change. */ if (onEvents) { var _loop_1 = function (eventName) { if (Object.prototype.hasOwnProperty.call(onEvents, eventName) && typeof eventName === "string" && typeof onEvents[eventName] === "function") { // Remove old event listener chart.off(eventName); // Add new event listener chart.on(eventName, function (event) { onEvents[eventName](event, chart); }); } }; for (var eventName in onEvents) { _loop_1(eventName); } } }, UPDATE_THROTTLE_MS, // (thuang): Trailing guarantees that the last call to the function will // be executed { trailing: true }); }, [ axisPointer, camera, chart, data, emphasis, xAxisData, yAxisData, width, height, encode, itemStyle, symbol, symbolSize, grid, options, onEvents, ]); React.useEffect(function () { return function () { return throttledUpdateChart.cancel(); }; }, [throttledUpdateChart]); // Update the charts React.useEffect(function () { throttledUpdateChart(); }, [ axisPointer, camera, chart, data, emphasis, xAxisData, yAxisData, throttledUpdateChart, width, height, encode, itemStyle, symbol, symbolSize, grid, options, onEvents, ]); } var ChartContainer = styled__default.default("div")(templateObject_1$1 || (templateObject_1$1 = __makeTemplateObject(["\n ", "\n"], ["\n ", "\n"])), getWidthAndHeight); function getWidthAndHeight(_a) { var width = _a.width, height = _a.height; return "\n width: ".concat(width, "px;\n height: ").concat(height, "px;\n "); } var templateObject_1$1; var HeatmapChart = React.forwardRef(function (props, ref // eslint-disable-next-line sonarjs/cognitive-complexity ) { var axisPointer = props.axisPointer, width = props.width, height = props.height, _a = props.echartsRendererMode, echartsRendererMode = _a === void 0 ? "svg" : _a, camera = props.camera, onEvents = props.onEvents, xAxisData = props.xAxisData, yAxisData = props.yAxisData, data = props.data, encode = props.encode, emphasis = props.emphasis, itemStyle = props.itemStyle, symbol = props.symbol, _b = props.symbolSize, symbolSize = _b === void 0 ? 5 : _b, grid = props.grid, options = props.options, rest = __rest(props, ["axisPointer", "width", "height", "echartsRendererMode", "camera", "onEvents", "xAxisData", "yAxisData", "data", "encode", "emphasis", "itemStyle", "symbol", "symbolSize", "grid", "options"]); // Validate width and height if (!width || !height) { throw Error("Heatmap must have width and height bigger than Zero!"); } // Ref for the chart container var innerRef = React.useRef(null); /** * (thuang): We need both a state and a ref to store the chart instance, so * some hooks can opt out of re-rendering when the chart instance changes. */ var _c = React.useState(null), chart = _c[0], setChart = _c[1]; var chartRef = React.useRef(chart); /** * (thuang): Use this ref to store the onEvents prop to prevent * unnecessary re-renders when the onEvents prop changes. * NOTE: This implies that `onEvents` prop changes alone from the parent * won't re-render the chart */ var onEventsRef = React.useRef(onEvents); /** * (thuang): Use this function to dispose the chart instance for both * the state and the ref. This is to prevent memory leaks. */ var disposeChart = React.useCallback(function () { var _a; (_a = chartRef.current) === null || _a === void 0 ? void 0 : _a.dispose(); chartRef.current = null; setChart(null); }, []); // Function to initialize the chart var initChart = React.useCallback(function () { var onEventsCurrent = onEventsRef.current; var current = innerRef.current; if (!current || chartRef.current || // (thuang): echart's `init()` will throw error if the container has 0 width or height (current === null || current === void 0 ? void 0 : current.getAttribute("height")) === "0" || (current === null || current === void 0 ? void 0 : current.getAttribute("width")) === "0") { return; } // Initialize ECharts instance var rawChart = echarts.init(current, EMPTY_OBJECT$1, { renderer: echartsRendererMode, useDirtyRect: true, }); // Bind events if provided if (onEventsCurrent) { bindEvents(rawChart, onEventsCurrent); } setChart(rawChart); chartRef.current = rawChart; // Cleanup function return function () { disposeChart(); // Unbind events if provided if (onEventsCurrent) { for (var eventName in onEventsCurrent) { if (Object.prototype.hasOwnProperty.call(onEventsCurrent, eventName) && typeof eventName === "string" && typeof onEventsCurrent[eventName] === "function") { rawChart.off(eventName, onEventsCurrent[eventName]); } } } }; }, [echartsRendererMode, disposeChart]); // Initialize charts on component mount React.useEffect(function () { disposeChart(); initChart(); }, [initChart, disposeChart]); // Hook to update chart data and options useUpdateChart({ axisPointer: axisPointer, camera: camera, chart: chart, data: data, emphasis: emphasis, encode: encode, grid: grid, height: height, itemStyle: itemStyle, onEvents: onEvents, options: options, symbol: symbol, symbolSize: symbolSize, width: width, xAxisData: xAxisData, yAxisData: yAxisData, }); // Render the chart container return (jsxRuntime.jsx(ChartContainer, __assign$1({ height: height, width: width, ref: handleRef }, rest))); // Function to bind events to the ECharts instance function bindEvents(instance, events) { function innerBindEvent(eventName, func) { // Ignore invalid event configurations if (typeof eventName === "string" && typeof func === "function") { // Bind event instance.on(eventName, function (param) { func(param, instance); }); } } // Loop through events and bind them for (var eventName in events) { if (Object.prototype.hasOwnProperty.call(events, eventName)) { innerBindEvent(eventName, events[eventName]); } } } // Function to handle the ref of the chart container function handleRef(element) { innerRef.current = element; if (!ref) return; // (thuang): `ref` from `forwardRef` can be a function or a ref object if (typeof ref === "function") { ref(element); } else { ref.current = element; } } }); var index$1 = React.memo(HeatmapChart); /** * table-core * * Copyright (c) TanStack * * This source code is licensed under the MIT license found in the * LICENSE.md file in the root directory of this source tree. * * @license MIT */ // type Person = { // firstName: string // lastName: string // age: number // visits: number // status: string // progress: number // createdAt: Date // nested: { // foo: [ // { // bar: 'bar' // } // ] // bar: { subBar: boolean }[] // baz: { // foo: 'foo' // bar: { // baz: 'baz' // } // } // } // } // Is this type a tuple? // If this type is a tuple, what indices are allowed? /// function functionalUpdate(updater, input) { return typeof updater === 'function' ? updater(input) : updater; } function makeStateUpdater(key, instance) { return updater => { instance.setState(old => { return { ...old, [key]: functionalUpdate(updater, old[key]) }; }); }; } function isFunction(d) { return d instanceof Function; } function isNumberArray(d) { return Array.isArray(d) && d.every(val => typeof val === 'number'); } function flattenBy(arr, getChildren) { const flat = []; const recurse = subArr => { subArr.forEach(item => { flat.push(item); const children = getChildren(item); if (children != null && children.length) { recurse(children); } }); }; recurse(arr); return flat; } function memo(getDeps, fn, opts) { let deps = []; let result; return depArgs => { let depTime; if (opts.key && opts.debug) depTime = Date.now(); const newDeps = getDeps(depArgs); const depsChanged = newDeps.length !== deps.length || newDeps.some((dep, index) => deps[index] !== dep); if (!depsChanged) { return result; } deps = newDeps; let resultTime; if (opts.key && opts.debug) resultTime = Date.now(); result = fn(...newDeps); opts == null || opts.onChange == null || opts.onChange(result); if (opts.key && opts.debug) { if (opts != null && opts.debug()) { const depEndTime = Math.round((Date.now() - depTime) * 100) / 100; const resultEndTime = Math.round((Date.now() - resultTime) * 100) / 100; const resultFpsPercentage = resultEndTime / 16; const pad = (str, num) => { str = String(str); while (str.length < num) { str = ' ' + str; } return str; }; console.info(`%c⏱ ${pad(resultEndTime, 5)} /${pad(depEndTime, 5)} ms`, ` font-size: .6rem; font-weight: bold; color: hsl(${Math.max(0, Math.min(120 - 120 * resultFpsPercentage, 120))}deg 100% 31%);`, opts == null ? void 0 : opts.key); } } return result; }; } function getMemoOptions(tableOptions, debugLevel, key, onChange) { return { debug: () => { var _tableOptions$debugAl; return (_tableOptions$debugAl = tableOptions == null ? void 0 : tableOptions.debugAll) != null ? _tableOptions$debugAl : tableOptions[debugLevel]; }, key: process.env.NODE_ENV === 'development' && key, onChange }; } function createCell(table, row, column, columnId) { const getRenderValue = () => { var _cell$getValue; return (_cell$getValue = cell.getValue()) != null ? _cell$getValue : table.options.renderFallbackValue; }; const cell = { id: `${row.id}_${column.id}`, row, column, getValue: () => row.getValue(columnId), renderValue: getRenderValue, getContext: memo(() => [table, column, row, cell], (table, column, row, cell) => ({ table, column, row, cell: cell, getValue: cell.getValue, renderValue: cell.renderValue }), getMemoOptions(table.options, 'debugCells', 'cell.getContext')) }; table._features.forEach(feature => { feature.createCell == null || feature.createCell(cell, column, row, table); }, {}); return cell; } function createColumn(table, columnDef, depth, parent) { var _ref, _resolvedColumnDef$id; const defaultColumn = table._getDefaultColumnDef(); const resolvedColumnDef = { ...defaultColumn, ...columnDef }; const accessorKey = resolvedColumnDef.accessorKey; let id = (_ref = (_resolvedColumnDef$id = resolvedColumnDef.id) != null ? _resolvedColumnDef$id : accessorKey ? typeof String.prototype.replaceAll === 'function' ? accessorKey.replaceAll('.', '_') : accessorKey.replace(/\./g, '_') : undefined) != null ? _ref : typeof resolvedColumnDef.header === 'string' ? resolvedColumnDef.header : undefined; let accessorFn; if (resolvedColumnDef.accessorFn) { accessorFn = resolvedColumnDef.accessorFn; } else if (accessorKey) { // Support deep accessor keys if (accessorKey.includes('.')) { accessorFn = originalRow => { let result = originalRow; for (const key of accessorKey.split('.')) { var _result; result = (_result = result) == null ? void 0 : _result[key]; if (process.env.NODE_ENV !== 'production' && result === undefined) { console.warn(`"${key}" in deeply nested key "${accessorKey}" returned undefined.`); } } return result; }; } else { accessorFn = originalRow => originalRow[resolvedColumnDef.accessorKey]; } } if (!id) { if (process.env.NODE_ENV !== 'production') { throw new Error(resolvedColumnDef.accessorFn ? `Columns require an id when using an accessorFn` : `Columns require an id when using a non-string header`); } throw new Error(); } let column = { id: `${String(id)}`, accessorFn, parent: parent, depth, columnDef: resolvedColumnDef, columns: [], getFlatColumns: memo(() => [true], () => { var _column$columns; return [column, ...((_column$columns = column.columns) == null ? void 0 : _column$columns.flatMap(d => d.getFlatColumns()))]; }, getMemoOptions(table.options, 'debugColumns', 'column.getFlatColumns')), getLeafColumns: memo(() => [table._getOrderColumnsFn()], orderColumns => { var _column$columns2; if ((_column$columns2 = column.columns) != null && _column$columns2.length) { let leafColumns = column.columns.flatMap(column => column.getLeafColumns()); return orderColumns(leafColumns); } return [column]; }, getMemoOptions(table.options, 'debugColumns', 'column.getLeafColumns')) }; for (const feature of table._features) { feature.createColumn == null || feature.createColumn(column, table); } // Yes, we have to convert table to unknown, because we know more than the compiler here. return column; } const debug = 'debugHeaders'; // function createHeader(table, column, options) { var _options$id; const id = (_options$id = options.id) != null ? _options$id : column.id; let header = { id, column, index: options.index, isPlaceholder: !!options.isPlaceholder, placeholderId: options.placeholderId, depth: options.depth, subHeaders: [], colSpan: 0, rowSpan: 0, headerGroup: null, getLeafHeaders: () => { const leafHeaders = []; const recurseHeader = h => { if (h.subHeaders && h.subHeaders.length) { h.subHeaders.map(recurseHeader); } leafHeaders.push(h); }; recurseHeader(header); return leafHeaders; }, getContext: () => ({ table, header: header, column }) }; table._features.forEach(feature => { feature.createHeader == null || feature.createHeader(header, table); }); return header; } const Headers = { createTable: table => { // Header Groups table.getHeaderGroups = memo(() => [table.getAllColumns(), table.getVisibleLeafColumns(), table.getState().columnPinning.left, table.getState().columnPinning.right], (allColumns, leafColumns, left, right) => { var _left$map$filter, _right$map$filter; const leftColumns = (_left$map$filter = left == null ? void 0 : left.map(columnId => leafColumns.find(d => d.id === columnId)).filter(Boolean)) != null ? _left$map$filter : []; const rightColumns = (_right$map$filter = right == null ? void 0 : right.map(columnId => leafColumns.find(d => d.id === columnId)).filter(Boolean)) != null ? _right$map$filter : []; const centerColumns = leafColumns.filter(column => !(left != null && left.includes(column.id)) && !(right != null && right.includes(column.id))); const headerGroups = buildHeaderGroups(allColumns, [...leftColumns, ...centerColumns, ...rightColumns], table); return headerGroups; }, getMemoOptions(table.options, debug, 'getHeaderGroups')); table.getCenterHeaderGroups = memo(() => [table.getAllColumns(), table.getVisibleLeafColumns(), table.getState().columnPinning.left, table.getState().columnPinning.right], (allColumns, leafColumns, left, right) => { leafColumns = leafColumns.filter(column => !(left != null && left.includes(column.id)) && !(right != null && right.includes(column.id))); return buildHeaderGroups(allColumns, leafColumns, table, 'center'); }, getMemoOptions(table.options, debug, 'getCenterHeaderGroups')); table.getLeftHeaderGroups = memo(() => [table.getAllColumns(), table.getVisibleLeafColumns(), table.getState().columnPinning.left], (allColumns, leafColumns, left) => { var _left$map$filter2; const orderedLeafColumns = (_left$map$filter2 = left == null ? void 0 : left.map(columnId => leafColumns.find(d => d.id === columnId)).filter(Boolean)) != null ? _left$map$filter2 : []; return buildHeaderGroups(allColumns, orderedLeafColumns, table, 'left'); }, getMemoOptions(table.options, debug, 'getLeftHeaderGroups')); table.getRightHeaderGroups = memo(() => [table.getAllColumns(), table.getVisibleLeafColumns(), table.getState().columnPinning.right], (allColumns, leafColumns, right) => { var _right$map$filter2; const orderedLeafColumns = (_right$map$filter2 = right == null ? void 0 : right.map(columnId => leafColumns.find(d => d.id === columnId)).filter(Boolean)) != null ? _right$map$filter2 : []; return buildHeaderGroups(allColumns, orderedLeafColumns, table, 'right'); }, getMemoOptions(table.options, debug, 'getRightHeaderGroups')); // Footer Groups table.getFooterGroups = memo(() => [table.getHeaderGroups()], headerGroups => { return [...headerGroups].reverse(); }, getMemoOptions(table.options, debug, 'getFooterGroups')); table.getLeftFooterGroups = memo(() => [table.getLeftHeaderGroups()], headerGroups => { return [...headerGroups].reverse(); }, getMemoOptions(table.options, debug, 'getLeftFooterGroups')); table.getCenterFooterGroups = memo(() => [table.getCenterHeaderGroups()], headerGroups => { return [...headerGroups].reverse(); }, getMemoOptions(table.options, debug, 'getCenterFooterGroups')); table.getRightFooterGroups = memo(() => [table.getRightHeaderGroups()], headerGroups => { return [...headerGroups].reverse(); }, getMemoOptions(table.options, debug, 'getRightFooterGroups')); // Flat Headers table.getFlatHeaders = memo(() => [table.getHeaderGroups()], headerGroups => { return headerGroups.map(headerGroup => { return headerGroup.headers; }).flat(); }, getMemoOptions(table.options, debug, 'getFlatHeaders')); table.getLeftFlatHeaders = memo(() => [table.getLeftHeaderGroups()], left => { return left.map(headerGroup => { return headerGroup.headers; }).flat(); }, getMemoOptions(table.options, debug, 'getLeftFlatHeaders')); table.getCenterFlatHeaders = memo(() => [table.getCenterHeaderGroups()], left => { return left.map(headerGroup => { return headerGroup.headers; }).flat(); }, getMemoOptions(table.options, debug, 'getCenterFlatHeaders')); table.getRightFlatHeaders = memo(() => [table.getRightHeaderGroups()], left => { return left.map(headerGroup => { return headerGroup.headers; }).flat(); }, getMemoOptions(table.options, debug, 'getRightFlatHeaders')); // Leaf Headers table.getCenterLeafHeaders = memo(() => [table.getCenterFlatHeaders()], flatHeaders => { return flatHeaders.filter(header => { var _header$subHeaders; return !((_header$subHeaders = header.subHeaders) != null && _header$subHeaders.length); }); }, getMemoOptions(table.options, debug, 'getCenterLeafHeaders')); table.getLeftLeafHeaders = memo(() => [table.getLeftFlatHeaders()], flatHeaders => { return flatHeaders.filter(header => { var _header$subHeaders2; return !((_header$subHeaders2 = header.subHeaders) != null && _header$subHeaders2.length); }); }, getMemoOptions(table.options, debug, 'getLeftLeafHeaders')); table.getRightLeafHeaders = memo(() => [table.getRightFlatHeaders()], flatHeaders => { return flatHeaders.filter(header => { var _header$subHeaders3; return !((_header$subHeaders3 = header.subHeaders) != null && _header$subHeaders3.length); }); }, getMemoOptions(table.options, debug, 'getRightLeafHeaders')); table.getLeafHeaders = memo(() => [table.getLeftHeaderGroups(), table.getCenterHeaderGroups(), table.getRightHeaderGroups()], (left, center, right) => { var _left$0$headers, _left$, _center$0$headers, _center$, _right$0$headers, _right$; return [...((_left$0$headers = (_left$ = left[0]) == null ? void 0 : _left$.headers) != null ? _left$0$headers : []), ...((_center$0$headers = (_center$ = center[0]) == null ? void 0 : _center$.headers) != null ? _center$0$headers : []), ...((_right$0$headers = (_right$ = right[0]) == null ? void 0 : _right$.headers) != null ? _right$0$headers : [])].map(header => { return header.getLeafHeaders(); }).flat(); }, getMemoOptions(table.options, debug, 'getLeafHeaders')); } }; function buildHeaderGroups(allColumns, columnsToGroup, table, headerFamily) { var _headerGroups$0$heade, _headerGroups$; // Find the max depth of the columns: // build the leaf column row // build each buffer row going up // placeholder for non-existent level // real column for existing level let maxDepth = 0; const findMaxDepth = function (columns, depth) { if (depth === void 0) { depth = 1; } maxDepth = Math.max(maxDepth, depth); columns.filter(column => column.getIsVisible()).forEach(column => { var _column$columns; if ((_column$columns = column.columns) != null && _column$columns.length) { findMaxDepth(column.columns, depth + 1); } }, 0); }; findMaxDepth(allColumns); let headerGroups = []; const createHeaderGroup = (headersToGroup, depth) => { // The header group we are creating const headerGroup = { depth, id: [headerFamily, `${depth}`].filter(Boolean).join('_'), headers: [] }; // The parent columns we're going to scan next const pendingParentHeaders = []; // Scan each column for parents headersToGroup.forEach(headerToGroup => { // What is the latest (last) parent column? const latestPendingParentHeader = [...pendingParentHeaders].reverse()[0]; const isLeafHeader = headerToGroup.column.depth === headerGroup.depth; let column; let isPlaceholder = false; if (isLeafHeader && headerToGroup.column.parent) { // The parent header is new column = headerToGroup.column.parent; } else { // The parent header is repeated column = headerToGroup.column; isPlaceholder = true; } if (latestPendingParentHeader && (latestPendingParentHeader == null ? void 0 : latestPendingParentHeader.column) === column) { // This column is repeated. Add it as a sub header to the next batch latestPendingParentHeader.subHeaders.push(headerToGroup); } else { // This is a new header. Let's create it const header = createHeader(table, column, { id: [headerFamily, depth, column.id, headerToGroup == null ? void 0 : headerToGroup.id].filter(Boolean).join('_'), isPlaceholder, placeholderId: isPlaceholder ? `${pendingParentHeaders.filter(d => d.column === column).length}` : undefined, depth, index: pendingParentHeaders.length }); // Add the headerToGroup as a subHeader of the new header header.subHeaders.push(headerToGroup); // Add the new header to the pendingParentHeaders to get grouped // in the next batch pendingParentHeaders.push(header); } headerGroup.headers.push(headerToGroup); headerToGroup.headerGroup = headerGroup; }); headerGroups.push(headerGroup); if (depth > 0) { createHeaderGroup(pendingParentHeaders, depth - 1); } }; const bottomHeaders = columnsToGroup.map((column, index) => createHeader(table, column, { depth: maxDepth, index })); createHeaderGroup(bottomHeaders, maxDepth - 1); headerGroups.reverse(); // headerGroups = headerGroups.filter(headerGroup => { // return !headerGroup.headers.every(header => header.isPlaceholder) // }) const recurseHeadersForSpans = headers => { const filteredHeaders = headers.filter(header => header.column.getIsVisible()); return filteredHeaders.map(header => { let colSpan = 0; let rowSpan = 0; let childRowSpans = [0]; if (header.subHeaders && header.subHeaders.length) { childRowSpans = []; recurseHeadersForSpans(header.subHeaders).forEach(_ref => { let { colSpan: childColSpan, rowSpan: childRowSpan } = _ref; colSpan += childColSpan; childRowSpans.push(childRowSpan); }); } else { colSpan = 1; } const minChildRowSpan = Math.min(...childRowSpans); rowSpan = rowSpan + minChildRowSpan; header.colSpan = colSpan; header.rowSpan = rowSpan; return { colSpan, rowSpan }; }); }; recurseHeadersForSpans((_headerGroups$0$heade = (_headerGroups$ = headerGroups[0]) == null ? void 0 : _headerGroups$.headers) != null ? _headerGroups$0$heade : []); return headerGroups; } const createRow = (table, id, original, rowIndex, depth, subRows, parentId) => { let row = { id, index: rowIndex, original, depth, parentId, _valuesCache: {}, _uniqueValuesCache: {}, getValue: columnId => { if (row._valuesCache.hasOwnProperty(columnId)) { return row._valuesCache[columnId]; } const column = table.getColumn(columnId); if (!(column != null && column.accessorFn)) { return undefined; } row._valuesCache[columnId] = column.accessorFn(row.original, rowIndex); return row._valuesCache[columnId]; }, getUniqueValues: columnId => { if (row._uniqueValuesCache.hasOwnProperty(columnId)) { return row._uniqueValuesCache[columnId]; } const column = table.getColumn(columnId); if (!(column != null && column.accessorFn)) { return undefined; } if (!column.columnDef.getUniqueValues) { row._uniqueValuesCache[columnId] = [row.getValue(columnId)]; return row._uniqueValuesCache[columnId]; } row._uniqueValuesCache[columnId] = column.columnDef.getUniqueValues(row.original, rowIndex); return row._uniqueValuesCache[columnId]; }, renderValue: columnId => { var _row$getValue; return (_row$getValue = row.getValue(columnId)) != null ? _row$getValue : table.options.renderFallbackValue; }, subRows: [], getLeafRows: () => flattenBy(row.subRows, d => d.subRows), getParentRow: () => row.parentId ? table.getRow(row.parentId, true) : undefined, getParentRows: () => { let parentRows = []; let currentRow = row; while (true) { const parentRow = currentRow.getParentRow(); if (!parentRow) break; parentRows.push(parentRow); currentRow = parentRow; } return parentRows.reverse(); }, getAllCells: memo(() => [table.getAllLeafColumns()], leafColumns => { return leafColumns.map(column => { return createCell(table, row, column, column.id); }); }, getMemoOptions(table.options, 'debugRows', 'getAllCells')), _getAllCellsByColumnId: memo(() => [row.getAllCells()], allCells => { return allCells.reduce((acc, cell) => { acc[cell.column.id] = cell; return acc; }, {}); }, getMemoOptions(table.options, 'debugRows', 'getAllCellsByColumnId')) }; for (let i = 0; i < table._features.length; i++) { const feature = table._features[i]; feature == null || feature.createRow == null || feature.createRow(row, table); } return row; }; // const ColumnFaceting = { createColumn: (column, table) => { column._getFacetedRowModel = table.options.getFacetedRowModel && table.options.getFacetedRowModel(table, column.id); column.getFacetedRowModel = () => { if (!column._getFacetedRowModel) { return table.getPreFilteredRowModel(); } return column._getFacetedRowModel(); }; column._getFacetedUniqueValues = table.options.getFacetedUniqueValues && table.options.getFacetedUniqueValues(table, column.id); column.getFacetedUniqueValues = () => { if (!column._getFacetedUniqueValues) { return new Map(); } return column._getFacetedUniqueValues(); }; column._getFacetedMinMaxValues = table.options.getFacetedMinMaxValues && table.options.getFacetedMinMaxValues(table, column.id); column.getFacetedMinMaxValues = () => { if (!column._getFacetedMinMaxValues) { return undefined; } return column._getFacetedMinMaxValues(); }; } }; const includesString = (row, columnId, filterValue) => { var _filterValue$toString, _row$getValue; const search = filterValue == null || (_filterValue$toString = filterValue.toString()) == null ? void 0 : _filterValue$toString.toLowerCase(); return Boolean((_row$getValue = row.getValue(columnId)) == null || (_row$getValue = _row$getValue.toString()) == null || (_row$getValue = _row$getValue.toLowerCase()) == null ? void 0 : _row$getValue.includes(search)); }; includesString.autoRemove = val => testFalsey(val); const includesStringSensitive = (row, columnId, filterValue) => { var _row$getValue2; return Boolean((_row$getValue2 = row.getValue(columnId)) == null || (_row$getValue2 = _row$getValue2.toString()) == null ? void 0 : _row$getValue2.includes(filterValue)); }; includesStringSensitive.autoRemove = val => testFalsey(val); const equalsString = (row, columnId, filterValue) => { var _row$getValue3; return ((_row$getValue3 = row.getValue(columnId)) == null || (_row$getValue3 = _row$getValue3.toString()) == null ? void 0 : _row$getValue3.toLowerCase()) === (filterValue == null ? void 0 : filterValue.toLowerCase()); }; equalsString.autoRemove = val => testFalsey(val); const arrIncludes = (row, columnId, filterValue) => { var _row$getValue4; return (_row$getValue4 = row.getValue(columnId)) == null ? void 0 : _row$getValue4.includes(filterValue); }; arrIncludes.autoRemove = val => testFalsey(val); const arrIncludesAll = (row, columnId, filterValue) => { return !filterValue.some(val => { var _row$getValue5; return !((_row$getValue5 = row.getValue(columnId)) != null && _row$getValue5.includes(val)); }); }; arrIncludesAll.autoRemove = val => testFalsey(val) || !(val != null && val.length); const arrIncludesSome = (row, columnId, filterValue) => { return filterValue.some(val => { var _row$getValue6; return (_row$getValue6 = row.getValue(columnId)) == null ? void 0 : _row$getValue6.includes(val); }); }; arrIncludesSome.autoRemove = val => testFalsey(val) || !(val != null && val.length); const equals = (row, columnId, filterValue) => { return row.getValue(columnId) === filterValue; }; equals.autoRemove = val => testFalsey(val); const weakEquals = (row, columnId, filterValue) => { return row.getValue(columnId) == filterValue; }; weakEquals.autoRemove = val => testFalsey(val); const inNumberRange = (row, columnId, filterValue) => { let [min, max] = filterValue; const rowValue = row.getValue(columnId); return rowValue >= min && rowValue <= max; }; inNumberRange.resolveFilterValue = val => { let [unsafeMin, unsafeMax] = val; let parsedMin = typeof unsafeMin !== 'number' ? parseFloat(unsafeMin) : unsafeMin; let parsedMax = typeof unsafeMax !== 'number' ? parseFloat(unsafeMax) : unsafeMax; let min = unsafeMin === null || Number.isNaN(parsedMin) ? -Infinity : parsedMin; let max = unsafeMax === null || Number.isNaN(parsedMax) ? Infinity : parsedMax; if (min > max) { const temp = min; min = max; max = temp; } return [min, max]; }; inNumberRange.autoRemove = val => testFalsey(val) || testFalsey(val[0]) && testFalsey(val[1]); // Export const filterFns = { includesString, includesStringSensitive, equalsString, arrIncludes, arrIncludesAll, arrIncludesSome, equals, weakEquals, inNumberRange }; // Utils function testFalsey(val) { return val === undefined || val === null || val === ''; } // const ColumnFiltering = { getDefaultColumnDef: () => { return { filterFn: 'auto' }; }, getInitialState: state => { return { columnFilters: [], ...state }; }, getDefaultOptions: table => { return { onColumnFiltersChange: makeStateUpdater('columnFilters', table), filterFromLeafRows: false, maxLeafRowFilterDepth: 100 }; }, createColumn: (column, table) => { column.getAutoFilterFn = () => { const firstRow = table.getCoreRowModel().flatRows[0]; const value = firstRow == null ? void 0 : firstRow.getValue(column.id); if (typeof value === 'string') { return filterFns.includesString; } if (typeof value === 'number') { return filterFns.inNumberRange; } if (typeof value === 'boolean') { return filterFns.equals; } if (value !== null && typeof value === 'object') { return filterFns.equals; } if (Array.isArray(value)) { return filterFns.arrIncludes; } return filterFns.weakEquals; }; column.getFilterFn = () => { var _table$options$filter, _table$options$filter2; return isFunction(column.columnDef.filterFn) ? column.columnDef.filterFn : column.columnDef.filterFn === 'auto' ? column.getAutoFilterFn() : // @ts-ignore (_table$options$filter = (_table$options$filter2 = table.options.filterFns) == null ? void 0 : _table$options$filter2[column.columnDef.filterFn]) != null ? _table$options$filter : filterFns[column.columnDef.filterFn]; }; column.getCanFilter = () => { var _column$columnDef$ena, _table$options$enable, _table$options$enable2; return ((_column$columnDef$ena = column.columnDef.enableColumnFilter) != null ? _column$columnDef$ena : true) && ((_table$options$enable = table.options.enableColumnFilters) != null ? _table$options$enable : true) && ((_table$options$enable2 = table.options.enableFilters) != null ? _table$options$enable2 : true) && !!column.accessorFn; }; column.getIsFiltered = () => column.getFilterIndex() > -1; column.getFilterValue = () => { var _table$getState$colum; return (_table$getState$colum = table.getState().columnFilters) == null || (_table$getState$colum = _table$getState$colum.find(d => d.id === column.id)) == null ? void 0 : _table$getState$colum.value; }; column.getFilterIndex = () => { var _table$getState$colum2, _table$getState$colum3; return (_table$getState$colum2 = (_table$getState$colum3 = table.getState().columnFilters) == null ? void 0 : _table$getState$colum3.findIndex(d => d.id === column.id)) != null ? _table$getState$colum2 : -1; }; column.setFilterValue = value => { table.setColumnFilters(old => { const filterFn = column.getFilterFn(); const previousFilter = old == null ? void 0 : old.find(d => d.id === column.id); const newFilter = functionalUpdate(value, previousFilter ? previousFilter.value : undefined); // if (shouldAutoRemoveFilter(filterFn, newFilter, column)) { var _old$filter; return (_old$filter = old == null ? void 0 : old.filter(d => d.id !== column.id)) != null ? _old$filter : []; } const newFilterObj = { id: column.id, value: newFilter }; if (previousFilter) { var _old$map; return (_old$map = old == null ? void 0 : old.map(d => { if (d.id === column.id) { return newFilterObj; } return d; })) != null ? _old$map : []; } if (old != null && old.length) { return [...old, newFilterObj]; } return [newFilterObj]; }); }; }, createRow: (row, _table) => { row.columnFilters = {}; row.columnFiltersMeta = {}; }, createTable: table => { table.setColumnFilters = updater => { const leafColumns = table.getAllLeafColumns(); const updateFn = old => { var _functionalUpdate; return (_functionalUpdate = functionalUpdate(updater, old)) == null ? void 0 : _functionalUpdate.filter(filter => { const column = leafColumns.find(d