Christian Wahl

SVG gauge with threshold

06 Mar 2022 • Christian Wahl

Based on a question asked on StackOverflow I made this example of a gauge in SVG.

I think that this is my first example where I make use of the pathLength attribute on a <circle>. Not that it is magic, but I find it more clean than turning a <path> into a circle. The threshold doesn’t do anything in this example, but it is a nice feature that the text flips then passing 50% (6 o’clock).

JavaScript

var meter = document.getElementById('meter');
var threshold = document.getElementById('threshold');

document.forms.form01.addEventListener('change', e => {
  let newval = e.target.value;
  switch(e.target.name){
    case 'val':
      meter.setAttribute('stroke-dasharray', `${newval} 100`);
      break;
    case 'tval':
      threshold.setAttribute('transform', `translate(50 50) rotate(-90) rotate(${3.6*newval})`);
      let text = threshold.querySelector('text');
      text.textContent = newval;
      let transformStr = 'translate(43 -1)';
      if(newval > 50) transformStr += ' rotate(180) translate(-5 -2)';
      text.setAttribute('transform', transformStr);
      break;
  }
});

HTML

<form name="form01">
<lable>Value: <input name="val" type="range" min="0" max="100" value="25"/></lable>
<lable>Threshold: <input name="tval" type="range" min="0" max="100" value="33"/></lable>
</form>
<svg width="300" viewBox="0 0 100 100" fill="none" stroke-width="5" stroke-linecap="round">
  <circle stroke="silver" cx="50" cy="50" r="40"/>
  <circle id="meter" transform="rotate(-90 50 50)" stroke="green" cx="50" cy="50" r="40"
  pathLength="100" stroke-dasharray="25 100"/>
  <g id="threshold" transform="translate(50 50) rotate(-90) rotate(120)">
    <line x1="37.5" y1="0" x2="47.5" y2="0" stroke="black" stroke-width="1"/>
    <text transform="translate(43 -1)" font-size="4" fill="black">33</text>
  </g>
</svg>

Example

Here is a working example in an iframe: