Feature/add vertical hover line to line chart component (#963)
* Add vertical hover line * Improve tooltips of charts * Update changelog
This commit is contained in:
parent
34d4212f55
commit
15dda886a0
@ -7,8 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added a vertical hover line to inspect data points in the line chart component
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
- Improved the tooltips of the chart components (content and style)
|
||||||
- Simplified the pricing page
|
- Simplified the pricing page
|
||||||
|
|
||||||
## 1.153.0 - 27.05.2022
|
## 1.153.0 - 27.05.2022
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
<gf-line-chart
|
<gf-line-chart
|
||||||
class="mb-4"
|
class="mb-4"
|
||||||
[historicalDataItems]="historicalDataItems"
|
[historicalDataItems]="historicalDataItems"
|
||||||
|
[locale]="locale"
|
||||||
[showXAxis]="true"
|
[showXAxis]="true"
|
||||||
[showYAxis]="true"
|
[showYAxis]="true"
|
||||||
|
[symbol]="symbol"
|
||||||
></gf-line-chart>
|
></gf-line-chart>
|
||||||
<div *ngFor="let itemByMonth of marketDataByMonth | keyvalue" class="d-flex">
|
<div *ngFor="let itemByMonth of marketDataByMonth | keyvalue" class="d-flex">
|
||||||
<div class="date px-1 text-nowrap">{{ itemByMonth.key }}</div>
|
<div class="date px-1 text-nowrap">{{ itemByMonth.key }}</div>
|
||||||
|
@ -7,11 +7,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<gf-line-chart
|
<gf-line-chart
|
||||||
class="mb-3"
|
class="mb-3"
|
||||||
|
symbol="Fear & Greed Index"
|
||||||
yMax="100"
|
yMax="100"
|
||||||
yMaxLabel="Greed"
|
yMaxLabel="Greed"
|
||||||
yMin="0"
|
yMin="0"
|
||||||
yMinLabel="Fear"
|
yMinLabel="Fear"
|
||||||
[historicalDataItems]="historicalData"
|
[historicalDataItems]="historicalData"
|
||||||
|
[locale]="user?.settings?.locale"
|
||||||
[showXAxis]="true"
|
[showXAxis]="true"
|
||||||
[showYAxis]="true"
|
[showYAxis]="true"
|
||||||
></gf-line-chart>
|
></gf-line-chart>
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
<gf-line-chart
|
<gf-line-chart
|
||||||
symbol="Performance"
|
symbol="Performance"
|
||||||
[historicalDataItems]="historicalDataItems"
|
[historicalDataItems]="historicalDataItems"
|
||||||
|
[locale]="user?.settings?.locale"
|
||||||
[ngClass]="{ 'pr-3': deviceType === 'mobile' }"
|
[ngClass]="{ 'pr-3': deviceType === 'mobile' }"
|
||||||
[showGradient]="true"
|
[showGradient]="true"
|
||||||
[showLoader]="false"
|
[showLoader]="false"
|
||||||
|
@ -6,11 +6,18 @@ import {
|
|||||||
Input,
|
Input,
|
||||||
OnChanges,
|
OnChanges,
|
||||||
OnDestroy,
|
OnDestroy,
|
||||||
OnInit,
|
|
||||||
ViewChild
|
ViewChild
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
import {
|
||||||
|
getTooltipOptions,
|
||||||
|
getTooltipPositionerMapTop,
|
||||||
|
getVerticalHoverLinePlugin
|
||||||
|
} from '@ghostfolio/common/chart-helper';
|
||||||
import { primaryColorRgb } from '@ghostfolio/common/config';
|
import { primaryColorRgb } from '@ghostfolio/common/config';
|
||||||
import {
|
import {
|
||||||
|
getBackgroundColor,
|
||||||
|
getDateFormatString,
|
||||||
|
getTextColor,
|
||||||
parseDate,
|
parseDate,
|
||||||
transformTickToAbbreviation
|
transformTickToAbbreviation
|
||||||
} from '@ghostfolio/common/helper';
|
} from '@ghostfolio/common/helper';
|
||||||
@ -21,7 +28,8 @@ import {
|
|||||||
LineElement,
|
LineElement,
|
||||||
LinearScale,
|
LinearScale,
|
||||||
PointElement,
|
PointElement,
|
||||||
TimeScale
|
TimeScale,
|
||||||
|
Tooltip
|
||||||
} from 'chart.js';
|
} from 'chart.js';
|
||||||
import { addDays, isAfter, parseISO, subDays } from 'date-fns';
|
import { addDays, isAfter, parseISO, subDays } from 'date-fns';
|
||||||
|
|
||||||
@ -32,9 +40,11 @@ import { addDays, isAfter, parseISO, subDays } from 'date-fns';
|
|||||||
styleUrls: ['./investment-chart.component.scss']
|
styleUrls: ['./investment-chart.component.scss']
|
||||||
})
|
})
|
||||||
export class InvestmentChartComponent implements OnChanges, OnDestroy {
|
export class InvestmentChartComponent implements OnChanges, OnDestroy {
|
||||||
|
@Input() currency: string;
|
||||||
@Input() daysInMarket: number;
|
@Input() daysInMarket: number;
|
||||||
@Input() investments: InvestmentItem[];
|
@Input() investments: InvestmentItem[];
|
||||||
@Input() isInPercent = false;
|
@Input() isInPercent = false;
|
||||||
|
@Input() locale: string;
|
||||||
|
|
||||||
@ViewChild('chartCanvas') chartCanvas;
|
@ViewChild('chartCanvas') chartCanvas;
|
||||||
|
|
||||||
@ -47,8 +57,12 @@ export class InvestmentChartComponent implements OnChanges, OnDestroy {
|
|||||||
LineController,
|
LineController,
|
||||||
LineElement,
|
LineElement,
|
||||||
PointElement,
|
PointElement,
|
||||||
TimeScale
|
TimeScale,
|
||||||
|
Tooltip
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Tooltip.positioners['top'] = (elements, position) =>
|
||||||
|
getTooltipPositionerMapTop(this.chart, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ngOnChanges() {
|
public ngOnChanges() {
|
||||||
@ -98,6 +112,7 @@ export class InvestmentChartComponent implements OnChanges, OnDestroy {
|
|||||||
data: this.investments.map((position) => {
|
data: this.investments.map((position) => {
|
||||||
return position.investment;
|
return position.investment;
|
||||||
}),
|
}),
|
||||||
|
label: 'Investment',
|
||||||
segment: {
|
segment: {
|
||||||
borderColor: (context: unknown) =>
|
borderColor: (context: unknown) =>
|
||||||
this.isInFuture(
|
this.isInFuture(
|
||||||
@ -114,6 +129,9 @@ export class InvestmentChartComponent implements OnChanges, OnDestroy {
|
|||||||
if (this.chartCanvas) {
|
if (this.chartCanvas) {
|
||||||
if (this.chart) {
|
if (this.chart) {
|
||||||
this.chart.data = data;
|
this.chart.data = data;
|
||||||
|
this.chart.options.plugins.tooltip = <unknown>(
|
||||||
|
this.getTooltipPluginConfiguration()
|
||||||
|
);
|
||||||
this.chart.update();
|
this.chart.update();
|
||||||
} else {
|
} else {
|
||||||
this.chart = new Chart(this.chartCanvas.nativeElement, {
|
this.chart = new Chart(this.chartCanvas.nativeElement, {
|
||||||
@ -124,13 +142,20 @@ export class InvestmentChartComponent implements OnChanges, OnDestroy {
|
|||||||
tension: 0
|
tension: 0
|
||||||
},
|
},
|
||||||
point: {
|
point: {
|
||||||
|
hoverBackgroundColor: getBackgroundColor(),
|
||||||
|
hoverRadius: 2,
|
||||||
radius: 0
|
radius: 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
interaction: { intersect: false, mode: 'index' },
|
||||||
maintainAspectRatio: true,
|
maintainAspectRatio: true,
|
||||||
plugins: {
|
plugins: <unknown>{
|
||||||
legend: {
|
legend: {
|
||||||
display: false
|
display: false
|
||||||
|
},
|
||||||
|
tooltip: this.getTooltipPluginConfiguration(),
|
||||||
|
verticalHoverLine: {
|
||||||
|
color: `rgba(${getTextColor()}, 0.1)`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
responsive: true,
|
responsive: true,
|
||||||
@ -138,16 +163,21 @@ export class InvestmentChartComponent implements OnChanges, OnDestroy {
|
|||||||
x: {
|
x: {
|
||||||
display: true,
|
display: true,
|
||||||
grid: {
|
grid: {
|
||||||
|
borderColor: `rgba(${getTextColor()}, 0.1)`,
|
||||||
|
color: `rgba(${getTextColor()}, 0.8)`,
|
||||||
display: false
|
display: false
|
||||||
},
|
},
|
||||||
type: 'time',
|
type: 'time',
|
||||||
time: {
|
time: {
|
||||||
|
tooltipFormat: getDateFormatString(this.locale),
|
||||||
unit: 'year'
|
unit: 'year'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
y: {
|
y: {
|
||||||
display: !this.isInPercent,
|
display: !this.isInPercent,
|
||||||
grid: {
|
grid: {
|
||||||
|
borderColor: `rgba(${getTextColor()}, 0.1)`,
|
||||||
|
color: `rgba(${getTextColor()}, 0.8)`,
|
||||||
display: false
|
display: false
|
||||||
},
|
},
|
||||||
ticks: {
|
ticks: {
|
||||||
@ -161,6 +191,7 @@ export class InvestmentChartComponent implements OnChanges, OnDestroy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
plugins: [getVerticalHoverLinePlugin(this.chartCanvas)],
|
||||||
type: 'line'
|
type: 'line'
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -169,6 +200,19 @@ export class InvestmentChartComponent implements OnChanges, OnDestroy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getTooltipPluginConfiguration() {
|
||||||
|
return {
|
||||||
|
...getTooltipOptions(
|
||||||
|
this.isInPercent ? undefined : this.currency,
|
||||||
|
this.isInPercent ? undefined : this.locale
|
||||||
|
),
|
||||||
|
mode: 'index',
|
||||||
|
position: <unknown>'top',
|
||||||
|
xAlign: 'center',
|
||||||
|
yAlign: 'bottom'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private isInFuture<T>(aContext: any, aValue: T) {
|
private isInFuture<T>(aContext: any, aValue: T) {
|
||||||
return isAfter(new Date(aContext?.p1?.parsed?.x), new Date())
|
return isAfter(new Date(aContext?.p1?.parsed?.x), new Date())
|
||||||
? aValue
|
? aValue
|
||||||
|
@ -23,7 +23,9 @@
|
|||||||
class="mb-4"
|
class="mb-4"
|
||||||
benchmarkLabel="Average Unit Price"
|
benchmarkLabel="Average Unit Price"
|
||||||
[benchmarkDataItems]="benchmarkDataItems"
|
[benchmarkDataItems]="benchmarkDataItems"
|
||||||
|
[currency]="SymbolProfile?.currency"
|
||||||
[historicalDataItems]="historicalDataItems"
|
[historicalDataItems]="historicalDataItems"
|
||||||
|
[locale]="data.locale"
|
||||||
[showGradient]="true"
|
[showGradient]="true"
|
||||||
[showXAxis]="true"
|
[showXAxis]="true"
|
||||||
[showYAxis]="true"
|
[showYAxis]="true"
|
||||||
|
@ -2,21 +2,17 @@
|
|||||||
<div class="investment-chart row">
|
<div class="investment-chart row">
|
||||||
<div class="col-lg">
|
<div class="col-lg">
|
||||||
<h3 class="d-flex justify-content-center mb-3" i18n>Analysis</h3>
|
<h3 class="d-flex justify-content-center mb-3" i18n>Analysis</h3>
|
||||||
<mat-card class="mb-3">
|
<div class="mb-3">
|
||||||
<mat-card-header>
|
<div class="h5 mb-3" i18n>Investment Timeline</div>
|
||||||
<mat-card-title class="align-items-center d-flex" i18n
|
<gf-investment-chart
|
||||||
>Investment Timeline</mat-card-title
|
class="h-100"
|
||||||
>
|
[currency]="user?.settings?.baseCurrency"
|
||||||
</mat-card-header>
|
[daysInMarket]="daysInMarket"
|
||||||
<mat-card-content>
|
[isInPercent]="hasImpersonationId || user.settings.isRestrictedView"
|
||||||
<gf-investment-chart
|
[investments]="investments"
|
||||||
class="h-100"
|
[locale]="user?.settings?.locale"
|
||||||
[daysInMarket]="daysInMarket"
|
></gf-investment-chart>
|
||||||
[isInPercent]="hasImpersonationId || user.settings.isRestrictedView"
|
</div>
|
||||||
[investments]="investments"
|
|
||||||
></gf-investment-chart>
|
|
||||||
</mat-card-content>
|
|
||||||
</mat-card>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
83
libs/common/src/lib/chart-helper.ts
Normal file
83
libs/common/src/lib/chart-helper.ts
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
import { Chart, TooltipPosition } from 'chart.js';
|
||||||
|
|
||||||
|
import { getBackgroundColor, getTextColor } from './helper';
|
||||||
|
|
||||||
|
export function getTooltipOptions(currency = '', locale = '') {
|
||||||
|
return {
|
||||||
|
backgroundColor: getBackgroundColor(),
|
||||||
|
bodyColor: `rgb(${getTextColor()})`,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: `rgba(${getTextColor()}, 0.1)`,
|
||||||
|
callbacks: {
|
||||||
|
label: (context) => {
|
||||||
|
let label = context.dataset.label || '';
|
||||||
|
if (label) {
|
||||||
|
label += ': ';
|
||||||
|
}
|
||||||
|
if (context.parsed.y !== null) {
|
||||||
|
if (currency) {
|
||||||
|
label += `${context.parsed.y.toLocaleString(locale, {
|
||||||
|
maximumFractionDigits: 2,
|
||||||
|
minimumFractionDigits: 2
|
||||||
|
})} ${currency}`;
|
||||||
|
} else {
|
||||||
|
label += context.parsed.y.toFixed(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
caretSize: 0,
|
||||||
|
cornerRadius: 2,
|
||||||
|
footerColor: `rgb(${getTextColor()})`,
|
||||||
|
itemSort: (a, b) => {
|
||||||
|
// Reverse order
|
||||||
|
return b.datasetIndex - a.datasetIndex;
|
||||||
|
},
|
||||||
|
titleColor: `rgb(${getTextColor()})`,
|
||||||
|
usePointStyle: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTooltipPositionerMapTop(
|
||||||
|
chart: Chart,
|
||||||
|
position: TooltipPosition
|
||||||
|
) {
|
||||||
|
if (!position) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
x: position.x,
|
||||||
|
y: chart.chartArea.top
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getVerticalHoverLinePlugin(chartCanvas) {
|
||||||
|
return {
|
||||||
|
afterDatasetsDraw: (chart, x, options) => {
|
||||||
|
const active = chart.getActiveElements();
|
||||||
|
|
||||||
|
if (!active || active.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const color = options.color || `rgb(${getTextColor()})`;
|
||||||
|
const width = options.width || 1;
|
||||||
|
|
||||||
|
const {
|
||||||
|
chartArea: { bottom, top }
|
||||||
|
} = chart;
|
||||||
|
const xValue = active[0].element.x;
|
||||||
|
|
||||||
|
const context = chartCanvas.nativeElement.getContext('2d');
|
||||||
|
context.lineWidth = width;
|
||||||
|
context.strokeStyle = color;
|
||||||
|
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(xValue, top);
|
||||||
|
context.lineTo(xValue, bottom);
|
||||||
|
context.stroke();
|
||||||
|
},
|
||||||
|
id: 'verticalHoverLine'
|
||||||
|
};
|
||||||
|
}
|
@ -13,6 +13,7 @@ import {
|
|||||||
ViewChild
|
ViewChild
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { FormBuilder, FormControl } from '@angular/forms';
|
import { FormBuilder, FormControl } from '@angular/forms';
|
||||||
|
import { getTooltipOptions } from '@ghostfolio/common/chart-helper';
|
||||||
import { primaryColorRgb } from '@ghostfolio/common/config';
|
import { primaryColorRgb } from '@ghostfolio/common/config';
|
||||||
import { transformTickToAbbreviation } from '@ghostfolio/common/helper';
|
import { transformTickToAbbreviation } from '@ghostfolio/common/helper';
|
||||||
import {
|
import {
|
||||||
@ -182,10 +183,7 @@ export class FireCalculatorComponent
|
|||||||
options: {
|
options: {
|
||||||
plugins: {
|
plugins: {
|
||||||
tooltip: {
|
tooltip: {
|
||||||
itemSort: (a, b) => {
|
...getTooltipOptions(),
|
||||||
// Reverse order
|
|
||||||
return b.datasetIndex - a.datasetIndex;
|
|
||||||
},
|
|
||||||
mode: 'index',
|
mode: 'index',
|
||||||
callbacks: {
|
callbacks: {
|
||||||
footer: (items) => {
|
footer: (items) => {
|
||||||
|
@ -10,8 +10,17 @@ import {
|
|||||||
OnDestroy,
|
OnDestroy,
|
||||||
ViewChild
|
ViewChild
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
import {
|
||||||
|
getTooltipOptions,
|
||||||
|
getTooltipPositionerMapTop,
|
||||||
|
getVerticalHoverLinePlugin
|
||||||
|
} from '@ghostfolio/common/chart-helper';
|
||||||
import { primaryColorRgb, secondaryColorRgb } from '@ghostfolio/common/config';
|
import { primaryColorRgb, secondaryColorRgb } from '@ghostfolio/common/config';
|
||||||
import { getBackgroundColor } from '@ghostfolio/common/helper';
|
import {
|
||||||
|
getBackgroundColor,
|
||||||
|
getDateFormatString,
|
||||||
|
getTextColor
|
||||||
|
} from '@ghostfolio/common/helper';
|
||||||
import {
|
import {
|
||||||
Chart,
|
Chart,
|
||||||
Filler,
|
Filler,
|
||||||
@ -19,7 +28,8 @@ import {
|
|||||||
LineElement,
|
LineElement,
|
||||||
LinearScale,
|
LinearScale,
|
||||||
PointElement,
|
PointElement,
|
||||||
TimeScale
|
TimeScale,
|
||||||
|
Tooltip
|
||||||
} from 'chart.js';
|
} from 'chart.js';
|
||||||
|
|
||||||
import { LineChartItem } from './interfaces/line-chart.interface';
|
import { LineChartItem } from './interfaces/line-chart.interface';
|
||||||
@ -33,7 +43,9 @@ import { LineChartItem } from './interfaces/line-chart.interface';
|
|||||||
export class LineChartComponent implements AfterViewInit, OnChanges, OnDestroy {
|
export class LineChartComponent implements AfterViewInit, OnChanges, OnDestroy {
|
||||||
@Input() benchmarkDataItems: LineChartItem[] = [];
|
@Input() benchmarkDataItems: LineChartItem[] = [];
|
||||||
@Input() benchmarkLabel = '';
|
@Input() benchmarkLabel = '';
|
||||||
|
@Input() currency: string;
|
||||||
@Input() historicalDataItems: LineChartItem[];
|
@Input() historicalDataItems: LineChartItem[];
|
||||||
|
@Input() locale: string;
|
||||||
@Input() showGradient = false;
|
@Input() showGradient = false;
|
||||||
@Input() showLegend = false;
|
@Input() showLegend = false;
|
||||||
@Input() showLoader = true;
|
@Input() showLoader = true;
|
||||||
@ -57,8 +69,12 @@ export class LineChartComponent implements AfterViewInit, OnChanges, OnDestroy {
|
|||||||
LineElement,
|
LineElement,
|
||||||
PointElement,
|
PointElement,
|
||||||
LinearScale,
|
LinearScale,
|
||||||
TimeScale
|
TimeScale,
|
||||||
|
Tooltip
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Tooltip.positioners['top'] = (elements, position) =>
|
||||||
|
getTooltipPositionerMapTop(this.chart, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ngAfterViewInit() {
|
public ngAfterViewInit() {
|
||||||
@ -142,26 +158,43 @@ export class LineChartComponent implements AfterViewInit, OnChanges, OnDestroy {
|
|||||||
if (this.chartCanvas) {
|
if (this.chartCanvas) {
|
||||||
if (this.chart) {
|
if (this.chart) {
|
||||||
this.chart.data = data;
|
this.chart.data = data;
|
||||||
|
this.chart.options.plugins.tooltip = <unknown>(
|
||||||
|
this.getTooltipPluginConfiguration()
|
||||||
|
);
|
||||||
this.chart.update();
|
this.chart.update();
|
||||||
} else {
|
} else {
|
||||||
this.chart = new Chart(this.chartCanvas.nativeElement, {
|
this.chart = new Chart(this.chartCanvas.nativeElement, {
|
||||||
data,
|
data,
|
||||||
options: {
|
options: {
|
||||||
animation: false,
|
animation: false,
|
||||||
plugins: {
|
elements: {
|
||||||
|
point: {
|
||||||
|
hoverBackgroundColor: getBackgroundColor(),
|
||||||
|
hoverRadius: 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
interaction: { intersect: false, mode: 'index' },
|
||||||
|
plugins: <unknown>{
|
||||||
legend: {
|
legend: {
|
||||||
align: 'start',
|
align: 'start',
|
||||||
display: this.showLegend,
|
display: this.showLegend,
|
||||||
position: 'bottom'
|
position: 'bottom'
|
||||||
|
},
|
||||||
|
tooltip: this.getTooltipPluginConfiguration(),
|
||||||
|
verticalHoverLine: {
|
||||||
|
color: `rgba(${getTextColor()}, 0.1)`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
scales: {
|
scales: {
|
||||||
x: {
|
x: {
|
||||||
display: this.showXAxis,
|
display: this.showXAxis,
|
||||||
grid: {
|
grid: {
|
||||||
|
borderColor: `rgba(${getTextColor()}, 0.1)`,
|
||||||
|
color: `rgba(${getTextColor()}, 0.8)`,
|
||||||
display: false
|
display: false
|
||||||
},
|
},
|
||||||
time: {
|
time: {
|
||||||
|
tooltipFormat: getDateFormatString(this.locale),
|
||||||
unit: 'year'
|
unit: 'year'
|
||||||
},
|
},
|
||||||
type: 'time'
|
type: 'time'
|
||||||
@ -169,6 +202,8 @@ export class LineChartComponent implements AfterViewInit, OnChanges, OnDestroy {
|
|||||||
y: {
|
y: {
|
||||||
display: this.showYAxis,
|
display: this.showYAxis,
|
||||||
grid: {
|
grid: {
|
||||||
|
borderColor: `rgba(${getTextColor()}, 0.1)`,
|
||||||
|
color: `rgba(${getTextColor()}, 0.8)`,
|
||||||
display: false
|
display: false
|
||||||
},
|
},
|
||||||
max: this.yMax,
|
max: this.yMax,
|
||||||
@ -204,6 +239,7 @@ export class LineChartComponent implements AfterViewInit, OnChanges, OnDestroy {
|
|||||||
},
|
},
|
||||||
spanGaps: true
|
spanGaps: true
|
||||||
},
|
},
|
||||||
|
plugins: [getVerticalHoverLinePlugin(this.chartCanvas)],
|
||||||
type: 'line'
|
type: 'line'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -211,4 +247,14 @@ export class LineChartComponent implements AfterViewInit, OnChanges, OnDestroy {
|
|||||||
|
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getTooltipPluginConfiguration() {
|
||||||
|
return {
|
||||||
|
...getTooltipOptions(this.currency, this.locale),
|
||||||
|
mode: 'index',
|
||||||
|
position: <unknown>'top',
|
||||||
|
xAlign: 'center',
|
||||||
|
yAlign: 'bottom'
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import {
|
|||||||
Output,
|
Output,
|
||||||
ViewChild
|
ViewChild
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
import { getTooltipOptions } from '@ghostfolio/common/chart-helper';
|
||||||
import { UNKNOWN_KEY } from '@ghostfolio/common/config';
|
import { UNKNOWN_KEY } from '@ghostfolio/common/config';
|
||||||
import { getTextColor } from '@ghostfolio/common/helper';
|
import { getTextColor } from '@ghostfolio/common/helper';
|
||||||
import { PortfolioPosition, UniqueAsset } from '@ghostfolio/common/interfaces';
|
import { PortfolioPosition, UniqueAsset } from '@ghostfolio/common/interfaces';
|
||||||
@ -255,8 +256,9 @@ export class PortfolioProportionChartComponent
|
|||||||
if (this.chartCanvas) {
|
if (this.chartCanvas) {
|
||||||
if (this.chart) {
|
if (this.chart) {
|
||||||
this.chart.data = data;
|
this.chart.data = data;
|
||||||
this.chart.options.plugins.tooltip =
|
this.chart.options.plugins.tooltip = <unknown>(
|
||||||
this.getTooltipPluginConfiguration(data);
|
this.getTooltipPluginConfiguration(data)
|
||||||
|
);
|
||||||
this.chart.update();
|
this.chart.update();
|
||||||
} else {
|
} else {
|
||||||
this.chart = new Chart(this.chartCanvas.nativeElement, {
|
this.chart = new Chart(this.chartCanvas.nativeElement, {
|
||||||
@ -339,6 +341,7 @@ export class PortfolioProportionChartComponent
|
|||||||
|
|
||||||
private getTooltipPluginConfiguration(data: ChartConfiguration['data']) {
|
private getTooltipPluginConfiguration(data: ChartConfiguration['data']) {
|
||||||
return {
|
return {
|
||||||
|
...getTooltipOptions(this.baseCurrency, this.locale),
|
||||||
callbacks: {
|
callbacks: {
|
||||||
label: (context) => {
|
label: (context) => {
|
||||||
const labelIndex =
|
const labelIndex =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user