@swimlane/ngx-charts
Version:
Declarative Charting Framework for Angular2 and beyond!
158 lines (138 loc) • 4.17 kB
text/typescript
import {
Component,
Input,
Output,
EventEmitter,
ElementRef,
SimpleChanges,
OnChanges,
ChangeDetectionStrategy
} from '@angular/core';
import d3 from '../d3';
import { id } from '../utils/id';
export class PieArcComponent implements OnChanges {
fill;
startAngle: number = 0;
endAngle: number = Math.PI * 2;
innerRadius;
outerRadius;
cornerRadius: number = 0;
value;
max;
data;
explodeSlices: boolean = false;
gradient: boolean = false;
animate: boolean = true;
pointerEvents: boolean = true;
isActive: boolean = false;
select = new EventEmitter();
activate = new EventEmitter();
deactivate = new EventEmitter();
element: HTMLElement;
path: any;
startOpacity: number;
radialGradientId: string;
linearGradientId: string;
gradientFill: string;
initialized: boolean = false;
constructor(element: ElementRef) {
this.element = element.nativeElement;
}
ngOnChanges(changes: SimpleChanges): void {
this.update();
}
update(): void {
let arc = this.calculateArc();
this.path = arc.startAngle(this.startAngle).endAngle(this.endAngle)();
this.startOpacity = 0.5;
let pageUrl = window.location.href;
this.radialGradientId = 'linearGrad' + id().toString();
this.gradientFill = `url(${pageUrl}#${this.radialGradientId})`;
if (this.animate) {
if (this.initialized) {
this.updateAnimation();
} else {
this.loadAnimation();
this.initialized = true;
}
}
}
calculateArc(): any {
let outerRadius = this.outerRadius;
if (this.explodeSlices && this.innerRadius === 0) {
outerRadius = this.outerRadius * this.value / this.max;
}
return d3.arc()
.innerRadius(this.innerRadius)
.outerRadius(outerRadius)
.cornerRadius(this.cornerRadius);
}
loadAnimation(): void {
let node = d3.select(this.element).selectAll('.arc').data([{startAngle: this.startAngle, endAngle: this.endAngle}]);
let arc = this.calculateArc();
node
.transition()
.attrTween('d', function(d) {
this._current = this._current || d;
let copyOfD = Object.assign({}, d);
copyOfD.endAngle = copyOfD.startAngle;
let interpolate = d3.interpolate(copyOfD, copyOfD);
this._current = interpolate(0);
return function(t) {
return arc(interpolate(t));
};
})
.transition().duration(750)
.attrTween('d', function(d) {
this._current = this._current || d;
let interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
return arc(interpolate(t));
};
});
}
updateAnimation(): void {
let node = d3.select(this.element).selectAll('.arc').data([{startAngle: this.startAngle, endAngle: this.endAngle}]);
let arc = this.calculateArc();
node
.transition().duration(750)
.attrTween('d', function(d) {
this._current = this._current || d;
let interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
return arc(interpolate(t));
};
});
}
onClick(): void {
this.select.emit(this.data);
}
}