From 92ba778bf16b440a622d085ae206cc4fc6a309da Mon Sep 17 00:00:00 2001 From: Grant Forsythe Date: Wed, 20 Mar 2024 21:04:42 -0400 Subject: [PATCH] feat: add horizontal bar chart component --- .../bar-horizontal.component.html | 16 ++++ .../bar-horizontal.component.spec.ts | 81 +++++++++++++++++++ .../bar-horizontal.component.ts | 22 +++++ .../feature/dashboard/dashboard.routes.ts | 2 + 4 files changed, 121 insertions(+) create mode 100644 src/app/reports/feature/dashboard/charts/bar-horizontal/bar-horizontal.component.html create mode 100644 src/app/reports/feature/dashboard/charts/bar-horizontal/bar-horizontal.component.spec.ts create mode 100644 src/app/reports/feature/dashboard/charts/bar-horizontal/bar-horizontal.component.ts diff --git a/src/app/reports/feature/dashboard/charts/bar-horizontal/bar-horizontal.component.html b/src/app/reports/feature/dashboard/charts/bar-horizontal/bar-horizontal.component.html new file mode 100644 index 0000000..3f077f7 --- /dev/null +++ b/src/app/reports/feature/dashboard/charts/bar-horizontal/bar-horizontal.component.html @@ -0,0 +1,16 @@ +
+ + +
diff --git a/src/app/reports/feature/dashboard/charts/bar-horizontal/bar-horizontal.component.spec.ts b/src/app/reports/feature/dashboard/charts/bar-horizontal/bar-horizontal.component.spec.ts new file mode 100644 index 0000000..69d4b71 --- /dev/null +++ b/src/app/reports/feature/dashboard/charts/bar-horizontal/bar-horizontal.component.spec.ts @@ -0,0 +1,81 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ChartsBarHorizontalComponent } from './bar-horizontal.component'; +import { provideMockStore, MockStore } from '@ngrx/store/testing'; +import { NgxChartsModule } from '@swimlane/ngx-charts'; +import { CategoryGroup } from '../../../../../shared/services/ynab/interfaces/categories/categoryGroup'; +import { Account } from '../../../../../shared/services/ynab/interfaces/accounts/account'; +import { Transaction } from '../../../../../shared/services/ynab/interfaces/transactions/transaction'; +import { selectReportResults } from '../../../../data-access/report.selectors'; +import { provideAnimationsAsync } from '@angular/platform-browser/animations/async'; + +describe('ChartsBarHorizontalComponent', () => { + let component: ChartsBarHorizontalComponent; + let fixture: ComponentFixture; + let store: MockStore; + + const initialState: { + categoryGroups: CategoryGroup[]; + accounts: Account[]; + transactions: Transaction[]; + } = { + categoryGroups: [], + accounts: [], + transactions: [], + }; + + afterEach(() => { + store?.resetSelectors(); + }); + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + providers: [ + NgxChartsModule, + provideAnimationsAsync(), + provideMockStore({ + initialState, + selectors: [ + { + selector: selectReportResults, + value: [ + { + name: 'Groceries', + value: 100, + }, + { + name: 'Pet Care', + value: 25, + }, + { + name: 'Internet', + value: 50, + }, + ], + }, + ], + }), + ], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ChartsBarHorizontalComponent); + component = fixture.componentInstance; + store = TestBed.inject(MockStore); + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeDefined(); + }); + + it('should call populate chart on #ngOnInit()', () => { + component.ngOnInit(); + fixture.detectChanges(); + + const legend: HTMLElement = fixture.nativeElement.querySelector('ul.legend-labels'); + expect(legend.textContent).toContain('Groceries'); + expect(legend.textContent).toContain('Pet Care'); + expect(legend.textContent).toContain('Internet'); + }); +}); diff --git a/src/app/reports/feature/dashboard/charts/bar-horizontal/bar-horizontal.component.ts b/src/app/reports/feature/dashboard/charts/bar-horizontal/bar-horizontal.component.ts new file mode 100644 index 0000000..49fffb3 --- /dev/null +++ b/src/app/reports/feature/dashboard/charts/bar-horizontal/bar-horizontal.component.ts @@ -0,0 +1,22 @@ +import { AsyncPipe } from '@angular/common'; +import { Component, inject, OnInit } from '@angular/core'; +import { Observable } from 'rxjs'; +import { NgxChartsModule } from '@swimlane/ngx-charts'; +import { Store } from '@ngrx/store'; +import { selectReportResults } from '../../../../data-access/report.selectors'; + +@Component({ + selector: 'app-charts-bar-horizontal', + standalone: true, + imports: [AsyncPipe, NgxChartsModule], + templateUrl: './bar-horizontal.component.html', +}) +export class ChartsBarHorizontalComponent implements OnInit { + store = inject(Store); + + results$: Observable<{ value: number; name: string }[]> | undefined; + + ngOnInit(): void { + this.results$ = this.store.select(selectReportResults); + } +} diff --git a/src/app/reports/feature/dashboard/dashboard.routes.ts b/src/app/reports/feature/dashboard/dashboard.routes.ts index 9ad80b4..f464992 100644 --- a/src/app/reports/feature/dashboard/dashboard.routes.ts +++ b/src/app/reports/feature/dashboard/dashboard.routes.ts @@ -1,6 +1,8 @@ import { Routes } from '@angular/router'; import { ChartsBarVerticalComponent } from './charts/bar-vertical/bar-vertical.component'; +import { ChartsBarHorizontalComponent } from './charts/bar-horizontal/bar-horizontal.component'; export const dashboardRoutes: Routes = [ { path: 'bar-vert', component: ChartsBarVerticalComponent }, + { path: 'bar-horz', component: ChartsBarHorizontalComponent }, ];