|
|
@ -16,8 +16,8 @@ import { |
|
|
Input, |
|
|
Input, |
|
|
OnChanges, |
|
|
OnChanges, |
|
|
OnDestroy, |
|
|
OnDestroy, |
|
|
ViewChild, |
|
|
output, |
|
|
output |
|
|
viewChild |
|
|
} from '@angular/core'; |
|
|
} from '@angular/core'; |
|
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; |
|
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; |
|
|
import { |
|
|
import { |
|
|
@ -55,7 +55,7 @@ import { |
|
|
startOfMonth, |
|
|
startOfMonth, |
|
|
sub |
|
|
sub |
|
|
} from 'date-fns'; |
|
|
} from 'date-fns'; |
|
|
import { isNil, isNumber } from 'lodash'; |
|
|
import { isNumber } from 'lodash'; |
|
|
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; |
|
|
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; |
|
|
import { debounceTime } from 'rxjs'; |
|
|
import { debounceTime } from 'rxjs'; |
|
|
|
|
|
|
|
|
@ -90,8 +90,6 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { |
|
|
@Input() retirementDate: Date; |
|
|
@Input() retirementDate: Date; |
|
|
@Input() savingsRate = 0; |
|
|
@Input() savingsRate = 0; |
|
|
|
|
|
|
|
|
@ViewChild('chartCanvas') chartCanvas: ElementRef<HTMLCanvasElement>; |
|
|
|
|
|
|
|
|
|
|
|
public calculatorForm = this.formBuilder.group({ |
|
|
public calculatorForm = this.formBuilder.group({ |
|
|
annualInterestRate: new FormControl<number | null>(null), |
|
|
annualInterestRate: new FormControl<number | null>(null), |
|
|
paymentPerPeriod: new FormControl<number | null>(null), |
|
|
paymentPerPeriod: new FormControl<number | null>(null), |
|
|
@ -99,23 +97,30 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { |
|
|
projectedTotalAmount: new FormControl<number | null>(null), |
|
|
projectedTotalAmount: new FormControl<number | null>(null), |
|
|
retirementDate: new FormControl<Date | null>(null) |
|
|
retirementDate: new FormControl<Date | null>(null) |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
public chart: Chart<'bar'>; |
|
|
public chart: Chart<'bar'>; |
|
|
public isLoading = true; |
|
|
public isLoading = true; |
|
|
public minDate = addDays(new Date(), 1); |
|
|
public minDate = addDays(new Date(), 1); |
|
|
public periodsToRetire = 0; |
|
|
public periodsToRetire = 0; |
|
|
|
|
|
|
|
|
protected readonly annualInterestRateChanged = output<number>(); |
|
|
protected readonly annualInterestRateChanged = output<number>(); |
|
|
|
|
|
|
|
|
protected readonly calculationCompleted = |
|
|
protected readonly calculationCompleted = |
|
|
output<FireCalculationCompleteEvent>(); |
|
|
output<FireCalculationCompleteEvent>(); |
|
|
|
|
|
|
|
|
protected readonly projectedTotalAmountChanged = output<number>(); |
|
|
protected readonly projectedTotalAmountChanged = output<number>(); |
|
|
protected readonly retirementDateChanged = output<Date>(); |
|
|
protected readonly retirementDateChanged = output<Date>(); |
|
|
protected readonly savingsRateChanged = output<number>(); |
|
|
protected readonly savingsRateChanged = output<number>(); |
|
|
|
|
|
|
|
|
private readonly CONTRIBUTION_PERIOD = 12; |
|
|
private readonly CONTRIBUTION_PERIOD = 12; |
|
|
|
|
|
|
|
|
private readonly DEFAULT_RETIREMENT_DATE = startOfMonth( |
|
|
private readonly DEFAULT_RETIREMENT_DATE = startOfMonth( |
|
|
addYears(new Date(), 10) |
|
|
addYears(new Date(), 10) |
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
private readonly chartCanvas = |
|
|
|
|
|
viewChild.required<ElementRef<HTMLCanvasElement>>('chartCanvas'); |
|
|
|
|
|
|
|
|
public constructor( |
|
|
public constructor( |
|
|
private changeDetectorRef: ChangeDetectorRef, |
|
|
private changeDetectorRef: ChangeDetectorRef, |
|
|
private fireCalculatorService: FireCalculatorService, |
|
|
private fireCalculatorService: FireCalculatorService, |
|
|
@ -272,7 +277,7 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { |
|
|
|
|
|
|
|
|
const chartData = this.getChartData(); |
|
|
const chartData = this.getChartData(); |
|
|
|
|
|
|
|
|
if (this.chartCanvas) { |
|
|
if (this.chartCanvas()) { |
|
|
if (this.chart) { |
|
|
if (this.chart) { |
|
|
this.chart.data.labels = chartData.labels; |
|
|
this.chart.data.labels = chartData.labels; |
|
|
|
|
|
|
|
|
@ -282,7 +287,7 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { |
|
|
|
|
|
|
|
|
this.chart.update(); |
|
|
this.chart.update(); |
|
|
} else { |
|
|
} else { |
|
|
this.chart = new Chart<'bar'>(this.chartCanvas.nativeElement, { |
|
|
this.chart = new Chart<'bar'>(this.chartCanvas().nativeElement, { |
|
|
data: chartData, |
|
|
data: chartData, |
|
|
options: { |
|
|
options: { |
|
|
plugins: { |
|
|
plugins: { |
|
|
@ -303,7 +308,7 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { |
|
|
}).format(totalAmount)}`;
|
|
|
}).format(totalAmount)}`;
|
|
|
}, |
|
|
}, |
|
|
label: (context) => { |
|
|
label: (context) => { |
|
|
let label = context.dataset.label || ''; |
|
|
let label = context.dataset.label ?? ''; |
|
|
|
|
|
|
|
|
if (label) { |
|
|
if (label) { |
|
|
label += ': '; |
|
|
label += ': '; |
|
|
@ -473,7 +478,7 @@ export class GfFireCalculatorComponent implements OnChanges, OnDestroy { |
|
|
'projectedTotalAmount' |
|
|
'projectedTotalAmount' |
|
|
)?.value; |
|
|
)?.value; |
|
|
|
|
|
|
|
|
if (!isNil(projectedTotalAmount)) { |
|
|
if (projectedTotalAmount) { |
|
|
return projectedTotalAmount; |
|
|
return projectedTotalAmount; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|