@swimlane/ngx-charts
Version:
Declarative Charting Framework for Angular2 and beyond!
131 lines (111 loc) • 3.54 kB
text/typescript
import {
Component,
Input,
OnChanges,
ChangeDetectionStrategy
} from '@angular/core';
import d3 from '../d3';
export class GaugeAxisComponent implements OnChanges {
bigSegments: any;
smallSegments: any;
min: any;
max: any;
angleSpan: number;
startAngle: number;
radius: any;
valueScale: any;
ticks: any[];
rotationAngle: number;
rotate: string = '';
ngOnChanges() {
this.update();
}
update(): void {
this.rotationAngle = -90 + this.startAngle;
this.rotate = `rotate(${ this.rotationAngle })`;
this.ticks = this.getTicks();
}
getTicks(): any {
let bigTickSegment = this.angleSpan / this.bigSegments;
let smallTickSegment = bigTickSegment / (this.smallSegments);
let tickLength = 20;
let ticks = {
big: [],
small: []
};
let startDistance = this.radius + 10;
let textDist = startDistance + tickLength + 10;
for (let i = 0; i <= this.bigSegments; i++) {
let angleDeg = i * bigTickSegment;
let angle = angleDeg * Math.PI / 180;
let textAnchor = this.getTextAnchor(angleDeg);
ticks.big.push({
line: this.getTickPath(startDistance, tickLength, angle),
textAnchor,
text: Number.parseInt(this.valueScale.invert(angleDeg).toString()).toLocaleString(),
textTransform: `
translate(${textDist * Math.cos(angle)}, ${textDist * Math.sin(angle)}) rotate(${ -this.rotationAngle })
`
});
if (i === this.bigSegments) {
continue;
}
for (let j = 1; j <= this.smallSegments; j++) {
let smallAngleDeg = angleDeg + j * smallTickSegment;
let smallAngle = smallAngleDeg * Math.PI / 180;
ticks.small.push({
line: this.getTickPath(startDistance, tickLength / 2, smallAngle)
});
}
}
return ticks;
}
getTextAnchor(angle) {
// [0, 45] = 'middle';
// [46, 135] = 'start';
// [136, 225] = 'middle';
// [226, 315] = 'end';
angle = (this.startAngle + angle) % 360;
let textAnchor = 'middle';
if (angle > 45 && angle <= 135) {
textAnchor = 'start';
} else if (angle > 225 && angle <= 315) {
textAnchor = 'end';
}
return textAnchor;
}
getTickPath(startDistance, tickLength, angle): any {
let y1 = startDistance * Math.sin(angle);
let y2 = (startDistance + tickLength) * Math.sin(angle);
let x1 = startDistance * Math.cos(angle);
let x2 = (startDistance + tickLength) * Math.cos(angle);
let points = [{x: x1, y: y1}, {x: x2, y: y2}];
let line = d3.line().x(d => d.x).y(d => d.y);
return line(points);
}
}