import { Component, NgZone, ElementRef, Input, Output, EventEmitter, 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 * as am4plugins_forceDirected from "@amcharts/amcharts4/plugins/forceDirected"; import am4themes_material from "@amcharts/amcharts4/themes/material"; export type ChartTypes = "default" | "img" | "svg"; /** linkWith sampleData * * [{ "name": "First", "value": 1, "link": ["Second","Third"] }, { "name": "Second", "value": 1, "link": ["Third"] }, { "name": "Third", "value": 1, "link": ["First"] }] */ @Component({ selector: "rd-amchart-bubble-tree", template: `
` }) export class AmChartBubbleTree extends BaseAmChart implements OnChanges, AfterViewInit { constructor(zone: NgZone, public element: ElementRef, portlet: Portlet) { super(zone, element, portlet); } @Input("rd-data") data: Array = []; @Input("rd-type") type: ChartTypes = "default"; @Input("rd-key-field") keyField: string; @Input("rd-value-field") valueField: string; @Input("rd-legend-enabled") legendEnabled: boolean = true; @Input("rd-maxLevels") maxLevels: number = 2; @Output("rd-click") clickEvent: EventEmitter = new EventEmitter(); chart: am4plugins_forceDirected.ForceDirectedTree series: am4plugins_forceDirected.ForceDirectedSeries ngAfterViewInit() { this.zone.runOutsideAngular(() => { am4core.useTheme(am4themes_material); this.chart = am4core.create(this.container, am4plugins_forceDirected.ForceDirectedTree); this.chart.hiddenState.properties.opacity = 0; this.chart.data = this.data; this.chart.titles.create().text = this.title; this.setSeries(); 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.setSeries(); } setSeries() { this.chart.series.clear(); this.series = this.chart.series.push(new am4plugins_forceDirected.ForceDirectedSeries()); this.series.nodes.template.outerCircle.filters.push(new am4core.DropShadowFilter()); this.series.dataFields.id = this.keyField; this.series.dataFields.name = this.keyField; this.series.dataFields.value = this.valueField; this.series.dataFields.children = "children"; this.series.dataFields.color = "color"; this.series.dataFields.collapsed = "collapsed"; this.series.dataFields.linkWith = "link"; this.series.fontSize = 8; this.series.maxLevels = this.maxLevels; this.series.nodes.template.label.text = "{name}"; this.series.nodes.template.tooltipText = "{name}: [bold]{value}[/]"; let subSubChildren: Array = []; let getSubChilds = (children, hitnodelevel = 0) => { children.forEach((c) => { if (c.level > hitnodelevel + 1) subSubChildren.push(c); if (c.children) getSubChilds(c.children.values); }); } this.series.nodes.template.events.on("hit", (e) => { subSubChildren = []; if (e.target.isActive && e.target.dataItem.children) { getSubChilds(e.target.dataItem.children.values, e.target.dataItem.level); } subSubChildren.forEach(s => s.node.hide()); }); switch (this.type) { case "default": this.series.nodes.template.fillOpacity = 1; this.series.nodes.template.label.hideOversized = true; this.series.nodes.template.label.truncate = true; this.series.maxRadius = 60; this.series.manyBodyStrength = -30; break; case "img": case "svg": this.series.nodes.template.label.valign = "bottom"; this.series.nodes.template.label.fill = am4core.color("#000"); this.series.nodes.template.label.dy = 10; this.series.nodes.template.circle.disabled = true; this.series.minRadius = 30; this.series.maxRadius = 30; this.series.centerStrength = 0.2; let icon; if (this.type == "img") { icon = this.series.nodes.template.createChild(am4core.Image); icon.propertyFields.href = "img"; } else { icon = this.series.nodes.template.createChild(am4core.Sprite); icon.propertyFields.path = "svg"; } icon.horizontalCenter = "middle"; icon.verticalCenter = "middle"; icon.width = 60; icon.height = 60; break; } } }