Skip to content

Commit

Permalink
fix sorting
Browse files Browse the repository at this point in the history
  • Loading branch information
sgratzl committed Nov 17, 2018
1 parent 0f605da commit 8cdae14
Show file tree
Hide file tree
Showing 12 changed files with 132 additions and 118 deletions.
6 changes: 5 additions & 1 deletion src/model/BooleanColumn.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Category, toolbar} from './annotations';
import CategoricalColumn from './CategoricalColumn';
import Column, {widthChanged, labelChanged, metaDataChanged, dirty, dirtyHeader, dirtyValues, rendererTypeChanged, groupRendererChanged, summaryRendererChanged, visibilityChanged} from './Column';
import Column, {widthChanged, labelChanged, metaDataChanged, dirty, dirtyHeader, dirtyValues, rendererTypeChanged, groupRendererChanged, summaryRendererChanged, visibilityChanged, ECompareValueType} from './Column';
import ValueColumn, {IValueColumnDesc, dataLoaded} from './ValueColumn';
import {ICategoricalColumn, ICategory} from './ICategoricalColumn';
import {IDataRow} from './interfaces';
Expand Down Expand Up @@ -185,6 +185,10 @@ export default class BooleanColumn extends ValueColumn<boolean> implements ICate
return v ? 1 : 0;
}

toCompareValueType() {
return ECompareValueType.BINARY;
}

group(row: IDataRow) {
const enabled = this.getValue(row);
return enabled ? BooleanColumn.GROUP_TRUE : BooleanColumn.GROUP_FALSE;
Expand Down
1 change: 1 addition & 0 deletions src/model/Column.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export declare type ICompareValue = string | number | null;

export enum ECompareValueType {
FLOAT,
BINARY,
UINT,
STRING
}
Expand Down
2 changes: 1 addition & 1 deletion src/model/DateColumn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ export default class DateColumn extends ValueColumn<Date> implements IDateColumn
}

