added some numerical values in dashboard (wip)
This commit is contained in:
parent
bd851a06f7
commit
641acf7c12
@ -8,20 +8,6 @@ div.gauge svg {
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gauge-bg {
|
.gauge-bg {
|
||||||
fill: rgb(255,255,255);
|
fill: rgb(255,255,255);
|
||||||
stroke-width: 2;
|
stroke-width: 2;
|
||||||
|
@ -54,11 +54,11 @@ export class Gauge extends Widget {
|
|||||||
|
|
||||||
let value = Math.max(0.0, Math.min(this.gaugeMaxValue, this.gaugeValue.get()));
|
let value = Math.max(0.0, Math.min(this.gaugeMaxValue, this.gaugeValue.get()));
|
||||||
|
|
||||||
let integralValue = Math.floor(value);
|
let valueStr = value.toFixed(this.decimals);
|
||||||
let decimalValue = value - integralValue;
|
let parts = valueStr.split('.');
|
||||||
|
|
||||||
this.integralValueElement.innerText = integralValue.toFixed(0);
|
this.integralValueElement.innerText = parts[0];
|
||||||
this.decimalValueElement.innerText = this.decimals > 0 ? decimalValue.toFixed(this.decimals).substr(1) : '';
|
this.decimalValueElement.innerText = this.decimals > 0 ? '.' + parts[1] : '';
|
||||||
|
|
||||||
let ratio = value / this.gaugeMaxValue;
|
let ratio = value / this.gaugeMaxValue;
|
||||||
let numBars = this.bars.length;
|
let numBars = this.bars.length;
|
||||||
|
13
WebApp/src/components/widgets/numeric-value.css
Normal file
13
WebApp/src/components/widgets/numeric-value.css
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
div.widget span.integral-value {
|
||||||
|
font-size: 2.3rem;
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.widget span.decimal-value {
|
||||||
|
font-size: 1.6rem;
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.widget span.unit {
|
||||||
|
font-size: 1.6rem;
|
||||||
|
}
|
47
WebApp/src/components/widgets/numeric-value.tsx
Normal file
47
WebApp/src/components/widgets/numeric-value.tsx
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import m from 'mithril';
|
||||||
|
import { Widget } from 'components/widgets/widget';
|
||||||
|
import { Pipe } from 'utilities/pipe';
|
||||||
|
|
||||||
|
require('./numeric-value.css');
|
||||||
|
|
||||||
|
export class NumericValue extends Widget {
|
||||||
|
private value: Pipe<number>;
|
||||||
|
private unit: string;
|
||||||
|
private decimals: number;
|
||||||
|
|
||||||
|
private integralValueElement: HTMLElement;
|
||||||
|
private decimalValueElement: HTMLElement;
|
||||||
|
|
||||||
|
constructor(vnode: any) {
|
||||||
|
super(vnode);
|
||||||
|
|
||||||
|
this.value = vnode.attrs.value || new Pipe(0.0);
|
||||||
|
this.unit = vnode.attrs.unit || '';
|
||||||
|
this.decimals = vnode.attrs.decimals || 0;
|
||||||
|
|
||||||
|
this.value.onChange(() => this.onValueChange());
|
||||||
|
}
|
||||||
|
|
||||||
|
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>
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
onValueChange() {
|
||||||
|
let value = this.value.get();
|
||||||
|
|
||||||
|
let valueStr = value.toFixed(this.decimals);
|
||||||
|
let parts = valueStr.split('.');
|
||||||
|
|
||||||
|
this.integralValueElement.innerText = parts[0];
|
||||||
|
this.decimalValueElement.innerText = this.decimals > 0 ? '.' + parts[1] : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
oncreate(vnode: any) {
|
||||||
|
this.integralValueElement = vnode.dom.querySelector('span.integral-value');
|
||||||
|
this.decimalValueElement = vnode.dom.querySelector('span.decimal-value');
|
||||||
|
|
||||||
|
this.onValueChange();
|
||||||
|
}
|
||||||
|
}
|
@ -44,8 +44,8 @@ export class MonitorApi {
|
|||||||
v: (Math.cos(t*0.4)+1.0)*0.5 * 6000 + 36000,
|
v: (Math.cos(t*0.4)+1.0)*0.5 * 6000 + 36000,
|
||||||
c: (Math.cos(t*0.7)+1.0)*0.5 * 30000,
|
c: (Math.cos(t*0.7)+1.0)*0.5 * 30000,
|
||||||
s: (Math.cos(t*0.3)+1.0)*0.5 * 14000,
|
s: (Math.cos(t*0.3)+1.0)*0.5 * 14000,
|
||||||
t: Math.random() * 400 - 100,
|
t: (Math.cos(t*0.2)+1.0)*0.5 * 400 - 100,
|
||||||
alt: Math.random() * 4500000 - 200000
|
alt: (Math.cos(t*0.0001)+1.0)*0.5 * 4500000 - 200000 + (Math.cos(t*0.03))*0.5 * 60000
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
apiStatus = await new Promise<ApiStatus>((resolve, error) => {
|
apiStatus = await new Promise<ApiStatus>((resolve, error) => {
|
||||||
|
@ -4,6 +4,7 @@ import { MonitorApi, Status } from 'monitor-api';
|
|||||||
import { Pipe } from 'utilities/pipe';
|
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 { 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';
|
||||||
@ -18,6 +19,17 @@ 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 lastRefreshTime = 0.0;
|
||||||
|
private movementTime = 0.0;
|
||||||
|
private distance = new Pipe(0.0);
|
||||||
|
private averageSpeed = new Pipe(0.0);
|
||||||
|
private energy = new Pipe(0.0);
|
||||||
|
private averageConsumption = new Pipe(0.0);
|
||||||
|
private ascendingElevation = new Pipe(0.0);
|
||||||
|
private lastElevation = -100000;
|
||||||
|
private altitude = new Pipe(0.0);
|
||||||
|
private temperature = new Pipe(0.0);
|
||||||
|
|
||||||
oninit() {
|
oninit() {
|
||||||
this.status = MonitorApi.get().getStatus();
|
this.status = MonitorApi.get().getStatus();
|
||||||
this.refresh();
|
this.refresh();
|
||||||
@ -33,7 +45,8 @@ export class DashboardPage extends Page {
|
|||||||
m.redraw();
|
m.redraw();
|
||||||
this.status = newStatus;
|
this.status = newStatus;
|
||||||
|
|
||||||
this.power.set(this.status.batteryVoltage * this.status.motorCurrent);
|
let power = this.status.batteryVoltage * this.status.motorCurrent;
|
||||||
|
this.power.set(power);
|
||||||
|
|
||||||
const minVoltage = 36.0;
|
const minVoltage = 36.0;
|
||||||
const maxVoltage = 42.0;
|
const maxVoltage = 42.0;
|
||||||
@ -42,6 +55,31 @@ 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
|
||||||
|
|
||||||
|
let now = Date.now() / 1000;
|
||||||
|
if(this.lastRefreshTime == 0.0) this.lastRefreshTime = now;
|
||||||
|
let dt = now - this.lastRefreshTime;
|
||||||
|
this.lastRefreshTime = now;
|
||||||
|
|
||||||
|
if(this.status.speed > 0.0)
|
||||||
|
this.movementTime += dt;
|
||||||
|
this.distance.set(this.distance.get() + this.status.speed * dt / 1000);
|
||||||
|
if(this.movementTime > 0.0)
|
||||||
|
this.averageSpeed.set(this.distance.get() / (this.movementTime / 3600));
|
||||||
|
|
||||||
|
if(this.lastElevation == -100000)
|
||||||
|
this.lastElevation = this.status.altitude;
|
||||||
|
let elevationChange = this.status.altitude - this.lastElevation;
|
||||||
|
this.lastElevation = this.status.altitude;
|
||||||
|
if(elevationChange > 0.0)
|
||||||
|
this.ascendingElevation.set(this.ascendingElevation.get() + elevationChange);
|
||||||
|
this.altitude.set(this.status.altitude);
|
||||||
|
|
||||||
|
this.temperature.set(this.status.temperature);
|
||||||
|
|
||||||
|
this.energy.set(this.energy.get() + power * dt / 3600);
|
||||||
|
if(this.distance.get() > 0.1)
|
||||||
|
this.averageConsumption.set(this.energy.get() / this.distance.get());
|
||||||
|
|
||||||
if(this.autoRefresh)
|
if(this.autoRefresh)
|
||||||
setTimeout(() => { if(this.autoRefresh) this.refresh(); }, 150);
|
setTimeout(() => { if(this.autoRefresh) this.refresh(); }, 150);
|
||||||
}
|
}
|
||||||
@ -52,11 +90,29 @@ export class DashboardPage extends Page {
|
|||||||
<div class="widgets-row">
|
<div class="widgets-row">
|
||||||
<Clock/>
|
<Clock/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="widgets-row" style="height: 40%">
|
<div class="widgets-row" style="height: 40%">
|
||||||
<GaugeLinear widgetWidth={0.2} gaugeValue={this.power} gaugeMaxValue={999.0} bottomWidth={0.4} unit="W" />
|
<GaugeLinear widgetWidth={0.2} gaugeValue={this.power} gaugeMaxValue={999.0} bottomWidth={0.4} unit="W" />
|
||||||
<GaugeCircular widgetWidth={0.6} gaugeValue={this.speed} gaugeMaxValue={50.0} decimals={1} unit="km/h" />
|
<GaugeCircular widgetWidth={0.6} gaugeValue={this.speed} gaugeMaxValue={50.0} decimals={1} unit="km/h" />
|
||||||
<GaugeBattery widgetWidth={0.2} gaugeValue={this.battery} gaugeMaxValue={100.0} unit="%" />
|
<GaugeBattery widgetWidth={0.2} gaugeValue={this.battery} gaugeMaxValue={100.0} unit="%" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="widgets-row">
|
||||||
|
<NumericValue widgetWidth={0.5} value={this.distance} decimals={1} unit="km" />
|
||||||
|
</div>
|
||||||
|
<div class="widgets-row">
|
||||||
|
<NumericValue widgetWidth={0.5} value={this.averageSpeed} decimals={1} unit="km/h" />
|
||||||
|
<NumericValue widgetWidth={0.5} value={this.ascendingElevation} decimals={1} unit="m" />
|
||||||
|
</div>
|
||||||
|
<div class="widgets-row">
|
||||||
|
<NumericValue widgetWidth={0.5} value={this.averageConsumption} decimals={1} unit="Wh/km" />
|
||||||
|
<NumericValue widgetWidth={0.5} value={this.energy} decimals={1} unit="Wh" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="widgets-row">
|
||||||
|
<NumericValue widgetWidth={0.5} value={this.temperature} decimals={1} unit="°C" />
|
||||||
|
<NumericValue widgetWidth={0.5} value={this.altitude} decimals={1} unit="m" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
: <p>Chargement...</p>;
|
: <p>Chargement...</p>;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user