Skip to content

Commit 911d55b

Browse files
committed
Fix time graph filtering and collapsing
Only clear excluded rows if the EXCLUDED filtering expressions have changed. This prevents unnecessarily redoing filtering of rows when only the search string has changed. Determine the list of rows that have only changed y-position, for example due to collapsing of preceding rows. If these rows do not need to be fetched because their current model is valid, then rebuild the rows using their current model to update each child element's position. If no rows at all need to be fetched but there were some moved rows, perform a fetch to update the arrows which may have changed their start and/or end position. Remove unused code for updating and removing of gap states, as the states and gaps are always added from scratch when updating a row. Remove the reference to gap state components in the row model states. Signed-off-by: Patrick Tasse <patrick.tasse@gmail.com>
1 parent 61780be commit 911d55b

1 file changed

Lines changed: 62 additions & 72 deletions

File tree

timeline-chart/src/layer/time-graph-chart.ts

Lines changed: 62 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as PIXI from "pixi.js-legacy";
22
import { TimeGraphAnnotationComponent, TimeGraphAnnotationStyle } from "../components/time-graph-annotation";
3-
import { TimeGraphComponent, TimeGraphStyledRect } from "../components/time-graph-component";
3+
import { TimeGraphComponent } from "../components/time-graph-component";
44
import { TimeGraphRectangle } from "../components/time-graph-rectangle";
55
import { TimeGraphRow, TimeGraphRowStyle } from "../components/time-graph-row";
66
import { TimeGraphStateComponent, TimeGraphStateStyle } from "../components/time-graph-state";
@@ -388,10 +388,12 @@ export class TimeGraphChart extends TimeGraphChartLayer {
388388
}
389389

390390
updateChart(filterExpressionsMap?: {[key: number]: string[]}) {
391-
const update = true;
391+
if (!isEqual(filterExpressionsMap?.[EXCLUDED], this._filterExpressionsMap?.[EXCLUDED])) {
392+
this._excludedRows.clear();
393+
}
392394
this._filterExpressionsMap = filterExpressionsMap;
393395
if (this.unitController && this.stateController) {
394-
this.maybeFetchNewData(update);
396+
this.maybeFetchNewData(true);
395397
}
396398
}
397399

