import { Component, OnInit, Input, Output, ViewChild, EventEmitter, ElementRef, NgZone, ChangeDetectorRef } from '@angular/core'; import { Router } from "@angular/router"; import * as d3 from 'd3'; import { SessionService } from '@shared/services/session.service'; import { ApiService } from '@shared/services/api.service'; import { AppConstants } from '../../app.constants'; @Component({ selector: 'app-pie-chart', templateUrl: './pie-chart.component.html', styleUrls: ['./pie-chart.component.sass'] }) export class PieChartComponent implements OnInit { public type: any; public heading: string; @Input() category: string; @Input() PieType: string; @Input() piechartData: any; public pieData: any = {}; public pieLegends: any = {}; @ViewChild('chart') elementView: ElementRef; @Output() onApiSuccess: EventEmitter<any> = new EventEmitter(); public dataSet: Object[]; public colorCodes2: Array<any> = ["#ff9c2c", "#d11d55", "#1d1e52", "#f75a38", "#008b8f", "#ebebeb"]; public colorCodes: Array<any> = ["#ff9c2c", "#d11d55", "#1d1e52", "#f75a38", "#008b8f"]; public colorCodesLegends = {}; public margin = { top: 0, right: 20, bottom: 0, left: 20 }; public width: number; public height: number; public radius: number; public arc: any; public labelArc: any; public pie: any; public color: any; public svg: any; public count = 0; public showGraph: boolean = false; public legendsOnload = []; constructor( private zone: NgZone, private route: Router, private SessionService: SessionService, public _apiCallService: ApiService, private cdRef: ChangeDetectorRef ) { } ngOnChanges(changes) { this.piechartData = changes.piechartData.currentValue; this.ngOnInit(); } ngOnInit() { this.legendsOnload = []; this.colorCodesLegends ={ "Upto 1500cc": "#ff9c2c", "1500cc-2100cc": "#d11d55", "2100cc-3500cc": "#1d1e52", "3500 Above": "#f75a38", "Electric": "#008b8f" }; this.type = AppConstants.HTML_MODERATE; if (this.piechartData) { this.piechartData.map((obj, index) => { if (obj.percentage == 0) { this.count++ } if (index == 4) this.showGraph = true; }); } if (this.showGraph && this.count == 5) { this.piechartData[5] = { "field": "empty", "value": 100, "percentage": 100 } this.getEmptyCategoryData(); } else { this.getCategoryData(); } this.cdRef.detectChanges(); } getCategoryData() { let list = {}, valList = {}; this.piechartData.map((obj, index) => { list[obj.field] = obj.percentage; valList[obj.field] = obj.value; if(obj.percentage > 0) this.legendsOnload.push(obj.field) }) this.pieData = { "dataSet": { "Upto 1500cc": list["Upto 1500cc"], "1500cc-2100cc": list["1500cc-2100cc"], "2100cc-3500cc": list["2100cc-3500cc"], "3500 Above": list["3500 Above"], "Electric": list["Electric"] }, "tooltipDataSet": { "Upto 1500cc": valList["Upto 1500cc"], "1500cc-2100cc": valList["1500cc-2100cc"], "2100cc-3500cc": valList["2100cc-3500cc"], "3500 Above": valList["3500 Above"], "Electric": valList["Electric"], "Empty": valList["empty"] }, "legends": [ "Upto 1500cc", "1500cc-2100cc", "2100cc-3500cc", "3500cc Above", "Electric" ], "dataSetMap": [ "Upto 1500cc", "1500cc-2100cc", "2100cc-3500cc", "3500 Above", "Electric" ], "totalVal": 100 } this.buildChart(); } getEmptyCategoryData() { let list = {}, valList = {}; this.piechartData.map((obj) => { list[obj.field] = obj.percentage; valList[obj.field] = obj.value; }) this.legendsOnload = [ "Upto 1500cc", "1500cc-2100cc", "2100cc-3500cc", "3500cc Above", "Electric", "Empty" ] this.pieData = { "dataSet": { "Upto 1500cc": list["Upto 1500cc"], "1500cc-2100cc": list["1500cc-2100cc"], "2100cc-3500cc": list["2100cc-3500cc"], "3500 Above": list["3500 Above"], "Electric": list["Electric"], "Empty": list["empty"] }, "tooltipDataSet": { "Upto 1500cc": valList["Upto 1500cc"], "1500cc-2100cc": valList["1500cc-2100cc"], "2100cc-3500cc": valList["2100cc-3500cc"], "3500 Above": valList["3500 Above"], "Electric": valList["Electric"], "Empty": valList["empty"] }, "legends": [ "Upto 1500cc", "1500cc-2100cc", "2100cc-3500cc", "3500cc Above", "Electric", "Empty" ], "dataSetMap": [ "Upto 1500cc", "1500cc-2100cc", "2100cc-3500cc", "3500 Above", "Electric", "Empty" ], "totalVal": 100 } this.buildChart(); } buildData() { let newDataCollection: Array<any> = []; this.pieData.dataSetMap.forEach((key, i) => { let obj: Object = { tooltipVal: this.pieData.tooltipDataSet[key], val: this.pieData.dataSet[key], perCentVal: Math.round((this.pieData.dataSet[key] / this.pieData.totalVal) * 100), label: this.pieData.legends[i].toUpperCase() }; newDataCollection.push(obj); }); return newDataCollection; } buildChart() { this.dataSet = this.buildData(); this.width = this.elementView.nativeElement.offsetWidth - this.margin.left - this.margin.right; this.height = this.elementView.nativeElement.offsetHeight - this.margin.top - this.margin.bottom; this.radius = Math.min(200,this.width, this.height) / 2; // console.log(this.width, this.height, 'r= '+this.radius, Math.min(this.width, this.height) ) this.heading = (this.category === "user") ? "User Categories" : "Risk Categories"; this.initSvg() } public initSvg() { let colors; if (this.count == 5) colors = this.colorCodes2 else colors = this.colorCodes this.color = d3.scaleOrdinal() .range(colors); this.arc = d3.arc() .outerRadius(this.radius - 10) .innerRadius(0); this.labelArc = d3.arc() .outerRadius(this.radius - 40) .innerRadius(this.radius - 40); this.pie = d3.pie() .sort(null) .value((d: any) => d.perCentVal); this.svg = d3.select("svg#"+this.PieType) .append("g") .attr("class", "parent-g") .attr("transform", "translate(" + this.width / 2 + "," + this.height / 3 + ")"); this.drawPie(); } public drawPie() { let g = this.svg.selectAll(".arc") .data(this.pie(this.dataSet)) .enter().append("g") .attr("class", "arc"); g.append("path").attr("d", this.arc) .style("fill", (d: any) => this.colorCodes[d.index]); g.append("text").attr("font-weight", "bold") .attr("fill", "#ffffff") .attr("font-size", "12") .attr("transform", (d: any) => "translate(" + this.labelArc.centroid(d) + ")") .attr("dy", "-0.2em") .attr("dx", "-0.6em") .text((d: any) => (d.data.perCentVal > 0) ? d.data.perCentVal + "%" : ""); g.on("mouseover", (d) => { d3.select("#" + this.category + "-tooltip") .attr("class", "") .style("position", "absolute") .style("left", (d3.event.offsetX + 80) + "px") .style("top", (d3.event.offsetY + 80) + "px") .style("opacity", 1) .select("#" + this.category + "-value") .text(d.data.tooltipVal); }).on("mouseout", () => { d3.select("#" + this.category + "-tooltip") .style("opacity", 0);; }) // g.attr("cursor", "pointer") // .on("click", (d) => { // this.SessionService.deleteCategory() // let label = d.data.label === "NEW DRIVERS" ? "UNCATEGORIZED" : d.data.label; // this.route.navigate(["user-categories/categories"], { queryParams: {type: label, page: "1"} }); // }); } onResize(e) { let width = this.elementView.nativeElement.offsetWidth - this.margin.left - this.margin.right; let height = this.elementView.nativeElement.offsetHeight - this.margin.top - this.margin.bottom; let g = d3.select("#" + this.category).select("g.parent-g").attr("transform", "translate(" + width / 2 + ", " + height / 2 + ")"); } }