From 48fb012e544d6e9a8cb8779a85c45f2ba03b08c1 Mon Sep 17 00:00:00 2001 From: Youen Toupin Date: Tue, 12 Apr 2022 23:06:58 +0200 Subject: [PATCH] added widget layout styling added basic system to render linear gauges (wip) --- WebApp/src/components/component.ts | 4 ++ WebApp/src/components/widgets/clock.tsx | 10 ++- .../src/components/widgets/gauge-linear.css | 32 +++++++++ .../src/components/widgets/gauge-linear.tsx | 71 +++++++++++++++++++ WebApp/src/components/widgets/widget.css | 3 + WebApp/src/components/widgets/widget.ts | 19 +++++ WebApp/src/layout.css | 16 ++++- WebApp/src/pages/dashboard/dashboard-page.css | 13 ++++ WebApp/src/pages/dashboard/dashboard-page.tsx | 13 +++- WebApp/webpack.config.js | 1 + 10 files changed, 174 insertions(+), 8 deletions(-) create mode 100644 WebApp/src/components/widgets/gauge-linear.css create mode 100644 WebApp/src/components/widgets/gauge-linear.tsx create mode 100644 WebApp/src/components/widgets/widget.css create mode 100644 WebApp/src/components/widgets/widget.ts create mode 100644 WebApp/src/pages/dashboard/dashboard-page.css diff --git a/WebApp/src/components/component.ts b/WebApp/src/components/component.ts index 8016793..22037d4 100644 --- a/WebApp/src/components/component.ts +++ b/WebApp/src/components/component.ts @@ -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) {} diff --git a/WebApp/src/components/widgets/clock.tsx b/WebApp/src/components/widgets/clock.tsx index 235a6eb..3dd38af 100644 --- a/WebApp/src/components/widgets/clock.tsx +++ b/WebApp/src/components/widgets/clock.tsx @@ -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
+ return

{days[now.getDay()]}

{('0'+now.getDate()).slice(-2) + '/' + ('0'+now.getMonth()).slice(-2)}

diff --git a/WebApp/src/components/widgets/gauge-linear.css b/WebApp/src/components/widgets/gauge-linear.css new file mode 100644 index 0000000..5ffe4e5 --- /dev/null +++ b/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) +} diff --git a/WebApp/src/components/widgets/gauge-linear.tsx b/WebApp/src/components/widgets/gauge-linear.tsx new file mode 100644 index 0000000..4ebb168 --- /dev/null +++ b/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
+

643W

+ + +
; + } + + 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); + } +} diff --git a/WebApp/src/components/widgets/widget.css b/WebApp/src/components/widgets/widget.css new file mode 100644 index 0000000..91f075f --- /dev/null +++ b/WebApp/src/components/widgets/widget.css @@ -0,0 +1,3 @@ +div.widget svg { + flex: 1; +} diff --git a/WebApp/src/components/widgets/widget.ts b/WebApp/src/components/widgets/widget.ts new file mode 100644 index 0000000..840133f --- /dev/null +++ b/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) { + super(vnode); + if(vnode.attrs.widgetWidth !== undefined) + this.widgetWidth = vnode.attrs.widgetWidth; + } +}; diff --git a/WebApp/src/layout.css b/WebApp/src/layout.css index 7cb6790..fffb86a 100644 --- a/WebApp/src/layout.css +++ b/WebApp/src/layout.css @@ -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; +} diff --git a/WebApp/src/pages/dashboard/dashboard-page.css b/WebApp/src/pages/dashboard/dashboard-page.css new file mode 100644 index 0000000..926c749 --- /dev/null +++ b/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; +} diff --git a/WebApp/src/pages/dashboard/dashboard-page.tsx b/WebApp/src/pages/dashboard/dashboard-page.tsx index 35d7972..662b516 100644 --- a/WebApp/src/pages/dashboard/dashboard-page.tsx +++ b/WebApp/src/pages/dashboard/dashboard-page.tsx @@ -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 ?
- +
+ +
+
+ +
:

Chargement...

; } diff --git a/WebApp/webpack.config.js b/WebApp/webpack.config.js index 0cccebb..edf69b3 100644 --- a/WebApp/webpack.config.js +++ b/WebApp/webpack.config.js @@ -41,6 +41,7 @@ module.exports = { }), new PurgecssPlugin({ paths: glob.sync('./src/**/*', { nodir: true }), + safelist: ['html', 'body'] }) ] };