<template>
  <svg class="chart-pie" ref="chart" id="chart-pie" viewBox="-1 -1 2 2"></svg>
</template>

<script lang="ts">
// https://codepen.io/soluhmin/pen/jexywg
import { Component, Prop, Vue, Watch } from 'vue-property-decorator'
import ISlice from '@/models/ISlice'

@Component
export default class ChartPie extends Vue {
  @Prop({ type: Array, default: () => [] })
  public slices!: ISlice[]
  public svgEl: Element | null = null

  public mounted(): void {
    this.svgEl = this.$refs.chart as Element
    this.constructChart()
  }

  public getCoordinatesForPercent(percent: number): number[] {
    const x = Math.cos(2 * Math.PI * percent)
    const y = Math.sin(2 * Math.PI * percent)
    return [x, y]
  }

  public clearSvg(): void {
    if (!this.svgEl) {
      return
    }
    const svgEl = this.svgEl
    while (svgEl.lastChild) {
      svgEl.removeChild(svgEl.lastChild)
    }
  }

  public constructChart(): void {
    if (!this.svgEl) {
      return
    }
    const svgEl = this.svgEl
    this.clearSvg()
    let cumulativePercent = 0

    this.slices.forEach((slice: ISlice) => {
      const [startX, startY] = this.getCoordinatesForPercent(cumulativePercent)
      cumulativePercent += slice.percent
      const [endX, endY] = this.getCoordinatesForPercent(cumulativePercent)

      /*
       * if the slice is more than 50%,
       * take the large arc (the long way around)
       */
      const largeArcFlag = slice.percent > 0.5 ? 1 : 0

      const pathData = [
        `M ${startX} ${startY}`, // Move
        `A 1 1 0 ${largeArcFlag} 1 ${endX} ${endY}`, // Arc
        `L 0 0` // Line
      ].join(' ')

      const pathEl = document.createElementNS(
        'http://www.w3.org/2000/svg',
        'path'
      )
      pathEl.setAttribute('d', pathData)
      pathEl.setAttribute('fill', slice.color)
      svgEl.appendChild(pathEl)
    })
  }

  @Watch('slices')
  public onSliceChange(): void {
    this.constructChart()
  }
}
</script>

<style scoped>
.chart-pie {
  transform: rotate(-90deg);
  /* height: 200px; */
  max-width: 400pt;
}
</style>
