I am using amChart5 graph in a component as child component with angular13 and I am sending data from parent component to child component through input decorator it working fine for first-time load but I can't change/update the chart on @Input() decorator data change.
parent component code
<div class="div3">
<mat-card class="div3-left shadow"> <app-stacked-bar-chart></app-stacked-bar-chart> </mat-card>
<mat-card class="div3-right shadow">
<p style="position:absolute;top: 5px;left :25rem;color: grey;font-style: italic;font-size: small;">Time(24hr
format)</p>
<app-heat-map [graphData]="heatMapData" [uniqueVal]="'5'"> </app-heat-map>
<mat-icon class="btn" data-bs-toggle="modal" data-bs-target="#exampleModal"
style="position: absolute;right: 1rem;bottom: .5rem;font-weight: 900;color: grey;"> fullscreen
</mat-icon>
</mat-card>
</div>
child componenet code
import { Component, Inject, Input, NgZone, OnChanges, OnInit, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
// amCharts imports
import * as am5 from '@amcharts/amcharts5';
import * as am5xy from '@amcharts/amcharts5/xy';
import am5themes_Animated from '@amcharts/amcharts5/themes/Material';
@Component({
selector: 'app-heat-map',
templateUrl: './heat-map.component.html',
styleUrls: ['./heat-map.component.css']
})
export class HeatMapComponent implements OnInit,OnChanges {
@Input() uniqueVal: any="5"
@Input() graphData: any = []
graphData2:any
private root: am5.Root | undefined;
constructor(@Inject(PLATFORM_ID) private platformId:any, private zone: NgZone) { }
ngOnInit(): void {
}
// Run the function only in the browser
browserOnly(f: () => void) {
if (isPlatformBrowser(this.platformId)) {
this.zone.runOutsideAngular(() => {
f();
});
}
}
ngOnChanges() {
function dateToDay(data: any) {
var dayArr: any = []
data.forEach((e: any) => {
function getDayName(dateStr: any, locale: any) {
var date = new Date(dateStr);
return date.toLocaleDateString(locale, { weekday: 'long' });
}
let day = getDayName(e.utc_dates, "en-US")
dayArr.push({ "utc_day": day, "utc_hour": e.utc_hour, "sum_data": e.sum_data })
})
return dayArr
}
this.graphData2=dateToDay(this.graphData)
console.log("graphdata2",this.graphData2);
/* Chart code */
let root = am5.Root.new(`chartdiv${this.uniqueVal}`);
// Set themes
root.setThemes([
am5themes_Animated.new(root)
]);
// Create chart
let chart = root.container.children.push(am5xy.XYChart.new(root, {
panX: false,
panY: false,
wheelX: "none",
wheelY: "none",
layout: root.verticalLayout
}));
// Create axes and their renderers
let yRenderer = am5xy.AxisRendererY.new(root, {
visible: false,
minGridDistance: 20,
inversed: true
});
yRenderer.grid.template.set("visible", false);
let yAxis = chart.yAxes.push(am5xy.CategoryAxis.new(root, {
maxDeviation: 0,
renderer: yRenderer,
categoryField: "utc_day"
}));
let xRenderer = am5xy.AxisRendererX.new(root, {
visible: false,
minGridDistance: 30,
opposite: true
});
xRenderer.grid.template.set("visible", false);
let xAxis = chart.xAxes.push(am5xy.CategoryAxis.new(root, {
renderer: xRenderer,
categoryField: "utc_hour"
}));
// Create series
let series = chart.series.push(am5xy.ColumnSeries.new(root, {
calculateAggregates: true,
stroke: am5.color(0xffffff),
clustered: false,
xAxis: xAxis,
yAxis: yAxis,
categoryXField: "utc_hour",
categoryYField: "utc_day",
valueField: "sum_data"
}));
series.columns.template.setAll({
tooltipText: "{sum_data}",
strokeOpacity: 1,
strokeWidth: 2,
width: am5.percent(100),
height: am5.percent(100)
});
series.columns.template.events.on("pointerover", function (event) {
let di: any = event.target.dataItem;
if (di) {
heatLegend.showValue(di.get("value", 0));
}
});
series.events.on("datavalidated", function () {
heatLegend.set("startValue", series.getPrivate("valueHigh"));
heatLegend.set("endValue", series.getPrivate("valueLow"));
});
// Set up heat rules
series.set("heatRules", [{
target: series.columns.template,
min: am5.color(0xfffb77),
max: am5.color(0xfe131a),
dataField: "sum_data",
key: "fill"
}]);
// Add heat legend
let heatLegend = chart.bottomAxesContainer.children.push(am5.HeatLegend.new(root, {
orientation: "horizontal",
endColor: am5.color(0xfffb77),
startColor: am5.color(0xfe131a)
}));
// Set data
let data = [...dateToDay(this.graphData)]
console.log("data", data);
series.data.setAll(data)
yAxis.data.setAll([
{ utc_day: "Sunday" },
{ utc_day: "Monday" },
{ utc_day: "Tuesday" },
{ utc_day: "Wednesday" },
{ utc_day: "Thursday" },
{ utc_day: "Friday" },
{ utc_day: "Saturday" }
]);
xAxis.data.setAll([
{ utc_hour: "0" },
{ utc_hour: "1" },
{ utc_hour: "2" },
{ utc_hour: "3" },
{ utc_hour: "4" },
{ utc_hour: "5" },
{ utc_hour: "6" },
{ utc_hour: "7" },
{ utc_hour: "8" },
{ utc_hour: "9" },
{ utc_hour: "10" },
{ utc_hour: "11" },
{ utc_hour: "12" },
{ utc_hour: "13" },
{ utc_hour: "14" },
{ utc_hour: "15" },
{ utc_hour: "16" },
{ utc_hour: "17" },
{ utc_hour: "18" },
{ utc_hour: "19" },
{ utc_hour: "20" },
{ utc_hour: "21" },
{ utc_hour: "22" },
{ utc_hour: "23" },
{ utc_hour: "24" }
]);
// Make stuff animate on load
chart.appear(500, 10);
}
ngOnDestroy() {
this.ngOnChanges()
// Clean up chart when the component is removed
this.browserOnly(() => {
if (this.root) {
this.root.dispose();
}
});
}
}