import { Component, NgZone, ElementRef, Input, OnChanges, AfterViewInit } 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"; import am4themes_material from "@amcharts/amcharts4/themes/material"; @Component({ selector: "rd-amchart-live", template: `
` }) export class AmChartLive extends BaseAmChart implements OnChanges, AfterViewInit { constructor(zone: NgZone, public element: ElementRef, portlet: Portlet) { super(zone, element, portlet); } @Input("rd-data") data: Array = []; @Input("rd-key-field") keyField: string; @Input("rd-value-field") valueField: string; chart: am4charts.XYChart ngAfterViewInit() { this.zone.runOutsideAngular(() => { am4core.useTheme(am4themes_material); this.chart = am4core.create(this.container, am4charts.XYChart); this.chart.hiddenState.properties.opacity = 0; this.chart.data = this.data; this.chart.padding(0, 0, 0, 0); this.chart.zoomOutButton.disabled = true; let dateAxis = this.chart.xAxes.push(new am4charts.DateAxis()); dateAxis.renderer.grid.template.location = 0; dateAxis.renderer.minGridDistance = 30; dateAxis.dateFormats.setKey("second", "ss"); dateAxis.periodChangeDateFormats.setKey("second", "[bold]h:mm a"); dateAxis.periodChangeDateFormats.setKey("minute", "[bold]h:mm a"); dateAxis.periodChangeDateFormats.setKey("hour", "[bold]h:mm a"); dateAxis.renderer.inside = true; dateAxis.renderer.axisFills.template.disabled = true; dateAxis.renderer.ticks.template.disabled = true; dateAxis.interpolationDuration = 500; dateAxis.rangeChangeDuration = 500; let valueAxis = this.chart.yAxes.push(new am4charts.ValueAxis()); valueAxis.tooltip.disabled = true; valueAxis.interpolationDuration = 500; valueAxis.rangeChangeDuration = 500; valueAxis.renderer.inside = true; valueAxis.renderer.minLabelPosition = 0.05; valueAxis.renderer.maxLabelPosition = 0.95; valueAxis.renderer.axisFills.template.disabled = true; valueAxis.renderer.ticks.template.disabled = true; let series = this.chart.series.push(new am4charts.LineSeries()); series.dataFields.dateX = this.keyField; series.dataFields.valueY = this.valueField; series.interpolationDuration = 500; series.defaultState.transitionDuration = 0; series.tensionX = 0.8; let interval; let startInterval = function () { let self = this; interval = setInterval(function () { if (!self.chart || !series.dataItems.length) return; let last = series.dataItems.last; let first = series.dataItems.first; self.chart.addData({ date: new Date(last.dateX.getTime() + 1000), value: first.valueY }, 1); }.bind(self), 1000); }.bind(this); startInterval(); this.chart.events.on("datavalidated", () => { dateAxis.zoom({ start: 1 / 15, end: 1.2 }, false, true); }); document.addEventListener("visibilitychange", () => { if (document.hidden && interval) clearInterval(interval); else startInterval(); }, false); series.fillOpacity = 1; let gradient = new am4core.LinearGradient(); gradient.addColor(this.chart.colors.getIndex(0), 0.2); gradient.addColor(this.chart.colors.getIndex(0), 0); series.fill = gradient; dateAxis.renderer.labels.template.adapter.add("fillOpacity", (fillOpacity, target) => { let dataItem = target.dataItem; return dataItem.position; }); dateAxis.events.on("validated", () => { am4core.iter.each(dateAxis.renderer.labels.iterator(), (label) => { label.fillOpacity = label.fillOpacity; }) }); dateAxis.renderer.labels.template.adapter.add("rotation", (rotation, target) => { let dataItem = target.dataItem; if (dataItem.date && dataItem.date.getTime() == am4core.time.round(new Date(dataItem.date.getTime()), "minute", 0).getTime()) { target.verticalCenter = "middle"; target.horizontalCenter = "left"; return -90; } else { target.verticalCenter = "bottom"; target.horizontalCenter = "middle"; return 0; } }); let bullet = series.createChild(am4charts.CircleBullet); bullet.circle.radius = 5; bullet.fillOpacity = 1; bullet.fill = this.chart.colors.getIndex(0); bullet.isMeasured = false; series.events.on("validated", () => { bullet.moveTo(series.dataItems.last.point); bullet.validatePosition(); }); }); } ngOnChanges(changes) { if (!this.chart) return; if (changes.data) this.chart.data = this.data; } }