<template>
  <!-- 树形图谱 -->
  <el-tabs v-model="activeName" @tab-click="handleTabClick">
    <el-tab-pane label="树形图谱" name="first">
      <div id="container"></div>
    </el-tab-pane>
    <el-tab-pane label="统计信息" name="second">

    </el-tab-pane>
  </el-tabs>
</template>

<script>
import G6 from '@antv/g6';
import request from "@/utils/request";
import {tripletToTree} from "@/utils/common";

let data;
var vm;
var graph;
export default {
  data() {
    return {
      activeName: 'first'
    }
  },
  created() {
    vm = this;
  },
  mounted() {

  },
  methods: {
    queryTreeData(ontologyId) {
      if (graph) {
        return;
      }
      request({
        url: `/nebula_model/findtreebyontologyid/${ontologyId}`,
        method: 'post',
        data: {}
      }).then(res => {
        data = {
          id: "root",
          properties: {tagName: '根节点'},
          children: tripletToTree({
            nodes: res.data.nodes,
            relations: res.data.relations,
            idName: 'vid',
            sourceName: 'srcId',
            targetName: 'dstId'
          })
        };
        vm.initTree();
      });

    },
    destroyTree() {
      if (graph) {
        graph = null;
        document.getElementById('container').innerHTML = "";
      }
    },
    initTree() { // 初始化数据
      const container = document.getElementById('container');
      const width = container.scrollWidth;
      const height = (container.scrollHeight || 800) - 20;
      graph = new G6.TreeGraph({
        container: 'container',
        width,
        height,
        modes: {
          default: [
            'drag-canvas',
            'zoom-canvas',
            {
              type: 'drag-node',
              enableDelegate: true,
            },
          ],
        },
        defaultNode: {
          size: 25,
          anchorPoints: [
            [0, 0.5],
            [1, 0.5],
          ],
          style: {

            fill: '#68BDF6',
            stroke: '#4b4b4b',
          },
        },
        defaultEdge: {
          type: 'cubic-horizontal',
          style: {
            stroke: '#A3B1BF',
          },
        },
        nodeStateStyles: {
          closest: {
            fill: '#004f80',
          },
        },
        layout: {
          type: 'compactBox',
          direction: 'LR',
          getId: function getId(d) {
            return d.id;
          },
          getHeight: function getHeight() {
            return 16;
          },
          getWidth: function getWidth() {
            return 16;
          },
          getVGap: function getVGap() {
            return 10;
          },
          getHGap: function getHGap() {
            return 100;
          },
        },
      });

      graph.node(function (node) {
        node.tagName = (node.properties && node.properties.tagName) ? node.properties.tagName : '未命名';
        return {
          label: node.tagName,
          labelCfg: {
            offset: 10,
            position: node.children && node.children.length > 0 ? 'left' : 'right',
          },
        };
      });

      graph.data(data);
      graph.render();
      graph.fitView();

      let minDisNode;
      graph.on('node:dragstart', (e) => {
        minDisNode = undefined;
      });
      graph.on('node:drag', (e) => {
        minDisNode = undefined;
        const item = e.item;
        const model = item.getModel();
        const nodes = graph.getNodes();
        let minDis = Infinity;
        nodes.forEach((inode) => {
          graph.setItemState(inode, 'closest', false);
          const node = inode.getModel();
          if (node.id === model.id) return;
          const dis = (node.x - e.x) * (node.x - e.x) + (node.y - e.y) * (node.y - e.y);
          if (dis < minDis) {
            minDis = dis;
            minDisNode = inode;
          }
        });
        // console.log('minDis', minDis, minDisNode);
        if (minDis < 2000) graph.setItemState(minDisNode, 'closest', true);
        else minDisNode = undefined;
      });

      graph.on('node:dragend', (e) => {
        if (!minDisNode) {
          // descriptionDiv.innerHTML = '失败,拖动的节点附近没有节点';
          return;
        }
        const item = e.item;
        const id = item.getID();
        const data = graph.findDataById(id);
        // if the minDisNode is a descent of the dragged node, return
        let isDescent = false;
        const minDisNodeId = minDisNode.getID();
        console.log('dragend', minDisNodeId, isDescent, data, id);

        G6.Util.traverseTree(data, (d) => {
          if (d.id === minDisNodeId) isDescent = true;
        });
        if (isDescent) {
          vm.$message.error("目标节点是被拖动节点的后代");
          return;
        }
        graph.removeChild(id);

        setTimeout(() => {
          const newParentData = graph.findDataById(minDisNodeId);
          let newChildren = newParentData.children;
          if (newChildren) newChildren.push(data);
          else newChildren = [data];
          graph.updateChildren(newChildren, minDisNodeId);
          vm.$message.success("操作成功");
        }, 600);
      });

      if (typeof window !== 'undefined')
        window.onresize = () => {
          if (!graph || graph.get('destroyed')) return;
          if (!container || !container.scrollWidth || !container.scrollHeight) return;
          graph.changeSize(container.scrollWidth, container.scrollHeight - 20);
        };
    },
    destroyTreeGraph() {

    },
    handleTabClick(tab, event) {
      console.log(tab, event);
    },
    submitUpdate() { // 更新
      vm.$parent.submitUpdateEdge(vm.modifyCmd);
    },
  }
}

</script>

<style>

.node-box {
  overflow: hidden;
}

.form-title {
  font-size: 16px;
  margin: 15px 0;

}

.add-attribute-box {
  margin-top: 10px;
  color: #409EFF;
  cursor: pointer;
  text-align: right;
}

.info-content > div {
  margin-bottom: 5px;
  line-height: 20px;
}


</style>