@@ -485,42 +487,39 @@ export class TimeGraphChart extends TimeGraphChartLayer {
485487
fine = true;
486488
}
487489
this._allRowIds = this.providers.rowProvider().rowIds;
488-
if (update) {
489-
this._excludedRows.clear();
490-
this.rowIds = this._allRowIds.slice();
491-
} else {
492-
this.rowIds = this._allRowIds.filter(rowId => !this._excludedRows.has(rowId));
493-
}
490+
this.rowIds = this._allRowIds.filter(rowId => !this._excludedRows.has(rowId));
494491
const visibleRowIds = this.getVisibleRowIds(VISIBLE_ROW_BUFFER);
495-
if (update) {
496-
// update position of existing rows and remove deleted rows
497-
this.rowComponents.forEach((rowComponent, rowId) => {
498-
const index = this.rowIds.indexOf(rowId);
499-
if (index == -1) {
492+
// update position of existing rows and remove deleted rows
493+
const movedRows: TimeGraphRow[] = [];
494+
this.rowComponents.forEach((rowComponent, rowId) => {
495+
const index = this.rowIds.indexOf(rowId);
496+
if (index == -1) {
497+
this.rowComponents.delete(rowId);
498+
this.removeChild(rowComponent);
499+
} else {
500+
const y = this.rowController.rowHeight * index;
501+
if (!visibleRowIds.includes(rowId)) {
500502
this.rowComponents.delete(rowId);
501503
this.removeChild(rowComponent);
502-
} else {
503-
rowComponent.position.y = this.rowController.rowHeight * index;
504-
if (!visibleRowIds.includes(rowId)) {
505-
this.rowComponents.delete(rowId);
506-
this.removeChild(rowComponent);
507-
}
508-
}
509-
});
510-
// update selected row
511-
if (this.rowController.selectedRow) {
512-
this.rowController.selectedRowIndex = this.rowIds.indexOf(this.rowController.selectedRow.id);
513-
if (this.rowController.selectedRowIndex === -1) {
514-
this.rowController.selectedRow = undefined;
504+
} else if (rowComponent.position.y !== y) {
505+
movedRows.push(rowComponent);
515506
}
507+
rowComponent.position.y = y;
508+
}
509+
});
510+
// update selected row
511+
if (this.rowController.selectedRow) {
512+
this.rowController.selectedRowIndex = this.rowIds.indexOf(this.rowController.selectedRow.id);
513+
if (this.rowController.selectedRowIndex === -1) {
514+
this.rowController.selectedRow = undefined;
516515
}
517-
// create placeholder rows
518-
this.rowIds.forEach((rowId) => {
519-
if (!this.rowComponents.get(rowId)) {
520-
this.addRow(rowId);
521-
}
522-
});
523516
}
517+
// create placeholder rows
518+
this.rowIds.forEach((rowId) => {
519+
if (!this.rowComponents.get(rowId)) {
520+
this.addRow(rowId);
521+
}
522+
});
524523
const { viewRange } = this.unitController;
525524
const worldRange = this.stateController.computeWorldRangeFromViewRange();
526525
const resolutionFactor = fine ? FINE_RESOLUTION_FACTOR : this._coarseResolutionFactor;
@@ -539,6 +538,13 @@ export class TimeGraphChart extends TimeGraphChartLayer {
539538
resolution < rowComponent.providedModel.resolution || !isEqual(rowComponent.providedModel.filterExpressionsMap, this._filterExpressionsMap)
540539
);
541540
});
541+
// rebuild rows that have changed position but that won't be fetched
542+
movedRows.forEach(rowComponent => {
543+
if (rowComponent.model && !rowIds.includes(rowComponent.model.id) && rowComponent.providedModel) {
544+
const rowData = { rows: [rowComponent.model], range: rowComponent.providedModel?.range, resolution: rowComponent.providedModel?.resolution };
545+
this.addOrUpdateRows(rowData);
546+
}
547+
});
542548
if (fullSearch && this._filterExpressionsMap?.[EXCLUDED]) {
543549
this._excludedRows.forEach((range, rowId) => {
544550
// add excluded rows to request to determine if they should reappear
@@ -600,9 +606,16 @@ export class TimeGraphChart extends TimeGraphChartLayer {
600606
}
601607
}
602608
}
603-
} else if (!fine && this._coarseResolutionFactor !== FINE_RESOLUTION_FACTOR) {
604-
// no row to update for coarse resolution, try fine resolution
605-
this.maybeFetchNewData(update, true);
609+
} else {
610+
if (movedRows.length > 0) {
611+
// no rows to update but may need to fetch arrows
612+
const request = { worldRange, resolution, rowIds: [], additionalParams: {}, fullSearch };
613+
await this.fetchRows(request, true, fine);
614+
}
615+
if (!fine && this._coarseResolutionFactor !== FINE_RESOLUTION_FACTOR) {
616+
// no row to update for coarse resolution, try fine resolution
617+
this.maybeFetchNewData(update, true);
618+
}
606619
}
607620
}
608621

@@ -787,43 +800,20 @@ export class TimeGraphChart extends TimeGraphChartLayer {
787800
(x > lastX || (lastBlank && !state.data?.style && state.range.start > lastTime)) &&
788801
!isFilteredOut
789802
) {
790-
const gap = state.data?.gap;
791-
if (gap) {
792-
const width = Math.max(1, x - lastX);
793-
const opts: TimeGraphStyledRect = {
794-
height: gap.height,
795-
position: {
796-
x: lastX,
797-
y: gap.position.y
798-
},
799-
width: width,
800-
displayWidth: width
801-
}
802-
gap.update(opts);
803-
} else {
804-
const stateModel = {
805-
id: rowComponent.id + '-gap',
806-
range: {
807-
start: lastTime,
808-
end: state.range.start
809-
},
810-
data: {
811-
style: gapStyle
812-
}
813-
};
814-
const gap = this.createNewState(stateModel, rowComponent);
815-
if (gap) {
816-
rowComponent.addChild(gap);
817-
if (state.data) {
818-
state.data['gap'] = gap;
819-
}
820-
this.addElementInteractions(gap);
803+
const stateModel = {
804+
id: rowComponent.id + '-gap',
805+
range: {
806+
start: lastTime,
807+
end: state.range.start
808+
},
809+
data: {
810+
style: gapStyle
821811
}
822-
}
823-
} else {
824-
if (state.data && state.data?.gap) {
825-
rowComponent.removeChild(state.data?.gap);
826-
state.data.gap = undefined;
812+
};
813+
const gap = this.createNewState(stateModel, rowComponent);
814+
if (gap) {
815+
rowComponent.addChild(gap);
816+
this.addElementInteractions(gap);
827817
}
828818
}
829819
}

0 commit comments

Comments
 (0)