I have an Angular project which has a chart generated by ng2-charts which is populated by data entered by the user themselves via a select box for the labels and an input field for the data. While I can get it to update with the data, if I change the values at all then it won't update the values, it'll just add them as new ones. See the screenshots below:
I've tried checking on here and other areas of the web, but I haven't found an answer that solves my problem. I believe it has something to do with targeting the specific area of the array, but I can't quite hit upon the right code to do so.
Here is my current code which will allow me to add the data but not update. I'm quite new to Angular so forgive me if some of the code is a bit... rustic.
HTML:
<div class="deposit-container">
<div class="chart-container">
<canvas
baseChart
width="290"
height="290"
[data]="doughnutChartData"
[labels]="doughnutChartLabels"
[options]="doughnutChartOptions"
[colors]="doughnutChartColors"
[chartType]="doughnutChartType"
></canvas>
</div>
<div class="source-container">
<div
*ngFor="let depositSource of depositSources; let depositParent = index"
id="{{ 'source' + depositParent }}"
class="deposit-source"
>
<mat-form-field class="dropdown">
<mat-select placeholder="Deposit source" [(ngModel)]="depositSourceValue[depositParent]" [ngModelOptions]="{ standalone: true }" (selectionChange)="getLabel(depositParent)">
<mat-option
*ngFor="let deposit of deposits; let depositSourceOption = index"
[value]="deposit.value"
id="{{ 'option' + depositSourceOption }}"
>
{{ deposit.value }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="textfield">
<input
matInput
currencyMask
[options]="{ align: 'right', prefix: '£ ', thousands: ',', precision: 0 }"
placeholder="£ 0"
[(ngModel)]="depositSourceAmount[depositParent]"
[ngModelOptions]="{ standalone: true }"
(focusout)="getData(depositParent)"
/>
</mat-form-field>
<mat-icon (click)="removeDeposit(depositSource); removeData();">delete</mat-icon>
</div>
<a id="addDepositSource" (click)="appendDeposit()">+ Add Deposit Source</a>
</div>
</div>
TS file:
deposits: Deposit[] = [
{ value: 'Builders Gift', viewValue: 'Builders Gift' },
{ value: 'Gift', viewValue: 'Gift' },
{ value: 'Loan', viewValue: 'Loan' },
{ value: 'Savings', viewValue: 'Savings' },
{ value: 'Sale of Property', viewValue: 'Sale of Property' },
{ value: 'Inheritance', viewValue: 'Inheritance' },
{ value: 'Vendor Gifted', viewValue: 'Vendor Gifted' },
{ value: 'Equity', viewValue: 'Equity' },
{ value: 'Forces Help to Buy Loan', viewValue: 'Forces Help to Buy Loan' },
{ value: 'Help to Buy ISA', viewValue: 'Help to Buy ISA' },
{ value: 'Porting', viewValue: 'Porting' },
{ value: 'Other', viewValue: 'Other' },
];
public doughnutChartLabels: any [] = [];
public doughnutChartData: any [] = [];
public doughnutChartType = 'doughnut';
public doughnutChartOptions = {
legend: {
display: false,
}
};
public doughnutChartColors: Array<any> = [
{
backgroundColor: [
'rgba(0,0,0,0.1)',
'rgba(254, 11, 48, 1)',
'rgba(86, 223, 144, 1)',
'rgba(186, 223, 86, 1)',
'rgba(191, 86, 223, 1)',
'rgba(235, 5, 5, 1)',
'rgba(43, 203, 186, 1)',
'rgba(5, 235, 235, 1)',
'rgba(169, 86, 223, 1)',
'rgba(252, 92, 101, 1)',
'rgba(86, 160, 223, 1)',
'rgba(102, 86, 223, 1)',
'rgba(223, 86, 218, 1)',
],
hoverBackgroundColor: [
'rgba(0,0,0,0.1)',
'rgba(254, 11, 48, 1)',
'rgba(86, 223, 144, 1)',
'rgba(186, 223, 86, 1)',
'rgba(191, 86, 223, 1)',
'rgba(235, 5, 5, 1)',
'rgba(43, 203, 186, 1)',
'rgba(5, 235, 235, 1)',
'rgba(169, 86, 223, 1)',
'rgba(252, 92, 101, 1)',
'rgba(86, 160, 223, 1)',
'rgba(102, 86, 223, 1)',
'rgba(223, 86, 218, 1)',
],
borderWidth: 0
},
];
getLabel(depositParent) {
let target = this.depositSourceValue[depositParent];
this.doughnutChartLabels.push(target);
this.chart.chart.update();
}
getData(depositParent) {
let data = this.depositSourceAmount[depositParent];
this.doughnutChartData.push(data);
this.chart.chart.update();
}
I've tried adding on the index value on like so:
this.doughnutChartLabels[depositParent].push(target);
this.doughnutChartData[depositParent].push(data);
But this just gives me the following error:
DigitalPortalComponent.html:30 ERROR TypeError: this.doughnutChartLabels[depositParent].push is not a function
at DigitalPortalComponent.getLabel (digital-portal.component.ts:499)
I've also tried setting up the chart with a dataset:
HTML:
<canvas
baseChart
width="290"
height="290"
[datasets]="doughnutChartDataset"
[labels]="doughnutChartLabels"
[options]="doughnutChartOptions"
[colors]="doughnutChartColors"
[chartType]="doughnutChartType"></canvas>
TS:
public doughnutChartDataset: any [] =
[
{ data: [], label: 'Deposit Source' }
];
public doughnutChartLabels: any [] = ['a'];
public doughnutChartType = 'doughnut';
public doughnutChartOptions = {
legend: {
display: false,
}
};
But I can't figure out how to push the data to a dataset so I can't even get as far as adding data to the chart with this method.
Anyone have any ideas? I feel like I'm not far off, but can't quite crack it.
EDIT:
Tried using "splice" to see if I could update the relevant data in the array, but this doesn't work either. Just serves to add the data onto the end of the array still.
changeData(depositParent) {
let depositData = this.depositSourceAmount[depositParent];
this.doughnutChartData.splice(depositParent, 0, depositData);
this.chart.chart.update();
}
Getting to the end of my rope. Has anyone had to do anything similar here where they need to dynamically edit data within an array?