UNPKG

@gooddata/react-components

Version:

GoodData.UI - A powerful JavaScript library for building analytical applications

151 lines (123 loc) 4.72 kB
// (C) 2007-2018 GoodData Corporation import max = require("lodash/max"); import { IGridRow } from "./agGridTypes"; import { isMappingHeaderAttributeItem } from "../../../interfaces/MappingHeader"; interface IAttributesRowItemUris { [columnId: string]: string[]; } interface IAttributesRowItemRepetitions { [columnId: string]: boolean[]; } export interface IGroupingProvider { reset: () => void; isRepeatedValue: (columnId: string, rowIndex: number) => boolean; isGroupBoundary: (rowIndex: number) => boolean; isColumnWithGrouping: (columnId: string) => boolean; processPage: (pageRows: IGridRow[], rowOffset: number, columnIds: string[]) => void; } class DefaultGroupingProvider implements IGroupingProvider { // tslint:disable-next-line:no-empty public reset() {} public isGroupBoundary(_rowIndex: number) { return false; } public isColumnWithGrouping(_columnId: string) { return false; } // tslint:disable-next-line:no-empty public processPage(_pageRows: IGridRow[], _rowOffset: number, _columnIds: string[]) {} public isRepeatedValue(_columnId: string, _rowIndex: number) { return false; } } class AttributeGroupingProvider implements IGroupingProvider { private itemUris: IAttributesRowItemUris; private itemRepetitions: IAttributesRowItemRepetitions; private repetitionsCounts: number[]; private maxRepetitions: number; constructor() { this.reset(); } public reset() { this.itemUris = {}; this.itemRepetitions = {}; this.repetitionsCounts = []; this.maxRepetitions = 0; } public isRepeatedValue(columnId: string, rowIndex: number) { if (this.itemRepetitions[columnId]) { return this.itemRepetitions[columnId][rowIndex] === true; } return false; } public isGroupBoundary(rowIndex: number) { return ( !!this.repetitionsCounts && (this.repetitionsCounts[rowIndex] === undefined || this.repetitionsCounts[rowIndex] < this.maxRepetitions) ); } public isColumnWithGrouping(columnId: string) { return Object.keys(this.itemRepetitions).indexOf(columnId) < this.maxRepetitions; } public processPage(pageRows: IGridRow[], rowOffset: number, columnIds: string[]) { columnIds.forEach(columnId => { if (!this.itemUris[columnId]) { this.itemUris[columnId] = []; } pageRows.forEach((row: IGridRow, rowIndex: number) => { const headerItem = row.headerItemMap[columnId]; if (isMappingHeaderAttributeItem(headerItem)) { const attributeItemUri = headerItem.attributeHeaderItem.uri; this.itemUris[columnId][rowIndex + rowOffset] = attributeItemUri; } }); }); this.update(); } private update() { this.repetitionsCounts = null; this.maxRepetitions = 0; let previousColumnId: string = null; Object.keys(this.itemUris).forEach(columnId => { const rowCount = this.itemUris[columnId].length; this.itemRepetitions[columnId] = Array(rowCount).fill(false); if (this.repetitionsCounts === null) { this.repetitionsCounts = Array(rowCount).fill(0); } this.updateAttributeColumn( this.itemUris[columnId], this.itemRepetitions[columnId], previousColumnId !== null ? this.itemRepetitions[previousColumnId] : null, ); previousColumnId = columnId; }); this.maxRepetitions = max(this.repetitionsCounts); } private updateAttributeColumn( itemUris: string[], itemRepetitions: boolean[], previousAttributeItemRepetitions: boolean[], ) { let previousItemUri: string = null; itemUris.forEach((itemUri, rowIndex) => { let repeatedItem = previousItemUri === itemUri; if (previousAttributeItemRepetitions !== null) { repeatedItem = repeatedItem && previousAttributeItemRepetitions[rowIndex]; } if (repeatedItem) { itemRepetitions[rowIndex] = true; this.repetitionsCounts[rowIndex] += 1; } previousItemUri = itemUri; }); } } export class GroupingProviderFactory { public static createProvider(groupRows: boolean): IGroupingProvider { if (groupRows) { return new AttributeGroupingProvider(); } return new DefaultGroupingProvider(); } }