<template>
  <div class="relation-chart" ref="ref_main">
    <div class="chart" id="container"/>
  </div>
</template>

<script setup lang="ts">
import {getCurrentInstance, onMounted, reactive, ref, watch} from "vue";
import {Graph} from "@antv/g6";

const emit = defineEmits(['chartPage'])
const {proxy} = getCurrentInstance()
const props = defineProps({
  data: {}
})
const state: any = reactive({
  resizeObserver: <any>null,
})
const ref_main = ref()
const setNodes = (data) => {
  data.nodes.forEach(v => {
    v.style = {
      badge: true,
      badges:[{text: String(v.num), placement: 'top-right', offsetX: -10, offsetY: 10}],
      // icon: false,
      iconSrc: 'https://gw.alipayobjects.com/zos/basement_prod/012bcf4f-423b-4922-8c24-32a89f8c41ce.svg',
    }
  })
}
const setEdges = (data) => {
  data.edges.forEach(v => {
    v.style = {
      labelText: '关系描述'
    }
  })
}
const initChart = () => {
  if (props.data?.nodes?.length > 0) {
    const data = JSON.parse(JSON.stringify(props.data))
    setNodes(data)
    setEdges(data)
    const mainColor = getComputedStyle(document.documentElement).getPropertyValue('--cus-main-color')
    const mainColorHex2 = getComputedStyle(document.documentElement).getPropertyValue('--cus-main-color-hex-2')
    const graph = new Graph({
      container: 'container',
      data,
      // autoResize: true,
      autoFit: 'view',
      behaviors: ['drag-canvas', 'drag-element', 'zoom-canvas', {
        type: 'click-select',
        degree: 1,
        enable: (event) => event.targetType === "node",
      }],
      layout: {
        type: 'radial',
        focusNode: '3',
        linkDistance: 200,
        preventOverlap: true,
        unitRadius: 200,
        maxPreventOverlapIteration: 100,
        strictRadial: false
      },
      node: {
        style: {
          // circle
          size: (v) => v.weight,
          fill: 'transparent',
          lineWidth: 2,
          stroke: mainColor,
          // label
          label: true,
          labelPlacement: 'bottom',
          labelText: (v) => v.name,
          labelFill: '#ffffff',
          labelPadding: [4, 10],
          labelBackground: true,
          labelBackgroundFill: mainColor,
          labelBackgroundRadius: 2,
          labelFontSize: 14,
          labelOffsetY: 6,
          // badge
          badgeFontSize: 12,
          badgePadding: [2, 4, 0, 4],
          badgeBackgroundFill: mainColor,
          halo: false,
          haloLineDash: 0,
          haloLineWidth: 12,
          haloStrokeOpacity: 0.25,
        },
        state: {
          selected: {
            lineWidth: 4,
            stroke: mainColor,
            labelFontSize: 14,
            labelFontWeight: 'normal',
          }
        }
      },
      edge: {
        style: {
          endArrow: true,
          endArrowType: 'triangle',
          endArrowSize: 8,
          stroke: mainColor,
          labelAutoRotate: false,
          labelFill: '#ffffff',
          labelPadding: [2, 4, 0, 4],
          labelBackground: true,
          labelBackgroundFill: mainColor,
          labelBackgroundRadius: 20,
          labelFontSize: 12,
          halo: true,
          haloLineDash: 4,
          haloLineWidth: 2,
        },
        state: {
          selected: {
            labelFontSize: 12,
            labelFontWeight: 'normal'
          }
        }
      },
    } as any);
    graph.render();
    graph.on('node:click', (e) => {
      emit('chartPage', e.target.id)
    })
    state.resizeObserver = new ResizeObserver((entries) => {
      for (const entry of entries) {
        graph && graph?.resize()
      }
    })
    state.resizeObserver.observe(ref_main.value);
  }
}
watch(() => props.data, () => {
  initChart()
})
onMounted(() => {
  return () => {
    state.resizeObserver?.unobserve(ref_main?.value)
    state.resizeObserver?.disconnect()
  }
})
</script>

<style lang="scss" scoped>
.relation-chart {
  width: 100%;
  height: 100%;
  background-color: rgba(var(--cus-main-color-rgb), 0.1);
  .chart {
    width: 100%;
    height: 100%;
  }
}
</style>
