@darwino/darwino
Version:
A set of Javascript classes and utilities
138 lines (123 loc) • 4.18 kB
JavaScript
/*
* (c) Copyright Darwino Inc. 2014-2017.
*/
/*
* Data coming from a cursor.
*/
export default class CursorEntries {
constructor(rawData) {
this.rawData = rawData
this.uncategorized = "(Not Categorized)"
}
getRows() {
if(!this.data) {
this._processRows()
}
return this.data;
}
_processRows() {
if(!this.rawData) {
this.data = [];
return;
}
if(!this.groupColumns && !this.processFct && !this.filter && !this.sort) {
this.data = this.rawData;
return;
}
this.data = null;
// 1- We should filter out the rows
if(this.filter) {
this.data = (this.data||this.rawData).filter(this.filter);
}
// 2- Sort for the groups and the sort order
if(this.groupColumns || this.sortColumns) {
if(this.inMemorySort) {
this.data = this._inMemorySort(this.data||this.rawData.slice(0));
}
}
// 3- We should create the groups
if(this.groupColumns) {
this.data = this._groupRows(this.data||this.rawData,0);
}
if(this.processFct) {
const fakegroup = {__meta: {indentLevel: -1, children:this.data||this.rawData.slice(0)}}
this._processGroup(fakegroup,[])
this.data = fakegroup.__meta.children
}
}
_inMemorySort(rows) {
return rows.sort((r1,r2) => {
if(this.groupColumns) {
for(let i=0; i<this.groupColumns.length; i++) {
const desc = this.groupColumns[i].descending || false
const v1 = (desc ? r2 : r1)[this.groupColumns[i].column]
const v2 = (desc ? r1 : r2)[this.groupColumns[i].column]
if(v1<v2) return -1;
if(v1>v2) return 1;
}
}
if(this.sortColumns) {
for(let i=0; i<this.sortColumns.length; i++) {
const desc = this.sortColumns[i].descending || false
const v1 = (desc ? r2 : r1)[this.sortColumns[i].column]
const v2 = (desc ? r1 : r2)[this.sortColumns[i].column]
if(v1<v2) return -1;
if(v1>v2) return 1;
}
}
return 0;
});
}
_groupRows(rows,colIdx) {
const groups = {}
const list = []
if(this.groupColumns[colIdx]) {
const column = this.groupColumns[colIdx].column
rows.forEach((row) => {
const key = row[column]||this.uncategorized
row.__meta.indentLevel = colIdx+1
let g = groups[key];
if(!g) {
g = groups[key] = {
key,
__meta: {
category: true,
indentLevel: colIdx,
group: true,
children: []
}
}
list.push(g)
}
g.__meta.children.push(row);
})
}
if(colIdx+1<this.groupColumns.length) {
list.forEach((group) => {
group.__meta.children = this._groupRows(group.__meta.children,colIdx+1)
});
}
return list;
}
_processGroup(group,groups) {
// deeper groups calculated first
if(group.__meta.indentLevel<this.groupColumns.length-1) {
const children = group.__meta.children;
children.forEach((row) => {
if(row.__meta.category) {
this._processGroup(row,[...groups,group])
}
});
}
this.processFct(group,groups)
}
groupBy(columns) {
this.groupColumns = columns
}
sortBy(columns) {
this.sortColumns = columns
}
processEntries(processFct) {
this.processFct = processFct
}
}