我对Angular还是比较陌生,但是我的任务是构建证明非常复杂的单页应用程序(无论如何对我来说)。
在此应用程序的一部分上,有一个通过Chart.js创建的图表,可以通过选择字段和输入字段进行动态更新。
这是一个平面设计的示例,其外观应为:
因此,用户将通过“添加存款来源”链接添加一个存款来源,这将依次显示选项字段和输入字段(我已经编码),以及当用户从中选择了一个选项时选择字段并在输入中输入一个值,图表应更新。然后,他们可以根据需要多次重复此过程。另外,当单击时,垃圾桶图标还应该能够从图表的数组中删除这些值,以及从页面中删除字段。
我已经能够分别获取这些值,因此我可以在用户选择一个选项时在数组中添加标签,并且可以在用户将焦点移到该字段之后从输入字段中添加值,但我无法让它们在一起发生。
这是我的HTML中的代码:
<div class="chart-container">
<canvas #lineChart id="depositBreakdown" width="300" height="300">{{chart}}</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" (selectionChange)="getLabel($event, chart, label, data)">
<mat-option *ngFor="let deposit of deposits; let depositSourceOption = index" [value]="deposit.value" id="{{'option' + depositSourceOption}}">
{{ deposit.viewValue }}
</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"
[ngModelOptions]="{ standalone: true }"
(focusout)="getData(index, chart, label, data)"
/>
</mat-form-field>
<mat-icon (click)="removeDeposit(depositSource)">delete</mat-icon>
</div>
<a id="addDepositSource" (click)="appendDeposit()">+ Add Deposit Source</a>
</div>
</div>
还有我的TS文件中与此相关的代码:
deposits: Deposit[] = [
{ value: 'buildersGift', viewValue: 'Builders Gift' },
{ value: 'gift', viewValue: 'Gift' },
{ value: 'loan', viewValue: 'Loan' },
{ value: 'savings', viewValue: 'Savings' },
{ value: 'saleOfProperty', viewValue: 'Sale of Property' },
{ value: 'inheritance', viewValue: 'Inheritance' },
{ value: 'vendorGifted', viewValue: 'Vendor Gifted' },
{ value: 'equity', viewValue: 'Equity' },
{ value: 'forcesHelp', viewValue: 'Forces Help to Buy Loan' },
{ value: 'helpToBuyISA', viewValue: 'Help to Buy ISA' },
{ value: 'porting', viewValue: 'Porting' },
{ value: 'other', viewValue: 'Other' }
];
ngAfterViewInit() {
this.chart = new Chart(this.chartRef.nativeElement, {
type: 'doughnut',
data: {
labels: [],
datasets: [{
label: 'Deposit Sources',
data: [],
backgroundColor: [
'rgba(254, 11, 48, 1)',
'rgba(252, 92, 101, 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(86, 160, 223, 1)',
'rgba(102, 86, 223, 1)',
'rgba(223, 86, 218, 1)',
]
}]
},
options: {
legend: {
display: false
},
scales: {
xAxes: [{
display: false
}],
yAxes: [{
display: false
}],
}
}
});
}
getLabel(event, chart, data) {
let target = event.source.selected._element.nativeElement;
chart.data.labels.push(target.innerText.trim());
chart.data.datasets.forEach((dataset) => {
dataset.data.push(data);
});
chart.update();
}
getData(event, chart, label, data) {
data = this.depositSourceAmount;
chart.data.datasets.forEach((dataset) => {
dataset.data.push(data);
});
chart.update();
}
depositSources: depositCreate[] = [];
appendDeposit() {
this.depositSources.push(new depositCreate());
}
removeDeposit = function(depositSource) {
this.depositSources.splice(this.depositSources.indexOf(depositSource), 1);
}
我尝试设置准系统StackBlitz,尽管它似乎比原始代码https://stackblitz.com/edit/angular-zpu7jh
还要麻烦我一直试图将我的getLabel()和getData()函数合并为一个函数,但是在达到我的知识极限之前陷入了僵局。我曾尝试在此处和网络的其余部分进行搜索,但找不到足够的信息来帮助我确定。我能得到的最好的结果是将标签和值添加到图表中但彼此分开。我的主要问题是设法使我了解嵌套的ngFor循环。
我希望我已经对此进行了充分的解释-我一直在周五和今天整天都在研究它,而我已经结束了它的束缚。任何帮助将不胜感激。
答案 0 :(得分:0)
杰里米·蒂尔(Jeremy Thille)给我的答复在正确的方向帮助了我。通过安装ng2-charts,我可以添加一个图表,使我可以更轻松地将标签和数据推送到图表:
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" (selectionChange)="getLabel($event)">
<mat-option *ngFor="let deposit of deposits; let depositSourceOption = index" [value]="deposit.value" id="{{'option' + depositSourceOption}}">
{{ deposit.viewValue }}
</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)">delete</mat-icon>
</div>
<a id="addDepositSource" (click)="appendDeposit()">+ Add Deposit Source</a>
</div>
</div>
TS:
public doughnutChartLabels = [];
public doughnutChartData = [];
public doughnutChartType = 'doughnut';
public doughnutChartOptions = {
legend: {
display: false
}
};
public doughnutChartColors: Array<any> = [
{
backgroundColor: [
'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)'
]
}
]
getLabel(event) {
let target = event.source.selected._element.nativeElement;
console.log(target.innerText.trim());
this.doughnutChartLabels.push(target.innerText.trim());
this.chart.chart.update();
}
getData(depositParent) {
let data = this.depositSourceAmount[depositParent];
this.doughnutChartData.push(data);
this.chart.chart.update();
}
depositSources: depositCreate[] = [];
appendDeposit() {
this.depositSources.push(new depositCreate());
}
removeDeposit = function(depositSource) {
this.depositSources.splice(this.depositSources.indexOf(depositSource), 1);
}
我仍然需要找出从正确位置编辑和删除数组中数据的方法,但这完全是一个单独的问题,因此我将其标记为已解决。