import { Component, NgZone, ElementRef, Input, Output, OnChanges, AfterViewInit, EventEmitter } 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_kelly from "@amcharts/amcharts4/themes/kelly"; export interface IBubbleSerieItem { name: string; valueX: string; valueY: string; size?: string; hidden?: boolean; } @Component({ selector: "rd-amchart-bubble", template: `
` }) export class AmChartBubble extends BaseAmChart implements OnChanges, AfterViewInit { constructor(zone: NgZone, public element: ElementRef, portlet: Portlet) { super(zone, element, portlet); } @Input("rd-data") data: Array = []; @Input("rd-series") series: Array = []; @Input("rd-legend-enabled") legendEnabled: boolean = true; @Input("rd-cursor") cursor: boolean = true; @Output("rd-event") event: EventEmitter = new EventEmitter(); chart: am4charts.XYChart3D; valueAxisX: am4charts.ValueAxis; valueAxisY: am4charts.ValueAxis; ngAfterViewInit() { this.zone.runOutsideAngular(() => { am4core.useTheme(am4themes_kelly); this.chart = am4core.create(this.container, am4charts.XYChart3D); this.chart.data = this.data; this.chart.titles.create().text = this.title; this.valueAxisX = this.chart.xAxes.push(new am4charts.ValueAxis()); this.valueAxisX.renderer.ticks.template.disabled = true; this.valueAxisX.renderer.axisFills.template.disabled = true; this.valueAxisY = this.chart.yAxes.push(new am4charts.ValueAxis()); this.valueAxisY.renderer.ticks.template.disabled = true; this.valueAxisY.renderer.axisFills.template.disabled = true; this.setSeriesAndBullets(); if (this.cursor) this.chart.cursor = new am4charts.XYCursor(); if (this.legendEnabled) this.chart.legend = new am4charts.Legend(); if (this.export) { this.chart.exporting.menu = new am4core.ExportMenu(); this.setExportMenu(); } }); } ngOnChanges(changes) { if (!this.chart) return; if (changes.data) this.chart.data = this.data; if (changes.series) this.setSeriesAndBullets(); } setSeriesAndBullets() { this.chart.series.clear(); for (let item of this.series || []) { let serie = this.chart.series.push(new am4charts.LineSeries()); serie.name = item.name; serie.hidden = item.hidden; serie.dataFields.valueY = item.valueY; serie.dataFields.valueX = item.valueX; serie.dataFields.value = item.size; serie.dataFields.dateX = "" serie.strokeOpacity = 0; serie.sequencedInterpolation = true; serie.tooltip.pointerOrientation = "vertical"; let bullet = serie.bullets.push(new am4charts.CircleBullet()); bullet.strokeOpacity = 0; bullet.strokeWidth = 2; bullet.fillOpacity = .5; bullet.stroke = am4core.color("#ffffff"); bullet.hiddenState.properties.opacity = 0; bullet.circle.tooltipText = "{name}: [bold]{valueY}[/]"; let outline = this.chart.plotContainer.createChild(am4core.Circle); outline.fillOpacity = 0; outline.strokeOpacity = .8; outline.stroke = am4core.color("#ff0000"); outline.strokeWidth = 3; outline.hide(0); let blurFilter = new am4core.BlurFilter(); outline.filters.push(blurFilter); bullet.events.on("over", (e) => { let target = e.target; this.valueAxisX.tooltip.disabled = false; this.valueAxisY.tooltip.disabled = false; outline.radius = target.circle.pixelRadius + 2 outline.x = target.pixelX; outline.y = target.pixelY; outline.show(); this.event.emit(e); }); bullet.events.on("out", (e) => { this.valueAxisX.tooltip.disabled = true; this.valueAxisY.tooltip.disabled = true; outline.hide(); this.event.emit(e); }); let hoverState = bullet.states.create("hover"); hoverState.properties.fillOpacity = 1; hoverState.properties.strokeOpacity = 1; serie.heatRules.push({ target: bullet.circle, min: 5, max: 60, property: "radius" }); bullet.circle.adapter.add("tooltipY", (tooltipY, target) => { return -target.radius; }); } } }