added widget layout styling
added basic system to render linear gauges (wip)
This commit is contained in:
parent
81c2d82e1d
commit
48fb012e54
@ -3,6 +3,10 @@ import m from 'mithril';
|
||||
export abstract class Component {
|
||||
abstract view(vnode: m.Vnode): m.Children;
|
||||
|
||||
constructor(vnode?: m.Vnode) {
|
||||
|
||||
}
|
||||
|
||||
oninit(vnode: m.Vnode) {}
|
||||
|
||||
oncreate(vnode: m.Vnode) {}
|
||||
|
@ -1,16 +1,20 @@
|
||||
import m from 'mithril';
|
||||
import { Component } from 'components/component'
|
||||
import { Widget } from 'components/widgets/widget';
|
||||
|
||||
require("./clock.css");
|
||||
|
||||
export default class Clock extends Component {
|
||||
export class Clock extends Widget {
|
||||
constructor(vnode: any) {
|
||||
super(vnode);
|
||||
}
|
||||
|
||||
view(vnode: m.Vnode<{}, {}>): m.Children {
|
||||
var now = new Date();
|
||||
var days = ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'];
|
||||
var nextUpdateDelay = 61 - now.getSeconds();
|
||||
setTimeout(() => m.redraw(), nextUpdateDelay * 1000);
|
||||
|
||||
return <div class="clock">
|
||||
return <div class="widget clock">
|
||||
<div class="date">
|
||||
<p class="day">{days[now.getDay()]}</p>
|
||||
<p class="date">{('0'+now.getDate()).slice(-2) + '/' + ('0'+now.getMonth()).slice(-2)}</p>
|
||||
|
32
WebApp/src/components/widgets/gauge-linear.css
Normal file
32
WebApp/src/components/widgets/gauge-linear.css
Normal file
@ -0,0 +1,32 @@
|
||||
div.gauge-linear {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
div.gauge-linear p.value {
|
||||
font-size: 2.3rem;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
div.gauge-linear span.unit {
|
||||
font-size: 1.6rem;
|
||||
font-family: initial;
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
71
WebApp/src/components/widgets/gauge-linear.tsx
Normal file
71
WebApp/src/components/widgets/gauge-linear.tsx
Normal file
@ -0,0 +1,71 @@
|
||||
import m from 'mithril';
|
||||
import { Widget } from 'components/widgets/widget';
|
||||
|
||||
require('./gauge-linear.css');
|
||||
|
||||
export class GaugeLinear extends Widget {
|
||||
private bars: SVGRectElement[] = [];
|
||||
|
||||
constructor(vnode: any) {
|
||||
super(vnode);
|
||||
}
|
||||
|
||||
view(vnode: m.Vnode<{}, {}>): m.Children {
|
||||
return <div class="widget gauge-linear" style={'flex: ' + this.widgetWidth}>
|
||||
<p class="value">643<span class="unit">W</span></p>
|
||||
<svg>
|
||||
</svg>
|
||||
</div>;
|
||||
}
|
||||
|
||||
createSvg(svgElement: SVGElement) {
|
||||
let w = Math.round(svgElement.clientWidth);
|
||||
let h = Math.round(svgElement.clientHeight);
|
||||
|
||||
svgElement.setAttribute('viewBox', "0 0 "+w+" "+h);
|
||||
|
||||
let bg = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
|
||||
bg.setAttribute('width', w.toString());
|
||||
bg.setAttribute('height', h.toString());
|
||||
bg.classList.add('gauge-linear-bg');
|
||||
svgElement.append(bg);
|
||||
|
||||
let barHeight = 15;
|
||||
const barGap = barHeight * 0.2;
|
||||
let numBars = Math.round(h / (barHeight + barGap));
|
||||
|
||||
let bh = (h - (numBars+1)*barGap) / numBars;
|
||||
barHeight = Math.round(bh);
|
||||
|
||||
for(let barIdx = 0; barIdx < numBars; ++barIdx) {
|
||||
let bar = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
|
||||
bar.setAttribute('width', (w - barGap * 2).toString());
|
||||
bar.setAttribute('height', barHeight.toString());
|
||||
bar.classList.add('gauge-linear-bar');
|
||||
bar.classList.toggle('lit', false);
|
||||
|
||||
bar.setAttribute('x', barGap.toString());
|
||||
bar.setAttribute('y', (h - barIdx * (bh+barGap) - barGap - barHeight).toString());
|
||||
|
||||
svgElement.append(bar);
|
||||
|
||||
this.bars.push(bar);
|
||||
}
|
||||
}
|
||||
|
||||
renderGaugeRatio(ratio: number) {
|
||||
let numBars = this.bars.length;
|
||||
let litBars = Math.round(ratio * numBars);
|
||||
console.log(litBars);
|
||||
for(let barIdx = 0; barIdx < numBars; ++barIdx) {
|
||||
let bar = this.bars[barIdx];
|
||||
bar.classList.toggle('lit', barIdx < litBars);
|
||||
}
|
||||
}
|
||||
|
||||
oncreate(vnode: any) {
|
||||
let svgElement: SVGElement = vnode.dom.querySelector('svg');
|
||||
this.createSvg(svgElement);
|
||||
this.renderGaugeRatio(0.2);
|
||||
}
|
||||
}
|
3
WebApp/src/components/widgets/widget.css
Normal file
3
WebApp/src/components/widgets/widget.css
Normal file
@ -0,0 +1,3 @@
|
||||
div.widget svg {
|
||||
flex: 1;
|
||||
}
|
19
WebApp/src/components/widgets/widget.ts
Normal file
19
WebApp/src/components/widgets/widget.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import m from 'mithril';
|
||||
import { Component } from 'components/component'
|
||||
|
||||
require('./widget.css');
|
||||
|
||||
interface WidgetAttrs
|
||||
{
|
||||
widgetWidth: number;
|
||||
}
|
||||
|
||||
export abstract class Widget extends Component {
|
||||
public widgetWidth = 1.0;
|
||||
|
||||
constructor(vnode?: m.Vnode<WidgetAttrs>) {
|
||||
super(vnode);
|
||||
if(vnode.attrs.widgetWidth !== undefined)
|
||||
this.widgetWidth = vnode.attrs.widgetWidth;
|
||||
}
|
||||
};
|
@ -1,3 +1,13 @@
|
||||
/*html body {
|
||||
font-size: 3rem;
|
||||
}*/
|
||||
html, html > body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
html > body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
html > body > section {
|
||||
flex: 1;
|
||||
}
|
||||
|
13
WebApp/src/pages/dashboard/dashboard-page.css
Normal file
13
WebApp/src/pages/dashboard/dashboard-page.css
Normal file
@ -0,0 +1,13 @@
|
||||
div.dashboard-page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
div.widgets-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
div.widget {
|
||||
flex: 1;
|
||||
}
|
@ -1,7 +1,11 @@
|
||||
import m from 'mithril';
|
||||
import { Page } from 'components/page';
|
||||
import { MonitorApi, Status } from 'monitor-api';
|
||||
import Clock from 'components/widgets/clock';
|
||||
|
||||
import { Clock } from 'components/widgets/clock';
|
||||
import { GaugeLinear } from 'components/widgets/gauge-linear';
|
||||
|
||||
require('./dashboard-page.css');
|
||||
|
||||
export class DashboardPage extends Page {
|
||||
status: Status = null;
|
||||
@ -29,7 +33,12 @@ export class DashboardPage extends Page {
|
||||
view() {
|
||||
return this.status
|
||||
? <div class="dashboard-page">
|
||||
<Clock/>
|
||||
<div class="widgets-row">
|
||||
<Clock/>
|
||||
</div>
|
||||
<div class="widgets-row" style="height: 40%">
|
||||
<GaugeLinear widgetWidth={0.2} />
|
||||
</div>
|
||||
</div>
|
||||
: <p>Chargement...</p>;
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ module.exports = {
|
||||
}),
|
||||
new PurgecssPlugin({
|
||||
paths: glob.sync('./src/**/*', { nodir: true }),
|
||||
safelist: ['html', 'body']
|
||||
})
|
||||
]
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user