BreakdownStatusChart

by tnhu

HTML

<svg viewBox="-1 -1 2 2">
  <defs>    
    <mask id="mask">
      <circle cx="0" cy="0" r="50%" fill="white" />
      <circle cx="0" cy="0" r="35%" fill="black" />
    </mask>
    
    <pattern id="running" height="100%" width = "100%" patternContentUnits = "objectBoundingBox">
       <image href="https://localhost:8000/img/deployments/icon-deployments-running.svg" preserveAspectRatio="none" width = "1" height = "1"/>
    </pattern>
  </defs>
  <circle class="icon" cx="0" cy="0" r=".45" fill="url('#running')"/> 
</svg>




<img src="https://i.imgur.com/0POBFcV.png" width="100px" height="100px"/>
<br/>
<img src="https://i.imgur.com/0POBFcV.png" width="100px" height="100px"/>

CSS

body {
  --color-blue: #00ade4;
  --color-blue-light: #80d6f2;
  --color-blue-dark: #0f749d;
  --color-green: #59b147;
  --color-green-light: #acd8a3;
  --color-yellow: #fdb813;
  --color-yellow-light: #fedc89;
  --color-red: #e64555;
  --color-red-light: #f79a92;
  --color-black: #060000;
  --color-white: #fff;
  --color-grey: #b6b8ba;
  --color-grey-dark: #77787b;
  --color-grey-dark-50: #bbbcbd;
  --color-grey: #b6b8ba;
  --color-grey-50: #dbdcdd;
  --color-grey-light: #ededee;
  --color-grey-light-50: #f8f8f8;
  
  width: 100%;
  height: 100%;
  background: var(--color-grey-light-50);
}

svg {
  height: 250px; // the contents will scale to fit because of viewBox
  width: 250px;
  display: inline-block;
  margin: 5px;
  cursor: pointer;
}

svg circle.icon {
  // background: url('https://localhost:8000/img/deployments/icon-deployments-running.svg');
//  fill: red;
}

JavaScript

const svgEl = document.querySelector('svg');
const slices = [
  { percent: 0.20, color: 'transparent' },
  { percent: 0.25, color: 'var(--color-grey)' },
  { percent: 0.10, color: 'var(--color-red)' },
  { percent: 0.15, color: 'var(--color-blue)' },
  { percent: 0.30, color: 'var(--color-green)' },
];
let cumulativePercent = 0.30/2;

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);
  pathEl.setAttribute('mask', 'url(#mask)')
  pathEl.setAttribute('title', 'lineone &#xA; linetwo &#xA; etc...')
  svgEl.append(pathEl);
});