Reputation: 139
In my Statistics module I got a signal that defines the type of the charts that should appear and this signal is updated using a radio button group.
The signal: typeSignal = signal<string>('OIA')
The radio buttons that sets the :
<div class="btn-group w-auto" role="group">
@for (type of types; track $index) {
<input type="radio" class="btn-check" name="btnradio" [id]="type" autocomplete="off"
[checked]="type==typeSignal()">
<label class="btn btn-primary" for="btnradio1" (click)="typeSignal.set(type)">{{type}}</label>
}
</div>
However, I got another computed signal that creates the charts data according to the type signal. Here's the charts signal:
charts = computed(() => {
const chartsArr:ChartData[] = []
if (this.typeSignal() == "OIA") {
chartsArr.push(this.createBarChart("Status of Incident", ['Closed', 'Ongoing'], "status", "Advisories", true))
chartsArr.push(this.createBarChart("Severity of Incident", ['Severity 0', 'Severity 1', 'Severity 2', 'Severity 3', 'Severity 4'], "impacts", "Advisories", false))
chartsArr.push(this.createDonutChart("Communication type", ['Incident', 'Change'], 300))
} else if (this.typeSignal() == "Portail de l'information") {
chartsArr.push(this.createBarChart("Status of Incident", ['Scheduled', 'Archived', 'Ongoing'], "status", "Advisories", true))
chartsArr.push(this.createBarChart("Impact of Incident", ['Major', 'Minor', 'Grave'], "impacts", "Advisories", false))
chartsArr.push(this.createDonutChart("Communication type", ['Incident', 'Change'], 300))
} else if (this.typeSignal() == "Bulletin Board") {
chartsArr.push(this.createBarChart("Status of Change", ['Closed', 'Ongoing', 'Scheduled'], "status", "Advisories", true))
chartsArr.push(this.createBarChart("Outage of Incident", ['Complete Outage', 'Partial Outage', 'Info'], "impacts", "Advisories", false))
chartsArr.push(this.createDonutChart("Communication type", ['Info', 'Incident', 'Change'], 300))
}
console.log(chartsArr);
return structuredClone(chartsArr)
})
and I read this charts signal in my template
@if (["OIA","Portail de l'information","Bulletin Board"].includes(typeSignal())) {
<div class="row row-cols-2 g-5 mx-1">
@for (chart of charts(); track $index) {
@if (chart.type == "bar") {
<app-bar-chart [title]="chart.title" [axissLabels]="chart.labels" [values]="chart.values"
[valuesType]="chart.valuesType!" [isHorizontal]="chart.isHorizontal!"></app-bar-chart>
}@else if (chart.type=="donut") {
<app-donut-chart [title]="chart.title" [values]="chart.values" [labels]="chart.labels"
[minWidth]="chart.minWidth!"></app-donut-chart>
}
}
</div>
}
The problem here is that the charts signal doesn't update the for loop although the console.log(chartsArr);
inside it gets logged whenever I toggle the radio buttons.
Upvotes: 2
Views: 701
Reputation: 139
I found that the problem wasn't in the signal itself.
The problem was related with the child components BarChartComponent and DonutChartComponent.
They weren't detecting the update changes. So, I added OnChanges.
Here's the code of DonutChartComponent after modification:
export type ChartOptions = {
series: ApexNonAxisChartSeries;
chart: ApexChart;
responsive: ApexResponsive[];
labels: string[];
title: ApexTitleSubtitle;
};
@Component({
selector: 'app-donut-chart',
standalone: true,
imports: [NgApexchartsModule],
templateUrl: './donut-chart.component.html',
styleUrl: './donut-chart.component.scss'
})
export class DonutChartComponent implements OnInit, OnChanges {
@ViewChild("chart") chart!: ChartComponent;
chartOptions!: Partial<ChartOptions>;
@Input() values: number[] = []
@Input() labels: string[] = []
@Input() title!: string
@Input() minWidth!: number
ngOnInit(): void {
this.createChart()
}
ngOnChanges(changes: SimpleChanges) {
if (Object.keys(changes).length > 0) {
if (changes['values']?.currentValue) {
this.values = changes['values']?.currentValue
}
if (changes['labels']?.currentValue) {
this.labels = changes['labels']?.currentValue
}
if (changes['title']?.currentValue) {
this.title = changes['title']?.currentValue
}
if (changes['minWidth']?.currentValue) {
this.minWidth = changes['minWidth']?.currentValue
}
this.createChart()
}
}
createChart() {
this.chartOptions = {
title: {
text: this.title
},
series: this.values,
chart: {
type: "donut",
},
labels: this.labels,
responsive: [
{
breakpoint: this.minWidth,
options: {
chart: {
width: this.minWidth,
},
legend: {
position: "bottom",
},
},
},
],
};
}
}
Upvotes: 0