PieMeister Dev.to Article #1

Pie Chart WebComponent with SVG circles,

by WebComponents

HTML

<pie-chart>
  <slice size="90" stroke="green">HTML</slice>
  <slice size="1" stroke="red">JavaScript</slice>
  <slice size="9" stroke="blue">CSS</slice>
</pie-chart>

CSS

svg {
    margin: 0 70px;
  }

JavaScript

/* A BaseClass for any Web Component that does SVG thingy things */
class SVGMeisterElement extends HTMLElement {
  // ########################################################## createCircle()
  createSVGCircle(
    // one args parameter Object for all parameters
    {
      ...args
    }
  ) {
    // calc circle size
    const circleSize = this.pieSize / 2;
    const pathLength = 100;
    const slice = this.createSVGElement({
      tag: "circle",
      attributes: {
        "pathLength": pathLength, // 100 for a 100% Pie
        "size": args.size || pathLength,
        "stroke-dasharray": args.dashArray || args.size + " " + (pathLength - args.size),
        "stroke-dashoffset": args.offset || 0,
        "stroke-width": args.strokeWidth || circleSize,
        "stroke": args.stroke || "black",
        "fill": args.fill || "none",
        // center point can be declared in multiple notations:
        "cx": args.cx || (args.point && args.point.x) || this.width / 2,
        "cy": args.cy || (args.point && args.point.y) || this.height / 2,
        "r": args.r || circleSize / 2,
      }
    });

    // -------------------------------------------------- slice.getPointAt()
    // function on EACH slice so config parameters are re-used
    // default getPointAt( .5 , config.size/2 ) is the SLICE middle point
    slice.getPointAt = (
      distance = .5, // 0=CIRCLE center , .5=middle , 1=circle outer edge
      offset = slice.size / 2, // 0=start slice , size/2=middle slice , size=end slice
    ) => {
      // need to create a temporary DOM element 
      // so the default .getPointAtLength and .getTotalLength functions can be used
      const tempPt = this.svg.appendChild(
        this.createSVGCircle({
          //...config, // use same circle settings
          ...slice.attributes,
          // but a diffent radius
          r: circleSize * distance,
        })
      );
      // calculate startoffset relative to the start of the slice
      let len = offset -...