in packages/tablesorter/src/providers/JSONDataProvider.ts [176:277]
private getFilteredData(options: IQueryOptions) {
let final = this.data.slice(0);
// If we are handling filtering, and their is a filter being applied
if (this.handleFilter && options.query && options.query.length) {
options.query.forEach((filter) => {
let filterMethod = JSONDataProvider.checkStringFilter as any;
// There HAS to be some value and a column for us to be able to filter correctly
if (filter.value && filter.column) {
const explictValues = filter.value && (<IExplicitFilter>filter.value).values;
const filteredDomain = filter.value && (<INumericalFilter>filter.value).domain;
if (explictValues) {
filterMethod = JSONDataProvider.checkExplicitFilter as any;
// A numerical filter
} else if (filteredDomain) {
const actualDomain = this.domains[filter.column];
// If the filtered domain is ACTUALLY different from the full domain, then filter
// This case is specifically for null values, if the dataset contains null values
// and we apply a filter with the same domain as the actual domain, then null values get filtered
// out since they don't actually fall within the domain
if (filteredDomain[0] !== actualDomain[0] || filteredDomain[1] !== actualDomain[1]) {
filterMethod = JSONDataProvider.checkNumberFilter as any;
} else {
// Otherwise, we don't need a filter
filterMethod = undefined;
}
}
final = final.filter((item) => !filterMethod || filterMethod(item, filter));
}
});
}
// If we are handling sort, and there is a sort applied to tablesorter
if (this.handleSort && options.sort && options.sort.length) {
const sortItem = options.sort[0];
const basicSort = (aValue: any, bValue: any, asc: boolean) => {
const dir = asc ? 1 : -1;
/* tslint:disable */
if (aValue == bValue) {
/* tslint:enable */
return 0;
}
return (aValue > bValue ? 1 : -1) * dir;
};
const calcStackedValue = (
item: any,
sortToCheck: ITableSorterSort,
minMax: { [col: string]: { min: number, max: number }}) => {
const columns = sortToCheck.stack.columns;
if (columns) {
const sortVal = columns.reduce((a, v) => {
/**
* This calculates the percent that this guy is of the max value
*/
const min = minMax[v.column].min || 0;
const max = minMax[v.column].max || min;
let value = item[v.column];
// We only need to do the actual weighting with items that have values
if (value !== null && value !== undefined) { //tslint:disable-line
// The max is the min, in this case, the value should be 100% (or 1)
if (max === min) {
value = 1;
} else {
value = ((value - min) / (max - min));
}
return a + (value * v.weight);
}
// Null/undefined values have no value, so just ignore them
return a;
}, 0);
return sortVal;
}
return 0;
};
let maxValues: { [col: string]: { min: number, max: number }};
if (sortItem.stack) {
maxValues = sortItem.stack.columns.reduce((a, b) => {
const [min, max] = this.domains[b.column];
a[b.column] = {
max,
min,
};
return a;
}, <any>{});
}
final.sort((a, b) => {
if (sortItem.stack) {
return basicSort(calcStackedValue(a, sortItem, maxValues), calcStackedValue(b, sortItem, maxValues), sortItem.asc);
}
return basicSort(a[sortItem.column], b[sortItem.column], sortItem.asc);
});
}
return final;
}