Skip to content

Commit

Permalink
More performant gender index page
Browse files Browse the repository at this point in the history
  • Loading branch information
akariv committed Jan 16, 2024
1 parent 743ffed commit b797319
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 110 deletions.
Expand Up @@ -8,7 +8,6 @@ import { I18nService } from '../i18n.service';
})
export class GenderIndexPageBrowserHeaderElementComponent implements OnInit {

@Input() selected: string;
@Input() active: string;
@Input() slug: string;
@Input() name: string;
Expand Down
Expand Up @@ -13,4 +13,4 @@
</a>
</div>
</div>
<app-search-results [results]='charts' (shown)='active.next(name)'></app-search-results>
<app-search-results [results]='charts'></app-search-results>
Expand Up @@ -15,7 +15,6 @@ export class GenderIndexPageBrowserSectionComponent implements OnInit, OnChanges
@Input() slug: string;
@Input() name: string;
@Input() display: string;
@Output() active = new EventEmitter<string>();

open = false;
selected: string = null;
Expand Down
@@ -1,33 +1,33 @@
<div class='sticky-header'>
<div class='inner'>
<app-gender-index-page-browser-header-element [selected]='selected' slug='aducation' name='השכלה' display='השכלה' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element [selected]='selected' slug='market' name='שוק העבודה' display='שוק העבודה' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element [selected]='selected' slug='occupation' name='מגדור מקצועי' display='מגדור מקצועי' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element [selected]='selected' slug='poverty' name='ביטחון כלכלי ועוני' display='ביטחון כלכלי ועוני' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element [selected]='selected' slug='power' name='עוצמה' display='עוצמה' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element [selected]='selected' slug='culture' name='תרבות ותקשורת' display='תרבות ותקשורת' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element [selected]='selected' slug='family' name='משפחה וילודה' display='משפחה וילודה' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element [selected]='selected' slug='age65' name='גיל 65+' display='גיל 65+' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element [selected]='selected' slug='time' name='זמן' display='זמן' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element [selected]='selected' slug='violence' name='אלימות מגדרית' display='אלימות מגדרית' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element [selected]='selected' slug='health' name='בריאות' display='בריאות' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element [selected]='selected' slug='arabic' name='החברה הערבית' display='החברה הערבית' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element [selected]='selected' slug='religious' name='החברה החרדית' display='החברה החרדית' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element [selected]='selected' slug='suburbs' name='פריפריה' display='פריפריה' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element slug='aducation' name='השכלה' display='השכלה' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element slug='market' name='שוק העבודה' display='שוק העבודה' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element slug='occupation' name='מגדור מקצועי' display='מגדור מקצועי' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element slug='poverty' name='ביטחון כלכלי ועוני' display='ביטחון כלכלי ועוני' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element slug='power' name='עוצמה' display='עוצמה' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element slug='culture' name='תרבות ותקשורת' display='תרבות ותקשורת' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element slug='family' name='משפחה וילודה' display='משפחה וילודה' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element slug='age65' name='גיל 65+' display='גיל 65+' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element slug='time' name='זמן' display='זמן' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element slug='violence' name='אלימות מגדרית' display='אלימות מגדרית' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element slug='health' name='בריאות' display='בריאות' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element slug='arabic' name='החברה הערבית' display='החברה הערבית' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element slug='religious' name='החברה החרדית' display='החברה החרדית' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
<app-gender-index-page-browser-header-element slug='suburbs' name='פריפריה' display='פריפריה' [active]='active' i18n-display></app-gender-index-page-browser-header-element>
</div>
</div>

<app-gender-index-page-browser-section [results]='results' slug='aducation' name='השכלה' display='השכלה' (active)='setActive($event)' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='market' name='שוק העבודה' display='שוק העבודה' (active)='setActive($event)' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='occupation' name='מגדור מקצועי' display='מגדור מקצועי' (active)='setActive($event)' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='poverty' name='ביטחון כלכלי ועוני' display='ביטחון כלכלי ועוני' (active)='setActive($event)' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='power' name='עוצמה' display='עוצמה' (active)='setActive($event)' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='culture' name='תרבות ותקשורת' display='תרבות ותקשורת' (active)='setActive($event)' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='family' name='משפחה וילודה' display='משפחה וילודה' (active)='setActive($event)' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='age65' name='גיל 65+' display='גיל 65+' (active)='setActive($event)' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='time' name='זמן' display='זמן' (active)='setActive($event)' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='violence' name='אלימות מגדרית' display='אלימות מגדרית' (active)='setActive($event)' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='health' name='בריאות' display='בריאות' (active)='setActive($event)' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='arabic' name='החברה הערבית' display='החברה הערבית' (active)='setActive($event)' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='religious' name='החברה החרדית' display='החברה החרדית' (active)='setActive($event)' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='suburbs' name='פריפריה' display='פריפריה' (active)='setActive($event)' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='aducation' name='השכלה' display='השכלה' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='market' name='שוק העבודה' display='שוק העבודה' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='occupation' name='מגדור מקצועי' display='מגדור מקצועי' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='poverty' name='ביטחון כלכלי ועוני' display='ביטחון כלכלי ועוני' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='power' name='עוצמה' display='עוצמה' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='culture' name='תרבות ותקשורת' display='תרבות ותקשורת' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='family' name='משפחה וילודה' display='משפחה וילודה' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='age65' name='גיל 65+' display='גיל 65+' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='time' name='זמן' display='זמן' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='violence' name='אלימות מגדרית' display='אלימות מגדרית' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='health' name='בריאות' display='בריאות' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='arabic' name='החברה הערבית' display='החברה הערבית' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='religious' name='החברה החרדית' display='החברה החרדית' i18n-display></app-gender-index-page-browser-section>
<app-gender-index-page-browser-section [results]='results' slug='suburbs' name='פריפריה' display='פריפריה' i18n-display></app-gender-index-page-browser-section>
@@ -1,26 +1,24 @@
import { Component, OnInit, Input, AfterContentInit, ElementRef } from '@angular/core';
import { Component, OnInit, Input, AfterViewInit, ElementRef, OnDestroy, AfterContentInit, AfterContentChecked, AfterViewChecked } from '@angular/core';
import { ApiService } from '../api.service';
import { ActivatedRoute } from '@angular/router';
import { timer } from 'rxjs';
import { take } from 'rxjs/operators';

@Component({
selector: 'app-gender-index-page-browser',
templateUrl: './gender-index-page-browser.component.html',
styleUrls: ['./gender-index-page-browser.component.less']
})
export class GenderIndexPageBrowserComponent implements OnInit {
export class GenderIndexPageBrowserComponent implements OnInit, OnDestroy {

@Input() active = null;

results: any[] = [];
selected = null;

observer: IntersectionObserver;

constructor(private api: ApiService, private activatedRoute: ActivatedRoute, private el: ElementRef) {
this.activatedRoute.fragment.subscribe((fragment) => {
const dimension = fragment;
if (dimension) {
this.selected = dimension;
}
});
}

ngOnInit() {
Expand All @@ -30,10 +28,54 @@ export class GenderIndexPageBrowserComponent implements OnInit {
.filter((x) => x.kind === 'Gender Index')
.sort((a, b) => a.series[0].order_index - b.series[0].order_index);
this.results = gender_index_results;
timer(1000).subscribe(() => {
this.setupObserver();
this.activatedRoute.fragment.pipe(
take(1),
).subscribe((fragment) => {
const dimension = fragment;
if (dimension) {
const el = this.el.nativeElement as HTMLElement;
const section = el.querySelector(`app-gender-index-page-browser-section[name="${dimension}"]`);
if (section) {
const boundingClientRect = section.getBoundingClientRect();
const parent = document.scrollingElement;
parent.scrollTop = boundingClientRect.top + parent.scrollTop - 158;
}
}
});
});
});
}

setActive(section) {
this.active = section;
}

setupObserver(): void {
this.observer = new IntersectionObserver((entries) => {
let intersectionHeight = -1;
for (const entry of entries) {
if (entry.isIntersecting) {
const entryIntersectionHeight = entry.intersectionRect.height;
const el: HTMLElement = entry.target as HTMLElement;
if (entryIntersectionHeight > intersectionHeight) {
intersectionHeight = entryIntersectionHeight;
this.setActive(el.getAttribute('name'));
}
}
}
}, {threshold: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.9, 1]});
const el = this.el.nativeElement as HTMLElement;
el.querySelectorAll('app-gender-index-page-browser-section').forEach((section) => {
this.observer.observe(section);
});
}

ngOnDestroy(): void {
if (this.observer) {
this.observer.disconnect();
}
this.observer = null;
}
}
38 changes: 7 additions & 31 deletions src/app/result-card-dataset/result-card-dataset.component.ts
Expand Up @@ -9,7 +9,7 @@ import { BehaviorSubject, ReplaySubject, Subscription } from 'rxjs';
templateUrl: './result-card-dataset.component.html',
styleUrls: ['./result-card-dataset.component.less']
})
export class ResultCardDatasetComponent implements OnInit, OnChanges, OnDestroy {
export class ResultCardDatasetComponent implements OnChanges {

@Input() result: any;
@Input() genderIndex: boolean;
Expand All @@ -19,46 +19,22 @@ export class ResultCardDatasetComponent implements OnInit, OnChanges, OnDestroy
@Input() title = true;

colorScale = cs;
_savedResult = null;
_analyzedColors = null;
_chart = null;
ratio = 65;

iobs: IntersectionObserver;
visible$ = new BehaviorSubject<boolean>(false);
visibleSub: Subscription = null;

constructor(public _: I18nService, private el: ElementRef) {}

ngOnInit() {
this.visibleSub = this.visible$.subscribe((visible) => {
if (visible) {
this._chart = this._savedResult;
if (this._analyzedColors !== this._chart) {
analyzeColors(this._chart);
this._analyzedColors = this._chart;
}
} else {
this._chart = null;
}
});
}

ngOnDestroy() {
this.visibleSub.unsubscribe();
if (this.iobs) {
this.iobs.unobserve(this.el.nativeElement);
this.iobs.disconnect();
}
}

ngOnChanges() {
if (this.result !== this._savedResult) {
this._savedResult = this.result;
if (this.result !== this._chart) {
this._chart = this.result;
}
if (this._analyzedColors !== this._chart) {
analyzeColors(this._chart);
this._analyzedColors = this._chart;
}
const chart_type = this.result.chart_type || '';
this.ratio = chart_type.indexOf('hbars') === 0 ? 200 : 60;
this.visible$.next(this.visible);
}

}
43 changes: 3 additions & 40 deletions src/app/search-results/search-results.component.ts
Expand Up @@ -11,11 +11,11 @@ import { debounceTime, map } from 'rxjs/operators';
templateUrl: './search-results.component.html',
styleUrls: ['./search-results.component.less']
})
export class SearchResultsComponent implements OnInit, OnDestroy, OnChanges, AfterContentInit {
export class SearchResultsComponent implements OnInit, OnDestroy, OnChanges {

@Input() manager: SearchManager;
@Input() results: any[];
@Output() shown = new EventEmitter<void>();

columns = [[], []];
columnAll = [];
@ViewChild('column0') column0ref: ElementRef;
Expand All @@ -26,9 +26,7 @@ export class SearchResultsComponent implements OnInit, OnDestroy, OnChanges, Aft
visible = false;

iobs: IntersectionObserver;
visible$ = new BehaviorSubject<boolean>(false);
visibleSub: Subscription = null;


constructor(public api: ApiService,
private bottommer: BottommerService,
private el: ElementRef) {
Expand All @@ -42,35 +40,7 @@ export class SearchResultsComponent implements OnInit, OnDestroy, OnChanges, Aft
}
});
this.visible = true;
} else {
this.visibleSub = this.visible$.subscribe((visible) => {
if (!this.visible && visible) {
this.visible = visible;
this.shown.next();
}
this.visible = visible;
});
}
}

restartObserver() {
if (this.iobs) {
this.iobs.disconnect();
}
this.iobs.observe(this.el.nativeElement);
}

ngAfterContentInit() {
this.iobs = new IntersectionObserver(
(entries) => {
this.visible$.next(entries[0].isIntersecting);
},
{
rootMargin: '0px',
threshold: 0
}
);
this.restartObserver();
}

clear() {
Expand All @@ -87,10 +57,6 @@ export class SearchResultsComponent implements OnInit, OnDestroy, OnChanges, Aft
this.searchResultsSubs.unsubscribe();
this.searchResultsSubs = null;
}
if (this.visibleSub) {
this.visibleSub.unsubscribe();
this.visibleSub = null;
}
}

ngOnChanges() {
Expand All @@ -105,9 +71,6 @@ export class SearchResultsComponent implements OnInit, OnDestroy, OnChanges, Aft
});
} else if (this.results && this.results.length) {
this.assignCards(this.results);
setTimeout(() => {
this.restartObserver();
}, 0);
}
}

Expand Down

0 comments on commit b797319

Please sign in to comment.