Browse Source

initial rendering works

merge-requests/1/merge
rozetko 4 years ago
parent
commit
4ad842bfe7
  1. 14
      examples/01-basic.html
  2. 149
      src/index.ts
  3. 4
      src/types.ts

14
examples/01-basic.html

@ -12,9 +12,19 @@
<script type="text/javascript"> <script type="text/javascript">
var pod = new ChartwerkGaugePod( var pod = new ChartwerkGaugePod(
document.getElementById('chart'), document.getElementById('chart'),
[{ target: 'test', datapoints: [[90, 5], [0, 10], [245, 15], [180, 20], [100, 25]] }], [{ target: 'test', datapoints: [[5, 5], [0, 10], [30, 15], [50, 20], [30, 25]] }],
{ {
stops: [10, 30, 100] stops: [
{
color: 'green',
value: 10
},
{
color: 'yellow',
value: 30
}
],
defaultColor: 'red'
} }
); );
pod.render(); pod.render();

149
src/index.ts

@ -17,15 +17,25 @@ const DEFAULT_GAUGE_OPTIONS: GaugeOptions = {
type: ZoomType.NONE type: ZoomType.NONE
}, },
colors: ['green', 'yellow', 'red'], stops: [
stops: [10, 30], {
color: 'green',
value: 10
},
{
color: 'yellow',
value: 20
}
],
defaultColor: 'red',
stat: Stat.CURRENT, stat: Stat.CURRENT,
innerRadius: 50, innerRadius: 50,
outerRadius: 80 outerRadius: 80
}; };
export class ChartwerkGaugePod extends ChartwerkPod<GaugeTimeSerie, GaugeOptions> { export class ChartwerkGaugePod extends ChartwerkPod<GaugeTimeSerie, GaugeOptions> {
gaugeTransform = ''; // TODO: better name
private _gaugeTransform = '';
constructor(el: HTMLElement, _series: GaugeTimeSerie[] = [], _options: GaugeOptions = {}) { constructor(el: HTMLElement, _series: GaugeTimeSerie[] = [], _options: GaugeOptions = {}) {
super( super(
@ -34,74 +44,17 @@ export class ChartwerkGaugePod extends ChartwerkPod<GaugeTimeSerie, GaugeOptions
); );
} }
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;
}
get colors(): string[] {
return this.options.colors;
}
get stat(): Stat {
return this.options.stat;
}
get stops(): number[] {
return [...this.options.stops, this.options.maxValue || this.maxValue];
}
get innerRadius(): number {
return this.options.innerRadius;
}
get outerRadius(): number {
return this.options.outerRadius;
}
get aggregatedValue(): number {
switch(this.stat) {
case Stat.CURRENT:
return _.last(this.series[0].datapoints)[0];
default:
throw new Error(`Unsupported stat: ${this.stat}`);
}
}
renderNeedle(): void {
const maxValue = this.options.maxValue || this.maxValue;
let scale = d3.scaleLinear()
.domain([0, maxValue])
.range([0, 180])
.clamp(true);
this.chartContainer.selectAll('.needle').data([this.aggregatedValue])
.transition()
.ease(d3.easeElasticOut)
.duration(1000)
.attr('transform', (d: number) => {
return this.gaugeTransform + 'rotate(' + scale(d) + ')'
});
}
renderMetrics(): void { renderMetrics(): void {
if (this.series.length === 0 || this.series[0].datapoints.length === 0) { if (this.series.length === 0 || this.series[0].datapoints.length === 0) {
this.renderNoDataPointsMessage(); this.renderNoDataPointsMessage();
return; return;
} }
this.gaugeTransform = `translate(${this.width / 2},${this.height - 10})`; this._gaugeTransform = `translate(${this.width / 2},${this.height - 10})`;
const arc = d3.arc() const arc = d3.arc()
.innerRadius(this.innerRadius) .innerRadius(this._innerRadius)
.outerRadius(this.outerRadius) .outerRadius(this._outerRadius)
.padAngle(0); .padAngle(0);
const pie = d3.pie() const pie = d3.pie()
@ -109,17 +62,17 @@ export class ChartwerkGaugePod extends ChartwerkPod<GaugeTimeSerie, GaugeOptions
.endAngle(Math.PI / 2) .endAngle(Math.PI / 2)
.sort(null); .sort(null);
const arcs = pie(this.valueRange); const arcs = pie(this._valueRange);
this.chartContainer.selectAll('path') this.chartContainer.selectAll('path')
.data(arcs) .data(arcs)
.enter() .enter()
.append('path') .append('path')
.style('fill', (d: object, i: number) => { .style('fill', (d: object, i: number) => {
return this.colors[i]; return this._colors[i];
}) })
.attr('d', arc as any) .attr('d', arc as any)
.attr('transform', this.gaugeTransform) .attr('transform', this._gaugeTransform)
const needle = this.chartContainer.selectAll('.needle') const needle = this.chartContainer.selectAll('.needle')
.data([0]) .data([0])
@ -132,12 +85,72 @@ export class ChartwerkGaugePod extends ChartwerkPod<GaugeTimeSerie, GaugeOptions
.classed('needle', true) .classed('needle', true)
.style('stroke', 'black') .style('stroke', 'black')
.attr('transform', (d: number) => { .attr('transform', (d: number) => {
return this.gaugeTransform + 'rotate(' + d + ')' return this._gaugeTransform + 'rotate(' + d + ')'
}); });
this.renderNeedle(); this._renderNeedle();
}
// TODO: better name
private get _valueRange(): number[] {
// TODO: refactor
const stopValues = [...this.options.stops.map(stop => stop.value), this.options.maxValue || this.maxValue]
if(stopValues.length < 2) {
return stopValues;
}
let range = [stopValues[0]];
for(let i = 1; i < stopValues.length; i++) {
range.push(stopValues[i] - stopValues[i-1]);
}
return range;
}
private get _colors(): string[] {
// TODO: refactor
return [...this.options.stops.map(stop => stop.color), this.options.defaultColor];
}
private get _stat(): Stat {
return this.options.stat;
}
private get _innerRadius(): number {
return this.options.innerRadius;
}
private get _outerRadius(): number {
return this.options.outerRadius;
}
private get aggregatedValue(): number {
switch(this._stat) {
case Stat.CURRENT:
return _.last(this.series[0].datapoints)[0];
// TODO: support other stats
default:
throw new Error(`Unsupported stat: ${this._stat}`);
}
}
private get _maxValue(): number {
return this.options.maxValue || this.maxValue;
} }
private _renderNeedle(): void {
let scale = d3.scaleLinear()
.domain([0, this._maxValue])
.range([0, 180])
.clamp(true);
this.chartContainer.selectAll('.needle').data([this.aggregatedValue])
.transition()
.ease(d3.easeElasticOut)
.duration(1000)
.attr('transform', (d: number) => {
return this._gaugeTransform + 'rotate(' + scale(d) + ')'
});
}
/* handlers and overloads */ /* handlers and overloads */
onMouseOver(): void {} onMouseOver(): void {}

4
src/types.ts

@ -14,8 +14,8 @@ export type GaugeOptionsParams = {
outerRadius: number; outerRadius: number;
// TODO: minValue // TODO: minValue
maxValue: number; maxValue: number;
stops: number[]; stops: { color: string , value: number }[];
colors: string[]; defaultColor: string;
stat: Stat; stat: Stat;
} }
export type GaugeOptions = Options & Partial<GaugeOptionsParams>; export type GaugeOptions = Options & Partial<GaugeOptionsParams>;

Loading…
Cancel
Save