Skip to content

Commit

Permalink
Improved ontology tree performance (#1257)
Browse files Browse the repository at this point in the history
* Improved the ontology tree by removing unused functionality that was slowing down performance.

* Remove tests for removed code
  • Loading branch information
bherr2 authored May 16, 2024
1 parent 332cbcf commit a7eaceb
Show file tree
Hide file tree
Showing 5 changed files with 6 additions and 135 deletions.
6 changes: 2 additions & 4 deletions projects/ccf-eui/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { AppRootOverlayContainer } from './core/services/app-root-overlay/app-ro
import { ThemingService } from './core/services/theming/theming.service';
import { actionAsFn } from './core/store/action-as-fn';
import { DataStateSelectors } from './core/store/data/data.selectors';
import { DataQueryState, DataState } from './core/store/data/data.state';
import { DataState } from './core/store/data/data.state';
import { ListResultsState } from './core/store/list-results/list-results.state';
import { SceneState } from './core/store/scene/scene.state';
import {
Expand Down Expand Up @@ -123,9 +123,7 @@ export class AppComponent implements OnInit {
}

/** Emits true whenever the overlay spinner should activate. */
readonly spinnerActive$ = this.data.queryStatus$.pipe(
map(state => state === DataQueryState.Running)
);
readonly spinnerActive$ = this.data.state$.pipe(map((state) => state?.status !== 'Ready'));

readonly loadingMessage$ = this.data.state$.pipe(map(x => x?.statusMessage));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,15 @@

<!-- Templates with common structures for inner and leaf nodes -->
<ng-template #selectableRegion let-node="node">
<div class="text" [class.hidden]="node.label === highlightedNode?.label"
<div class="text"
[class.filtered-out]="!occurenceData[node.original.id] && !!termData[node.original.id]"
[class.unavailable]="!termData[node.original.id]" [class.selected]="isSelected(node)"
(click)="select($event.ctrlKey, node, true, !isSelected(node))">{{ getNodeLabel(node.label) }}</div>
</ng-template>

<!-- Leaf node template -->
<mat-tree-node *matTreeNodeDef="let node" class="node leaf-node block" matTreeNodePadding
[matTreeNodePaddingIndent]="indent" (mouseleave)="mouseOut(); slider1.reset()">

<div [style.display]="node.opacity !== -1 ? 'none' : 'block'">
<mat-icon class="icon opacity" [style.left]="getLeftIndent(node.level)" [class.fade]="node.visible !== true"
(mouseenter)="mouseOver(node)" svgIcon="app:opacity"></mat-icon>
<div class="slider" [style.left]="getLeftIndent(node.level)"
[class.hidden]="node.label !== highlightedNode?.label">
<ccf-opacity-slider #slider1 [visible]="node.visible" [opacity]="node.opacity"
(opacityChange)="updateOpacity(node, $event)" (opacityReset)="resetNode(node)"
(visibilityToggle)="toggleVisibility(node)">
</ccf-opacity-slider>
</div>
</div>

[matTreeNodePaddingIndent]="indent">
<!-- Disabled button used to add equal amount of space as an inner node's button -->
<div class="non-expandable"></div>
<div class="node-container">
Expand All @@ -40,21 +27,9 @@

<!-- Inner node template -->
<mat-tree-node *matTreeNodeDef="let node; when: isInnerNode" class="node inner-node block" matTreeNodePadding
[matTreeNodePaddingIndent]="indent" (mouseleave)="mouseOut(); slider2.reset()">

<div [style.display]="node.opacity !== -1 ? 'none' : 'block'">
<mat-icon class="icon opacity" [style.left]="getLeftIndent(node.level)" [class.fade]="node.visible !== true"
(mouseenter)="mouseOver(node)" svgIcon="app:opacity"></mat-icon>
<div class="slider" [style.left]="getLeftIndent(node.level)"
[class.hidden]="node.label !== highlightedNode?.label">
<ccf-opacity-slider #slider2 [visible]="node.visible" [opacity]="node.opacity"
(opacityChange)="updateOpacity(node, $event)" (opacityReset)="resetNode(node)"
(visibilityToggle)="toggleVisibility(node)">
</ccf-opacity-slider>
</div>
</div>
[matTreeNodePaddingIndent]="indent">
<div class="node-container">
<button class="toggle" [class.hidden]="node.label === highlightedNode?.label" mat-icon-button matTreeNodeToggle
<button class="toggle" mat-icon-button matTreeNodeToggle
attr.aria-label="Toggle {{ node.label }}">
<mat-icon class="icon font-icon">
{{ control.isExpanded(node) ? 'expand_less' : 'expand_more' }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,6 @@ describe('OntologyTreeComponent', () => {
expect(instance.nodes).toEqual([node1, node2]);
});

it('should return left indent', async () => {
const { instance } = await shallow.render();
expect(instance.getLeftIndent(1)).toEqual('-1.5rem');
});

it('should set children', async () => {
const { instance } = await shallow.render();
instance.getChildren = ()=>[];
Expand Down Expand Up @@ -157,24 +152,6 @@ describe('OntologyTreeComponent', () => {
expect(instance.isInnerNode(1, flatNode2)).toBeFalse();
});

it('should change highlightedNode when moused over', async () => {
const { instance } = await shallow.render();
instance.mouseOver(flatNode1);
expect(instance.highlightedNode).toEqual(flatNode1);
});

it('should remove highlightedNode when moused out', async () => {
const { instance } = await shallow.render();
instance.mouseOut();
expect(instance.highlightedNode).toBeUndefined();
});

it('should reset the node', async () => {
const { instance, outputs } = await shallow.render();
instance.resetNode(flatNode1);
expect(outputs.nodeChanged.emit).toHaveBeenCalled();
});

it('should return number of children when getNumResults is called', async () => {
const { instance } = await shallow.render();
expect(instance.getCountLabel(flatNode1)).toEqual('');
Expand All @@ -188,18 +165,6 @@ describe('OntologyTreeComponent', () => {
expect(instance.getNodeLabel('test')).toEqual('test');
});

it('should update the opacity', async () => {
const { instance } = await shallow.render();
instance.updateOpacity(flatNode1, 50);
expect(flatNode1.opacity).toEqual(50);
});

it('should toggle the visibility', async () => {
const { instance } = await shallow.render();
instance.toggleVisibility(flatNode1);
expect(flatNode1.visible).toBeFalse();
});

it('should re-run the gradient display logic on a scroll event', async () => {
const { instance, find } = await shallow.render();
const list = find('.ccf-ontology-tree');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,6 @@ export class OntologyTreeComponent implements OnInit, OnChanges {
*/
selectedNodes: FlatNode[] = [];

highlightedNode: FlatNode | undefined;



/**
* Expand the body node when the component is initialized.
*/
Expand Down Expand Up @@ -373,67 +369,6 @@ export class OntologyTreeComponent implements OnInit, OnChanges {
}
}

/**
* Sets the current highlighted node to the moused over node (reveals opacity slider)
*
* @param node
*/
mouseOver(node: FlatNode): void {
this.highlightedNode = node;
}

/**
* Deselects the highlighted node on mouse out
*/
mouseOut(): void {
this.highlightedNode = undefined;
}

/**
* Sets the opacity of a node
*
* @param node The node to be updated
* @param value Opacity value
*/
updateOpacity(node: FlatNode, value: number | undefined): void {
node.opacity = value;
this.ga.event('opacity_update', 'ontology_tree', node.label, value);
this.nodeChanged.emit(node);
}

/**
* Resets node to default opacity and visibility
*
* @param node The node to be reset
*/
resetNode(node: FlatNode): void {
node.opacity = 20;
node.visible = true;
this.ga.event('node_reset', 'ontology_tree', node.label);
this.nodeChanged.emit(node);
}

/**
* Toggles visibility of a node
*
* @param node The node to be toggled
*/
toggleVisibility(node: FlatNode): void {
node.visible = node.visible === true ? false : true;
this.ga.event('visibility_update', 'ontology_tree', node.label, +node.visible);
this.nodeChanged.emit(node);
}

/**
* Used to properly set the position of the slider popup on the ontology tree
*
* @param level Current level of a node in the ontology tree
* @returns left indent value
*/
getLeftIndent(level: number): string {
return `${level * -1.5}rem`;
}

/**
* Handles the scroll event to detect when scroll is at the bottom.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { MatTooltipModule } from '@angular/material/tooltip';
import { MatTreeModule } from '@angular/material/tree';

import { OntologyTreeComponent } from './ontology-tree.component';
import { OpacitySliderModule } from 'ccf-shared';
import { ButtonToggleModule } from '../../../shared/components/button-toggle/button-toggle.module';

@NgModule({
Expand All @@ -16,7 +15,6 @@ import { ButtonToggleModule } from '../../../shared/components/button-toggle/but
MatIconModule,
MatTooltipModule,
MatTreeModule,
OpacitySliderModule,
ButtonToggleModule
],
declarations: [OntologyTreeComponent],
Expand Down

0 comments on commit a7eaceb

Please sign in to comment.