toCompareGroupValueType() {
return ECompareValueType.NUMBER;
return ECompareValueType.UINT;
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/model/Group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import {IGroup} from './interfaces';


export interface IOrderedGroup extends IGroup {
order: number[];
index2pos: number[];
order: Uint32Array;
index2pos: Uint32Array;
}

export const defaultGroup: IGroup = {
Expand Down
2 changes: 1 addition & 1 deletion src/model/GroupColumn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,6 @@ export default class GroupColumn extends Column {
}

toCompareGroupValueType() {
return this.groupSortMethod === 'count' ? ECompareValueType.NUMBER : ECompareValueType.STRING;
return this.groupSortMethod === 'count' ? ECompareValueType.UINT : ECompareValueType.STRING;
}
}
4 changes: 2 additions & 2 deletions src/model/ICategoricalColumn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export function toCompareCategoryValue(v: ICategory | null) {
return [v.value, v.label.toLowerCase()];
}

export const COMPARE_CATEGORY_VALUE_TYPES = [ECompareValueType.NUMBER, ECompareValueType.STRING];
export const COMPARE_CATEGORY_VALUE_TYPES = [ECompareValueType.FLOAT, ECompareValueType.STRING];

function findMostFrequent(rows: IDataRow[], col: ICategoricalColumn): {cat: ICategory | null, count: number} {
const hist = new Map<ICategory | null, number>();
Expand Down Expand Up @@ -151,7 +151,7 @@ export function toGroupCompareCategoryValue(rows: IDataRow[], col: ICategoricalC
return [mostFrequent.cat.value, mostFrequent.cat.label.toLowerCase(), mostFrequent.count];
}

export const COMPARE_GROUP_CATEGORY_VALUE_TYPES = [ECompareValueType.NUMBER, ECompareValueType.STRING, ECompareValueType.NUMBER];
export const COMPARE_GROUP_CATEGORY_VALUE_TYPES = [ECompareValueType.FLOAT, ECompareValueType.STRING, ECompareValueType.UINT];


/** @internal */
Expand Down
2 changes: 1 addition & 1 deletion src/model/NumbersColumn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Column, {widthChanged, labelChanged, metaDataChanged, dirty, dirtyHeader,
import ValueColumn, {dataLoaded} from './ValueColumn';
import {IDataRow} from './interfaces';
import {
compareBoxPlot, DEFAULT_FORMATTER, EAdvancedSortMethod, getBoxPlotNumber, INumberFilter, INumbersColumn,
DEFAULT_FORMATTER, EAdvancedSortMethod, getBoxPlotNumber, INumberFilter, INumbersColumn,
noNumberFilter, isDummyNumberFilter, restoreNumberFilter, toCompareBoxPlotValue
} from './INumberColumn';
import {
Expand Down
120 changes: 71 additions & 49 deletions src/model/Ranking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,33 +110,6 @@ export default class Ranking extends AEventDispatcher implements IColumnParent {
*/
private readonly columns: Column[] = [];

readonly comparator = (a: IDataRow, b: IDataRow) => {
if (this.sortCriteria.length === 0) {
return a.i - b.i;
}
for (const sort of this.sortCriteria) {
const r = sort.col!.compare(a, b);
if (r !== 0) {
return sort.asc ? r : -r;
}
}
return a.i - b.i; //to have a deterministic order
};

readonly groupComparator = (a: IGroupData, b: IGroupData) => {
if (this.groupSortCriteria.length === 0) {
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
}
for (const sort of this.groupSortCriteria) {
const r = sort.col!.groupCompare(a, b);
if (r !== 0) {
return sort.asc ? r : -r;
}
}
return a.name.localeCompare(b.name);
};


readonly grouper = (row: IDataRow): IGroup => {
const g = this.groupColumns;
switch (g.length) {
Expand All @@ -158,7 +131,8 @@ export default class Ranking extends AEventDispatcher implements IColumnParent {
* the current ordering as an sorted array of indices
* @type {Array}
*/
private groups: IOrderedGroup[] = [Object.assign({order: <number[]>[], index2pos: <number[]>[]}, defaultGroup)];
private groups: IOrderedGroup[] = [Object.assign({order: new Uint32Array(0), index2pos: new Uint32Array(0)}, defaultGroup)];
private order = new Uint32Array(0);

constructor(public id: string, private maxSortCriteria = 2, private maxGroupColumns = 1) {
super();
Expand Down Expand Up @@ -214,25 +188,19 @@ export default class Ranking extends AEventDispatcher implements IColumnParent {
}

setGroups(groups: IOrderedGroup[]) {
const old = this.getOrder();
const old = this.order;
const oldGroups = this.groups;
this.groups = groups;
this.fire([Ranking.EVENT_ORDER_CHANGED, Ranking.EVENT_GROUPS_CHANGED, Ranking.EVENT_DIRTY_VALUES, Ranking.EVENT_DIRTY], old, this.getOrder(), oldGroups, groups);
this.order = toOrder(groups);
this.fire([Ranking.EVENT_ORDER_CHANGED, Ranking.EVENT_GROUPS_CHANGED, Ranking.EVENT_DIRTY_VALUES, Ranking.EVENT_DIRTY], old, this.order, oldGroups, groups);
}

getOrder() {
switch (this.groups.length) {
case 0:
return [];
case 1:
return this.groups[0].order;
default:
return (<number[]>[]).concat(...this.groups.map((g) => g.order));
}
return this.order;
}

getOrderLength() {
return this.groups.reduce((a,b) => a + b.order.length, 0);
return this.order.length;
}

getGroups() {
Expand Down Expand Up @@ -288,8 +256,18 @@ export default class Ranking extends AEventDispatcher implements IColumnParent {


toCompareValue(row: IDataRow) {
let vs : ICompareValue[] = [];
vs = vs.concat(...this.sortCriteria.map((d) => d.col.toCompareValue(row)));
if (this.sortCriteria.length === 0) {
return [row.i];
}
const vs : ICompareValue[] = [];
for (const s of this.sortCriteria) {
const r = s.col.toCompareValue(row);
if (Array.isArray(r)) {
vs.push(...r);
} else {
vs.push(r);
}
}
vs.push(row.i);
return vs;
}
Expand All @@ -298,25 +276,51 @@ export default class Ranking extends AEventDispatcher implements IColumnParent {
const vs : {asc: boolean, v: ECompareValueType}[] = [];
for (const s of this.sortCriteria) {
const types = s.col.toCompareValueType();
if (Array.isArray(types)) {
for (const v of types) {
vs.push({asc: s.asc, v});
}
} else {
if (!Array.isArray(types)) {
vs.push({asc: s.asc, v: types});
continue;
}
for (const v of types) {
vs.push({asc: s.asc, v});
}
}
vs.push({asc: true, v: ECompareValueType.NUMBER});
vs.push({asc: true, v: ECompareValueType.UINT});
return vs;
}

toGroupCompareValue(group: IGroupData) {
let vs : (number | string | null)[] = [];
vs = vs.concat(...this.groupSortCriteria.map((d) => d.col.toCompareGroupValue(group)));
if (this.groupSortCriteria.length === 0) {
return [group.name.toLowerCase()];
}
const vs : ICompareValue[] = [];
for (const s of this.groupSortCriteria) {
const r = s.col.toCompareGroupValue(group);
if (Array.isArray(r)) {
vs.push(...r);
} else {
vs.push(r);
}
}
vs.push(group.name.toLowerCase());
return vs;
}

toGroupCompareValueType() {
const vs : {asc: boolean, v: ECompareValueType}[] = [];
for (const s of this.groupSortCriteria) {
const types = s.col.toCompareGroupValueType();
if (!Array.isArray(types)) {
vs.push({asc: s.asc, v: types});
continue;
}
for (const v of types) {
vs.push({asc: s.asc, v});
}
}
vs.push({asc: true, v: ECompareValueType.STRING});
return vs;
}


flatten(r: IFlatColumn[], offset: number, levelsToGo = 0, padding = 0) {
let acc = offset; // + this.getWidth() + padding;
Expand Down Expand Up @@ -767,3 +771,21 @@ function equalCriteria(a: ISortCriteria[], b: ISortCriteria[]) {
return ai.col === bi.col && ai.asc === bi.asc;
});
}

function toOrder(groups: IOrderedGroup[]) {
switch (groups.length) {
case 0:
return new Uint32Array(0);
case 1:
return groups[0].order;
default:
const total = groups.reduce((a, b) => a + b.order.length, 0);
const r = new Uint32Array(total);
let shift = 0;
for (const g of groups) {
r.set(g.order, shift);
shift += g.order.length;
}
return r;
}
}
6 changes: 5 additions & 1 deletion src/model/SelectionColumn.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Category, SupportType, toolbar} from './annotations';
import {IDataRow, IGroup} from './interfaces';
import Column, {widthChanged, labelChanged, metaDataChanged, dirty, dirtyHeader, dirtyValues, rendererTypeChanged, groupRendererChanged, summaryRendererChanged, visibilityChanged} from './Column';
import Column, {widthChanged, labelChanged, metaDataChanged, dirty, dirtyHeader, dirtyValues, rendererTypeChanged, groupRendererChanged, summaryRendererChanged, visibilityChanged, ECompareValueType} from './Column';
import ValueColumn, {IValueColumnDesc, dataLoaded} from './ValueColumn';
import {IEventListener} from '../internal/AEventDispatcher';

Expand Down Expand Up @@ -120,6 +120,10 @@ export default class SelectionColumn extends ValueColumn<boolean> {
return v ? 1 : 0;
}

toCompareValueType() {
return ECompareValueType.BINARY;
}

group(row: IDataRow) {
const isSelected = this.getValue(row);
return isSelected ? SelectionColumn.SELECTED_GROUP : SelectionColumn.NOT_SELECTED_GROUP;
Expand Down
2 changes: 1 addition & 1 deletion src/model/SetColumn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,6 @@ export default class SetColumn extends ValueColumn<string[]> implements IArrayCo
}

toCompareValueType() {
return [ECompareValueType.UINT].concat(this.categories.map(() => ECompareValueType.UINT));
return [ECompareValueType.UINT].concat(this.categories.map(() => ECompareValueType.BINARY));
}
}
Loading

0 comments on commit 8cdae14

Please sign in to comment.