Skip to content

Commit

Permalink
implement different states
Browse files Browse the repository at this point in the history
  • Loading branch information
sgratzl committed Dec 14, 2018
1 parent 1603620 commit 2b55c50
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 63 deletions.
11 changes: 5 additions & 6 deletions src/model/AggregateGroupColumn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@ export function createAggregateDesc(label: string = 'Aggregate Groups') {
}

export interface IAggregateGroupColumnDesc extends IColumnDesc {
// -1 = no, 0 = fully aggregated, N = show top N
isAggregated(ranking: Ranking, group: IGroup): number;
isAggregated(ranking: Ranking, group: IGroup): 'collapse' | 'expand' | 'expand_top';

setAggregated(ranking: Ranking, group: IGroup, value: number): void;
setAggregated(ranking: Ranking, group: IGroup, value: 'collapse' | 'expand' | 'expand_top'): void;
}

/**
Expand Down Expand Up @@ -74,8 +73,8 @@ export default class AggregateGroupColumn extends Column {
return false;
}

setAggregated(group: IGroup, value: boolean | number) {
const n = typeof value === 'boolean' ? (value ? 0 : -1): value;
setAggregated(group: IGroup, value: boolean | 'collapse' | 'expand' | 'expand_top') {
const n = typeof value === 'boolean' ? (value ? 'expand' : 'collapse'): value;
const ranking = this.findMyRanker()!;
const current = ((<IAggregateGroupColumnDesc>this.desc).isAggregated) && (<IAggregateGroupColumnDesc>this.desc).isAggregated(ranking, group);
if (current === n) {
Expand All @@ -85,7 +84,7 @@ export default class AggregateGroupColumn extends Column {
if ((<IAggregateGroupColumnDesc>this.desc).setAggregated) {
(<IAggregateGroupColumnDesc>this.desc).setAggregated(ranking, group, n);
}
this.fire(AggregateGroupColumn.EVENT_AGGREGATE, ranking, group, n >= 0, n);
this.fire(AggregateGroupColumn.EVENT_AGGREGATE, ranking, group, n !== 'collapse', n);
return false;
}
}
2 changes: 1 addition & 1 deletion src/model/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export interface IGroupParent extends IGroup {
subGroups: (Readonly<IGroupParent> | Readonly<IGroup>)[];
}

export declare type IGroupMeta = 'first' | 'last' | 'first last' | 'inner' | null;
export declare type IGroupMeta = 'first' | 'last' | 'first last' | 'inner' | 'first top' | null;

export interface IGroupItem {
readonly dataIndex: number;
Expand Down
34 changes: 27 additions & 7 deletions src/provider/ADataProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ abstract class ADataProvider extends AEventDispatcher implements IDataProvider {
private readonly selection = new OrderedSet<number>();

//Map<ranking.id@group.name, showTopN>
private readonly aggregations = new Map<string, number>();
private readonly aggregations = new Map<string, number>(); // not part of = show all

private uid = 0;

Expand Down Expand Up @@ -288,6 +288,7 @@ abstract class ADataProvider extends AEventDispatcher implements IDataProvider {
const reason = dirtyReason || [EDirtyReason.UNKNOWN];
Promise.resolve(this.sort(ranking, reason)).then(({groups, index2pos}) => {
unifyParents(groups);
this.initAggregateState(ranking, groups);
ranking.setGroups(groups, index2pos, reason);
this.fireBusy(false);
});
Expand Down Expand Up @@ -421,8 +422,8 @@ abstract class ADataProvider extends AEventDispatcher implements IDataProvider {
(<ISelectionColumnDesc>desc).setter = (index: number, value: boolean) => value ? this.select(index) : this.deselect(index);
(<ISelectionColumnDesc>desc).setterAll = (indices: IndicesArray, value: boolean) => value ? this.selectAll(indices) : this.deselectAll(indices);
} else if (desc.type === 'aggregate') {
(<IAggregateGroupColumnDesc>desc).isAggregated = (ranking: Ranking, group: IGroup) => this.getTopNAggregated(ranking, group);
(<IAggregateGroupColumnDesc>desc).setAggregated = (ranking: Ranking, group: IGroup, value: number) => this.setTopNAggregated(ranking, group, value);
(<IAggregateGroupColumnDesc>desc).isAggregated = (ranking: Ranking, group: IGroup) => this.getAggregatedState(ranking, group);
(<IAggregateGroupColumnDesc>desc).setAggregated = (ranking: Ranking, group: IGroup, value: 'expand' | 'collapse' | 'expand_top') => this.setAggregateState(ranking, group, value);
}
return desc;
}
Expand Down Expand Up @@ -632,6 +633,15 @@ abstract class ADataProvider extends AEventDispatcher implements IDataProvider {
return this.getTopNAggregated(ranking, group) >= 0;
}

getAggregatedState(ranking: Ranking, group: IGroup) {
const n = this.getTopNAggregated(ranking, group);
return n < 0 ? 'expand' : (n === 0 ? 'collapse' : 'expand_top');
}

setAggregateState(ranking: Ranking, group: IGroup, value: 'collapse' | 'expand' | 'expand_top') {
this.setTopNAggregated(ranking, group, value === 'collapse' ? 0 : (value === 'expand' ? -1 : this.showTopN));
}

getTopNAggregated(ranking: Ranking, group: IGroup) {
let g: IGroup | undefined | null = group;
while (g) {
Expand All @@ -644,7 +654,7 @@ abstract class ADataProvider extends AEventDispatcher implements IDataProvider {
}
g = g.parent;
}
return this.showTopN;
return -1;
}

private unaggregateParents(ranking: Ranking, group: IGroup) {
Expand All @@ -655,6 +665,16 @@ abstract class ADataProvider extends AEventDispatcher implements IDataProvider {
}
}

private initAggregateState(ranking: Ranking, groups: IGroup[]) {
// by default show top N
for (const group of groups) {
const key = `${ranking.id}@${toGroupID(group)}`;
if (!this.aggregations.has(key)) {
this.aggregations.set(key, this.showTopN);
}
}
}

setAggregated(ranking: Ranking, group: IGroup, value: boolean) {
return this.setTopNAggregated(ranking, group, value ? 0 : -1);
}
Expand All @@ -677,19 +697,19 @@ abstract class ADataProvider extends AEventDispatcher implements IDataProvider {
aggregateAllOf(ranking: Ranking, aggregateAll: boolean | number) {
const v = typeof aggregateAll === 'boolean' ? (aggregateAll ? 0 : -1) : aggregateAll;
const groups = ranking.getGroups();
groups.forEach((group) => {
for(const group of groups) {
this.unaggregateParents(ranking, group);
const current = this.getTopNAggregated(ranking, group);
if (current === v) {
return;
continue;
}
const key = `${ranking.id}@${toGroupID(group)}`;
if (v >= 0) {
this.aggregations.set(key, v);
} else {
this.aggregations.delete(key);
}
});
}
this.fire([ADataProvider.EVENT_GROUP_AGGREGATION_CHANGED, ADataProvider.EVENT_DIRTY_VALUES, ADataProvider.EVENT_DIRTY], ranking, groups, v >= 0, v);
}

Expand Down
21 changes: 10 additions & 11 deletions src/renderer/AggregateGroupRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,22 @@ export default class AggregateGroupRenderer implements ICellRendererFactory {
};
}

createGroup(col: AggregateGroupColumn, context: IRenderContext) {
createGroup(col: AggregateGroupColumn) {
return {
template: `<div><div title="Expand Group"></div><div title="Show All | Show Top ${AGGREGATE_TO_TOP}"></div></div>`,
update(node: HTMLElement, group: IGroup, meta: IGroupMeta) {
const toggleAggregate = <HTMLElement>node.firstElementChild!;
const toggleMore = <HTMLElement>node.lastElementChild!;

const agg = context.provider.getTopNAggregated(col.findMyRanker()!, group);
if (agg < 0) {
const isGroupOnly = meta === 'first last';
const isTopX = meta === 'first top';
const isShowAll = !isGroupOnly && !isTopX;

if (isShowAll) {
// expanded
toggleAggregate.title = 'Collapse Group';
toggleMore.title = 'Show Top';
} else if (agg === 0) {
} else if (isGroupOnly) {
// collapse
toggleAggregate.title = 'Expand Group';
toggleMore.title = 'Show Top';
Expand All @@ -54,20 +57,16 @@ export default class AggregateGroupRenderer implements ICellRendererFactory {
toggleAggregate.title = 'Collapse Group';
toggleMore.title = 'Show All';
}
if (!meta) {
delete node.dataset.meta;
} else {
node.dataset.meta = meta;
}
node.dataset.meta = meta!;
toggleAggregate.onclick = function (event) {
event.preventDefault();
event.stopPropagation();
col.setAggregated(group, false);
col.setAggregated(group, isGroupOnly ? 'expand_top' : 'collapse');
};
toggleMore.onclick = function (event) {
event.preventDefault();
event.stopPropagation();
col.setAggregated(group, false);
col.setAggregated(group, isShowAll ? 'expand_top' : 'expand');
};
}
};
Expand Down
101 changes: 65 additions & 36 deletions src/styles/renderer/_aggregate.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,59 +5,88 @@
text-align: center;
overflow-x: unset;

&::after {
// content: '';
position: absolute;
pointer-events: none;
top: -2px; // FIXME right padding
width: $lu_aggregate_square_bracket_width;
right: 0;
bottom: 0;
border-left: $lu_aggregate_square_bracket_stroke_width solid $lu_aggregate_square_bracket_stroke_color;
box-sizing: border-box;
}
// &::after {
// // content: '';
// position: absolute;
// pointer-events: none;
// top: -2px; // FIXME right padding
// width: $lu_aggregate_square_bracket_width;
// right: 0;
// bottom: 0;
// border-left: $lu_aggregate_square_bracket_stroke_width solid $lu_aggregate_square_bracket_stroke_color;
// box-sizing: border-box;
// }
}

.#{$lu_css_prefix}-renderer-aggregate.#{$lu_css_prefix}-low::after {
border-left: none;
}
// .#{$lu_css_prefix}-renderer-aggregate.#{$lu_css_prefix}-low::after {
// content: unset;
// }

.#{$lu_css_prefix}-renderer-aggregate[data-meta~=first] {
cursor: pointer;

&::before {
@include lu_icons();
> :first-child {
cursor: pointer;

content: $lu_icon_caret_down;
padding-right: $lu_aggregate_square_bracket_width;
}
&::before {
@include lu_icons();

&::after {
top: 0;
border-top: $lu_aggregate_square_bracket_stroke_width solid $lu_aggregate_square_bracket_stroke_color;
content: $lu_icon_caret_down;
padding-right: $lu_aggregate_square_bracket_width;
}
}
}

.#{$lu_css_prefix}-renderer-aggregate[data-meta=last] {
&::after {
border-bottom: $lu_aggregate_square_bracket_stroke_width solid $lu_aggregate_square_bracket_stroke_color;
> :last-child {
cursor: pointer;

&::before {
@include lu_icons();

content: $lu_icon_ellipsis_h;
transform: rotate(270);
padding-right: $lu_aggregate_square_bracket_width;
}
}

// &::after {
// top: 0;
// border-top: $lu_aggregate_square_bracket_stroke_width solid $lu_aggregate_square_bracket_stroke_color;
// }
}

.#{$lu_css_prefix}-renderer-aggregate[data-meta='first last'] {
padding-right: $lu_aggregate_square_bracket_width;
cursor: pointer;
> :first-child::before {
content: $lu_icon_caret_right;
}

&::after {
top: 0;
border-top: $lu_aggregate_square_bracket_stroke_width solid $lu_aggregate_square_bracket_stroke_color;
border-bottom: $lu_aggregate_square_bracket_stroke_width solid $lu_aggregate_square_bracket_stroke_color;
> :last-child::before {
content: unset;
}
}

.#{$lu_css_prefix}-group.#{$lu_css_prefix}-renderer-aggregate::before {
content: $lu_icon_caret_right;
}
// .#{$lu_css_prefix}-renderer-aggregate[data-meta=last] {
// &::after {
// border-bottom: $lu_aggregate_square_bracket_stroke_width solid $lu_aggregate_square_bracket_stroke_color;
// }
// }

// .#{$lu_css_prefix}-renderer-aggregate[data-meta=inner] {
// &::after {
// border-bottom: $lu_aggregate_square_bracket_stroke_width solid $lu_aggregate_square_bracket_stroke_color;
// }
// }


// .#{$lu_css_prefix}-renderer-aggregate[data-meta='first last'] {
// padding-right: $lu_aggregate_square_bracket_width;
// cursor: pointer;

// // &::after {
// // top: 0;
// // border-top: $lu_aggregate_square_bracket_stroke_width solid $lu_aggregate_square_bracket_stroke_color;
// // border-bottom: $lu_aggregate_square_bracket_stroke_width solid $lu_aggregate_square_bracket_stroke_color;
// // }
// }


.#{$lu_css_prefix}-summary.#{$lu_css_prefix}-renderer-aggregate {
padding-right: $lu_aggregate_square_bracket_width;
Expand Down
4 changes: 2 additions & 2 deletions src/ui/EngineRanking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {IExceptionContext, nonUniformContext, uniformContext, PrefetchMixin, Gri
import {HOVER_DELAY_SHOW_DETAIL} from '../config';
import AEventDispatcher, {IEventContext, IEventHandler, IEventListener} from '../internal/AEventDispatcher';
import debounce from '../internal/debounce';
import {IGroupData, IGroupItem, isGroup, isMultiLevelColumn, toGroupMeta, defaultGroup, IGroupMeta, IOrderedGroup} from '../model';
import {IGroupData, IGroupItem, isGroup, isMultiLevelColumn, defaultGroup, IGroupMeta, IOrderedGroup} from '../model';
import Column from '../model/Column';
import Ranking from '../model/Ranking';
import StackColumn from '../model/StackColumn';
Expand Down Expand Up @@ -852,7 +852,7 @@ export default class EngineRanking extends ACellTableSection<RenderColumn> imple
const n = provider.getTopNAggregated(this.ranking, group);

// always the group for stratified datasets
r.push(Object.assign({meta: <IGroupMeta>(n === 0 ? `first last` : `first`)}, group));
r.push(Object.assign({meta: <IGroupMeta>(n === 0 ? `first last` : (n > 0 ? 'first top' : `first`))}, group));

const slice = Math.min(n >= 0 ? n : Number.POSITIVE_INFINITY, length);

Expand Down

0 comments on commit 2b55c50

Please sign in to comment.