responsive gauge
by dgrebb
HTML
<h1>Fully responsive animated gauge</h1>
<div class="speed-gauge" data-speed-percentage="25">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<defs>
<linearGradient id="speed-range__gauge-gradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#5736cb"/>
<stop offset="50%" stop-color="#aa2dc1"/>
<stop offset="80%" stop-color="#d9003a"/>
</linearGradient>
</defs>
<g>
<path d="M16 84 A 47 47, 0, 1, 1, 84, 84" fill="none" stroke="#D3D3D3" stroke-dasharray="700 480" class="speed-range__gauge-gutter" vector-effect="non-scaling-stroke" />
<path d="M16 84 A 47 47, 0, 1, 1, 84, 84" fill="none" stroke="url(#speed-range__gauge-gradient)" stroke-dasharray="0 500" class="speed-range__gauge-arc animate" vector-effect="non-scaling-stroke" />
</g>
</svg>
</div>
CSS
.speed-gauge {
width: 100%;
height: 400px;
box-sizing: border-box;
display: block;
}
.speed-gauge svg {
width: 100%;
display: block;
border: 1px solid black;
min-width: 100%;
max-width: 100%;
height: 100%;
}
.speed-range__gauge-gutter,
.speed-range__gauge-arc {
stroke-width: 4;
}
.speed-range__gauge-arc {
transition: .5s stroke-dasharray;
}
Babel + JSX
// set up selectors
const gutter = document.querySelector('.speed-range__gauge-gutter');
const gauge = document.querySelector('.speed-range__gauge-arc');
const gaugeContainer = document.querySelector('.speed-gauge');
// get the percentage to fill the gauge
const amount = Number(gaugeContainer.dataset.speedPercentage);
const calculateGauge = (amount) => {
console.log('window adj');
// get necessary style values
const strokeStyles = window.getComputedStyle(gauge);
const strokeWidth = Number( strokeStyles.getPropertyValue('stroke-width').replace('px', '') );
const gaugeWidth = Number(gaugeContainer.offsetWidth - strokeWidth*2);
const gutterLength = gaugeWidth * Math.PI;
const gapLength = gutterLength * .25; // our gap is a 45 degree angle
const gaugeAmount = Math.ceil( ( gutterLength - gapLength ) * (amount / 400 ) );
//the below line is needed to calculate the percentage for internet explorer 11 and Edge
//const gaugeAmount = Math.ceil( ( gutterLength - gapLength ) * (amount / 250 ) );
gauge.style.strokeDasharray = `${gaugeAmount} ${gutterLength}`;
gutter.style.strokeDasharray = gutterLength;
}
calculateGauge(amount);
window.addEventListener( 'resize', function(e) {
calculateGauge(amount)
}, false );