I'm failing to access my portfolio
input property inside the labelFormatting
method.
I need this portfolio data in order to calculate the sum, so as to format the label data into percentages.
The problem I'm facing is that the portfolio
object is persistently undefined
when called within the context of the labelFormatting
. I'm assuming this happens because this method is called before the input property is ready, when the chart is first created.
Here is my component:
export class PortfolioPreviewCardComponent {
@Input() portfolio!: IPortfolio;
data = [...];
// options
showLegend = false;
showLabels = true;
isDoughnut = true;
...
...
...
labelFormatting(name: string) { // this name will contain the name you defined in chartData[]
const self: any = this; // this "this" will refer to the chart component
const data: DataItem[] = self.series.filter((x: { name: string }) => x.name == name);
// portfolio is undefined here
const sum = this.portfolio.holdings.reduce((accumulator, item) => {
return accumulator + item.total;
}, 0);
if(data.length > 0) {
return (((data[0].value / sum) * 100).toFixed(2) + '%');
} else {
return name;
}
}
}
Here is the template:
<ngx-charts-pie-chart
*ngIf="portfolio"
scheme="cool"
[results]="data"
[legend]="showLegend"
[labels]="showLabels"
[doughnut]="isDoughnut"
[labelFormatting]="labelFormatting"
(select)="onSelect($event)"
(activate)="onActivate($event)"
(deactivate)="onDeactivate($event)"
>
</ngx-charts-pie-chart>
I mananged to find a solution where I explicitly set the labelFormatting
function of the chart in the AfterViewInit
hook, like so:
@ViewChild('pieChart') pieChart!: PieChartComponent; // template chart reference
...
...
ngAfterViewInit(): void {
if (this.pieChart) {
// used a chartManager service to deal with the labelFormatting logic
this.pieChart.labelFormatting = (name: string) => this.chartManager.labelFormatting(name);
}
}