<template>
  <div class="node-chart-content" style="position: relative;">
    <div :id="chartContentId" />
  </div>
</template>
<script>
import G6 from '@antv/g6'
import { graphIcon } from '@/utils/staticData'
export default {
  props: {
    chartContentId: {
      type: String,
      default: ''
    },
    graphData: {
      type: Object,
      default: () => {
        return {}
      }
    }
  },
  watch: {
    // 'graphData': {
    //   handler(newValue, oldValue) {
    //     console.log('G66666666------watch')
    //     if (newValue) {
    //       this.init(newValue)
    //     }
    //   },
    //   deep: true
    // }
  },
  mounted() {
    setTimeout(() => {
      this.init(this.graphData)
    }, 1000)
  },
  methods: {
    init(data) {
      /**
     * by Shiwu
     */
      if (data) {
        data.edges && data.edges.length > 0 && data.edges.forEach(edge => {
          edge.label = `${'调用：' + edge.attrs.request_total + '次' + '平均延迟：' + Number(edge.attrs.duration_average).toFixed(2) + '毫秒' + '\n错误率：' + (edge.attrs.error_rate * 100).toFixed(2) + '%'}`
        })

        const colors = {
          'err': 'rgb(234, 70, 61)',
          'ok': 'rgb(0, 181, 79)'
        }
        if (data && data.combos && data.combos.length === 1) {
          delete data.combos
        }
        data.nodes && data.nodes.length > 0 && data.nodes.forEach(node => {
          node.donutColorMap = colors
          node.size = 0
          node.label = node.name
          node.iconType = node.type
          node.donutAttrs = node.attrs// donutAttrs
          node.comboId = node.combo_id
          Object.keys(node.donutAttrs).forEach(key => {
            node.size += Number(node.donutAttrs[key])
          })
          node.size = Math.sqrt(node.size) * 60
          delete node.type
        })

        const legendData = {
          nodes: [
            // {
            //   id: 'err',
            //   label: '失败率',
            //   order: 0,
            //   style: {
            //     fill: 'rgb(234, 70, 61)'
            //   }
            // },
            {
              id: 'ok',
              label: '成功率',
              order: 0,
              style: {
                fill: 'rgb(0, 181, 79)'
              }
            }]
        }

        const legend = new G6.Legend({
          data: legendData,
          align: 'center',
          layout: 'horizontal', // vertical
          position: 'bottom-left',
          vertiSep: 12,
          horiSep: 24,
          offsetY: -24,
          padding: [4, 8, 4, 8],
          containerStyle: {
            fill: '#ccc',
            lineWidth: 1
          },
          title: ' ',
          titleConfig: {
            offsetY: -8
          }

        })
        this.$nextTick(() => {
          const container = document.getElementById(this.chartContentId)
          const width = container.scrollWidth
          const height = container.scrollHeight || 500
          const graph = new G6.Graph({
            container: this.chartContentId,
            width,
            height,
            fitView: true,
            fitViewPadding: data.nodes.length <= 8 ? [120] : [0],
            maxZoom: 8, // 默认值是10
            minZoom: 0.02, // 默认值是0.02
            // translate the graph to align the canvas's center, support by v3.5.1
            fitCenter: true,
            groupByTypes: false,
            plugins: [legend],
            modes: {
              default: ['drag-canvas', 'drag-node', 'zoom-canvas', 'drag-combo', 'collapse-expand-combo', 'click-select',
                {
                  type: 'tooltip', // 提示框
                  // offset:0,
                  formatText(model) {
                  // 提示框文本内容
                    return `<div  style="background-color: rgba(0,0,0, 0.65);  box-shadow: rgb(174, 174, 174) 0px 0px 10px;
                width: fit-content;
                color: #fff;
                padding: 10px;
                border-radius:4px;">
                  <div ">
                    <span >成功率：</span>
                    <span>${model.attrs.ok == '0.00000' ? 0 : model.attrs.ok == '1.00000' ? '100%' : (model.attrs.ok * 100).toFixed(2) + '%'}</span>
                  </div>
                  </div>`
                  }
                }
              ] // 启用拖拽画布和缩放画布的交互模式
            },
            layout: {
              type: 'radial',
              focusNode: 'li',
              unitRadius: 200,
              preventOverlap: true, // 防止节点重叠
              nodeSpacing: 500,
              // 防碰撞必须设置nodeSize或size,否则不生效，由于节点的size设置了40，虽然节点不碰撞了，但是节点之间的距离很近，label几乎都挤在一起，所以又重新设置了大一点的nodeSize,这样效果会好很多
              nodeSize: 60,
              strictRadial: false,
              linkDistance: data && data.nodes && data.nodes.length > 6 ? 400 : 200 // 指定边距离为150
            },
            defaultCombo: {
              type: 'rect',
              size: [200, 100], // The minimum size of the Combo
              // padding: [30, 20, 10, 20],
              style: {
                lineWidth: 1
              },
              labelCfg: {
                refY: 10,
                refX: 20,
                position: 'bottom',
                style: {
                  fontSize: 10
                }
              }
            },
            comboStateStyles: {
              dragenter: {
                lineWidth: 2,
                stroke: '#FE9797'
              }
            },
            defaultNode: {
              /* node type, the priority is lower than the type in the node data */
              type: 'donut',
              /* node size */
              size: 40,
              /* style for the keyShape */
              style: {
                lineWidth: 0 // 设置甜甜圈的宽度
              },
              labelCfg: {
                /* label's position, options: center, top, bottom, left, right */
                position: 'bottom',
                /* label's offset to the keyShape, 4 by default */
                //   offset: 12,
                /* label's style */
                style: {
                  fontSize: 10
                  // fontWeight: 500
                }
              }
            },
            defaultEdge: {
              style: {
                endArrow: true
              },
              labelCfg: { // 标签文本配置项
                autoRotate: true,
                style: {
                  // stroke: '#fff',
                  // fill: '#999',
                  fontSize: 5,
                  lineWidth: 5
                }
              }
            }
          })
          // 节点配置中使用
          graph.node((node) => {
            return {
              icon: {
                show: true,
                // 使用函数动态指定图标路径 imgObj[node.iconType] || imgObj.default
                img: graphIcon[node.iconType] || graphIcon.default
              }
            }
          })
          graph.data(data)
          graph.render()
          graph.on('node:mouseenter', (evt) => {
            const { item } = evt
            graph.setItemState(item, 'active', true)
          })

          graph.on('node:mouseleave', (evt) => {
            const { item } = evt
            graph.setItemState(item, 'active', false)
          })
          graph.on('node:click', (evt) => {
            const { item } = evt
            const node = item._cfg.model
            // graph.setItemState(item, 'selected', true);
          })
          graph.on('combo:dragend', (e) => {
            graph.getCombos().forEach((combo) => {
              graph.setItemState(combo, 'dragenter', false)
            })
          })

          graph.on('node:dragend', (e) => {
            graph.getCombos().forEach((combo) => {
              graph.setItemState(combo, 'dragenter', false)
            })
          })

          graph.on('combo:dragenter', (e) => {
            graph.setItemState(e.item, 'dragenter', true)
          })
          graph.on('combo:dragleave', (e) => {
            graph.setItemState(e.item, 'dragenter', false)
          })

          graph.on('combo:mouseenter', (evt) => {
            const { item } = evt
            graph.setItemState(item, 'active', true)
          })

          graph.on('combo:mouseleave', (evt) => {
            const { item } = evt
            graph.setItemState(item, 'active', false)
          })
        })
      }
    }
  }

}
</script>
<style lang="scss" scoped>
.node-chart-content{
  width:100%;
  height: 100%;
}
</style>
