Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
domdir committed Oct 7, 2018
1 parent 80fc751 commit 56c676a
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 86 deletions.
71 changes: 25 additions & 46 deletions src/ui/CanvasTextureRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export interface ITextureRenderer {

export default class CanvasTextureRenderer implements ITextureRenderer {
static readonly MAX_CANVAS_SIZE = 32767;
static readonly AGGRIGATED_ROW_HEIGHT = 45;

readonly node: HTMLElement;
readonly canvas: any;
Expand All @@ -45,7 +46,7 @@ export default class CanvasTextureRenderer implements ITextureRenderer {
private currentRankingWidths: number[] = [];
private engineRenderer: EngineRenderer;
private engineRankings: EngineRanking[][] = [];
private skipUpdateEvents: number = 0;
//private skipUpdateEvents: number = 0;
private alreadyExpanded: boolean = false;
private expandLaterRows: any[] = [];
private readonly options: Readonly<ILineUpOptions>;
Expand Down Expand Up @@ -80,7 +81,10 @@ export default class CanvasTextureRenderer implements ITextureRenderer {

update(rankings: EngineRanking[] = this.currentRankings, localData: IDataRow[][] = this.currentLocalData) {
this.detailParts = [];
this.currentLocalData = localData;
rankings.forEach((r, i) => {
const rankingIndex = this.currentRankings.findIndex((v) => v === r);
this.currentLocalData[rankingIndex] = localData[i];
});
this.currentNodeHeight = this.node.offsetHeight;
let totalWidth = 0;
rankings.forEach((r, i) => {
Expand All @@ -99,18 +103,20 @@ export default class CanvasTextureRenderer implements ITextureRenderer {

private renderColumns (rankings: EngineRanking[], localData: IDataRow[][]) {
rankings.forEach((r, i) => {
let notAggregatedCount = localData[i].length;
let gIndex = 0;
const aggregatedParts = <any>[];
r.ranking.getGroups().forEach((g) => {
if (this.engineRenderer.ctx.provider.isAggregated(r.ranking, g)) {
aggregatedParts.push([gIndex, gIndex + g.order.length - 1]);
notAggregatedCount -= g.order.length;
}
gIndex += g.order.length;
});
this.currentNodeHeight -= CanvasTextureRenderer.AGGRIGATED_ROW_HEIGHT * aggregatedParts.length;

const rankingIndex = this.currentRankings.findIndex((v) => v === r);
this.engineRankings[rankingIndex] = [];
//TODO: combine
this.detailParts = [];
let startIndex = -1;
for (let j = 0; j < localData[i].length; j++) {
Expand All @@ -131,7 +137,7 @@ export default class CanvasTextureRenderer implements ITextureRenderer {
aggregatedParts.forEach((g: any) => {
for (let j = 0; j < this.detailParts.length; j++) {
if (g[0] <= this.detailParts[j][0]) {
if (g[1] <= this.detailParts[j][0]) {
if (g[1] < this.detailParts[j][0]) {
this.detailParts.splice(j, 0, g);
aggregateIndices.push(j);
return;
Expand All @@ -142,16 +148,18 @@ export default class CanvasTextureRenderer implements ITextureRenderer {
return;
}
this.detailParts.splice(j, 1);
j--;
continue;
}
if (g[0] > this.detailParts[j][1]) {
return;
continue;
}
if (g[1] < this.detailParts[j][1]) {
this.detailParts.splice(j, 1, [this.detailParts[j][0], g[0] - 1], g, [g[1] + 1, this.detailParts[j][1]]);
aggregateIndices.push(j + 1);
return;
}
this.detailParts.splice(j, 1, [this.detailParts[j][0], g[0] - 1]);
this.detailParts.splice(j, 1, [this.detailParts[j][0], g[0] - 1], g, [g[1] + 1, this.detailParts[j][1]]);
aggregateIndices.push(j + 1);
return;
}
this.detailParts.splice(j, 1, [this.detailParts[j][0], g[0] - 1]);
}
this.detailParts.push(g);
aggregateIndices.push(this.detailParts.length - 1);
Expand Down Expand Up @@ -208,7 +216,7 @@ export default class CanvasTextureRenderer implements ITextureRenderer {
aggregateOffset += newOffset;

if (!aggregated) {
const height = data.length / localData[i].length * this.currentNodeHeight;
const height = data.length / notAggregatedCount * this.currentNodeHeight;
if (height >= 1) { //only render parts larger than 1px
const textureDiv = this.node.ownerDocument.createElement('div');
textureDiv.style.height = `${height}px`;
Expand Down Expand Up @@ -242,14 +250,14 @@ export default class CanvasTextureRenderer implements ITextureRenderer {
const engineRanking = table.pushTable((header, body, tableId, style) => new EngineRanking(r.ranking, header, body, tableId, style, this.engineRenderer.ctx, {
animation: this.options.animated,
customRowUpdate: this.options.customRowUpdate || (() => undefined),
levelOfDetail: this.options.levelOfDetail || (() => 'high'),
levelOfDetail: this.options.levelOfDetail || (() => 'high'),//
flags: this.options.flags
}));
}, true));

this.engineRenderer.render(engineRanking, <any>data);
this.engineRankings[rankingIndex].push(engineRanking);
engineRanking.on(EngineRanking.EVENT_UPDATE_DATA, () => this.handleUpdateEvent(r));
this.skipUpdateEvents++;
//engineRanking.on(EngineRanking.EVENT_UPDATE_DATA, () => this.handleUpdateEvent(r));
//this.skipUpdateEvents++;
};
if (this.alreadyExpanded || aggregated) {
expandLater();
Expand Down Expand Up @@ -480,6 +488,7 @@ export default class CanvasTextureRenderer implements ITextureRenderer {

addRanking(ranking: EngineRanking) {
this.currentRankings.push(ranking);
this.currentLocalData.push([]);
const rankingDiv = this.node.ownerDocument.createElement('div');
rankingDiv.classList.add('rankingContainer');
rankingDiv.setAttribute('data-ranking', `${this.currentRankings.length-1}`);
Expand All @@ -496,6 +505,7 @@ export default class CanvasTextureRenderer implements ITextureRenderer {
}
this.currentRankings.splice(index, 1);
this.engineRankings.splice(index, 1);
this.currentLocalData.splice(index, 1);
d3.select(this.node).select(`[data-ranking="${index}"]`).remove();
}

Expand All @@ -513,33 +523,10 @@ export default class CanvasTextureRenderer implements ITextureRenderer {

s2d() {
this.engineRenderer.ctx.provider.setDetail(this.engineRenderer.ctx.provider.getSelection());
//this.detailParts = [];
//let startIndex = -1;
//for (let i = 0; i < this.currentLocalData[0].length; i++) {
// if (this.engineRenderer.ctx.provider.isSelected(this.currentLocalData[0][i].i)) {
// if (startIndex === -1) {
// startIndex = i;
// }
// } else if (startIndex !== -1) {
// this.detailParts.push([startIndex, i-1]);
// startIndex = -1;
// }
//}
//if (startIndex !== -1) {
// this.detailParts.push([startIndex, this.currentLocalData[0].length-1]);
//}
//this.renderColumns(this.currentRankings, this.currentLocalData);
}

d2s() {
this.engineRenderer.ctx.provider.setSelection(this.engineRenderer.ctx.provider.getDetail());
//d3.select(this.node).selectAll('.engineRendererContainer').nodes().forEach((v: any, i: number) => {
// const first = d3.select(v).select('.lu-row:first-child').node();
// const last = d3.select(v).select('.lu-row:last-child').node();
// if (typeof first !== 'undefined' && typeof last !== 'undefined') {
// this.engineRankings[i].selection.select(i !== 0, <any>first, <any>last);
// }
//});
}

drawSelection() {
Expand All @@ -564,12 +551,4 @@ export default class CanvasTextureRenderer implements ITextureRenderer {
ctx.save();
});
}

private handleUpdateEvent (r: EngineRanking) {
if (this.skipUpdateEvents > 0) {
this.skipUpdateEvents--;
} else {
this.engineRenderer.update([r]);
}
}
}
70 changes: 36 additions & 34 deletions src/ui/EngineRanking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ export default class EngineRanking extends ACellTableSection<RenderColumn> imple
}
};

constructor(public readonly ranking: Ranking, header: HTMLElement, body: HTMLElement, tableId: string, style: GridStyleManager, private readonly ctx: IEngineRankingContext, roptions: Partial<IEngineRankingOptions> = {}) {
constructor(public readonly ranking: Ranking, header: HTMLElement, body: HTMLElement, tableId: string, style: GridStyleManager, private readonly ctx: IEngineRankingContext, roptions: Partial<IEngineRankingOptions> = {}, readonly noEvents: boolean = false) {
super(header, body, tableId, style, {mixins: [PrefetchMixin], batchSize: 10});
Object.assign(this.roptions, roptions);
body.classList.add('lu-row-body');
Expand All @@ -179,43 +179,45 @@ export default class EngineRanking extends ACellTableSection<RenderColumn> imple

this.delayedUpdateAll = debounce(() => this.updateAll(), 50);
this.delayedUpdateColumnWidths = debounce(() => this.updateColumnWidths(), 50);
ranking.on(`${Ranking.EVENT_ADD_COLUMN}.hist`, (col: Column, index: number) => {
this.columns.splice(index, 0, this.createCol(col, index));
this.reindex();
this.updateHist(col);
this.delayedUpdateAll();
});
ranking.on(`${Ranking.EVENT_REMOVE_COLUMN}.body`, (col: Column, index: number) => {
EngineRanking.disableListener(col);
this.columns.splice(index, 1);
this.reindex();
this.delayedUpdateAll();
});
ranking.on(`${Ranking.EVENT_MOVE_COLUMN}.body`, (col: Column, index: number, old: number) => {
//delete first
const c = this.columns.splice(old, 1)[0];
console.assert(c.c === col);
// adapt target index based on previous index, i.e shift by one
this.columns.splice(old < index ? index - 1 : index, 0, c);
this.reindex();
this.delayedUpdateAll();
});
ranking.on(`${Ranking.EVENT_COLUMN_VISIBILITY_CHANGED}.body`, (col: Column, _oldValue: boolean, newValue: boolean) => {
if (newValue) {
// become visible
const index = ranking.children.indexOf(col);
if (!noEvents) {
ranking.on(`${Ranking.EVENT_ADD_COLUMN}.hist`, (col: Column, index: number) => {
this.columns.splice(index, 0, this.createCol(col, index));
this.reindex();
this.updateHist(col);
} else {
// hide
const index = this.columns.findIndex((d) => d.c === col);
this.delayedUpdateAll();
});
ranking.on(`${Ranking.EVENT_REMOVE_COLUMN}.body`, (col: Column, index: number) => {
EngineRanking.disableListener(col);
this.columns.splice(index, 1);
}
this.reindex();
this.delayedUpdateAll();
});
ranking.on(`${Ranking.EVENT_ORDER_CHANGED}.body`, this.delayedUpdate);
this.reindex();
this.delayedUpdateAll();
});
ranking.on(`${Ranking.EVENT_MOVE_COLUMN}.body`, (col: Column, index: number, old: number) => {
//delete first
const c = this.columns.splice(old, 1)[0];
console.assert(c.c === col);
// adapt target index based on previous index, i.e shift by one
this.columns.splice(old < index ? index - 1 : index, 0, c);
this.reindex();
this.delayedUpdateAll();
});
ranking.on(`${Ranking.EVENT_COLUMN_VISIBILITY_CHANGED}.body`, (col: Column, _oldValue: boolean, newValue: boolean) => {
if (newValue) {
// become visible
const index = ranking.children.indexOf(col);
this.columns.splice(index, 0, this.createCol(col, index));
this.updateHist(col);
} else {
// hide
const index = this.columns.findIndex((d) => d.c === col);
EngineRanking.disableListener(col);
this.columns.splice(index, 1);
}
this.reindex();
this.delayedUpdateAll();
});
ranking.on(`${Ranking.EVENT_ORDER_CHANGED}.body`, this.delayedUpdate);
}

this.selection = new SelectionManager(this.ctx, body);
this.selection.on(SelectionManager.EVENT_SELECT_RANGE, (from: number, to: number, additional: boolean) => {
Expand Down
23 changes: 17 additions & 6 deletions src/ui/taggle/Taggle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {ALineUp} from '../ALineUp';
import SidePanel from '../panel/SidePanel';
import spaceFillingRule from './spaceFillingRule';
import TaggleRenderer from './TaggleRenderer';
import LocalDataProvider from '../../provider/LocalDataProvider';

export {ITaggleOptions} from '../../interfaces';

Expand Down Expand Up @@ -61,14 +62,24 @@ export default class Taggle extends ALineUp {
this.spaceFilling = <HTMLElement>this.node.querySelector('.lu-rule-button-chooser')!;
const ruleInput = <HTMLInputElement>this.spaceFilling.querySelector('input.spaceFilling');
ruleInput.onchange = () => {
let useTextureRenderer = true;
if (data instanceof LocalDataProvider) {
const ldp = <LocalDataProvider>data;
if (this.node.offsetHeight > ldp.data.length) {
useTextureRenderer = false;
}
}
const selected = this.spaceFilling!.classList.toggle('chosen');
//self.setTimeout(() => this.renderer.switchRule(selected ? spaceFilling : null));
this.renderer!.useTextureRenderer(selected);
if (selected) {
expandButton.style.display = '';
} else {
expandButton.style.display = 'none';
if (useTextureRenderer) {
this.renderer!.useTextureRenderer(selected);
if (selected) {
expandButton.style.display = '';
} else {
expandButton.style.display = 'none';
}
return;
}
self.setTimeout(() => this.renderer!.switchRule(selected ? spaceFilling : null));
};
if (this.options.overviewMode) {
ruleInput.checked = true;
Expand Down

0 comments on commit 56c676a

Please sign in to comment.