Browse Source

added chronometer

master
Youen Toupin 3 years ago
parent
commit
c7da034218
  1. 3
      WebApp/src/components/widgets/chronometer.css
  2. 54
      WebApp/src/components/widgets/chronometer.tsx
  3. 2
      WebApp/src/components/widgets/gauge.tsx
  4. 2
      WebApp/src/components/widgets/numeric-value.css
  5. 20
      WebApp/src/components/widgets/numeric-value.tsx
  6. 6
      WebApp/src/pages/dashboard/dashboard-page.tsx

3
WebApp/src/components/widgets/chronometer.css

@ -0,0 +1,3 @@
div.widget.chronometer span.integral-value {
font-size: 2.0rem;
}

54
WebApp/src/components/widgets/chronometer.tsx

@ -0,0 +1,54 @@
import { NumericValue } from 'components/widgets/numeric-value';
require('./chronometer.css');
export class Chronometer extends NumericValue {
private realTimeValue = 0;
private realTimeReference = 0;
private animating = false;
private shuttingDown = false;
protected mainClassName() { return 'numeric-value chronometer'; }
protected onValueChange(value: number) {
let now = Date.now() / 1000;
let realTimeValue = this.realTimeValue + (now - this.realTimeReference);
if(Math.abs(value - realTimeValue) < 2.0)
return;
this.realTimeValue = value;
this.realTimeReference = now;
realTimeValue = value;
this.startAnimation();
}
private startAnimation() {
if(this.animating)
return;
this.animating = true;
this.animate();
}
onbeforeremove(vnode: any) {
this.shuttingDown = true;
super.onbeforeremove(vnode);
}
private animate() {
if(this.shuttingDown) return;
let now = Date.now() / 1000;
let realTimeValue = this.realTimeValue + (now - this.realTimeReference);
let hours = Math.floor(realTimeValue / 3600);
let minutes = Math.floor((realTimeValue - hours * 3600)/60);
let seconds = Math.floor(realTimeValue - hours * 3600 - minutes * 60);
this.integralValueElement.innerText = (hours < 10 ? '0' : '') + hours + ':' + (minutes < 10 ? '0' : '') + minutes + ':' + (seconds < 10 ? '0' : '') + seconds;
setTimeout(() => this.animate(), (Math.ceil(realTimeValue) + 0.05 - realTimeValue) * 1000);
}
}

2
WebApp/src/components/widgets/gauge.tsx

