UNPKG

angular-advance-chart

Version:

Angular Advance Chart provides chart solution for Angular.Currently supports Bar, Pie and Donut chart

448 lines (439 loc) 18.3 kB
import { __decorate } from 'tslib'; import { CommonModule } from '@angular/common'; import { EventEmitter, Output, Input, Component, ViewChildren, ElementRef, Renderer2, HostListener, Directive, NgModule } from '@angular/core'; let BarChartComponent = class BarChartComponent { constructor() { this.selectedItem = new EventEmitter(); this.chartData = []; this.chartOptions = { roundedCorners: false, isHorizontal: false, showLegend: true, legendTitle: 'Total', }; this.view = { height: 200, width: 200 }; this.lines = []; this.totalSum = 0; this.isHorizontal = true; this.barLineType = 'round'; this.chartView = []; this.scale = 100; } ngOnInit() { this.chartView.push(this.view.height + 'px'); this.chartView.push(this.view.width + 'px'); this.barLineType = this.chartOptions['roundedCorners'] ? 'round' : 'butt'; this.isHorizontal = this.chartOptions['isHorizontal'] ? true : false; this.scale = this.isHorizontal ? this.view.width : this.view.height; this.getTotalSum(this.chartData); let value = Math.max.apply(Math, this.chartData.map(function (o) { return o.value; })); if (value > this.scale) { let normalizedValue = value / this.scale; this.chartData.map((y, index) => { this.chartData[index]['normalized'] = Number(y.value) / normalizedValue; }); } else { let normalizedValue = this.scale / value; this.chartData.map((y, index) => { this.chartData[index]['normalized'] = Number(y.value) * normalizedValue; }); } this.lines = this.isHorizontal ? this.calculateHorizontalBarLines(this.chartData) : this.calculateVerticalBarLines(this.chartData); } ngAfterViewInit() { } getItemClicked(line) { let selectedbar = { name: line.name, value: line.value }; this.selectedItem.emit(JSON.stringify(selectedbar)); } calculateHorizontalBarLines(graphData) { let barLines = []; graphData.map((x, index) => { let background = { x1: 10, y1: index * 20 + 20, y2: index * 20 + 20, x2: this.view.width, color: '#EBEBEB', name: x.name, value: x.value }; barLines.push(background); if (x.value > 0) { let line = { x1: 10, y1: index * 20 + 20, y2: index * 20 + 20, x2: x.normalized < 10 ? this.barLineType == 'butt' ? 11 : 10 : x.normalized, color: x.color, name: x.name, value: x.value }; barLines.push(line); } }); return barLines; } calculateVerticalBarLines(graphData) { let barLines = []; graphData.map((x, index) => { let background = { x1: index * 20 + 20, y1: 10, x2: index * 20 + 20, y2: this.scale, color: '#EBEBEB', name: x.name, value: x.value }; barLines.push(background); if (x.value > 0) { let line = { x1: index * 20 + 20, y1: (this.scale + 10) - x.normalized > this.scale ? this.barLineType == 'butt' ? (this.scale - 1) : this.scale : (this.scale + 10) - x.normalized, x2: index * 20 + 20, y2: this.scale, color: x.color, name: x.name, value: x.value }; barLines.push(line); } }); console.log(barLines); return barLines; } getTotalSum(chartData) { // Get total number of records this.totalSum = chartData.reduce(function (a, b) { return a + parseInt(b.value); }, 0); } }; __decorate([ Output() ], BarChartComponent.prototype, "selectedItem", void 0); __decorate([ Input() ], BarChartComponent.prototype, "chartData", void 0); __decorate([ Input() ], BarChartComponent.prototype, "chartOptions", void 0); __decorate([ Input() ], BarChartComponent.prototype, "view", void 0); BarChartComponent = __decorate([ Component({ selector: 'ngx-bar-chart', template: "<div class=\"chart-view ngx-bar\">\n <div class=\"chart-wrapper\" [ngStyle]=\"{'height': chartView[0],'width': chartView[1]}\">\n <svg id=\"lines\" [attr.viewBox]=\"'0 0 '+ (isHorizontal ? scale+40 : (lines[lines.length-1].x1 + 20))+' ' + (isHorizontal ? (lines[lines.length-1].y2 + 20) : (scale+20))\">\n <g>\n <line *ngFor=\"let line of lines\" stroke-width=\"10\" class=\"line\" [attr.x1]=\"line.x1\" [attr.y1]=\"line.y1 \"\n [attr.x2]=\"line.x2\" [attr.y2]=\"line.y2\" [attr.stroke]=\"line.color\" \u00A0\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0 [attr.stroke-linecap]=\"barLineType\"\n [attr.title]=\"line.name\" (click)=\"getItemClicked(line)\" chartTooltip tooltip={{line.name}} />\n </g>\n </svg>\n </div>\n <div class=\"legend\" *ngIf=\"chartOptions.showLegend\">\n <h4>{{chartOptions.legendTitle +' : '+ totalSum}}</h4>\n <div class=\"legend-item\" *ngFor=\"let item of chartData; let i=index\">\n <div class=\"legend-item-colour\" [ngStyle]=\"{'background': item.color}\"></div><span\n class=\"legend-item-name\">{{item.name}}</span><span class=\"legend-item-value\">{{item.value}}</span>\n </div>\n </div>\n\n</div>", styles: [".line{cursor:pointer}"] }) ], BarChartComponent); let DonutChartComponent = class DonutChartComponent { constructor() { this.selectedItem = new EventEmitter(); this.chartOptions = { showLegend: true, legendTitle: 'Total', }; this.view = { height: 200, width: 200, radius: 80, donutSize: 20 }; this.totalSum = 0; this.processedData = []; this.legendData = []; this.chartView = []; } ngOnInit() { if (this.chartData) { this.view['donutSize'] = this.view['donutSize'] ? this.view['donutSize'] : 20; this.chartView.push(this.view.height + 'px'); this.chartView.push(this.view.width + 'px'); // Get total number of records this.totalSum = this.chartData.reduce(function (a, b) { return a + b.value; }, 0); //generate Data for list let prevAngle = 0; this.chartData.map((x, index) => { let legend = { name: x.name, value: x.value, color: x.color }; this.legendData.push(legend); let percentage = this.getPercentage(x.value, this.totalSum); if (percentage > 0) { let circlePercentage = percentage / 10 * 36; let pieData = { color: x.color, a1: prevAngle, a2: prevAngle + circlePercentage, name: x.name }; prevAngle = prevAngle + circlePercentage; this.processedData.push(pieData); } }); } } getPercentage(partialValue, totalValue) { return (100 * partialValue) / totalValue; } ngAfterViewInit() { //create svg if (this.processedData.length > 0) { this.span.map((item, index) => { item.nativeElement.setAttribute('d', this.describeArc(this.view.height / 2, this.view.width / 2, this.view.radius, this.processedData[index].a1, this.processedData[index].a2 == 360 ? 359.99 : this.processedData[index].a2)); item.nativeElement.setAttribute('stroke', this.processedData[index].color); }); } } polarToCartesian(centerX, centerY, radius, angleInDegrees) { let angleInRadians = (angleInDegrees - 90) * Math.PI / 180.0; return { x: centerX + (radius * Math.cos(angleInRadians)), y: centerY + (radius * Math.sin(angleInRadians)) }; } describeArc(x, y, radius, startAngle, endAngle) { let start = this.polarToCartesian(x, y, radius, endAngle); let end = this.polarToCartesian(x, y, radius, startAngle); let largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1"; let d = [ "M", start.x, start.y, "A", radius, radius, 0, largeArcFlag, 0, end.x, end.y ].join(" "); return d; } getItemClicked(item) { let selected = { name: item.name, value: item.value }; this.selectedItem.emit(selected); } show(status) { } }; __decorate([ Input() ], DonutChartComponent.prototype, "chartData", void 0); __decorate([ Output() ], DonutChartComponent.prototype, "selectedItem", void 0); __decorate([ ViewChildren('el') ], DonutChartComponent.prototype, "span", void 0); __decorate([ Input() ], DonutChartComponent.prototype, "chartOptions", void 0); __decorate([ Input() ], DonutChartComponent.prototype, "view", void 0); DonutChartComponent = __decorate([ Component({ selector: 'ngx-donut-chart', template: "<div class=\"chart-view ngx-donut\">\n <svg class=\"chart-wrapper\" [ngStyle]=\"{'height': chartView[0],'width': chartView[1]}\">\n <path width=\"100%\" height=\"100%\" #el fill=\"none\" [attr.stroke-width]=\"this.view.donutSize\" *ngFor=\"let item of processedData; let i=index\"\n (click)=\"getItemClicked(item)\" chartTooltip tooltip={{item.name}}/>\n\n </svg>\n <div class=\"legend\" *ngIf=\"chartOptions.showLegend\">\n <h4>{{chartOptions.legendTitle +' : '+ totalSum}}</h4>\n <div class=\"legend-item\" *ngFor=\"let item of legendData; let i=index\" >\n <div class=\"legend-item-colour\" [ngStyle]=\"{'background': item.color}\"></div><span class=\"legend-item-name\" >{{item.name}}</span><span class=\"legend-item-value\" >{{item.value}}</span>\n </div>\n </div>\n</div>", styles: ["path:hover{cursor:pointer}"] }) ], DonutChartComponent); let PieChartComponent = class PieChartComponent { constructor() { this.selectedItem = new EventEmitter(); this.chartOptions = { showLegend: true, legendTitle: 'Total', }; this.view = { height: 200, width: 200, radius: 80 }; this.chartView = []; this.totalSum = 0; this.processedData = []; this.legendData = []; } ngOnInit() { this.chartView.push(this.view.height + 'px'); this.chartView.push(this.view.width + 'px'); if (this.chartData) { // Get total number of records this.totalSum = this.chartData.reduce(function (a, b) { return a + b.value; }, 0); //generate Data for piechart let prevAngle = 0; this.chartData.map((x, index) => { let legend = { name: x.name, value: x.value, color: x.color }; this.legendData.push(legend); let percentage = this.getPercentage(x.value, this.totalSum); if (percentage > 0) { let circlePercentage = percentage / 10 * 36; let pieData = { color: x.color, a1: prevAngle, a2: prevAngle + circlePercentage, name: x.name }; prevAngle = prevAngle + circlePercentage; this.processedData.push(pieData); } }); } } ngAfterViewInit() { // create svg if (this.processedData.length > 0) { this.span.map((item, index) => { this.processedData[index].a2 = this.processedData[index].a2 >= 360 ? 359.9 : this.processedData[index].a2; item.nativeElement.setAttribute('d', this.describeArc(this.view.height / 2, this.view.height / 2, this.view.radius, this.processedData[index].a1, this.processedData[index].a2)); item.nativeElement.setAttribute('fill', this.processedData[index].color); }); } } polarToCartesian(centerX, centerY, radius, angleInDegrees) { let angleInRadians = (angleInDegrees - 90) * Math.PI / 180.0; return { x: centerX + (radius * Math.cos(angleInRadians)), y: centerY + (radius * Math.sin(angleInRadians)) }; } describeArc(x, y, radius, startAngle, endAngle) { let start = this.polarToCartesian(x, y, radius, endAngle); let end = this.polarToCartesian(x, y, radius, startAngle); let arcSweep = endAngle - startAngle <= 180 ? "0" : "1"; let d = [ "M", start.x, start.y, "A", radius, radius, 0, arcSweep, 0, end.x, end.y, "L", x, y, "L", start.x, start.y ].join(" "); return d; } getPercentage(partialValue, totalValue) { return (100 * partialValue) / totalValue; } getItemClicked(item) { let selected = { name: item.name, value: item.value }; this.selectedItem.emit(selected); } }; __decorate([ Input() ], PieChartComponent.prototype, "chartData", void 0); __decorate([ ViewChildren('el') ], PieChartComponent.prototype, "span", void 0); __decorate([ Output() ], PieChartComponent.prototype, "selectedItem", void 0); __decorate([ Input() ], PieChartComponent.prototype, "chartOptions", void 0); __decorate([ Input() ], PieChartComponent.prototype, "view", void 0); PieChartComponent = __decorate([ Component({ selector: 'ngx-pie-chart', template: "<div class=\"chart-view ngx-pie\">\n <svg class=\"chart-wrapper\" [ngStyle]=\"{'height': chartView[0],'width': chartView[1]}\">\n <path #el class=\"pie-chart-path\" chartTooltip tooltip={{item.name}} (click)=\"getItemClicked(item)\" *ngFor=\"let item of processedData; let i=index\" />\n </svg>\n <div class=\"legend\" *ngIf=\"chartOptions.showLegend\">\n <h4>{{chartOptions.legendTitle +' : '+ totalSum}}</h4>\n <div class=\"legend-item\" *ngFor=\"let item of legendData; let i=index\">\n <div class=\"legend-item-colour\" [ngStyle]=\"{'background': item.color}\"></div><span class=\"legend-item-name\" >{{item.name}}</span><span class=\"legend-item-value\" >{{item.value}}</span>\n </div>\n </div>\n</div>", styles: ["path.pie-chart-path:hover{cursor:pointer}"] }) ], PieChartComponent); let TooltipDirective = class TooltipDirective { constructor(el, renderer) { this.el = el; this.renderer = renderer; } onMouseEnter(event) { if (!this.tooltip) { this.show(event); } } onMouseLeave() { if (this.tooltip) { this.hide(); } } show(event) { this.create(); this.setPosition(event); this.renderer.addClass(this.tooltip, 'chart-tooltip-show'); } hide() { this.renderer.removeClass(this.tooltip, 'chart-tooltip-show'); this.renderer.removeChild(document.body, this.tooltip); this.tooltip = null; } create() { this.tooltip = this.renderer.createElement('span'); this.renderer.appendChild(this.tooltip, this.renderer.createText(this.tooltipTitle) // textNode ); this.renderer.appendChild(document.body, this.tooltip); this.renderer.addClass(this.tooltip, 'chart-tooltip'); } setPosition(event) { const scrollPos = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; let top = event.y; let left = event.x; this.renderer.setStyle(this.tooltip, 'top', `${top + scrollPos}px`); this.renderer.setStyle(this.tooltip, 'left', `${left}px`); } }; TooltipDirective.ctorParameters = () => [ { type: ElementRef }, { type: Renderer2 } ]; __decorate([ Input('tooltip') ], TooltipDirective.prototype, "tooltipTitle", void 0); __decorate([ HostListener('mouseenter', ['$event']) ], TooltipDirective.prototype, "onMouseEnter", null); __decorate([ HostListener('mouseleave') ], TooltipDirective.prototype, "onMouseLeave", null); TooltipDirective = __decorate([ Directive({ selector: '[chartTooltip]' }) ], TooltipDirective); let AngularAdvanceChartModule = class AngularAdvanceChartModule { }; AngularAdvanceChartModule = __decorate([ NgModule({ declarations: [PieChartComponent, BarChartComponent, DonutChartComponent, TooltipDirective], imports: [ CommonModule ], exports: [PieChartComponent, BarChartComponent, DonutChartComponent] }) ], AngularAdvanceChartModule); /* * Public API Surface of angular-advance-chart */ /** * Generated bundle index. Do not edit. */ export { AngularAdvanceChartModule, BarChartComponent, DonutChartComponent, PieChartComponent, TooltipDirective as ɵa }; //# sourceMappingURL=angular-advance-chart.js.map