|
|
@ -1,6 +1,5 @@ |
|
|
import { |
|
|
import { |
|
|
getTooltipOptions, |
|
|
getTooltipOptions, |
|
|
getTooltipPositionerMapTop, |
|
|
|
|
|
getVerticalHoverLinePlugin, |
|
|
getVerticalHoverLinePlugin, |
|
|
transformTickToAbbreviation |
|
|
transformTickToAbbreviation |
|
|
} from '@ghostfolio/common/chart-helper'; |
|
|
} from '@ghostfolio/common/chart-helper'; |
|
|
@ -15,11 +14,13 @@ import { |
|
|
import { LineChartItem } from '@ghostfolio/common/interfaces'; |
|
|
import { LineChartItem } from '@ghostfolio/common/interfaces'; |
|
|
import { InvestmentItem } from '@ghostfolio/common/interfaces/investment-item.interface'; |
|
|
import { InvestmentItem } from '@ghostfolio/common/interfaces/investment-item.interface'; |
|
|
import { ColorScheme, GroupBy } from '@ghostfolio/common/types'; |
|
|
import { ColorScheme, GroupBy } from '@ghostfolio/common/types'; |
|
|
|
|
|
import { registerChartConfiguration } from '@ghostfolio/ui/chart'; |
|
|
|
|
|
|
|
|
import { CommonModule } from '@angular/common'; |
|
|
import { CommonModule } from '@angular/common'; |
|
|
import { |
|
|
import { |
|
|
ChangeDetectionStrategy, |
|
|
ChangeDetectionStrategy, |
|
|
Component, |
|
|
Component, |
|
|
|
|
|
type ElementRef, |
|
|
Input, |
|
|
Input, |
|
|
OnChanges, |
|
|
OnChanges, |
|
|
OnDestroy, |
|
|
OnDestroy, |
|
|
@ -34,9 +35,10 @@ import { |
|
|
LineController, |
|
|
LineController, |
|
|
LineElement, |
|
|
LineElement, |
|
|
PointElement, |
|
|
PointElement, |
|
|
|
|
|
type ScriptableLineSegmentContext, |
|
|
TimeScale, |
|
|
TimeScale, |
|
|
Tooltip, |
|
|
Tooltip, |
|
|
TooltipPosition |
|
|
type TooltipOptions |
|
|
} from 'chart.js'; |
|
|
} from 'chart.js'; |
|
|
import 'chartjs-adapter-date-fns'; |
|
|
import 'chartjs-adapter-date-fns'; |
|
|
import annotationPlugin from 'chartjs-plugin-annotation'; |
|
|
import annotationPlugin from 'chartjs-plugin-annotation'; |
|
|
@ -62,7 +64,7 @@ export class GfInvestmentChartComponent implements OnChanges, OnDestroy { |
|
|
@Input() locale = getLocale(); |
|
|
@Input() locale = getLocale(); |
|
|
@Input() savingsRate = 0; |
|
|
@Input() savingsRate = 0; |
|
|
|
|
|
|
|
|
@ViewChild('chartCanvas') chartCanvas; |
|
|
@ViewChild('chartCanvas') chartCanvas: ElementRef<HTMLCanvasElement>; |
|
|
|
|
|
|
|
|
public chart: Chart<'bar' | 'line'>; |
|
|
public chart: Chart<'bar' | 'line'>; |
|
|
private investments: InvestmentItem[]; |
|
|
private investments: InvestmentItem[]; |
|
|
@ -81,8 +83,7 @@ export class GfInvestmentChartComponent implements OnChanges, OnDestroy { |
|
|
Tooltip |
|
|
Tooltip |
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
Tooltip.positioners['top'] = (_elements, position: TooltipPosition) => |
|
|
registerChartConfiguration(); |
|
|
getTooltipPositionerMapTop(this.chart, position); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public ngOnChanges() { |
|
|
public ngOnChanges() { |
|
|
@ -121,12 +122,12 @@ export class GfInvestmentChartComponent implements OnChanges, OnDestroy { |
|
|
}), |
|
|
}), |
|
|
label: this.benchmarkDataLabel, |
|
|
label: this.benchmarkDataLabel, |
|
|
segment: { |
|
|
segment: { |
|
|
borderColor: (context: unknown) => |
|
|
borderColor: (context) => |
|
|
this.isInFuture( |
|
|
this.isInFuture( |
|
|
context, |
|
|
context, |
|
|
`rgba(${secondaryColorRgb.r}, ${secondaryColorRgb.g}, ${secondaryColorRgb.b}, 0.67)` |
|
|
`rgba(${secondaryColorRgb.r}, ${secondaryColorRgb.g}, ${secondaryColorRgb.b}, 0.67)` |
|
|
), |
|
|
), |
|
|
borderDash: (context: unknown) => this.isInFuture(context, [2, 2]) |
|
|
borderDash: (context) => this.isInFuture(context, [2, 2]) |
|
|
}, |
|
|
}, |
|
|
stepped: true |
|
|
stepped: true |
|
|
}, |
|
|
}, |
|
|
@ -143,12 +144,12 @@ export class GfInvestmentChartComponent implements OnChanges, OnDestroy { |
|
|
label: $localize`Total Amount`, |
|
|
label: $localize`Total Amount`, |
|
|
pointRadius: 0, |
|
|
pointRadius: 0, |
|
|
segment: { |
|
|
segment: { |
|
|
borderColor: (context: unknown) => |
|
|
borderColor: (context) => |
|
|
this.isInFuture( |
|
|
this.isInFuture( |
|
|
context, |
|
|
context, |
|
|
`rgba(${primaryColorRgb.r}, ${primaryColorRgb.g}, ${primaryColorRgb.b}, 0.67)` |
|
|
`rgba(${primaryColorRgb.r}, ${primaryColorRgb.g}, ${primaryColorRgb.b}, 0.67)` |
|
|
), |
|
|
), |
|
|
borderDash: (context: unknown) => this.isInFuture(context, [2, 2]) |
|
|
borderDash: (context) => this.isInFuture(context, [2, 2]) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
] |
|
|
] |
|
|
@ -157,8 +158,9 @@ export class GfInvestmentChartComponent implements OnChanges, OnDestroy { |
|
|
if (this.chartCanvas) { |
|
|
if (this.chartCanvas) { |
|
|
if (this.chart) { |
|
|
if (this.chart) { |
|
|
this.chart.data = chartData; |
|
|
this.chart.data = chartData; |
|
|
|
|
|
this.chart.options.plugins ??= {}; |
|
|
this.chart.options.plugins.tooltip = |
|
|
this.chart.options.plugins.tooltip = |
|
|
this.getTooltipPluginConfiguration() as unknown; |
|
|
this.getTooltipPluginConfiguration(); |
|
|
|
|
|
|
|
|
if ( |
|
|
if ( |
|
|
this.savingsRate && |
|
|
this.savingsRate && |
|
|
@ -201,7 +203,7 @@ export class GfInvestmentChartComponent implements OnChanges, OnDestroy { |
|
|
color: 'white', |
|
|
color: 'white', |
|
|
content: $localize`Savings Rate`, |
|
|
content: $localize`Savings Rate`, |
|
|
display: true, |
|
|
display: true, |
|
|
font: { size: '10px', weight: 'normal' }, |
|
|
font: { size: 10, weight: 'normal' }, |
|
|
padding: { |
|
|
padding: { |
|
|
x: 4, |
|
|
x: 4, |
|
|
y: 2 |
|
|
y: 2 |
|
|
@ -229,7 +231,7 @@ export class GfInvestmentChartComponent implements OnChanges, OnDestroy { |
|
|
verticalHoverLine: { |
|
|
verticalHoverLine: { |
|
|
color: `rgba(${getTextColor(this.colorScheme)}, 0.1)` |
|
|
color: `rgba(${getTextColor(this.colorScheme)}, 0.1)` |
|
|
} |
|
|
} |
|
|
} as unknown, |
|
|
}, |
|
|
responsive: true, |
|
|
responsive: true, |
|
|
scales: { |
|
|
scales: { |
|
|
x: { |
|
|
x: { |
|
|
@ -286,7 +288,9 @@ export class GfInvestmentChartComponent implements OnChanges, OnDestroy { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private getTooltipPluginConfiguration() { |
|
|
private getTooltipPluginConfiguration(): Partial< |
|
|
|
|
|
TooltipOptions<'bar' | 'line'> |
|
|
|
|
|
> { |
|
|
return { |
|
|
return { |
|
|
...getTooltipOptions({ |
|
|
...getTooltipOptions({ |
|
|
colorScheme: this.colorScheme, |
|
|
colorScheme: this.colorScheme, |
|
|
@ -296,13 +300,13 @@ export class GfInvestmentChartComponent implements OnChanges, OnDestroy { |
|
|
unit: this.isInPercent ? '%' : undefined |
|
|
unit: this.isInPercent ? '%' : undefined |
|
|
}), |
|
|
}), |
|
|
mode: 'index', |
|
|
mode: 'index', |
|
|
position: 'top' as unknown, |
|
|
position: 'top', |
|
|
xAlign: 'center', |
|
|
xAlign: 'center', |
|
|
yAlign: 'bottom' |
|
|
yAlign: 'bottom' |
|
|
}; |
|
|
}; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private isInFuture<T>(aContext: any, aValue: T) { |
|
|
private isInFuture<T>(aContext: ScriptableLineSegmentContext, aValue: T) { |
|
|
return isAfter(new Date(aContext?.p1?.parsed?.x), new Date()) |
|
|
return isAfter(new Date(aContext?.p1?.parsed?.x), new Date()) |
|
|
? aValue |
|
|
? aValue |
|
|
: undefined; |
|
|
: undefined; |
|
|
|