Skip to content

Instantly share code, notes, and snippets.

@sgruhier
Created September 30, 2016 07:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sgruhier/f7de65ec205d4f364f752e2347eee8c6 to your computer and use it in GitHub Desktop.
Save sgruhier/f7de65ec205d4f364f752e2347eee8c6 to your computer and use it in GitHub Desktop.
ng2
import { Component, OnChanges, OnDestroy, SimpleChange, ElementRef, Input } from '@angular/core';
import { D3Service } from 'd3-ng2-service';
import { BaseChart } from '../base.chart';
@Component({
selector: 'app-piechart',
template: `<ng-content></ng-content>`,
styleUrls: ['./piechart.component.scss'],
})
export class PiechartComponent extends BaseChart implements OnChanges, OnDestroy {
@Input() data: Array<any>;
@Input() startAngle: number = 0;
@Input() endAngle: number = 360;
@Input() padAngle: number = 0;
@Input() cornerRadius: number = 0;
@Input() duration: number = 1000;
private arc;
private pie;
private colors;
constructor(private element: ElementRef, private d3Service: D3Service) {
super(element, d3Service);
this.colors = this.d3.scaleOrdinal(this.d3.schemeCategory20c);
}
prepare(): void {
this.pie = this.d3.pie()
.sort(null)
.startAngle(this.startAngle)
.endAngle(this.endAngle)
.value((d: any) => d.value);
this.arc = this.d3.arc()
.outerRadius(this.height / 2)
.innerRadius(this.height / 4)
.padAngle(this.padAngle)
.cornerRadius(this.cornerRadius);
this.svg
.append('g')
.attr('transform', 'translate(' + [this.width / 2, this.height / 2] + ')');
}
draw(changes: { [propKey: string]: SimpleChange }): void {
let arc = this.arc;
let d3 = this.d3;
function arcTween(a) {
// First draw, set current to empty pie to have initial animation
if (!this._current) {
this._current = Object.assign({}, a, { startAngle: 2 * Math.PI, endAngle: 2 * Math.PI });
}
const i = d3.interpolate(this._current, a);
this._current = i(1);
return (t) => arc(i(t));
}
function arcTweenOut(a) {
let i = d3.interpolate(this._current, { startAngle: 0, endAngle: 0, value: 0 });
this._current = i(0);
return (t) => arc(i(t));
}
const g = this.svg.select('g');
// Add new arcs
let pieG = g.selectAll('.pie').data(this.pie(this.data), (d) => d.data.key);
pieG.enter()
.append('path')
.attr('class', 'pie')
.attr('d', this.arc)
.attr('stroke', 'gray')
.attr('fill', (d, i) => d.data.color || this.colors(i % 20));
// Run transition/exit on arcs
pieG = g.selectAll('.pie').data(this.pie(this.data), (d) => d.data.key);
pieG.transition()
.duration(this.duration)
.attrTween('d', arcTween);
pieG.exit()
.transition()
.duration(this.duration)
.attrTween('d', arcTweenOut)
.remove();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment