<template>
  <svg :width="width" :height="height">
    <g :transform="`translate(${width / 2}, ${height / 2})`">
      <text
        v-for="word in words"
        :key="word.text"
        :style="{
          fontSize: word.size + 'px',
          fontFamily: word.font,
        }"
        :transform="`translate(${word.x}, ${word.y})rotate(${word.rotate})`"
        text-anchor="middle"
        @click="highlightText(word.text)"
      >
        {{ word.text }}
      </text>
    </g>
  </svg>
</template>

<script lang="ts">
import cloud from "d3-cloud";
import * as skills from "@/data/skills";
import { defineComponent } from "vue";

export default defineComponent({
  props: {
    width: Number,
    height: Number,
  },
  data() {
    return {
      loading: false,
      words: [] as cloud.Word[],
      minFontSize: 8,
      maxFontSize: 40,
    };
  },
  created() {
    this.computeWords();
  },
  methods: {
    highlightText(text: string) {
      console.log(text);
    },
    computeWords() {
      this.loading = true;
      const words = Object.keys(skills)
        .map((p) => skills[p])
        .map((s) => ({ text: s.name, size: s.score }));

      const min = words
        .map((s) => s.size)
        .reduce((prev, current) => Math.min(prev, current));
      const max = words
        .map((s) => s.size)
        .reduce((prev, current) => Math.max(prev, current));
      const scaleFontSize = (size: number) => {
        const number =
          ((size - min) / (max - min)) * (this.maxFontSize - this.minFontSize) +
          this.minFontSize;
        return number;
      };
      const randomRotate = (s: number) => {
        const range = 120 * (1 - ((s - min) / (max - min)) * 0.7);
        return Math.random() * range - range / 2;
      };
      cloud<{ size: number } & cloud.Word>()
        .size([this.width!, this.height!])
        .words(words)
        .padding(1)
        .rotate((w) => randomRotate(w.size))
        .spiral("archimedean")
        .fontSize((d) => scaleFontSize(d.size))
        .on("end", (d: cloud.Word[]) => {
          console.log(
            `d: ${d.length} - w: ${words.length} - f: ${this.maxFontSize}`
          );
          if (d.length < words.length) {
            console.log("On recommence !");
            this.maxFontSize = this.maxFontSize - 2;
            this.computeWords();
          } else {
            this.words = d;
            this.loading = false;
          }
        })
        .start();
    },
  },
});
</script>
