|
|
|
@ -1,35 +1,82 @@
|
|
|
|
|
import { ChartwerkBase, VueChartwerkBaseMixin, TickOrientation, TimeFormat, AxisFormat } from '@chartwerk/base'; |
|
|
|
|
import { ChartwerkPod, VueChartwerkPodMixin } from '@chartwerk/base'; |
|
|
|
|
|
|
|
|
|
import * as d3 from 'd3'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export class ChartwerkGaugePod extends ChartwerkBase<any, any> { |
|
|
|
|
export class ChartwerkGaugePod extends ChartwerkPod<any, any> { |
|
|
|
|
gaugeCenter = ''; |
|
|
|
|
|
|
|
|
|
// TODO: define the type better
|
|
|
|
|
private _dValue: d3.Selection<SVGTextElement, unknown, null, undefined>; |
|
|
|
|
// it will be options
|
|
|
|
|
colors = ['green', 'yellow', 'red']; |
|
|
|
|
stops = [10, 30]; |
|
|
|
|
value = 40; |
|
|
|
|
|
|
|
|
|
constructor(el: HTMLElement, _series: any[] = [], _options: any = {}) { |
|
|
|
|
super(d3, el, _series, _options); |
|
|
|
|
this._init(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private _init() { |
|
|
|
|
this._initValueText(); |
|
|
|
|
get valueRange(): number[] { |
|
|
|
|
if(this.stops.length < 2) { |
|
|
|
|
return this.stops; |
|
|
|
|
} |
|
|
|
|
let range = [this.stops[0]]; |
|
|
|
|
for(let i = 1; i < this.stops.length; i++) { |
|
|
|
|
range.push(this.stops[i]-this.stops[i-1]); |
|
|
|
|
} |
|
|
|
|
return range; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private _initValueText(): void { |
|
|
|
|
this._dValue = this._chartContainer |
|
|
|
|
.append('text') |
|
|
|
|
.text('hey you') |
|
|
|
|
.attr('fill', 'black'); |
|
|
|
|
renderLine(): void { |
|
|
|
|
let scale = d3.scaleLinear().domain([0, this.maxValue]).range([0, 180]); |
|
|
|
|
this.chartContainer.selectAll('.needle').data([this.value]) |
|
|
|
|
.transition() |
|
|
|
|
.ease(d3.easeElasticOut) |
|
|
|
|
.duration(1000) |
|
|
|
|
.attr('transform', (d: number) => { |
|
|
|
|
return this.gaugeCenter + 'rotate(' + scale(d) + ')' |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_renderMetrics(): void { |
|
|
|
|
|
|
|
|
|
renderMetrics(): void { |
|
|
|
|
this.gaugeCenter = `translate(${this.width / 2},${this.height - 10})`; |
|
|
|
|
|
|
|
|
|
let arc = d3.arc() |
|
|
|
|
.innerRadius(50) |
|
|
|
|
.outerRadius(80) |
|
|
|
|
.padAngle(0); |
|
|
|
|
|
|
|
|
|
let pie = d3.pie() |
|
|
|
|
.startAngle((-1 * Math.PI) / 2) |
|
|
|
|
.endAngle(Math.PI / 2) |
|
|
|
|
|
|
|
|
|
let arcs = pie(this.valueRange); |
|
|
|
|
let background = this.chartContainer.selectAll('path') |
|
|
|
|
.data(arcs) |
|
|
|
|
.enter() |
|
|
|
|
.append('path') |
|
|
|
|
.style('fill', (d: object, i: number) => { |
|
|
|
|
return this.colors[i]; |
|
|
|
|
}) |
|
|
|
|
.attr('d', arc as any) |
|
|
|
|
.attr('transform', this.gaugeCenter) |
|
|
|
|
|
|
|
|
|
let needle = this.chartContainer.selectAll('.needle') |
|
|
|
|
.data([0]) |
|
|
|
|
.enter() |
|
|
|
|
.append('line') |
|
|
|
|
.attr('x1', 0) |
|
|
|
|
.attr('x2', -80) |
|
|
|
|
.attr('y1', 0) |
|
|
|
|
.attr('y2', 0) |
|
|
|
|
.classed('needle', true) |
|
|
|
|
.style('stroke', 'black') |
|
|
|
|
.attr('transform', (d: number) => { |
|
|
|
|
return this.gaugeCenter + 'rotate(' + d + ')' |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
this.renderLine(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -53,7 +100,7 @@ export const VueChartwerkGaugePodObject = {
|
|
|
|
|
} |
|
|
|
|
) |
|
|
|
|
}, |
|
|
|
|
mixins: [VueChartwerkBaseMixin], |
|
|
|
|
mixins: [VueChartwerkPodMixin], |
|
|
|
|
methods: { |
|
|
|
|
render() { |
|
|
|
|
const pod = new ChartwerkGaugePod(document.getElementById(this.id), this.series, this.options); |
|
|
|
|