Youen Toupin
3 years ago
10 changed files with 174 additions and 8 deletions
@ -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) |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,3 @@ |
|||||||
|
div.widget svg { |
||||||
|
flex: 1; |
||||||
|
} |
@ -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 { |
html, html > body { |
||||||
font-size: 3rem; |
height: 100%; |
||||||
}*/ |
width: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
html > body { |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
} |
||||||
|
|
||||||
|
html > body > section { |
||||||
|
flex: 1; |
||||||
|
} |
||||||
|
@ -0,0 +1,13 @@ |
|||||||
|
div.dashboard-page { |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
div.widgets-row { |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
} |
||||||
|
|
||||||
|
div.widget { |
||||||
|
flex: 1; |
||||||
|
} |
Loading…
Reference in new issue