<template>
  <div class="topo_inner">
    <div id="container" ref="conCav" class="canvas"></div>
    <div class="legend">
      <div class="legend_title">拓扑图图例</div>
      <div class="legend_inner">
        <div class="legend_in_tit">服务类型</div>
        <div id="nodes" ref="legendNodes" class="legend_nodes"></div>
        <div class="legend_in_tit">调用状态</div>
        <div id="edges" ref="legendEdges" class="legend_edges"></div>
      </div>
    </div>
  </div>
</template>

<script>
import G6 from "@antv/g6";
export default {
  props: {
    datas: {
      type: Object,
      default: () => {
        return {
          nodes: [],
          edges: [],
        };
      },
    },
    namespace: String,
  },
  data: () => {
    return {
      graph: null,
      legendNodes: null,
      legendEdges: null,
    };
  },
  mounted() {},
  watch: {
    datas(val) {
      this.getCavData();
      this.getLegendNodes();
      this.getLegendEdges();
    },
  },
  methods: {
    //   shu ju chu li
    getCavData() {
      let self = this;
      self.datas.nodes.map((node) => {
        node.id = node.data.id;
        switch (node.data.svcType) {
          case "基础支撑服务":
            node.type = "image";
            node.img = require("@/assets/svg/topology_ic_shujufw.svg");
            node.size = [15, 15];
            break;
          case "基础地图服务":
            node.type = "image";
            node.img = require("@/assets/svg/topology_ic_shikongfw.svg");
            node.size = [15, 15];
            break;
          case "视频图像服务":
            node.type = "image";
            node.img = require("@/assets/svg/topology_ic_shipinfw.svg");
            node.size = [15, 15];
            break;
          case "感知服务":
            node.type = "image";
            node.img = require("@/assets/svg/topology_ic_ganzhifw.svg");
            node.size = [15, 15];
            break;
          case "执法办案服务":
            node.type = "image";
            node.img = require("@/assets/svg/topology_ic_zonghefw.svg");
            node.size = [15, 15];
            break;
          default:
            node.type = "image";
            node.img = require("@/assets/svg/topology_ic_shujufw.svg");
            node.size = [15, 15];
            break;
        }
        node.label = node.data.svcAlias;
        // if (node.data.namespace != self.namespace) {
        //   node.label =
        //     node.data[node.data.nodeType] + "\n(" + node.data.namespace + ")";
        // } else {
        //   node.label = node.data[node.data.nodeType];
        // }
        node.labelCfg = {
          style: {
            fill: "#333",
            fontSize: 12,
            stroke: "#fffef9",
            lineWidth: 4,
            cursor: "pointer",
          },
          position: "bottom",
        };
      });
      self.datas.edges.map((edge) => {
        edge.id = edge.data.id;
        edge.source = edge.data.source;
        edge.target = edge.data.target;
        edge.label = edge.data.traffic.rates
          ? edge.data.traffic.rates.tcp
            ? edge.data.traffic.rates.tcp
            : edge.data.traffic.rates.http
          : "";
        edge.style = {
          stroke: "#494e8f",
          lineWidth: 1,
          lineAppendWidth: 5,
          endArrow: {
            path: "M -3,0 L 4,2 L 4,-2 Z", // 自定义箭头路径
            d: -2, // 偏移量
          },
          strokeOpacity: 1,
          cursor: "pointer",
        };
        if (edge.data.traffic.protocol == "tcp") {
          // tcp
          edge.type = "1";
          edge.style.stroke = "#c77eb5";
        } else if (edge.data.traffic.protocol == "http") {
          if (edge.data.traffic.responses) {
            let sta = 0;
            for (let i in edge.data.traffic.responses) {
              if (
                i.substring(i.length - 3, i.length - 2) == 5 ||
                i.substring(i.length - 3, i.length - 2) == 4
              ) {
                sta += edge.data.traffic.responses[i][0];
              } else {
                sta += 0;
              }
              if (sta > 20) {
                edge.style.stroke = "#d93a49";
                edge.type = "3";
              } else if (sta == 0) {
                edge.style.stroke = "#1d953f";
                edge.type = "2";
              } else {
                edge.style.stroke = "#f36c21";
                edge.type = "2";
              }
            }
          } else {
            edge.style.stroke = "#a1a3a6";
            edge.type = "0";
          }
        } else {
          edge.style.stroke = "#1d953f";
          edge.type = "2";
        }
      });
      self.getCav();
    },
    getCav() {
      if (this.graph) this.graph.destroy();
      const width = this.$refs.conCav.scrollWidth;
      const height = this.$refs.conCav.scrollHeight || 500;
      let self = this;
      // console.log(self.datas);
      this.graph = new G6.Graph({
        container: "container",
        width,
        height,
        fitView: false,
        fitCenter: true,
        layout: {
          // 流程图布局
          type: "dagre",
          rankdir: "LR",
          nodesep: 12,
        },
        modes: {
          default: ["zoom-canvas", "drag-canvas", "drag-node"],
        },
        defaultNode: {
          color: "#5B8FF9",
          style: {
            lineWidth: 2,
            fill: "#C6E5FF",
            cursor: "pointer",
          },
          labelCfg: {
            style: {
              fill: "#f36c21",
              fontSize: 10,
            },
            position: "bottom",
          },
        },
        defaultEdge: {
          style: {
            stroke: "#e2e2e2",
            lineWidth: 1,
            lineAppendWidth: 6,
            opacity: 1,
          },
          labelCfg: {
            style: {
              fontSize: 10,
              stroke: "#fffef9",
              fill: "#595959",
              lineWidth: 4,
            },
          },
        },
        nodeStateStyles: {
          highlight: {
            opacity: 1,
          },
          dark: {
            opacity: 0.2,
          },
        },
        edgeStateStyles: {
          highlight: {
            opacity: 1,
          },
          dark: {
            opacity: 0.2,
          },
          click: {
            lineWidth: 3,
          },
        },
        plugins: [],
      });
      // 节点点击
      this.graph.on("node:click", function (e) {});
      // 路径点击
      this.graph.on("edge:click", function (e) {});
      this.graph.on("node:dblclick", function (e) {});
      // 点击画布
      this.graph.on("canvas:click", function (e) {});
      this.graph.data(self.datas);
      this.graph.render();
    },
    getLegendNodes() {
      if (this.legendNodes) this.legendNodes.destroy();
      // legend. maybe you want use parames to reset it, but i did not do the extension
      const width = this.$refs.legendNodes.scrollWidth;
      const height = this.$refs.legendNodes.scrollHeight;
      this.legendNodes = new G6.Graph({
        container: "nodes",
        width: width,
        height: height,
        defaultNode: {
          style: {
            fill: "transparent", // 节点填充色
            stroke: "transparent", // 节点描边色
            lineWidth: 1, // 节点描边粗细
          },
          labelCfg: {
            position: "right",
            offset: 10,
            style: {
              fill: "#333",
            },
          },
        },
      });
      const legendX = 20;
      const legendBeginY = 20;
      const legendYPadding = 25;
      const legendData = {
        nodes: [
          //   specific legend
          {
            id: "level1",
            x: legendX,
            y: legendBeginY,
            type: "image",
            img: require("@/assets/svg/topology_ic_shujufw.svg"),
            size: [15, 15],
            label: "基础支撑服务",
          },
          {
            id: "level2",
            x: legendX,
            y: legendBeginY + legendYPadding * 1,
            type: "image",
            img: require("@/assets/svg/topology_ic_shikongfw.svg"),
            size: [15, 15],
            label: "基础地图服务",
          },
          {
            id: "level3",
            x: legendX,
            y: legendBeginY + legendYPadding * 2,
            type: "image",
            img: require("@/assets/svg/topology_ic_shipinfw.svg"),
            size: [15, 15],
            label: "视频图像服务",
          },
          {
            id: "level4",
            x: legendX,
            y: legendBeginY + legendYPadding * 3,
            type: "image",
            img: require("@/assets/svg/topology_ic_ganzhifw.svg"),
            size: [15, 15],
            label: "感知服务",
          },
          {
            id: "level5",
            x: legendX,
            y: legendBeginY + legendYPadding * 4,
            type: "image",
            img: require("@/assets/svg/topology_ic_zonghefw.svg"),
            size: [15, 15],
            label: "执法办案服务",
          },
        ],
      };
      this.legendNodes.data(legendData);
      this.legendNodes.render();
    },
    getLegendEdges() {
      if (this.legendEdges) this.legendEdges.destroy();
      // legend. maybe you want use parames to reset it, but i did not do the extension
      const width = this.$refs.legendEdges.scrollWidth;
      const height = this.$refs.legendEdges.scrollHeight;
      this.legendEdges = new G6.Graph({
        container: "edges",
        width: width,
        height: height,
        defaultNode: {
          style: {
            fill: "transparent", // 节点填充色
            stroke: "transparent", // 节点描边色
            lineWidth: 1, // 节点描边粗细
          },
          labelCfg: {
            position: "right",
            offset: 10,
            style: {
              fill: "#333",
            },
          },
        },
      });
      const legendX = 10;
      const legendBeginY = 20;
      const legendYPadding = 25;
      const legendData = {
        nodes: [
          //   line1 point 0
          {
            id: "line00",
            x: legendX,
            y: legendBeginY,
            type: "circle",
            size: 1,
          },
          //   line1 point 1
          {
            id: "line01",
            x: legendX + 30,
            y: legendBeginY,
            label: "正常",
            type: "circle",
            size: 1,
          },
          //   line2 point 0
          {
            id: "line10",
            x: legendX,
            y: legendBeginY + legendYPadding,
            type: "circle",
            size: 1,
          },
          //   line2 point 1
          {
            id: "line11",
            x: legendX + 30,
            y: legendBeginY + legendYPadding,
            label: "错误",
            type: "circle",
            size: 1,
          },
        ],
        edges: [
          {
            id: "line0",
            source: "line00",
            target: "line01",
            style: {
              stroke: "#25bdb1",
              lineWidth: 2,
              lineAppendWidth: 5,
              endArrow: {
                path: "M -3,0 L 4,2 L 4,-2 Z", // 自定义箭头路径
                d: -2, // 偏移量
              },
              cursor: "pointer",
            },
          },
          {
            id: "line1",
            source: "line10",
            target: "line11",
            style: {
              stroke: "#e15260",
              lineWidth: 2,
              lineAppendWidth: 5,
              endArrow: {
                path: "M -3,0 L 4,2 L 4,-2 Z", // 自定义箭头路径
                d: -2, // 偏移量
              },
              cursor: "pointer",
            },
          },
        ],
      };
      this.legendEdges.data(legendData);
      this.legendEdges.render();
    },
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.canvas {
  height: 100%;
  width: 100%;
  margin: 0 auto;
  position: relative;
}
.topo_inner {
  position: relative;
}
.legend {
  position: absolute;
  width: 140px;
  height: 90%;
  top: 20px;
  right: 20px;
}
.legend_title {
  color: #3f4f9c;
  font-size: 14px;
  font-weight: 700;
  margin: 10px;
}
.legend_inner {
  border: 2px #e5f0ff solid;
  border-radius: 8px;
  padding: 10px;
  background-color: #fff;
}
.legend_in_tit {
  color: #8890a7;
  font-size: 14px;
  line-height: 26px;
  padding: 0 10px;
  border-bottom: 2px #e5f0ff solid;
}
.legend_nodes {
  width: 100%;
  height: 150px;
}
.legend_edges {
  width: 100%;
  height: 60px;
}
</style>

