UNPKG

pivot-chart

Version:

pivot table react component

705 lines 27.6 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __values = (this && this.__values) || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; var __spread = (this && this.__spread) || function () { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; }; import { useCallback, useState, useMemo } from 'react'; import produce from 'immer'; import { sum } from 'cube-core'; import { getTheme } from './theme'; import { DynamicCube } from './cube'; var theme = getTheme(); export function useNestTree() { var _a = __read(useState({ id: theme.root.label, path: [] }), 2), nestTree = _a[0], setNestTree = _a[1]; var repaint = useCallback(function (path) { setNestTree(function (tree) { var newTree = produce(tree, function (draft) { var e_1, _a; var node = draft; try { for (var path_1 = __values(path), path_1_1 = path_1.next(); !path_1_1.done; path_1_1 = path_1.next()) { var i = path_1_1.value; node = node.children[i]; } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (path_1_1 && !path_1_1.done && (_a = path_1.return)) _a.call(path_1); } finally { if (e_1) throw e_1.error; } } node.expanded = !node.expanded; }); return newTree; }); }, [setNestTree]); return { nestTree: nestTree, setNestTree: setNestTree, repaint: repaint }; } var alphabetCmp = function (a, b) { if (a > b) return 1; if (a === b) return 0; if (a < b) return -1; }; export function sortPureNestTree(tree, dimensions, depth) { var e_2, _a; if (depth === void 0) { depth = 0; } if (depth <= dimensions.length && tree.children && tree.children.length > 0) { if (dimensions[depth].cmp) { tree.children.sort(function (a, b) { return dimensions[depth].cmp(a.id, b.id); }); } else { tree.children.sort(function (a, b) { return alphabetCmp(a.id, b.id); }); } try { for (var _b = __values(tree.children), _c = _b.next(); !_c.done; _c = _b.next()) { var child = _c.value; sortPureNestTree(child, dimensions, depth + 1); } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_2) throw e_2.error; } } } } export function getPureNestTree(dataSource, dimensions) { var hashTree = new Map(); var dataLen = dataSource.length; for (var i = 0; i < dataLen; i++) { insertNode(hashTree, dimensions, dataSource[i], 0); } return transHashTree2NestTree(hashTree); } ; function insertNode(tree, dimensions, record, depth) { if (depth === dimensions.length) { return; } var childKey = record[dimensions[depth]]; if (!tree.has(childKey)) { tree.set(childKey, new Map()); } insertNode(tree.get(childKey), dimensions, record, depth + 1); } function transHashTree2NestTree(hasTree) { var tree = { id: theme.root.label }; transHashDFS(hasTree, tree); return tree; } function transHashDFS(hashNode, node) { var e_3, _a; if (hashNode.size === 0) { return; } node.children = []; try { for (var hashNode_1 = __values(hashNode), hashNode_1_1 = hashNode_1.next(); !hashNode_1_1.done; hashNode_1_1 = hashNode_1.next()) { var child = hashNode_1_1.value; var childInNode = { id: child[0] }; transHashDFS(child[1], childInNode); node.children.push(childInNode); } } catch (e_3_1) { e_3 = { error: e_3_1 }; } finally { try { if (hashNode_1_1 && !hashNode_1_1.done && (_a = hashNode_1.return)) _a.call(hashNode_1); } finally { if (e_3) throw e_3.error; } } } export function transTree2LeafPathList(tree, hasAggChild) { var lpList = []; // 根左右序 var dfs = function (node, path) { var e_4, _a; if (hasAggChild) { lpList.push(path); } else { if (!(node.expanded && node.children && node.children.length > 0)) { lpList.push(path); } } if (node.expanded && node.children && node.children.length > 0) { try { for (var _b = __values(node.children), _c = _b.next(); !_c.done; _c = _b.next()) { var child = _c.value; dfs(child, __spread(path, [child.id])); } } catch (e_4_1) { e_4 = { error: e_4_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_4) throw e_4.error; } } } }; dfs(tree, []); return lpList; } /** * * @param cube * @param path * @param cubeDimensions * @param measures */ export function queryCube(cube, path, cubeDimensions) { var e_5, _a, e_6, _b, e_7, _c; var tree = cube.tree; var queryPath = []; var _loop_1 = function (dim) { var target = path.find(function (p) { return p.dimCode === dim; }); if (target) { queryPath.push(target); } else { queryPath.push({ dimCode: dim, dimValue: '*' }); } }; try { for (var cubeDimensions_1 = __values(cubeDimensions), cubeDimensions_1_1 = cubeDimensions_1.next(); !cubeDimensions_1_1.done; cubeDimensions_1_1 = cubeDimensions_1.next()) { var dim = cubeDimensions_1_1.value; _loop_1(dim); } } catch (e_5_1) { e_5 = { error: e_5_1 }; } finally { try { if (cubeDimensions_1_1 && !cubeDimensions_1_1.done && (_a = cubeDimensions_1.return)) _a.call(cubeDimensions_1); } finally { if (e_5) throw e_5.error; } } var queryNodeList = queryNode(tree, queryPath, 0); var subset = []; try { for (var queryNodeList_1 = __values(queryNodeList), queryNodeList_1_1 = queryNodeList_1.next(); !queryNodeList_1_1.done; queryNodeList_1_1 = queryNodeList_1.next()) { var node = queryNodeList_1_1.value; try { for (var _d = (e_7 = void 0, __values(node.rawData)), _e = _d.next(); !_e.done; _e = _d.next()) { var record = _e.value; subset.push(record); } } catch (e_7_1) { e_7 = { error: e_7_1 }; } finally { try { if (_e && !_e.done && (_c = _d.return)) _c.call(_d); } finally { if (e_7) throw e_7.error; } } } } catch (e_6_1) { e_6 = { error: e_6_1 }; } finally { try { if (queryNodeList_1_1 && !queryNodeList_1_1.done && (_b = queryNodeList_1.return)) _b.call(queryNodeList_1); } finally { if (e_6) throw e_6.error; } } return subset; } function queryNode(node, path, depth) { var e_8, _a; if (depth >= path.length) return []; var targetMember = path[depth].dimValue; var children = __spread(node.children.entries()); if (depth === path.length - 1) { if (targetMember === '*') { return children.map(function (child) { return child[1]; }); } return children.filter(function (child) { return child[0] === targetMember; }).map(function (child) { return child[1]; }); } var ans = []; try { for (var children_1 = __values(children), children_1_1 = children_1.next(); !children_1_1.done; children_1_1 = children_1.next()) { var child = children_1_1.value; if (targetMember === '*' || child[0] === targetMember) { ans.push.apply(ans, __spread(queryNode(child[1], path, depth + 1))); } } } catch (e_8_1) { e_8 = { error: e_8_1 }; } finally { try { if (children_1_1 && !children_1_1.done && (_a = children_1.return)) _a.call(children_1); } finally { if (e_8) throw e_8.error; } } return ans; } function aggregateAll(dataSource, measures) { var e_9, _a; // todo different handler for holistic and algebra. var result = {}; try { for (var measures_1 = __values(measures), measures_1_1 = measures_1.next(); !measures_1_1.done; measures_1_1 = measures_1.next()) { var mea = measures_1_1.value; var aggObj = mea.aggregator ? mea.aggregator(dataSource, [mea.id]) : sum(dataSource, [mea.id]); result[mea.id] = aggObj[mea.id]; } } catch (e_9_1) { e_9 = { error: e_9_1 }; } finally { try { if (measures_1_1 && !measures_1_1.done && (_a = measures_1.return)) _a.call(measures_1); } finally { if (e_9) throw e_9.error; } } return result; } export function getCossMatrix(visType, cube, rowLPList, columnLPList, rows, columns, measures, dimensionsInView) { if (rowLPList === void 0) { rowLPList = []; } if (columnLPList === void 0) { columnLPList = []; } var rowLen = rowLPList.length; var columnLen = columnLPList.length; var dimensions = rows.concat(columns); var crossMatrix = []; // function getCell (node: Node, path: string[], depth: number): Record { // if (typeof node === 'undefined') return null; // if (depth === path.length) { // return node._aggData; // } // return getCell(node.children.get(path[depth]), path, depth + 1); // } for (var i = 0; i < rowLen; i++) { crossMatrix.push([]); for (var j = 0; j < columnLen; j++) { var path = __spread(rowLPList[i].map(function (d, i) { return ({ dimCode: rows[i], dimValue: d }); }), columnLPList[j].map(function (d, i) { return ({ dimCode: columns[i], dimValue: d }); })); var result = queryCube(cube, path, dimensions); switch (visType) { case 'bar': case 'line': case 'scatter': crossMatrix[i].push(aggregateOnGroupBy(result, dimensionsInView, measures)); break; // case 'scatter': // crossMatrix[i].push(result); // break; case 'number': default: crossMatrix[i].push(aggregateAll(result, measures)); break; } } } return crossMatrix; } export function getNestFields(visType, rows, columns, measures) { switch (visType) { case 'number': return { nestRows: rows, nestColumns: columns, dimensionsInView: [], facetMeasures: measures, viewMeasures: measures }; case 'bar': case 'line': return { nestRows: rows, nestColumns: columns.slice(0, -1), dimensionsInView: columns.slice(-1), facetMeasures: measures, viewMeasures: measures }; case 'scatter': return { nestRows: rows, nestColumns: columns.slice(0, -1), dimensionsInView: columns.slice(-1), facetMeasures: measures, viewMeasures: measures.slice(-1), }; default: return { nestRows: rows, nestColumns: columns, dimensionsInView: [], facetMeasures: measures, viewMeasures: measures }; } } export function useNestFields(visType, rows, columns, measures) { var nestRows = rows; var _a = useMemo(function () { if (visType !== 'number') { return { nestColumns: columns.slice(0, -1), dimensionsInView: columns.slice(-1) }; } return { nestColumns: columns, dimensionsInView: [] }; }, [visType, columns]), nestColumns = _a.nestColumns, dimensionsInView = _a.dimensionsInView; var _b = useMemo(function () { if (visType === 'scatter') { return { facetMeasures: measures, viewMeasures: measures.slice(-1) }; } return { facetMeasures: measures, viewMeasures: measures }; }, [visType, measures]), facetMeasures = _b.facetMeasures, viewMeasures = _b.viewMeasures; return { nestRows: nestRows, nestColumns: nestColumns, dimensionsInView: dimensionsInView, facetMeasures: facetMeasures, viewMeasures: viewMeasures }; } export function aggregateOnGroupBy(dataSource, fields, measures) { var e_10, _a, e_11, _b, _c, e_12, _d; var groups = new Map(); // todo: support multi-dimensions. var field = fields[0]; var data = []; try { for (var dataSource_1 = __values(dataSource), dataSource_1_1 = dataSource_1.next(); !dataSource_1_1.done; dataSource_1_1 = dataSource_1.next()) { var record = dataSource_1_1.value; if (!groups.has(record[field])) { groups.set(record[field], []); } groups.get(record[field]).push(record); } } catch (e_10_1) { e_10 = { error: e_10_1 }; } finally { try { if (dataSource_1_1 && !dataSource_1_1.done && (_a = dataSource_1.return)) _a.call(dataSource_1); } finally { if (e_10) throw e_10.error; } } try { for (var _e = __values(groups.entries()), _f = _e.next(); !_f.done; _f = _e.next()) { var dataFrame = _f.value; var record = (_c = {}, _c[field] = dataFrame[0], _c); try { for (var measures_2 = (e_12 = void 0, __values(measures)), measures_2_1 = measures_2.next(); !measures_2_1.done; measures_2_1 = measures_2.next()) { var mea = measures_2_1.value; record[mea.id] = (mea.aggregator || sum)(dataFrame[1], [mea.id])[mea.id]; } } catch (e_12_1) { e_12 = { error: e_12_1 }; } finally { try { if (measures_2_1 && !measures_2_1.done && (_d = measures_2.return)) _d.call(measures_2); } finally { if (e_12) throw e_12.error; } } data.push(record); } } catch (e_11_1) { e_11 = { error: e_11_1 }; } finally { try { if (_f && !_f.done && (_b = _e.return)) _b.call(_e); } finally { if (e_11) throw e_11.error; } } return data; } var AsyncCacheCube = /** @class */ (function () { function AsyncCacheCube(props) { // private measures: string this.dimCompare = function (a, b) { if (a > b) return 1; if (a === b) return 0; if (a < b) return -1; }; var dimensions = props.dimensions, cmp = props.cmp, asyncCubeQuery = props.asyncCubeQuery; if (cmp) { this.dimCompare = cmp; } // this.dimensions = [...dimensions].sort(cmp); this.dynamicCube = new DynamicCube({ computeCuboid: asyncCubeQuery }); this.asyncCubeQuery = asyncCubeQuery; } // public appendDimension(dimension: string) { // let i = 0; // for (; i < this.dimensions.length; i++) { // let cmp = this.dimCompare(dimension, this.dimensions[i]); // if (cmp === 1) { // break; // } else if (cmp === 0) { // return; // } // } // this.dimensions.splice(i, 1, dimension); // } // public deleteDimension(dimension: string) { // for (let i = 0; i < this.dimensions.length; i++) { // let cmp = this.dimCompare(dimension, this.dimensions[i]); // if (cmp === 0) { // this.dimensions.splice(i, 1); // break; // } // } // } // private encode (values: string[]): string { // return values.join('-'); // } AsyncCacheCube.prototype.cacheQuery = function (originPath, measures) { return __awaiter(this, void 0, void 0, function () { var path, cuboidKey, cuboid; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: path = __spread(originPath).sort(function (a, b) { return _this.dimCompare(a.dimCode, b.dimCode); }); cuboidKey = path.map(function (p) { return p.dimCode; }); return [4 /*yield*/, this.dynamicCube.getCuboid(cuboidKey, measures)]; case 1: cuboid = _a.sent(); return [2 /*return*/, cuboid.get(path)]; } }); }); }; AsyncCacheCube.prototype.getCuboidNestTree = function (originPath, branchFilters) { return __awaiter(this, void 0, void 0, function () { var originPathCode, pathCode, cuboid, viewData, pureNestTree; return __generator(this, function (_a) { switch (_a.label) { case 0: originPathCode = originPath.map(function (p) { return p.id; }); pathCode = __spread(originPathCode).sort(this.dimCompare); return [4 /*yield*/, this.dynamicCube.getCuboid(pathCode, [])]; case 1: cuboid = _a.sent(); viewData = cuboid.dataSource; if (branchFilters && branchFilters.every(function (f) { return originPathCode.includes(f.id); })) { viewData = cuboid.dataSource.filter(function (record) { // must use == not === for key in map is string while the origin value is number, might try return branchFilters.every(function (f) { return f.values.find(function (v) { return v == record[f.id]; }); }); }); } pureNestTree = getPureNestTree(viewData, originPathCode); sortPureNestTree(pureNestTree, originPath, 0); return [2 /*return*/, pureNestTree]; } }); }); }; AsyncCacheCube.prototype.requestCossMatrix = function (visType, rowLPList, columnLPList, rows, columns, measures, dimensionsInView) { if (rowLPList === void 0) { rowLPList = []; } if (columnLPList === void 0) { columnLPList = []; } return __awaiter(this, void 0, void 0, function () { var rowLen, columnLen, crossMatrix, measureCodeList, i, j, path, dimensionsInView_1, dimensionsInView_1_1, dim, result; var e_13, _a; return __generator(this, function (_b) { switch (_b.label) { case 0: rowLen = rowLPList.length; columnLen = columnLPList.length; crossMatrix = []; measureCodeList = measures.map(function (m) { return m.id; }); i = 0; _b.label = 1; case 1: if (!(i < rowLen)) return [3 /*break*/, 6]; crossMatrix.push([]); j = 0; _b.label = 2; case 2: if (!(j < columnLen)) return [3 /*break*/, 5]; path = __spread(rowLPList[i].map(function (d, index) { return ({ dimCode: rows[index].id, dimValue: d }); }), columnLPList[j].map(function (d, index) { return ({ dimCode: columns[index].id, dimValue: d }); })); try { for (dimensionsInView_1 = (e_13 = void 0, __values(dimensionsInView)), dimensionsInView_1_1 = dimensionsInView_1.next(); !dimensionsInView_1_1.done; dimensionsInView_1_1 = dimensionsInView_1.next()) { dim = dimensionsInView_1_1.value; path.push({ dimCode: dim.id, dimValue: '*' }); } } catch (e_13_1) { e_13 = { error: e_13_1 }; } finally { try { if (dimensionsInView_1_1 && !dimensionsInView_1_1.done && (_a = dimensionsInView_1.return)) _a.call(dimensionsInView_1); } finally { if (e_13) throw e_13.error; } } return [4 /*yield*/, this.cacheQuery(path, measureCodeList)]; case 3: result = _b.sent(); switch (visType) { case 'bar': case 'line': case 'scatter': crossMatrix[i].push(result); break; case 'number': default: crossMatrix[i].push(result[0]); break; } _b.label = 4; case 4: j++; return [3 /*break*/, 2]; case 5: i++; return [3 /*break*/, 1]; case 6: return [2 /*return*/, crossMatrix]; } }); }); }; return AsyncCacheCube; }()); export { AsyncCacheCube }; export function arrayEqual(arr1, arr2) { if (arr1.length !== arr2.length) return false; for (var i = 0; i < arr1.length; i++) { if (arr1[i] !== arr2[i]) return false; } return true; } export function labelHighlightNode(tree, valuePath, hlPath, depth) { var e_14, _a; tree.isHighlight = true; if (tree.children) { try { for (var _b = __values(tree.children), _c = _b.next(); !_c.done; _c = _b.next()) { var child = _c.value; // == not === if (child.id == hlPath[depth]) { labelHighlightNode(child, __spread(valuePath, [child.id]), hlPath, depth + 1); } } } catch (e_14_1) { e_14 = { error: e_14_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_14) throw e_14.error; } } } } export function clearHighlight(tree) { var e_15, _a; tree.isHighlight = false; if (tree.children) { try { for (var _b = __values(tree.children), _c = _b.next(); !_c.done; _c = _b.next()) { var child = _c.value; clearHighlight(child); } } catch (e_15_1) { e_15 = { error: e_15_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_15) throw e_15.error; } } } } //# sourceMappingURL=utils.js.map