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; |
||||
margin: 0.2rem; |
||||
} |
||||
|
Loading…
Reference in new issue