...
Use a CLI command to generate a state component with a custom name and sidebar link. The link appears in the navigation menu on the left. (sidebar-navigation = default)
Code Block language bash linenumbers true eo g state custom
Use a CLI command to install the maps package (takes some time).
Code Block language bash linenumbers true npm install -P ng2-chartscharts@1.6.0
Import ChartsModule module to CustomStatesModule.
Code Block language js title custom-states.module.ts linenumbers true import {NgModule} from '@angular/core'; import {CommonModule} from '@angular/common'; import {Route, RouterModule} from '@angular/router'; import {EoFrameworkModule} from '@eo-sdk/client'; import {EoLinkPlugin} from '@eo-sdk/client'; import {AuthGuard} from '@eo-sdk/client'; import {CustomComponent} from './custom/custom.component'; import {ChartsModule} from 'ng2-charts'; export const routes: Route[] = [ {path: CustomComponent.path, component: CustomComponent, canActivate: [AuthGuard]}, ]; export const links: EoLinkPlugin[] = [ CustomComponent ]; @NgModule({ imports: [ CommonModule, EoFrameworkModule, RouterModule.forChild(routes), ChartsModule ], declarations: [CustomComponent] }) export class CustomStatesModule { }
Update custom.component.ts to load current chart data.
Code Block language js title custom.component.ts linenumbers true import {Component, ViewChild} from '@angular/core'; import {Chart} from 'chart.js'; import {TranslateService, SearchService} from '@eo-sdk/core'; import {BaseChartDirective} from 'ng2-charts'; import {AppSearchService, UnsubscribeOnDestroy} from '@eo-sdk/client'; import {takeUntil} from 'rxjs/operators'; @Component({ selector: 'eo-custom', templateUrl: './custom.component.html', styleUrls: ['./custom.component.scss'] }) export class CustomComponent extends UnsubscribeOnDestroy { static id = 'eo.custom.state.custom'; static path = 'custom/custom'; static matchType = new RegExp('sidebar-navigation'); groupCount: number; totalCount: number; chart; activeType = 0; types = []; @ViewChild(BaseChartDirective) chartEl: BaseChartDirective; constructor(private translate: TranslateService, private searchService: SearchService, private appSearchService: AppSearchService) { super(); this.fetchData(); } chartClicked(el?) { if (!el || (this.activeType === this.groupCount && el.active[0])) { this.activeType = el ? el.active[0]._index : this.groupCount; this.chart = this.dataToChart(this.types[this.activeType]); setTimeout(() => { this.chartEl.chart.config.data.labels = this.chart.labels; this.chartEl.chart.update(); }, 0); } } dataToChart(groups: any[]): Chart { return { data: [{ data: groups.map(g => g.count), label: '' }], labels: groups.map(g => g.label) }; } private fetchData() { this.appSearchService.setTerm(''); this.appSearchService .queryState$ .pipe( takeUntil(this.componentDestroyed$) ) .subscribe(res => { this.totalCount = res.count; this.groupCount = this.appSearchService.objectTypeGroups.length; this.types = []; const main = this.appSearchService.objectTypeGroups.map((g) => { const type = g.types.map(t => ({label: t.label, count: res.aggregations.type.get(t.qname) || 0})); this.types.push(type.sort((a, b) => b.count - a.count)); return { label: g.label === '0' ? this.translate.instant('eo.quicksearch.result.group.global') : g.label, count: type.map(t => t.count).reduce((a, b) => a + b, 0) }; }); this.types.push(main.sort((a, b) => b.count - a.count)); this.chartClicked(); } ); } }
Update custom-state.component.html to include a chart component.
Code Block language xml title custom-state.component.html linenumbers true <button class="summary" (click)="chartClicked()"> <span class="label" *ngIf="activeType != groupCount">{{types[groupCount][activeType].label}}: </span> <span class="count" *ngIf="activeType != groupCount"> {{types[groupCount][activeType].count}} of </span> <span class="total">{{totalCount}}</span> </button> <div class="chart-container"> <canvas baseChart *ngIf="chart" height="100%" [datasets]="chart.data" [labels]="chart.labels" [chartType]="'doughnut'" (chartClick)="chartClicked($event)"></canvas> </div>
To finish this state, add some styling
Code Block language css title custom-state.component.scss linenumbers true :host { flex: 1; display: flex; flex-flow: column; .summary { align-items: baseline; position: absolute; right: 30px; top: 30px; flex: 1 1 auto; display: flex; background: papayawhip; border-radius: 4px; padding: 16px; border: 1px solid rgba(255, 255, 255, 0.2); .label { font-size: 1.5em; } .count { font-size: 2.5em; } .total { font-size: 3.5em; } } .chart-container { flex: 0 0 auto; } }
Use a CLI command to generate labels/translations.
Code Block language bash linenumbers true eo g label eo.custom.state.custom --en "Custom state" --de "Custom state"
...