Skip to content

Instantly share code, notes, and snippets.

@leejoramo-d51
Created June 18, 2020 16:40
Show Gist options
  • Save leejoramo-d51/750599b733d3f1ab8459798ecbef68c1 to your computer and use it in GitHub Desktop.
Save leejoramo-d51/750599b733d3f1ab8459798ecbef68c1 to your computer and use it in GitHub Desktop.
<html><head>
<!--
PDSA project
demo of how to build a circle status widget using SVG/JS/CSS
-->
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<style>
svg {
height: 100px; // the contents will scale to fit because of viewBox
}
</style>
</head>
<body>
<svg viewBox="-1 -1 2 2" style="transform: rotate(0deg)"><path d="M 1 0 A 1 1 0 0 1 6.123233995736766e-17 1 L 0 0" fill="Coral"></path><text font-size=".25" x=".1" y="0.35">MET</text><path d="M 6.123233995736766e-17 1 A 1 1 0 0 1 -1 1.2246467991473532e-16 L 0 0" fill="CornflowerBlue"></path><text font-size=".25" x="-0.6" y="0.35">FAIL</text><path d="M -1 1.2246467991473532e-16 A 1 1 0 0 1 -1.8369701987210297e-16 -1 L 0 0" fill="rgba(100, 100, 100, .25"></path><text font-size=".25" x="-0.75" y="-0.15">PEND</text><path d="M -1.8369701987210297e-16 -1 A 1 1 0 0 1 1 -2.4492935982947064e-16 L 0 0" fill="Yellow"></path><text font-size=".25" x=".1" y="-0.15">Yes</text></svg>
<script>
const svgEl = document.querySelector('svg');
const slices = [{
percent: 0.25,
color: 'Coral',
text: 'MET',
x: '.1',
y: '0.35'
},
{
percent: 0.25,
color: 'CornflowerBlue',
text: 'FAIL',
x: '-0.6',
y: '0.35'
},
{
percent: 0.25,
color: 'rgba(100, 100, 100, .25',
text: 'PEND',
x: '-0.75',
y: '-0.15'
},
{
percent: 0.25,
color: 'Yellow',
text: 'Yes',
x: '.1',
y: '-0.15'
}
];
let cumulativePercent = 0;
function getCoordinatesForPercent(percent) {
const x = Math.cos(2 * Math.PI * percent);
const y = Math.sin(2 * Math.PI * percent);
return [x, y];
}
slices.forEach(slice => {
// destructuring assignment sets the two variables at once
const [startX, startY] = getCoordinatesForPercent(cumulativePercent);
// each slice starts where the last slice ended, so keep a cumulative percent
cumulativePercent += slice.percent;
const [endX, endY] = getCoordinatesForPercent(cumulativePercent);
// if the slice is more than 50%, take the large arc (the long way around)
const largeArcFlag = slice.percent > .5 ? 1 : 0;
// create an array and join it just for code readability
const pathData = [
`M ${startX} ${startY}`, // Move
`A 1 1 0 ${largeArcFlag} 1 ${endX} ${endY}`, // Arc
`L 0 0`, // Line
].join(' ');
// create a <path> and append it to the <svg> element
const pathEl = document.createElementNS('http://www.w3.org/2000/svg', 'path');
pathEl.setAttribute('d', pathData);
pathEl.setAttribute('fill', slice.color);
const textEl = document.createElementNS('http://www.w3.org/2000/svg', 'text');
const t = document.createElementNS("http://www.w3.org/2000/svg", "text");
t.textContent = slice.text;
t.setAttribute("font-size", ".25");
t.setAttribute("x", slice.x);
t.setAttribute("y", slice.y);
svgEl.appendChild(pathEl);
svgEl.appendChild(t)
});
</script>
</body></html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment