import { Component, NgZone, ElementRef, Input, Output, EventEmitter, AfterViewInit, OnChanges } from "@angular/core"; import { Portlet } from "../../portlet/portlet"; import { BaseAmChart } from "./baseAmChart"; import * as am4core from "@amcharts/amcharts4/core"; import * as am4charts from "@amcharts/amcharts4/charts"; export interface IHeatChartDataItem { x: string; y: string; value: any; } @Component({ selector: "rd-amchart-heat", template: `
` }) export class AmChartHeat extends BaseAmChart implements OnChanges, AfterViewInit { constructor(zone: NgZone, public element: ElementRef, portlet: Portlet) { super(zone, element, portlet); } @Input("rd-data") data: Array = []; @Output("rd-click") clickEvent: EventEmitter = new EventEmitter(); ngAfterViewInit() { this.zone.runOutsideAngular(() => { this.chart = am4core.create(this.container, am4charts.XYChart); this.chart.data = this.data; this.chart.maskBullets = false; let xAxis = this.chart.xAxes.push(new am4charts.CategoryAxis()); let yAxis = this.chart.yAxes.push(new am4charts.CategoryAxis()); xAxis.dataFields.category = "x"; yAxis.dataFields.category = "y"; xAxis.renderer.grid.template.disabled = true; xAxis.renderer.minGridDistance = 40; yAxis.renderer.grid.template.disabled = true; yAxis.renderer.inversed = true; yAxis.renderer.minGridDistance = 30; let series = this.chart.series.push(new am4charts.ColumnSeries()); series.dataFields.categoryX = "x"; series.dataFields.categoryY = "y"; series.dataFields.value = "value"; series.sequencedInterpolation = true; series.defaultState.transitionDuration = 3000; let bgColor = new am4core.InterfaceColorSet().getFor("background"); let columnTemplate = series.columns.template; columnTemplate.strokeWidth = 1; columnTemplate.strokeOpacity = 0.2; columnTemplate.stroke = bgColor; columnTemplate.tooltipText = "{categoryX}, {categoryY}: {value}"; columnTemplate.width = am4core.percent(100); columnTemplate.height = am4core.percent(100); series.heatRules.push({ target: columnTemplate, property: "fill", min: am4core.color(bgColor), max: this.chart.colors.getIndex(0) }); // heat legend let heatLegend = this.chart.bottomAxesContainer.createChild(am4charts.HeatLegend); heatLegend.width = am4core.percent(100); heatLegend.series = series; heatLegend.valueAxis.renderer.labels.template.fontSize = 9; heatLegend.valueAxis.renderer.minGridDistance = 30; function handleHover(column) { if (!isNaN(column.dataItem.value)) { heatLegend.valueAxis.showTooltipAt(column.dataItem.value) } else { heatLegend.valueAxis.hideTooltip(); } } // heat legend behavior series.columns.template.events.on("over", (e) => { handleHover(e.target); }); series.columns.template.events.on("hit", (e) => { handleHover(e.target); this.clickEvent.emit(e.target.dataItem._dataContext); }); series.columns.template.events.on("out", (e) => { heatLegend.valueAxis.hideTooltip(); }); }); } ngOnChanges(changes) { if (!this.chart) return; if (changes.data) this.chart.data = this.data; } }