Skip to content

Commit

Permalink
working version
Browse files Browse the repository at this point in the history
  • Loading branch information
sgratzl committed Dec 27, 2018
1 parent 68c4637 commit 8c843e7
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 79 deletions.
24 changes: 13 additions & 11 deletions src/model/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,37 +101,39 @@ export function isOrderedGroup(g: IOrderedGroup | Readonly<IGroupParent>): g is
return (<IOrderedGroup>g).order != null;
}

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

function toItemMeta(item: IGroupItem): IGroupMeta {
if (item.relativeIndex === 0) {
return item.group.order.length === 1 ? 'first last' : 'first';
export function toItemMeta(relativeIndex: number, group: IOrderedGroup): IGroupMeta {
if (relativeIndex === 0) {
return group.order.length === 1 ? 'first last' : 'first';
}
if (item.relativeIndex === item.group.order.length - 1) {
if (relativeIndex === group.order.length - 1) {
return 'last';
}
return null;
}

function groupParents(group: IGroup, meta: IGroupMeta) {
export function groupParents(group: IGroup, meta: IGroupMeta) {
const parents: {group: IGroup, meta: IGroupMeta}[] = [{group, meta}];

let prev = group;
let prevMeta = meta;
let parent: IGroupParent | undefined | null = group.parent;

while (parent) {
if (parent.subGroups.length === 1) {
if (parent.subGroups.length === 1 && (prevMeta === 'first last')) {
meta = 'first last';
} else if (parent.subGroups[0] === prev) {
} else if (parent.subGroups[0] === prev && (prevMeta === 'first last' || prevMeta === 'first')) {
meta = 'first';
} else if (parent.subGroups[parent.subGroups.length - 1] === prev) {
} else if (parent.subGroups[parent.subGroups.length - 1] === prev && (prevMeta === 'last' || prevMeta === 'first last')) {
meta = 'last';
} else {
meta = null;
}
parents.unshift({group: parent, meta});

prev = parent;
prevMeta = meta;
parent = parent.parent;
}
return parents;
Expand All @@ -141,7 +143,7 @@ function groupParents(group: IGroup, meta: IGroupMeta) {
* number of group levels this items ends
*/
export function groupEndLevel(item: IGroupData | IGroupItem) {
const last = isGroup(item) ? 'first last' : toItemMeta(item);
const last = isGroup(item) ? 'first last' : toItemMeta(item.relativeIndex, item.group);
if (last !== 'last' && last !== 'first last') {
return 0;
}
Expand All @@ -165,7 +167,7 @@ export function groupEndLevel(item: IGroupData | IGroupItem) {
}

export function toRowMeta(item: IGroupData | IGroupItem): string | null {
const last = isGroup(item) ? 'first last' : toItemMeta(item);
const last = isGroup(item) ? 'first last' : toItemMeta(item.relativeIndex, item.group);
if (last == null) {
return null;
}
Expand Down
112 changes: 57 additions & 55 deletions src/renderer/AggregateGroupRenderer.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import {IDataRow, IGroup, Column, AggregateGroupColumn, EAggregationState, IGroupParent, IOrderedGroup} from '../model';
import {IDataRow, IGroup, Column, AggregateGroupColumn, EAggregationState, IOrderedGroup} from '../model';
import {AGGREGATE, CANVAS_HEIGHT, cssClass} from '../styles';
import {IRenderContext, ICellRendererFactory} from './interfaces';
import {groupParents, toItemMeta} from '../model/internal';

function preventDefault(event: Event) {
event.preventDefault();
event.stopPropagation();
}

function matchNodes(node: HTMLElement, group: IGroup, meta: IGroupMeta, col: AggregateGroupColumn) {
const parents = groupParents(group, meta);
function matchNodes(node: HTMLElement, group: IOrderedGroup, relativeIndex: number, col: AggregateGroupColumn) {
const parents = groupParents(group, relativeIndex >= 0 ? toItemMeta(relativeIndex, group) : 'first last');
const doc = node.ownerDocument!;
const children = <HTMLElement[]>Array.from(node.children);
// add missing
Expand Down Expand Up @@ -58,11 +59,12 @@ export default class AggregateGroupRenderer implements ICellRendererFactory {
const width = context.colWidth(col);
return {
template: `<div><div class="${cssClass('agg-level')}"></div></div>`,
update(node: HTMLElement, _row: IDataRow, _i: number, group: IOrderedGroup) {
// matchNodes(node, group, meta, col);
update(node: HTMLElement, _row: IDataRow, i: number, group: IOrderedGroup) {
matchNodes(node, group, i, col);
},
render(ctx: CanvasRenderingContext2D, _row: IDataRow, _i: number, _group: IGroup) {
ctx.fillStyle = AGGREGATE.color;
// TODO draw all lines
ctx.fillRect(width - AGGREGATE.width, 0, AGGREGATE.strokeWidth, CANVAS_HEIGHT);
return Boolean(false);
}
Expand All @@ -74,7 +76,7 @@ export default class AggregateGroupRenderer implements ICellRendererFactory {
return {
template: `<div><div class="${cssClass('agg-level')}"></div></div>`,
update(node: HTMLElement, group: IOrderedGroup) {
// matchNodes(node, group, meta, col);
matchNodes(node, group, -1, col);

// const children = <HTMLElement[]>Array.from(node.children);

Expand Down Expand Up @@ -129,55 +131,55 @@ export default class AggregateGroupRenderer implements ICellRendererFactory {
return {
template: `<div><div class="${cssClass('agg-expand')}" title="Expand All Groups"></div><div class="${cssClass('agg-all')}" title="Show All"></div></div>`,
update: (node: HTMLElement) => {
const ranking = col.findMyRanker()!;
const groups = ranking.getGroups();

const toggleAggregate = <HTMLElement>node.firstElementChild!;
const toggleMore = <HTMLElement>node.lastElementChild!;

const isGroupOnly = groups.every((g) => col.isAggregated(g) === 'collapse');
const meta: IGroupMeta = groups.length <= 1 ? null : (isGroupOnly ? 'first last' : 'first top');
const isTopX = meta === 'first top';
const isShowAll = !isGroupOnly && !isTopX;

node.dataset.meta = meta!;
if (isShowAll) {
// expanded
toggleAggregate.title = 'Collapse Group';
toggleMore.title = 'Show Top';
} else if (isGroupOnly) {
// collapse
toggleAggregate.title = 'Expand Group';
toggleMore.title = 'Show Top';
} else {
// show top
toggleAggregate.title = 'Collapse Group';
toggleMore.title = 'Show All';
}

toggleAggregate.classList.toggle(cssClass('agg-collapse'), isGroupOnly);
toggleAggregate.onclick = function (event) {
preventDefault(event);
const ranking = col.findMyRanker();
if (!ranking || !context) {
return;
}

const meta = node.dataset.meta!;
node.dataset.meta = meta === 'first last' ? 'first top' : 'first last';
context.provider.aggregateAllOf(ranking, meta === 'first last' ? EAggregationState.EXPAND_TOP_N : EAggregationState.COLLAPSE);
};
toggleMore.onclick = function (event) {
preventDefault(event);
const ranking = col.findMyRanker();
if (!ranking || !context) {
return;
}

const meta = node.dataset.meta!;
node.dataset.meta = meta === 'first top' ? 'first' : 'first top';
context.provider.aggregateAllOf(ranking, meta === 'first top' ? EAggregationState.EXPAND : EAggregationState.EXPAND_TOP_N);
};
// const ranking = col.findMyRanker()!;
// const groups = ranking.getGroups();

// const toggleAggregate = <HTMLElement>node.firstElementChild!;
// const toggleMore = <HTMLElement>node.lastElementChild!;

// const isGroupOnly = groups.every((g) => col.isAggregated(g) === 'collapse');
// const meta: IGroupMeta = groups.length <= 1 ? null : (isGroupOnly ? 'first last' : 'first top');
// const isTopX = meta === 'first top';
// const isShowAll = !isGroupOnly && !isTopX;

// node.dataset.meta = meta!;
// if (isShowAll) {
// // expanded
// toggleAggregate.title = 'Collapse Group';
// toggleMore.title = 'Show Top';
// } else if (isGroupOnly) {
// // collapse
// toggleAggregate.title = 'Expand Group';
// toggleMore.title = 'Show Top';
// } else {
// // show top
// toggleAggregate.title = 'Collapse Group';
// toggleMore.title = 'Show All';
// }

// toggleAggregate.classList.toggle(cssClass('agg-collapse'), isGroupOnly);
// toggleAggregate.onclick = function (event) {
// preventDefault(event);
// const ranking = col.findMyRanker();
// if (!ranking || !context) {
// return;
// }

// const meta = node.dataset.meta!;
// node.dataset.meta = meta === 'first last' ? 'first top' : 'first last';
// context.provider.aggregateAllOf(ranking, meta === 'first last' ? EAggregationState.EXPAND_TOP_N : EAggregationState.COLLAPSE);
// };
// toggleMore.onclick = function (event) {
// preventDefault(event);
// const ranking = col.findMyRanker();
// if (!ranking || !context) {
// return;
// }

// const meta = node.dataset.meta!;
// node.dataset.meta = meta === 'first top' ? 'first' : 'first top';
// context.provider.aggregateAllOf(ranking, meta === 'first top' ? EAggregationState.EXPAND : EAggregationState.EXPAND_TOP_N);
// };
}
};
}
Expand Down
7 changes: 1 addition & 6 deletions src/styles/renderer/_aggregate.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,12 @@
pointer-events: none;
position: absolute;
left: 2px;
top: -2px; // TODO right padding
bottom: 0;
width: $lu_aggregate_square_bracket_width;
border-left: $lu_aggregate_square_bracket_stroke_width solid $lu_aggregate_square_bracket_stroke_color;
}

&[data-level='1']::after {
top: -7px; // TODO right padding
}

&[data-meta~=first]::after {
&[data-level][data-meta~=first]::after {
top: 0;
border-top: $lu_aggregate_square_bracket_stroke_width solid $lu_aggregate_square_bracket_stroke_color;
}
Expand Down
24 changes: 19 additions & 5 deletions src/ui/EngineRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,30 @@ export default class EngineRenderer extends AEventDispatcher {

//apply rules
{

this.style.addRule('lineup_rowPadding0', `
.${this.style.cssClasses.tr}`, {
marginTop: `${options.rowPadding}px`
});

for (let level = 0; level < 4; ++level) {
this.style.addRule(`lineup_groupPadding${level}`, `
.${this.style.cssClasses.tr}[data-meta~=last${level === 0 ? '': level}]`, {
.${this.style.cssClasses.tr}[data-meta~=last${level === 0 ? '' : level}]`, {
marginBottom: `${options.groupPadding * (level + 1)}px`
});
});
}
this.style.addRule('lineup_rowPadding0', `
.${this.style.cssClasses.tr}`, {
marginTop: `${options.rowPadding}px`


this.style.addRule('lineup_rowPaddingAgg0', `
.${cssClass('agg-level')}::after`, {
top: `-${options.rowPadding}px`
});
for (let level = 1; level <= 4; ++level) {
this.style.addRule(`lineup_rowPaddingAgg${level}`, `
.${cssClass('agg-level')}[data-level='${level}']::after`, {
top: `-${options.rowPadding + options.groupPadding}px`
});
}

// FIXME flat
this.style.addRule('lineup_rotation', `
Expand Down
4 changes: 2 additions & 2 deletions src/ui/taggle/rules.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {IGroupData, IGroupItem, isGroup} from '../../model';
import {groupEndLevel} from '../../model/internal';

export interface IRule {
apply(data: (IGroupData | IGroupItem)[], availableHeight: number, selection: Set<number>): IRuleInstance;
Expand Down Expand Up @@ -27,10 +28,9 @@ export function spaceFillingRule(config: {groupHeight: number, rowHeight: number
const visibleHeight = availableHeight - config.rowHeight - 5; // some padding for hover
const items = <IGroupItem[]>data.filter((d) => !isGroup(d));
const groups = data.length - items.length;
const lastItems = items.reduce((a, d) => a + (d.meta === 'last' || d.meta === 'first last' ? 1 : 0), 0);
const selected = items.reduce((a, d) => a + (selection.has(d.dataIndex) ? 1 : 0), 0);
const unselected = items.length - selected;
const groupSeparators = groups + lastItems;
const groupSeparators = items.reduce((a, d) => a + groupEndLevel(d), 0);

if (unselected <= 0) {
// doesn't matter since all are selected anyhow
Expand Down

0 comments on commit 8c843e7

Please sign in to comment.