Browse Source

added widget layout styling

added basic system to render linear gauges (wip)
master
Youen Toupin 3 years ago
parent
commit
48fb012e54
  1. 4
      WebApp/src/components/component.ts
  2. 10
      WebApp/src/components/widgets/clock.tsx
  3. 32
      WebApp/src/components/widgets/gauge-linear.css
  4. 71
      WebApp/src/components/widgets/gauge-linear.tsx
  5. 3
      WebApp/src/components/widgets/widget.css
  6. 19
      WebApp/src/components/widgets/widget.ts
  7. 16
      WebApp/src/layout.css
  8. 13
      WebApp/src/pages/dashboard/dashboard-page.css
  9. 11
      WebApp/src/pages/dashboard/dashboard-page.tsx
  10. 1
      WebApp/webpack.config.js

4
WebApp/src/components/component.ts

@ -3,6 +3,10 @@ import m from 'mithril';
export abstract class Component { export abstract class Component {
abstract view(vnode: m.Vnode): m.Children; abstract view(vnode: m.Vnode): m.Children;
constructor(vnode?: m.Vnode) {
}
oninit(vnode: m.Vnode) {} oninit(vnode: m.Vnode) {}
oncreate(vnode: m.Vnode) {} oncreate(vnode: m.Vnode) {}

10
WebApp/src/components/widgets/clock.tsx

@ -1,16 +1,20 @@
import m from 'mithril'; import m from 'mithril';
import { Component } from 'components/component' import { Widget } from 'components/widgets/widget';
require("./clock.css"); 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 { view(vnode: m.Vnode<{}, {}>): m.Children {
var now = new Date(); var now = new Date();
var days = ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi']; var days = ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'];
var nextUpdateDelay = 61 - now.getSeconds(); var nextUpdateDelay = 61 - now.getSeconds();
setTimeout(() => m.redraw(), nextUpdateDelay * 1000); setTimeout(() => m.redraw(), nextUpdateDelay * 1000);
return <div class="clock"> return <div class="widget clock">
<div class="date"> <div class="date">
<p class="day">{days[now.getDay()]}</p> <p class="day">{days[now.getDay()]}</p>
<p class="date">{('0'+now.getDate()).slice(-2) + '/' + ('0'+now.getMonth()).slice(-2)}</p> <p class="date">{('0'+now.getDate()).slice(-2) + '/' + ('0'+now.getMonth()).slice(-2)}</p>

32
WebApp/src/components/widgets/gauge-linear.css

@ -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

@ -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

@ -0,0 +1,3 @@
div.widget svg {
flex: 1;
}

19
WebApp/src/components/widgets/widget.ts

@ -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;
}
};

16
WebApp/src/layout.css

@ -1,3 +1,13 @@
/*html body { html, html > body {
font-size: 3rem; height: 100%;
}*/ width: 100%;
}
html > body {
display: flex;
flex-direction: column;
}
html > body > section {
flex: 1;
}

13
WebApp/src/pages/dashboard/dashboard-page.css

@ -0,0 +1,13 @@
div.dashboard-page {
width: 100%;
height: 100%;
}
div.widgets-row {
display: flex;
flex-direction: row;
}
div.widget {
flex: 1;
}

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

@ -1,7 +1,11 @@
import m from 'mithril'; import m from 'mithril';
import { Page } from 'components/page'; import { Page } from 'components/page';
import { MonitorApi, Status } from 'monitor-api'; 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 { export class DashboardPage extends Page {
status: Status = null; status: Status = null;
@ -29,8 +33,13 @@ export class DashboardPage extends Page {
view() { view() {
return this.status return this.status
? <div class="dashboard-page"> ? <div class="dashboard-page">
<div class="widgets-row">
<Clock/> <Clock/>
</div> </div>
<div class="widgets-row" style="height: 40%">
<GaugeLinear widgetWidth={0.2} />
</div>
</div>
: <p>Chargement...</p>; : <p>Chargement...</p>;
} }
} }

1
WebApp/webpack.config.js

@ -41,6 +41,7 @@ module.exports = {
}), }),
new PurgecssPlugin({ new PurgecssPlugin({
paths: glob.sync('./src/**/*', { nodir: true }), paths: glob.sync('./src/**/*', { nodir: true }),
safelist: ['html', 'body']
}) })
] ]
}; };

Loading…
Cancel
Save