@ -36,6 +36,8 @@ export class Gauge extends NumericValue {
protected onValueChange(value: number) { protected onValueChange(value: number) {
let now = Date.now() / 1000.0; let now = Date.now() / 1000.0;
super.onValueChange(value);
let ratio = value / (this.maxValue || 1.0); let ratio = value / (this.maxValue || 1.0);
let numBars = this.bars.length; let numBars = this.bars.length;
let threshold = 0.33 / numBars; let threshold = 0.33 / numBars;

2
WebApp/src/components/widgets/numeric-value.css

@ -1,5 +1,5 @@
div.widget span.integral-value { div.widget span.integral-value {
font-size: 2.3rem; font-size: 2.2rem;
font-family: monospace; font-family: monospace;
} }

20
WebApp/src/components/widgets/numeric-value.tsx

@ -13,8 +13,8 @@ export class NumericValue extends Widget {
protected icon?: string; protected icon?: string;
private integralValueElement: HTMLElement; protected integralValueElement: HTMLElement;
private decimalValueElement: HTMLElement; protected decimalValueElement: HTMLElement;
constructor(vnode: any) { constructor(vnode: any) {
super(vnode); super(vnode);
@ -27,7 +27,7 @@ export class NumericValue extends Widget {
this.icon = vnode.attrs.icon || null; this.icon = vnode.attrs.icon || null;
this.value.onChange(() => this.onValueChange_()); this.value.onChange(() => this.onValueChange(this.getClampedValue()));
} }
view(vnode: m.Vnode<{}, {}>): m.Children { view(vnode: m.Vnode<{}, {}>): m.Children {
@ -48,27 +48,25 @@ export class NumericValue extends Widget {
return []; return [];
} }
protected onValueChange(newValue: number) { private getClampedValue() {
}
private onValueChange_() {
let value = this.value.get(); let value = this.value.get();
if(this.minValue !== null) value = Math.max(value, this.minValue); if(this.minValue !== null) value = Math.max(value, this.minValue);
if(this.maxValue !== null) value = Math.min(value, this.maxValue); if(this.maxValue !== null) value = Math.min(value, this.maxValue);
return value;
}
let valueStr = value.toFixed(this.decimals); protected onValueChange(newValue: number) {
let valueStr = newValue.toFixed(this.decimals);
let parts = valueStr.split('.'); let parts = valueStr.split('.');
this.integralValueElement.innerText = parts[0]; this.integralValueElement.innerText = parts[0];
this.decimalValueElement.innerText = this.decimals > 0 ? '.' + parts[1] : ''; this.decimalValueElement.innerText = this.decimals > 0 ? '.' + parts[1] : '';
this.onValueChange(value);
} }
oncreate(vnode: any) { oncreate(vnode: any) {
this.integralValueElement = vnode.dom.querySelector('span.integral-value'); this.integralValueElement = vnode.dom.querySelector('span.integral-value');
this.decimalValueElement = vnode.dom.querySelector('span.decimal-value'); this.decimalValueElement = vnode.dom.querySelector('span.decimal-value');
this.onValueChange_(); this.onValueChange(this.getClampedValue());
} }
} }

6
WebApp/src/pages/dashboard/dashboard-page.tsx

@ -5,6 +5,7 @@ import { Pipe } from 'utilities/pipe';
import { Clock } from 'components/widgets/clock'; import { Clock } from 'components/widgets/clock';
import { NumericValue } from 'components/widgets/numeric-value'; import { NumericValue } from 'components/widgets/numeric-value';
import { Chronometer } from 'components/widgets/chronometer';
import { GaugeLinear } from 'components/widgets/gauge-linear'; import { GaugeLinear } from 'components/widgets/gauge-linear';
import { GaugeCircular } from 'components/widgets/gauge-circular'; import { GaugeCircular } from 'components/widgets/gauge-circular';
import { GaugeBattery } from 'components/widgets/gauge-battery'; import { GaugeBattery } from 'components/widgets/gauge-battery';
@ -28,6 +29,7 @@ export class DashboardPage extends Page {
private battery = new Pipe(0.0); private battery = new Pipe(0.0);
private speed = new Pipe(0.0); private speed = new Pipe(0.0);
private tripTotalTime = new Pipe(0.0);
private tripDistance = new Pipe(0.0); private tripDistance = new Pipe(0.0);
private tripAverageSpeed = new Pipe(0.0); private tripAverageSpeed = new Pipe(0.0);
private tripEnergy = new Pipe(0.0); private tripEnergy = new Pipe(0.0);
@ -62,6 +64,7 @@ export class DashboardPage extends Page {
this.speed.set(this.status.speed * 3.6); // convert m/s to km/h this.speed.set(this.status.speed * 3.6); // convert m/s to km/h
this.tripTotalTime.set(this.status.tripTotalTime);
this.tripDistance.set(this.status.tripDistance/1000); this.tripDistance.set(this.status.tripDistance/1000);
this.tripAverageSpeed.set(this.status.tripDistance/1000 / (Math.max(1.0, this.status.tripMovingTime)/3600)); this.tripAverageSpeed.set(this.status.tripDistance/1000 / (Math.max(1.0, this.status.tripMovingTime)/3600));
this.tripEnergy.set(this.status.tripMotorEnergy); this.tripEnergy.set(this.status.tripMotorEnergy);
@ -72,7 +75,7 @@ export class DashboardPage extends Page {
this.altitude.set(this.status.altitude); this.altitude.set(this.status.altitude);
if(this.autoRefresh) if(this.autoRefresh)
setTimeout(() => { if(this.autoRefresh) this.refresh(); }, 150); setTimeout(() => { if(this.autoRefresh) this.refresh(); }, 400);
} }
view() { view() {
@ -90,6 +93,7 @@ export class DashboardPage extends Page {
</div> </div>
<div class="widgets-row"> <div class="widgets-row">
<Chronometer icon={TimeIcon} widgetWidth={0.5} value={this.tripTotalTime} />
<NumericValue icon={DistanceIcon} widgetWidth={0.5} value={this.tripDistance} decimals={1} unit="km" /> <NumericValue icon={DistanceIcon} widgetWidth={0.5} value={this.tripDistance} decimals={1} unit="km" />
</div> </div>
<div class="widgets-row"> <div class="widgets-row">

Loading…
Cancel
Save