Youen Toupin
3 years ago
6 changed files with 107 additions and 11 deletions
@ -0,0 +1,81 @@ |
|||||||
|
import m from 'mithril'; |
||||||
|
import { Gauge } from 'components/widgets/gauge'; |
||||||
|
import { Pipe } from 'utilities/pipe'; |
||||||
|
|
||||||
|
require('./gauge-circular.css'); |
||||||
|
|
||||||
|
export class GaugeCircular extends Gauge { |
||||||
|
constructor(vnode: any) { |
||||||
|
super(vnode); |
||||||
|
} |
||||||
|
|
||||||
|
createSvg(svgElement: SVGElement) { |
||||||
|
let w = Math.round(svgElement.clientWidth); |
||||||
|
let h = Math.round(svgElement.clientHeight); |
||||||
|
|
||||||
|
svgElement.setAttribute('viewBox', "0 0 "+w+" "+h); |
||||||
|
|
||||||
|
let svgRound = (v: number) => Math.round(v * 100.0) / 100.0; |
||||||
|
|
||||||
|
const arcRatio = 0.75; // from 0.5 for half circle to 1.0 for full circle
|
||||||
|
const gaugeWidthRatio = 0.15; // relative to the smallest dimension of the drawing area
|
||||||
|
const lineThickness = 1; |
||||||
|
|
||||||
|
let gaugeWidth = Math.round(Math.min(w, h) * gaugeWidthRatio); |
||||||
|
let gaugeRadius = Math.round(Math.min(w, h) * 0.5 - gaugeWidth * 0.5 - lineThickness - 1); |
||||||
|
let cx = Math.round(w * 0.5); let cy = Math.round(h * 0.5); |
||||||
|
|
||||||
|
let openingHalfAngle = Math.PI * (1.0 - arcRatio); |
||||||
|
let arcLength = Math.PI * 2.0 * gaugeRadius * arcRatio; |
||||||
|
let startx = svgRound(cx - Math.sin(openingHalfAngle) * gaugeRadius); |
||||||
|
let starty = svgRound(cy + Math.cos(openingHalfAngle) * gaugeRadius); |
||||||
|
let dx = svgRound(2.0 * Math.sin(openingHalfAngle) * gaugeRadius); |
||||||
|
|
||||||
|
let outlineArcRatio = (arcLength + lineThickness*2.0) / (Math.PI * 2.0 * gaugeRadius); |
||||||
|
let outlineOpeningHalfAngle = Math.PI * (1.0 - outlineArcRatio); |
||||||
|
let outlineStartx = svgRound(cx - Math.sin(outlineOpeningHalfAngle) * gaugeRadius); |
||||||
|
let outlineStarty = svgRound(cy + Math.cos(outlineOpeningHalfAngle) * gaugeRadius); |
||||||
|
let outlineDx = svgRound(2.0 * Math.sin(outlineOpeningHalfAngle) * gaugeRadius); |
||||||
|
|
||||||
|
let bgOutline = document.createElementNS('http://www.w3.org/2000/svg', 'path'); |
||||||
|
bgOutline.setAttribute('d', 'M'+outlineStartx+' '+outlineStarty+' a'+gaugeRadius+' '+gaugeRadius+' 0 1 1 '+outlineDx+' 0'); |
||||||
|
bgOutline.setAttribute('style', 'stroke-width: '+(gaugeWidth+lineThickness*2)); |
||||||
|
bgOutline.classList.add('gauge-bg-outline'); |
||||||
|
svgElement.append(bgOutline); |
||||||
|
|
||||||
|
let bg = document.createElementNS('http://www.w3.org/2000/svg', 'path'); |
||||||
|
bg.setAttribute('d', 'M'+startx+' '+starty+' a'+gaugeRadius+' '+gaugeRadius+' 0 1 1 '+dx+' 0'); |
||||||
|
bg.setAttribute('style', 'stroke-width: '+(gaugeWidth)); |
||||||
|
bg.classList.add('gauge-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-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); |
||||||
|
}*/ |
||||||
|
} |
||||||
|
|
||||||
|
oncreate(vnode: any) { |
||||||
|
let svgElement: SVGElement = vnode.dom.querySelector('svg'); |
||||||
|
this.createSvg(svgElement); |
||||||
|
|
||||||
|
super.oncreate(vnode); |
||||||
|
} |
||||||
|
} |
@ -1,3 +1,11 @@ |
|||||||
div.widget svg { |
div.widgets-row { |
||||||
|
padding-top: 0.5rem; |
||||||
|
padding-bottom: 0.5rem; |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
} |
||||||
|
|
||||||
|
div.widget { |
||||||
flex: 1; |
flex: 1; |
||||||
|
margin: 0.2rem; |
||||||
} |
} |
||||||
|
Loading…
Reference in new issue