<template>
  <div
    class="relative"
    :style="{width: width + 'px', height: width + 'px'}"
  >
    <svg viewBox="0 0 100 100">
      <path
        stroke="#D3DFE6"
        stroke-linecap="round"
        :d="trackPath"
        :stroke-width="relativeStrokeWidth"
        fill="none"
        :style="trailPathStyle"
      />
      <path
        :stroke="color"
        stroke-linecap="round"
        :d="trackPath"
        :stroke-width="relativeStrokeWidth"
        fill="none"
        :style="circlePathStyle"
      />
    </svg>
    <div class="absolute top-0 left-0 w-full h-full flex items-center justify-center">
      <slot name="content">
        <div class="text-lg">
          {{ percentage + '%' }}
        </div>
      </slot>
    </div>
  </div>
</template>
<script lang="ts">
import Vue from 'vue'

  interface PathStyleObj {
    strokeDasharray: string,
    strokeDashoffset: string,
    [key: string]: string
  }

export default Vue.extend({
  name: 'Dashboard',
  props: {
    strokeWidth: {
      type: Number,
      default: 6
    },
    width: {
      type: Number,
      default: 100
    },
    percentage: {
      type: Number,
      validator: (val: number) => val >= 0 && val <= 100
    },
    color: {
      type: String,
      default: '#32B2F7'
    }
  },
  data() {
    return {
      rate: 0.8
    }
  },
  computed: {
    trackPath(): string {
      const radius = this.radius
      return `
          M 50 50
          m 0 ${radius}
          a ${radius} ${radius} 0 1 1 0 -${radius * 2}
          a ${radius} ${radius} 0 1 1 0 ${radius * 2}
        `
    },
    // 路径相对宽度
    relativeStrokeWidth(): string {
      const x = this.strokeWidth / this.width * 100
      return x.toFixed(1)
    },
    // 半径
    radius(): number {
      return parseInt(String(50 - parseFloat(this.relativeStrokeWidth) / 2), 10)
    },
    // 路径偏移
    strokeDashoffset(): string {
      const offset = -1 * this.perimeter * (1 - this.rate) / 2
      return `${offset}px`
    },
    // 背景路径样式
    trailPathStyle(): PathStyleObj {
      return {
        strokeDasharray: `${this.perimeter * this.rate}px, ${this.perimeter}px`,
        strokeDashoffset: this.strokeDashoffset
      }
    },
    // 填充路径样式
    circlePathStyle(): PathStyleObj {
      return {
        strokeDasharray: `${this.perimeter * this.rate * this.percentage / 100}px, ${this.perimeter}px`,
        strokeDashoffset: this.strokeDashoffset,
        transition: 'stroke-dasharray 0.6s ease 0s, stroke 0.6s ease'
      }
    },
    // 周长
    perimeter(): number {
      return 2 * Math.PI * this.radius
    }
  }
})
</script>
