refactored GaugeLinear to share implementation with other types of gauge
This commit is contained in:
parent
45ac1dd610
commit
b8bec376a0
@ -1,36 +0,0 @@
|
|||||||
div.gauge-linear {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.gauge-linear span.integral-value {
|
|
||||||
font-size: 2.3rem;
|
|
||||||
font-family: monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.gauge-linear span.decimal-value {
|
|
||||||
font-size: 1.6rem;
|
|
||||||
font-family: monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.gauge-linear span.unit {
|
|
||||||
font-size: 1.6rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
rect.gauge-linear-bg {
|
|
||||||
fill: rgb(255,255,255);
|
|
||||||
stroke-width: 2;
|
|
||||||
stroke: rgb(0,0,0)
|
|
||||||
}
|
|
||||||
|
|
||||||
rect.gauge-linear-bar {
|
|
||||||
fill: rgb(230,230,230);
|
|
||||||
stroke-width: 1;
|
|
||||||
stroke: rgb(180,180,180)
|
|
||||||
}
|
|
||||||
|
|
||||||
rect.gauge-linear-bar.lit {
|
|
||||||
fill: rgb(180,180,180);
|
|
||||||
stroke-width: 1;
|
|
||||||
stroke: rgb(0,0,0)
|
|
||||||
}
|
|
@ -1,36 +1,12 @@
|
|||||||
import m from 'mithril';
|
import m from 'mithril';
|
||||||
import { Widget } from 'components/widgets/widget';
|
import { Gauge } from 'components/widgets/gauge';
|
||||||
import { Pipe } from 'utilities/pipe';
|
import { Pipe } from 'utilities/pipe';
|
||||||
|
|
||||||
require('./gauge-linear.css');
|
require('./gauge-linear.css');
|
||||||
|
|
||||||
export class GaugeLinear extends Widget {
|
export class GaugeLinear extends Gauge {
|
||||||
private gaugeValue: Pipe<number>;
|
|
||||||
private gaugeMaxValue: number;
|
|
||||||
private unit: string;
|
|
||||||
private decimals: number;
|
|
||||||
|
|
||||||
private bars: SVGRectElement[] = [];
|
|
||||||
private integralValueElement: HTMLElement;
|
|
||||||
private decimalValueElement: HTMLElement;
|
|
||||||
|
|
||||||
constructor(vnode: any) {
|
constructor(vnode: any) {
|
||||||
super(vnode);
|
super(vnode);
|
||||||
|
|
||||||
this.gaugeValue = vnode.attrs.gaugeValue || new Pipe(0.0);
|
|
||||||
this.gaugeMaxValue = vnode.attrs.gaugeMaxValue || 1.0;
|
|
||||||
this.unit = vnode.attrs.unit || '';
|
|
||||||
this.decimals = vnode.attrs.decimals || 0;
|
|
||||||
|
|
||||||
this.gaugeValue.onChange(() => this.updateGauge());
|
|
||||||
}
|
|
||||||
|
|
||||||
view(vnode: m.Vnode<{}, {}>): m.Children {
|
|
||||||
return <div class="widget gauge-linear" style={'flex: ' + this.widgetWidth}>
|
|
||||||
<p><span class="integral-value"></span><span class="decimal-value"></span><span class="unit">{this.unit}</span></p>
|
|
||||||
<svg>
|
|
||||||
</svg>
|
|
||||||
</div>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
createSvg(svgElement: SVGElement) {
|
createSvg(svgElement: SVGElement) {
|
||||||
@ -42,7 +18,7 @@ export class GaugeLinear extends Widget {
|
|||||||
let bg = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
|
let bg = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
|
||||||
bg.setAttribute('width', w.toString());
|
bg.setAttribute('width', w.toString());
|
||||||
bg.setAttribute('height', h.toString());
|
bg.setAttribute('height', h.toString());
|
||||||
bg.classList.add('gauge-linear-bg');
|
bg.classList.add('gauge-bg');
|
||||||
svgElement.append(bg);
|
svgElement.append(bg);
|
||||||
|
|
||||||
let barHeight = 15;
|
let barHeight = 15;
|
||||||
@ -56,7 +32,7 @@ export class GaugeLinear extends Widget {
|
|||||||
let bar = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
|
let bar = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
|
||||||
bar.setAttribute('width', (w - barGap * 2).toString());
|
bar.setAttribute('width', (w - barGap * 2).toString());
|
||||||
bar.setAttribute('height', barHeight.toString());
|
bar.setAttribute('height', barHeight.toString());
|
||||||
bar.classList.add('gauge-linear-bar');
|
bar.classList.add('gauge-bar');
|
||||||
bar.classList.toggle('lit', false);
|
bar.classList.toggle('lit', false);
|
||||||
|
|
||||||
bar.setAttribute('x', barGap.toString());
|
bar.setAttribute('x', barGap.toString());
|
||||||
@ -68,31 +44,10 @@ export class GaugeLinear extends Widget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateGauge() {
|
|
||||||
let value = Math.max(0.0, Math.min(this.gaugeMaxValue, this.gaugeValue.get()));
|
|
||||||
|
|
||||||
let integralValue = Math.floor(value);
|
|
||||||
let decimalValue = value - integralValue;
|
|
||||||
|
|
||||||
this.integralValueElement.innerText = integralValue.toFixed(0);
|
|
||||||
this.decimalValueElement.innerText = this.decimals > 0 ? decimalValue.toFixed(this.decimals).substr(1) : '';
|
|
||||||
|
|
||||||
let ratio = value / this.gaugeMaxValue;
|
|
||||||
let numBars = this.bars.length;
|
|
||||||
let litBars = Math.round(ratio * numBars);
|
|
||||||
for(let barIdx = 0; barIdx < numBars; ++barIdx) {
|
|
||||||
let bar = this.bars[barIdx];
|
|
||||||
bar.classList.toggle('lit', barIdx < litBars);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
oncreate(vnode: any) {
|
oncreate(vnode: any) {
|
||||||
let svgElement: SVGElement = vnode.dom.querySelector('svg');
|
let svgElement: SVGElement = vnode.dom.querySelector('svg');
|
||||||
this.createSvg(svgElement);
|
this.createSvg(svgElement);
|
||||||
|
|
||||||
this.integralValueElement = vnode.dom.querySelector('span.integral-value');
|
super.oncreate(vnode);
|
||||||
this.decimalValueElement = vnode.dom.querySelector('span.decimal-value');
|
|
||||||
|
|
||||||
this.updateGauge();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
36
WebApp/src/components/widgets/gauge.css
Normal file
36
WebApp/src/components/widgets/gauge.css
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
div.gauge {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.gauge span.integral-value {
|
||||||
|
font-size: 2.3rem;
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.gauge span.decimal-value {
|
||||||
|
font-size: 1.6rem;
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.gauge span.unit {
|
||||||
|
font-size: 1.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
rect.gauge-bg {
|
||||||
|
fill: rgb(255,255,255);
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke: rgb(0,0,0)
|
||||||
|
}
|
||||||
|
|
||||||
|
rect.gauge-bar {
|
||||||
|
fill: rgb(230,230,230);
|
||||||
|
stroke-width: 1;
|
||||||
|
stroke: rgb(180,180,180)
|
||||||
|
}
|
||||||
|
|
||||||
|
rect.gauge-bar.lit {
|
||||||
|
fill: rgb(180,180,180);
|
||||||
|
stroke-width: 1;
|
||||||
|
stroke: rgb(0,0,0)
|
||||||
|
}
|
60
WebApp/src/components/widgets/gauge.tsx
Normal file
60
WebApp/src/components/widgets/gauge.tsx
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import m from 'mithril';
|
||||||
|
import { Widget } from 'components/widgets/widget';
|
||||||
|
import { Pipe } from 'utilities/pipe';
|
||||||
|
|
||||||
|
require('./gauge.css');
|
||||||
|
|
||||||
|
export class Gauge extends Widget {
|
||||||
|
private gaugeValue: Pipe<number>;
|
||||||
|
private gaugeMaxValue: number;
|
||||||
|
private unit: string;
|
||||||
|
private decimals: number;
|
||||||
|
|
||||||
|
protected bars: SVGRectElement[] = [];
|
||||||
|
private integralValueElement: HTMLElement;
|
||||||
|
private decimalValueElement: HTMLElement;
|
||||||
|
|
||||||
|
constructor(vnode: any) {
|
||||||
|
super(vnode);
|
||||||
|
|
||||||
|
this.gaugeValue = vnode.attrs.gaugeValue || new Pipe(0.0);
|
||||||
|
this.gaugeMaxValue = vnode.attrs.gaugeMaxValue || 1.0;
|
||||||
|
this.unit = vnode.attrs.unit || '';
|
||||||
|
this.decimals = vnode.attrs.decimals || 0;
|
||||||
|
|
||||||
|
this.gaugeValue.onChange(() => this.updateGauge());
|
||||||
|
}
|
||||||
|
|
||||||
|
view(vnode: m.Vnode<{}, {}>): m.Children {
|
||||||
|
return <div class="widget gauge" style={'flex: ' + this.widgetWidth}>
|
||||||
|
<p><span class="integral-value"></span><span class="decimal-value"></span><span class="unit">{this.unit}</span></p>
|
||||||
|
<svg>
|
||||||
|
</svg>
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateGauge() {
|
||||||
|
let value = Math.max(0.0, Math.min(this.gaugeMaxValue, this.gaugeValue.get()));
|
||||||
|
|
||||||
|
let integralValue = Math.floor(value);
|
||||||
|
let decimalValue = value - integralValue;
|
||||||
|
|
||||||
|
this.integralValueElement.innerText = integralValue.toFixed(0);
|
||||||
|
this.decimalValueElement.innerText = this.decimals > 0 ? decimalValue.toFixed(this.decimals).substr(1) : '';
|
||||||
|
|
||||||
|
let ratio = value / this.gaugeMaxValue;
|
||||||
|
let numBars = this.bars.length;
|
||||||
|
let litBars = Math.round(ratio * numBars);
|
||||||
|
for(let barIdx = 0; barIdx < numBars; ++barIdx) {
|
||||||
|
let bar = this.bars[barIdx];
|
||||||
|
bar.classList.toggle('lit', barIdx < litBars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
oncreate(vnode: any) {
|
||||||
|
this.integralValueElement = vnode.dom.querySelector('span.integral-value');
|
||||||
|
this.decimalValueElement = vnode.dom.querySelector('span.decimal-value');
|
||||||
|
|
||||||
|
this.updateGauge();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user