<template>
  <el-container>
    <div class="p_container">
      <!-- 左 -->
      <div class="grid-content1">
        <div class="left_top">
          <div class="title">统一门户</div>
          <div class="small_title">
            <img
              src="../../../../../assets/img/unified-resources/小标题.png"
              alt
            />
            <span>热点应用</span>
            <div>
              <span v-for="item in hotUse" :key="item" class="num_bg">{{
                item
              }}</span>
            </div>
          </div>
          <div class="use_content">
            <div class="use_count">
              <div class="use_count_item">
                <img
                  src="../../../../../assets/img/unified-resources/非信创应用.png"
                  alt
                />
                <div>
                  <div class="use_count_item_title">非信创应用</div>
                  <div class="use_count_item_num">20</div>
                </div>
              </div>
              <div class="use_count_item">
                <img
                  src="../../../../../assets/img/unified-resources/信创应用.png"
                  alt
                />
                <div>
                  <div class="use_count_item_title">信创应用</div>
                  <div class="use_count_item_num">15</div>
                </div>
              </div>
            </div>
            <div class="use_chart" ref="hot_chart">
              <!-- <div  ></div> -->
            </div>
          </div>
          <div class="small_title">
            <img
              src="../../../../../assets/img/unified-resources/小标题.png"
              alt
            />
            <span>常用浏览器</span>
            <!-- <div>
                <span v-for="item in hotUse" :key="item" class="num_bg">{{ item }}</span>
            </div>-->
          </div>
          <div class="use_content">
            <div class="use_count">
              <div class="use_count_item">
                <img
                  src="../../../../../assets/img/unified-resources/浏览器.png"
                  alt
                />
                <div>
                  <div class="use_count_item_num">80%</div>
                  <div class="use_count_item_title">8:00-19:00</div>
                </div>
              </div>
              <div class="use_count_item">
                <img
                  src="../../../../../assets/img/unified-resources/浏览器.png"
                  alt
                />
                <div>
                  <div class="use_count_item_num">20%</div>
                  <div class="use_count_item_title">19:00-8:00</div>
                </div>
              </div>
            </div>
            <div class="use_chart" ref="browser_chart">
              <!-- <div  ></div> -->
            </div>
          </div>
        </div>
        <div class="left_center">
          <div class="title">统一用户</div>
          <el-table
            :data="userTableData"
            stripe
            style="width: 100%"
            max-height="120"
          >
            <el-table-column prop="date" label></el-table-column>
            <el-table-column
              prop="name"
              label="用户总数"
              width="120"
            ></el-table-column>
          </el-table>
        </div>
        <div class="left_bottom">
          <div class="title">接入</div>
          <div ref="graphChartRef" class="graph_content"></div>
        </div>
      </div>

      <!-- 右 -->
      <div class="grid-content2">
        <div class="grid-content2_top">
          <div class="title">统一接入</div>
          <div class="grid-content2_top_box1">
            <div class="grid-content2_top_item1">
              <div class="grid-content2_top_item1_title">今日API接入总量</div>
              <div class="grid-content2_top_item1_count">
                <div>接口数量</div>
                <div class="grid-content2_top_item1_num">
                  {{ this.unifiedAccessObj.api.num }}
                </div>
              </div>
              <div class="grid-content2_top_item1_count">
                <div>业务量</div>
                <div class="grid-content2_top_item1_num">
                  <span>
                    {{ this.unifiedAccessObj.api.business }}
                  </span>
                </div>
              </div>
            </div>
            <div class="grid-content2_top_item1">
              <div class="grid-content2_top_item1_title">库表接入总量</div>
              <div class="grid-content2_top_item1_count">
                <div>MIDDB</div>
                <div class="grid-content2_top_item1_num">
                  {{ this.unifiedAccessObj.kb.num }}
                </div>
              </div>
              <div class="grid-content2_top_item1_count">
                <div>JKCLOUD</div>
                <div class="grid-content2_top_item1_num">
                  <span>
                    {{ this.unifiedAccessObj.kb.business }}
                  </span>
                </div>
              </div>
            </div>
            <div class="grid-content2_top_item1">
              <div class="grid-content2_top_item1_title">Kafka topic总量</div>
              <div class="grid-content2_top_item1_count">
                <div>topic数量</div>
                <div class="grid-content2_top_item1_num">
                  {{ this.unifiedAccessObj.kafka.num }}
                </div>
              </div>
              <div class="grid-content2_top_item1_count">
                <div>入湖</div>
                <div class="grid-content2_top_item1_num">
                  <span>
                    {{ this.unifiedAccessObj.kafka.business }}
                  </span>
                </div>
              </div>
            </div>
            <div class="grid-content2_top_item1">
              <div class="grid-content2_top_item1_title">文件</div>
              <div class="grid-content2_top_item1_count">
                <div>数据源</div>
                <div class="grid-content2_top_item1_num">100</div>
              </div>
              <div class="grid-content2_top_item1_count">
                <div>数据接收</div>
                <div class="grid-content2_top_item1_num">
                  <span>100</span>
                </div>
              </div>
            </div>
          </div>
          <div class="grid-content2_top_box2">
            <div class="grid-content2_top_item2">
              <div class="grid-content2_top_item2_img">
                <img
                  src="../../../../../assets/img/unified-resources/异常.png"
                  alt
                />
                <div>
                  <div class="grid-content2_top_item2_status_title">异常</div>
                  <div class="grid-content2_top_item2_num_danger">
                    {{ this.unifiedAccessObj.four.error }}
                  </div>
                </div>
              </div>
              <div class="grid-content2_top_item2_status_danger"></div>
            </div>

            <div class="grid-content2_top_item2">
              <div class="grid-content2_top_item2_img">
                <img
                  src="../../../../../assets/img/unified-resources/最高.png"
                  alt
                />
                <div>
                  <div class="grid-content2_top_item2_status_title">最高</div>
                  <div class="grid-content2_top_item2_num_success">
                    {{ this.unifiedAccessObj.four.big }}
                    <span>ms</span>
                  </div>
                </div>
              </div>
              <div class="grid-content2_top_item2_status_success"></div>
            </div>
            <div class="grid-content2_top_item2">
              <div class="grid-content2_top_item2_img">
                <img
                  src="../../../../../assets/img/unified-resources/平均.png"
                  alt
                />
                <div>
                  <div class="grid-content2_top_item2_status_title">平均</div>
                  <div class="grid-content2_top_item2_num_primary">
                    {{ this.unifiedAccessObj.four.average }}
                  </div>
                </div>
              </div>
              <div class="grid-content2_top_item2_status_primary"></div>
            </div>
            <div class="grid-content2_top_item2">
              <div class="grid-content2_top_item2_img">
                <img
                  src="../../../../../assets/img/unified-resources/最低.png"
                  alt
                />
                <div>
                  <div class="grid-content2_top_item2_status_title">最低</div>
                  <div class="grid-content2_top_item2_num_warning">
                    {{ this.unifiedAccessObj.four.small }}
                  </div>
                </div>
              </div>
              <div class="grid-content2_top_item2_status_warning"></div>
            </div>
          </div>
        </div>
        <div class="grid-content2_bottom">
          <div class="title">统一资源</div>
          <div class="grid-content2_bottom_content">
            <!--  -->
            <div class="count_box">
              <div class="title_box">
                <div v-for="item in titleData" :key="item">
                  {{ item.title }}
                </div>
              </div>
              <div class="num_box">
                <div class="num_box_top">
                  <div>
                    <div>数据目录</div>
                    <div class="num_content">
                      <span
                        v-for="item in hotUse"
                        :key="item"
                        class="b-num_bg"
                        >{{ item }}</span
                      >
                    </div>
                  </div>
                  <div>
                    <div>职责目录</div>
                    <div class="num_content">
                      <span
                        v-for="item in hotUse"
                        :key="item"
                        class="b-num_bg"
                        >{{ item }}</span
                      >
                    </div>
                  </div>
                  <div>
                    <div>接入数</div>
                    <div class="num_content">
                      <span
                        v-for="item in hotUse"
                        :key="item"
                        class="b-num_bg"
                        >{{ item }}</span
                      >
                    </div>
                  </div>
                </div>
                <div class="num_box_bottom">
                  <div class="num_box_bottom_item">
                    <div class="num_box_bottom_item_t">
                      <div>业务数据</div>
                      <div class="num_content">
                        <span
                          v-for="item in hotUse"
                          :key="item"
                          class="b-num_bg"
                          >{{ item }}</span
                        >
                      </div>
                    </div>
                    <div class="num_box_bottom_item_b">
                      <div>
                        <div>库表</div>
                        <span>20</span>
                      </div>
                      <div>
                        <div>服务</div>
                        <span>20</span>
                      </div>
                      <div>
                        <div>实时流</div>
                        <span>20</span>
                      </div>
                      <div>
                        <div>文件</div>
                        <span>20</span>
                      </div>
                    </div>
                  </div>
                  <div class="num_box_bottom_item">
                    <div class="num_box_bottom_item_t">
                      <div>业务数据</div>
                      <div class="num_content">
                        <span
                          v-for="item in hotUse"
                          :key="item"
                          class="b-num_bg"
                          >{{ item }}</span
                        >
                      </div>
                    </div>
                    <div class="num_box_bottom_item_b">
                      <div>
                        <div>基础</div>
                        <span>5</span>
                      </div>
                      <div>
                        <div>业务专题</div>
                        <span>10</span>
                      </div>
                      <div>
                        <div>工具</div>
                        <span>5</span>
                      </div>
                    </div>
                  </div>
                </div>
                <div class="num_box_bottom"></div>
              </div>
              <div class="bar_chart" ref="bar_chart"></div>
            </div>
            <!-- 表格 -->
            <div class="table_box">
              <div class="small_title">
                <img
                  src="../../../../../assets/img/unified-resources/小标题.png"
                  alt
                />
                <span>统一接口监控状态监听</span>
              </div>
              <div class="tab_table">
                <div
                  class="tab_img"
                  :class="{ tab_active: tabActive === 1 }"
                  @click="InterfaceChange(1)"
                >
                  API状态
                </div>
                <div
                  class="tab_img"
                  :class="{ tab_active: tabActive === 2 }"
                  @click="InterfaceChange(2)"
                >
                  监控预警
                </div>
              </div>
              <el-table
                :data="unifiedInterfaceStatusData"
                stripe
                style="width: 100%"
                max-height="200"
              >
                <el-table-column type="index" width="50"></el-table-column>
                <el-table-column prop="url" label="接口"></el-table-column>
                <el-table-column prop="status" label="状态" width="80">
                  <template slot-scope="scope">
                    <el-tag type="success" v-if="+scope.row.status === 1"
                      >正常</el-tag
                    >
                    <el-tag type="danger" v-if="+scope.row.status === 0"
                      >不正常</el-tag
                    >
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </div>
        </div>
      </div>
    </div>
  </el-container>
</template>

<script>
import * as echarts from "echarts";
import {
  getLookMonitor,
  getLookMonitorByUrlAndStatus,
} from "@/api/unified-resources/link-monitor/visualMonitor.js";
// 动态改变节点的大小来模拟呼吸动画
let scaleFactor = 1;
let increasing = true;
export default {
  data() {
    return {
      tabActive: 1,
      unifiedInterfaceStatusData: [],
      unifiedAccessObj: {
        four: {
          big: 32,
          average: 16,
          small: 1,
          error: 1,
        },
        kb: {
          num: 1,
          business: 1,
          url: null,
          status: null,
        },
        kafka: {
          num: 1,
          business: 123,
          url: null,
          status: null,
        },
        api: {
          num: 2,
          business: 2,
          url: null,
          status: null,
        },
      },
      userTableData: [],
      hotUse: [3, 5],
      // 热点应用
      hotChartData: [
        { name: "OA", success: 33, fail: 1 },
        { name: "lims", success: 30, fail: 1 },
        { name: "grp", success: 22, fail: 1 },
        { name: "应急系统", success: 19, fail: 1 },
        { name: "产品管理", success: 15, fail: 1 },
      ],
      color: ["#fe8f02", "#0a7cff", "#2cb68c", "#e23636"],
      browserChartData: [
        { name: "IE", value: 11, color: "#fe8f02", color2: "#faebcb" },
        { name: "Firefox", value: 5.6, color: "#0a7cff", color2: "#d0f3fe" },
        { name: "Chrome", value: 8, color: "#2cb68c", color2: "#f6e5e8" },
        { name: "Safari", value: 9, color: "#e23636", color2: "#d3fcf3" },
      ],
      chartData: [
        { name: "A", value: 120 },
        { name: "B", value: 200 },
        { name: "C", value: 150 },
        { name: "D", value: 80 },
        { name: "E", value: 70 },
        { name: "F", value: 110 },
      ],
      userTableData: [
        {
          date: "2016-05-02",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1518 弄",
        },
        {
          date: "2016-05-04",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1517 弄",
        },
        {
          date: "2016-05-01",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1519 弄",
        },
        {
          date: "2016-05-03",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1516 弄",
        },
      ],
      titleData: [
        { title: "上链" },
        { title: "数据归集" },
        { title: "数据共享" },
        { title: "数据目录" },
      ],
      tabData: [{ title: "存储空间" }, { title: "监控预警" }],

      chart: null,
      nodes: [
        {
          id: "center",
          name: "市疫情控",
          x: 400,
          y: 300,
          symbolSize: 50,
          children: [
            { id: "node1", name: "长三角（昆山）", x: 200, y: 150 },
            { id: "node2", name: "大数据中心", x: 600, y: 150 },
            { id: "node3", name: "卫建委", x: 200, y: 450 },
            { id: "node4", name: "长三角（嘉善）", x: 600, y: 450 },
            { id: "node5", name: "各卫生医疗机构", x: 600, y: 450 },
          ],
        },
      ],
      colorPool: [
        "#ff4d4f",
        "#52c41a",
        "#1890ff",
        "#fadb14",
        "#13c2c2",
        "#722ed1",
        "#fa8c16",
      ], // 预定义的颜色池
    };
  },
  mounted() {
    this.getUnifiedAccess();
    this.getUnifiedInterfaceStatusMonitor();

    this.initHotChart();
    this.initBrowserChart();

    this.drawShape();
    this.initGraphChart();
  },
  methods: {
    //统一接入
    getUnifiedAccess() {
      getLookMonitor().then((res) => {
        if (+res.code === 200) {
          this.unifiedAccessObj = res.data;
        }
      });
    },
    // 统一接口监控状态监听
    getUnifiedInterfaceStatusMonitor() {
      getLookMonitorByUrlAndStatus().then((res) => {
        if (+res.code === 200) {
          this.unifiedInterfaceStatusData = res.data;
        }
      });
    },
    InterfaceChange(type) {
      this.tabActive = type;
    },
    initHotChart() {
      const chart = echarts.init(this.$refs.hot_chart);
      const data = this.hotChartData;

      // 计算每个项目的总和并进行归一化
      const totalData = data.map((item) => item.success + item.fail);
      const normalizedData = data.map((item, index) => ({
        name: item.name,
        success: item.success / totalData[index], // 归一化成功比例
        fail: item.fail / totalData[index], // 归一化失败比例
      }));

      const option = {
        title: {
          text: "热点应用名称", // 主标题
          left: "left", // 标题居中
          top: "0%", // 设置标题距离顶部5%的位置
          textStyle: {
            fontSize: 12, // 字体大小
            fontWeight: "500", // 字体加粗
            color: "#333", // 字体颜色
          },
        },
        graphic: [
          {
            type: "text",
            right: "3%", // 将文字定位到右上角
            top: "5%",
            style: {
              text: "登录次数 成功/失败", // 显示的文本
              font: "10px sans-serif",
              fill: "#333",
            },
          },
        ],
        tooltip: {
          trigger: "item",
          // 格式化显示原始数据量，而非归一化后的比例
          formatter: (params) => {
            const currentData = data[params.dataIndex];
            return `登录次数 ${params.name}: 成功 ${currentData.success} / 失败 ${currentData.fail}`;
          },
        },
        grid: {
          left: "5%",
          right: "20%",
          top: "15%",
          bottom: "10%",
          containLabel: true,
        },
        xAxis: {
          type: "value",
          splitLine: { show: false },
          axisLine: { show: false },
          axisTick: { show: false },
          axisLabel: { show: false },
        },
        yAxis: {
          type: "category",
          data: data.map((item) => item.name),
          axisLine: { show: false },
          axisTick: { show: false },
          axisLabel: { show: true, textStyle: { color: "#333" } },
        },
        series: [
          {
            name: "成功",
            type: "bar",
            stack: "总量",
            data: normalizedData.map((item) => item.success), // 使用归一化后的数据
            itemStyle: {
              // 使用线性渐变，调整渐变颜色
              color: (params) => {
                const isEven = params.dataIndex % 2 === 0; // 判断是否为偶数索引
                return new echarts.graphic.LinearGradient(0, 0, 1, 0, [
                  {
                    offset: 0,
                    color: isEven ? "#d2ebfb" : "#fbf0e4", // 蓝色和黄色交替
                  },
                  {
                    offset: 1,
                    color: isEven ? "#0b91e9" : "#fe8e08", // 蓝色和黄色交替
                  },
                ]);
              },
            },
            label: {
              show: false,
              //   position: 'insideRight', // 标签显示在柱体右侧
              //   formatter: '{c}', // 显示归一化后的数值
              color: "#fff", // 标签字体颜色
            },
          },
          {
            name: "失败",
            type: "bar",
            stack: "总量",
            data: normalizedData.map((item) => item.fail), // 使用归一化后的数据
            itemStyle: {
              color: "#daebff", // 蓝灰色表示失败
            },
            label: {
              show: true,
              position: "insideRight", // 标签显示在柱体右侧
              formatter: (params) => {
                const currentData = data[params.dataIndex];
                return ` ${currentData.success} / ${currentData.fail}`;
              },
              color: "#000", // 标签字体颜色
              offset: [50, 0], // 调整标签位置，向右偏移
            },
          },
        ],
      };

      chart.setOption(option);
    },
    initBrowserChart() {
      const chart = echarts.init(this.$refs.browser_chart);
      const data = this.browserChartData;

      const option = {
        tooltip: {
          trigger: "item",
          formatter: "{b}: {c} ({d}%)",
        },
        grid: {
          left: "0%",
          right: "0%",
          top: "15%",
          bottom: "10%",
          containLabel: true,
        },
        // legend: {
        //   orient: "vertical",
        //   right: 0,
        //   top: 20,
        //   bottom: 20,
        //   // data: data.map((item) => item.name),
        //   data: data.map((item) => ({
        //       value: 1000,
        //       name: item.name,
        //       itemStyle: {
        //         color: item.color,
        //       },
        //     })),
        //   textStyle: {
        //     color: "#333",
        //   },
        // },
        // series: [
        //   {
        //     name: "浏览器市场份额",
        //     type: "pie",
        //     radius: ["40%", "50%"], // 设置环形图的内外半径
        //     center: ["30%", "50%"], // 调整环形图位置，向左移动
        //     color: ["#fe8f02", "#0a7cff", "#2cb68c", "#e23636"],
        //     labelLine: {
        //       show: true, // 显示标签连线
        //     },
        //     label: {
        //       formatter: "{b}: {c}", // 格式化显示名称和数值
        //     },

        //     data: data.map((item) => ({
        //       value: item.value,
        //       name: item.name,
        //     })),
        //     // itemStyle: {
        //     //   // 设置每个部分的颜色
        //     //   color: params => {
        //     //     // const colorList = ["#FF9F00", "#FF6F61", "#3E9D45", "#E74C3C"]; // 自定义颜色列表
        //     //     const colorList = ["#fe8f02", "#0a7cff", "#2cb68c", "#e23636"]; // 自定义颜色列表
        //     //     return colorList[params.dataIndex];
        //     //   }
        //     // }
        //   },
        // ],

        series: [
          //内圈阴影
          {
            name: "",
            type: "pie",
            radius: ["40%", "60%"],
            itemStyle: {
              borderColor: "#fff",
              borderWidth: 2,
            },
            avoidLabelOverlap: false,
            label: {
              show: false,
              position: "center",
            },
            labelLine: {
              show: false,
            },
            z: 10,
            emphasis: {
              scale: false, //鼠标划上不展示高亮放大效果
            },
            data: data.map((item) => ({
              value: 1000,
              name: item.name,
              itemStyle: {
                color: item.color,
                opacity: 0.3,
              },
            })),
          },
          //外圈
          {
            name: "",
            type: "pie",
            radius: ["50%", "60%"],
            itemStyle: {
              borderColor: "#fff",
              borderWidth: 2,
            },
            avoidLabelOverlap: false,
            labelLine: {
              show: true, // 显示标签连线
            },
            label: {
              formatter: "{b}: {c}", // 格式化显示名称和数值
            },
            // label: {
            //   show: false,
            //   position: "center",
            // },
            // labelLine: {
            //   show: false,
            // },
            z: 11,
            data: data.map((item) => ({
              value: 1000,
              name: item.name,
              itemStyle: {
                color: item.color,
              },
            })),
          },
        ],
      };

      chart.setOption(option);
    },
    initBarChart() {
      const chart = echarts.init(this.$refs.bar_chart);
      const data = this.chartData;

      const options = {
        tooltip: {
          trigger: "axis",
          axisPointer: { type: "shadow" }, // 使用阴影指示器
        },
        grid: {
          left: "3%",
          right: "4%",
          bottom: "3%",
          containLabel: true,
        },
        xAxis: {
          type: "category",
          data: data.map((item) => item.name),
          axisLabel: { color: "#333" },
          axisTick: {
            show: false, // 隐藏 X 轴刻度线
          },
        },

        yAxis: {
          type: "value",
          max: 200,
          axisLabel: {
            color: "#333",
          },
          splitLine: {
            lineStyle: { type: "dashed", color: "#e5f0fc" },
          },
        },
        tooltip: {
          trigger: "axis",
        },
        series: [
          {
            type: "custom",
            data: data.map((item) => item.value),
            barWidth: 30,
            renderItem(params, api) {
              // 基础坐标
              const basicsCoord = api.coord([api.value(0), api.value(1)]);
              // 顶部基础 y 轴
              const topBasicsYAxis = basicsCoord[1];
              // 基础 x 轴
              const basicsXAxis = basicsCoord[0];
              // 底部 y 轴
              const bottomYAxis = api.coord([api.value(0), 0])[1];
              return {
                type: "group",
                children: [
                  {
                    type: "leftShape",
                    shape: {
                      topBasicsYAxis,
                      basicsXAxis,
                      bottomYAxis,
                    },
                    style: {
                      fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                        {
                          offset: 0,
                          color: "rgb(31, 129, 239,0.8)",
                        },

                        {
                          offset: 0.8,
                          color: "rgb(31, 129, 2395,0.2)",
                        },
                        {
                          offset: 1,
                          color: "rgb(31, 129, 2395,0)",
                        },
                      ]),
                      emphasis: {
                        fill: "yellow", // 鼠标高亮时的填充颜色
                      },
                    },
                  },
                  {
                    type: "rightShape",
                    shape: {
                      topBasicsYAxis,
                      basicsXAxis,
                      bottomYAxis,
                    },
                    style: {
                      fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                        {
                          offset: 0,
                          color: "rgb(47, 144, 255,1) ",
                        },

                        {
                          offset: 0.8,
                          color: "rgb(47, 144, 255,0.6)",
                        },
                        {
                          offset: 1,
                          color: "rgb(47, 144, 255,0.2)",
                        },
                      ]),
                    },
                  },
                  {
                    type: "topShape",
                    shape: {
                      topBasicsYAxis,
                      basicsXAxis,
                      bottomYAxis,
                    },
                    style: {
                      fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                        {
                          offset: 0.3,
                          color: "#c0ddfe",
                        },
                        {
                          offset: 1,
                          color: "#c0ddfe",
                        },
                      ]),
                    },
                  },
                ],
              };
            },
          },
        ],
      };
      options && chart.setOption(options);
    },

    drawShape() {
      const leftShape = echarts.graphic.extendShape({
        buildPath(ctx, shape) {
          const { topBasicsYAxis, bottomYAxis, basicsXAxis } = shape;
          // 侧面宽度
          const WIDTH = 15;
          // 斜角高度
          const OBLIQUE_ANGLE_HEIGHT = 3.6;

          const p1 = [
            basicsXAxis - WIDTH,
            topBasicsYAxis - OBLIQUE_ANGLE_HEIGHT,
          ];
          const p2 = [basicsXAxis - WIDTH, bottomYAxis];
          const p3 = [basicsXAxis, bottomYAxis];
          const p4 = [basicsXAxis, topBasicsYAxis];

          ctx.moveTo(p1[0], p1[1]);
          ctx.lineTo(p2[0], p2[1]);
          ctx.lineTo(p3[0], p3[1]);
          ctx.lineTo(p4[0], p4[1]);
        },
      });

      const rightShape = echarts.graphic.extendShape({
        buildPath(ctx, shape) {
          const { topBasicsYAxis, bottomYAxis, basicsXAxis } = shape;
          // 侧面宽度
          const WIDTH = 15;
          // 斜角高度
          const OBLIQUE_ANGLE_HEIGHT = 3.6;

          const p1 = [basicsXAxis, topBasicsYAxis];
          const p2 = [basicsXAxis, bottomYAxis];
          const p3 = [basicsXAxis + WIDTH, bottomYAxis];
          const p4 = [
            basicsXAxis + WIDTH,
            topBasicsYAxis - OBLIQUE_ANGLE_HEIGHT,
          ];

          ctx.moveTo(p1[0], p1[1]);
          ctx.lineTo(p2[0], p2[1]);
          ctx.lineTo(p3[0], p3[1]);
          ctx.lineTo(p4[0], p4[1]);
        },
      });

      const topShape = echarts.graphic.extendShape({
        buildPath(ctx, shape) {
          const { topBasicsYAxis, basicsXAxis } = shape;
          // 侧面宽度
          const WIDTH = 15;
          // 斜角高度
          const OBLIQUE_ANGLE_HEIGHT = 3.6;

          const p1 = [basicsXAxis, topBasicsYAxis];
          const p2 = [
            basicsXAxis + WIDTH,
            topBasicsYAxis - OBLIQUE_ANGLE_HEIGHT,
          ];
          const p3 = [basicsXAxis, topBasicsYAxis - OBLIQUE_ANGLE_HEIGHT * 2];
          const p4 = [
            basicsXAxis - WIDTH,
            topBasicsYAxis - OBLIQUE_ANGLE_HEIGHT,
          ];

          ctx.moveTo(p1[0], p1[1]);
          ctx.lineTo(p2[0], p2[1]);
          ctx.lineTo(p3[0], p3[1]);
          ctx.lineTo(p4[0], p4[1]);
        },
      });

      echarts.graphic.registerShape("leftShape", leftShape);
      echarts.graphic.registerShape("rightShape", rightShape);
      echarts.graphic.registerShape("topShape", topShape);
      this.initBarChart();
    },

    // initGraphChart() {
    //   const container = this.$refs.graphChartRef;
    //   if (!container) return;

    //   // 初始化 ECharts 实例
    //   const myChart = echarts.init(container);

    //    // 设置图表配置项
    //    const option = {
    //     tooltip: {
    //       trigger: 'item',
    //     },
    //     animation: true,
    //     series: [
    //       {
    //         type: 'graph',
    //         layout: 'none',  // 设置布局为无布局
    //         symbolSize: 40,  // 节点大小
    //         roam: true,
    //         edgeSymbol: ['none', 'arrow'],
    //         edgeSymbolSize: [4, 10],
    //         lineStyle: {
    //           type: 'solid', // 设置边为实线
    //           width: 2, // 设置边宽
    //           color: '#000', // 设置边颜色
    //         },
    //         // 设置边为平滑曲线
    //         edgeShape: 'curve',  // 使用曲线
    //         smooth: 0.9,  // 控制曲线的平滑程度，值在 0 到 1 之间
    //         data: [
    //           {
    //             id: 'parent',
    //             name: '中心节点',
    //             x: 300,
    //             y: 300,
    //             symbol: 'circle', // 圆形节点
    //             symbolSize: 60,
    //             itemStyle: {
    //               color: 'blue',
    //               borderColor: 'blue',
    //               borderWidth: 5,
    //             },
    //             label: {
    //               show: true,
    //               position: 'top',  // 标签在节点下方
    //               color: '#000',
    //             },
    //           },
    //           {
    //             id: 'node1',
    //             name: '子节点1',
    //             symbol: 'circle', // 圆形节点
    //             itemStyle: {
    //               color: 'orange',
    //               borderColor: 'orange',
    //               borderWidth: 5,
    //             },
    //             label: {
    //               show: true,
    //               position: 'top',  // 标签在节点下方
    //               color: '#000',
    //             },
    //           },
    //           {
    //             id: 'node2',
    //             name: '子节点2',
    //             symbol: 'circle', // 圆形节点
    //             itemStyle: {
    //               color: 'green',
    //               borderColor: 'green',
    //               borderWidth: 5,
    //             },
    //             label: {
    //               show: true,
    //               position: 'top',  // 标签在节点下方
    //               color: '#000',
    //             },
    //           },
    //           {
    //             id: 'node3',
    //             name: '子节点3',
    //             symbol: 'circle', // 圆形节点
    //             itemStyle: {
    //               color: 'red',
    //               borderColor: 'red',
    //               borderWidth: 5,
    //             },
    //             label: {
    //               show: true,
    //               position: 'top',  // 标签在节点下方
    //               color: '#000',
    //             },
    //           },
    //           {
    //             id: 'node4',
    //             name: '子节点4',
    //             symbol: 'circle', // 圆形节点
    //             itemStyle: {
    //               color: 'purple',
    //               borderColor: 'purple',
    //               borderWidth: 5,
    //             },
    //             label: {
    //               show: true,
    //               position: 'top',  // 标签在节点下方
    //               color: '#000',
    //             },
    //           },
    //           {
    //             id: 'node5',
    //             name: '子节点5',
    //             symbol: 'circle', // 圆形节点
    //             itemStyle: {
    //               color: 'purple',
    //               borderColor: 'purple',
    //               borderWidth: 5,
    //             },
    //             label: {
    //               show: true,
    //               position: 'top',  // 标签在节点下方
    //               color: '#000',
    //             },
    //           },
    //         ],
    //         edges: [
    //           { source: 'parent', target: 'node1' },
    //           { source: 'parent', target: 'node2' },
    //           { source: 'parent', target: 'node3' },
    //           { source: 'parent', target: 'node4' },
    //           { source: 'parent', target: 'node5' },
    //         ],
    //       },
    //     ],
    //   };

    //   // 在这里手动计算节点的 `x` 和 `y` 坐标来实现辐射效果
    //   const radius = 200; // 调整半径，拉长连线
    //   const centerX = 300; // 中心点的 X 坐标
    //   const centerY = 300; // 中心点的 Y 坐标
    //   const nodes = option.series[0].data;

    //   nodes.slice(1).forEach((node, index) => {
    //     const angle = (index / (nodes.length - 1)) * Math.PI * 2;
    //     node.x = centerX + Math.cos(angle) * radius;
    //     node.y = centerY + Math.sin(angle) * radius;
    //   });

    //   // 设置配置项
    //   myChart.setOption(option);

    //   // 监听窗口变化，调整图表大小
    //   window.addEventListener('resize', () => {
    //     myChart.resize();
    //   });
    // },

    // ============================================

    initGraphChart() {
      this.chart = echarts.init(this.$refs.graphChartRef);
      const option = {
        series: [
          {
            type: "graph",
            layout: "force",
            force: {
              repulsion: 500, // 增加排斥力，增大节点间的距离
              edgeLength: [60, 200], // 增加连线的距离
              layoutAnimation: true,
            },
            symbolSize: 50, // 默认节点大小
            roam: true,
            label: {
              show: true,
              position: "top", // 标签放在节点上方
              color: "#000", // 文字颜色为黑色
            },
            data: this.createNodes(),
            links: this.createLinks(),
            lineStyle: {
              curveness: 0.3, // 适度的曲线连接线
              color: "source", // 连接线颜色
              width: 2,
            },
            itemStyle: {
              borderWidth: 3, // 边框宽度
              opacity: 0.9, // 保持不透明
              shadowColor: "rgba(0, 0, 0, 0.3)",
              shadowBlur: 10,
            },
          },
        ],
      };
      this.chart.setOption(option);

    },






    // 动态生成节点，父节点比子节点大
    createNodes() {
      const nodes = [];
      let colorIndex = 0; // 颜色池索引
      this.nodes.forEach((node) => {
        nodes.push({
          id: node.id,
          name: node.name,
          x: node.x,
          y: node.y,
          symbolSize: node.symbolSize, // 父节点大于子节点
          itemStyle: {
            color: this.colorPool[colorIndex % this.colorPool.length],
            borderColor: this.colorPool[colorIndex % this.colorPool.length],
            borderWidth: 3,
            opacity: 0.9,
            shadowColor: "rgba(0, 0, 0, 0.3)",
            shadowBlur: 10,
            borderType: "solid",
            // 增加渐变色的效果
            borderColor: new echarts.graphic.LinearGradient(0, 0, 1, 1, [
              { offset: 0, color: "#ff4d4f" }, // 渐变起始颜色
              { offset: 1, color: "#fa8c16" }, // 渐变结束颜色
            ]),
          },
          label: {
            show: true,
            position: "top",
            color: "#000", // 文字为黑色
            fontWeight: "bold",
          },
          animation: {
            duration: 2000, // 设置动画时长为2秒
            easing: "easeInOutSine",
            loop: true, // 无限循环
            scale: [1, 1.5], // 节点从 1x 到 1.5x 放大
          },
        });
        colorIndex++; // 增加颜色池索引
        if (node.children) {
          node.children.forEach((child) => {
            nodes.push({
              id: child.id,
              name: child.name,
              x: child.x,
              y: child.y,
              symbolSize: 40, // 子节点小于父节点
              itemStyle: {
                color: this.colorPool[colorIndex % this.colorPool.length],
                borderColor: this.colorPool[colorIndex % this.colorPool.length],
                borderWidth: 3,
                opacity: 0.8,
              },
              animation: {
                duration: 2000, // 设置动画时长为2秒
                easing: "easeInOutSine",
                loop: true, // 无限循环
                scale: [1, 1.5], // 节点从 1x 到 1.5x 放大
              },
              label: {
                show: true,
                position: "top",
                color: "#000",
              },
            });
            colorIndex++;
          });
        }
      });
      return nodes;
    },
    // 创建连线，连接父节点和子节点
    createLinks() {
      const links = [];
      this.nodes.forEach((node) => {
        if (node.children) {
          node.children.forEach((child) => {
            links.push({
              source: node.id,
              target: child.id,
            });
          });
        }
      });
      return links;
    },

    
  },
};
</script>

<style lang="scss" scoped>
* {
  box-sizing: border-box;
}
.el-container {
  width: 100%;
  box-sizing: border-box;
  padding: 20px;
  // padding: 20px 20px 0 0px;
  height: calc(100vh - 90px);
  background-color: #edf4fa;
}
.p_container {
  width: 100%;
  display: flex;
}
.title {
  padding-left: 30px;
  width: 340px;
  height: 38px;
  line-height: 38px;
  background: url(../../../../../assets/img/unified-resources/标题背景.png)
    no-repeat;
  background-size: 100% 100%;
  color: #ffffff;
}

.small_title {
  //   height: 40px;
  display: flex;
  align-items: center;

  > span {
    font-family: Alibaba PuHuiTi;
    font-weight: 500;
    font-size: 16px;
    color: #333333;
    margin: 0 10px;
  }

  > div {
    // height: 40px;
    display: flex;
    align-items: center;

    .num_bg {
      width: 25px;
      height: 31px;
      margin-right: 5px;
      background: url(../../../../../assets/img/unified-resources/数字背景.png)
        no-repeat;
      background-size: 100% 100%;
      color: #269cfd;
      text-align: center;
      line-height: 31px;
    }
  }
}

.grid-content1 {
  display: flex;
  flex-direction: column;
  width: 574px;
  //   height: 500px;
  // height: calc(100vh - 80px);
  height: 100%;
  margin-right: 20px;

  .left_top {
    box-sizing: border-box;
    width: 574px;
    height: 370px;
    background: rgba(255, 255, 255, 0.7);
    box-shadow: 0px 2px 15px 1px rgba(0, 26, 52, 0.08);
    padding: 15px;

    .use_content {
      //   height: 200px;
      width: 100%;
      display: flex;

      .use_count {
        // width: 110px;
        // height: 100px;

        .use_count_item {
          display: flex;
          margin: 10px 0;

          > img {
            width: 60px;
            height: 50px;
          }

          > div {
            .use_count_item_title {
              min-width: 140px;
              font-family: Alibaba PuHuiTi;
              font-weight: 500;
              font-size: 16px;
              color: #333333;
            }

            .use_count_item_num {
              font-family: DIN;
              font-weight: 500;
              font-size: 20px;
              color: #008ce6;
              // text-shadow: 0px 3px 0px rgba(174, 218, 255, 0.53);
              background: linear-gradient(0deg, #0787ff 0%, #45bcf9 100%);
              -webkit-background-clip: text;
              -webkit-text-fill-color: transparent;
            }
          }
        }
      }

      .use_chart {
        width: 360px;
        height: 140px;
      }
    }
  }
  .left_center {
    height: 200px;
    background: rgba(255, 255, 255, 0.7);
    box-shadow: 0px 2px 15px 1px rgba(0, 26, 52, 0.08);
    padding: 15px;
    box-sizing: border-box;
    margin: 10px 0;
  }
  .left_bottom {
    flex: 1;
    background: rgba(255, 255, 255, 0.7);
    box-shadow: 0px 2px 15px 1px rgba(0, 26, 52, 0.08);
    padding: 20px;
    box-sizing: border-box;
    .graph_content {
      height: calc(100% - 30px);
      width: 100%;
    }
  }
}

.grid-content2 {
  width: calc(100% - 594px);
  height: 100%;
  // flex: 1;
  display: flex;
  flex-direction: column;
  .grid-content2_top {
    width: 100%;
    height: 30%;
    background: rgba(255, 255, 255, 0.7);
    box-shadow: 0px 2px 15px 1px rgba(0, 26, 52, 0.08);
    padding: 20px;
    box-sizing: border-box;
    margin-bottom: 10px;
    .grid-content2_top_box1 {
      display: flex;
      justify-content: space-between;
      align-items: center;
      // gap: 20px;
      .grid-content2_top_item1 {
        // flex: 1;
        position: relative;
        font-size: 14px;

        .grid-content2_top_item1_title {
          position: absolute;
          top: 15px;
          left: 30px;
          font-size: 16px;
          color: #ffffff;
        }
        .grid-content2_top_item1_count {
          margin-top: 26px;
          line-height: 26px;
          .grid-content2_top_item1_num {
            font-family: DIN;
            font-weight: 500;
            font-size: 24px;
            color: #2c85d8;
            > span {
              color: #ffaa00;
            }
          }
        }

        // padding: 0px 30px 10px;
        display: flex;
        justify-content: space-around;
        align-items: center;
        // width: 292px;
        width: 25%;
        height: 120px;
        border: 1px solid #ffffff;
        background: url(../../../../../assets/img/unified-resources/框.png)
          no-repeat;
        background-size: 100% 100%;
      }
    }
    .grid-content2_top_box2 {
      display: flex;
      justify-content: space-between;
      align-items: center;
      .grid-content2_top_item2 {
        flex: 1;
        padding: 0 40px;
        height: 100px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        background: url(../../../../../assets/img/unified-resources/面板.png)
          no-repeat;
        background-size: 100% 100%;
        .grid-content2_top_item2_img {
          display: flex;
          align-items: center;
          // margin-left: 40px;

          > img {
            width: 52px;
            height: 52px;
            margin-right: 20px;
          }
          > div {
            line-height: 26px;
            .grid-content2_top_item2_status_title {
              font-size: 14px;
            }
            .grid-content2_top_item2_num_danger {
              color: #f98a8c;
              font-size: 20px;
            }
            .grid-content2_top_item2_num_success {
              color: #60daa8;
              font-size: 20px;
              > span {
                font-size: 12px;
              }
            }
            .grid-content2_top_item2_num_primary {
              color: #8bc7f9;
              font-size: 20px;
              > span {
                font-size: 12px;
              }
            }
            .grid-content2_top_item2_num_warning {
              color: #fdd58c;
              font-size: 20px;
              > span {
                font-size: 12px;
              }
            }
          }
        }
        .grid-content2_top_item2_status_danger {
          height: 30px;
          width: 2px;
          border-right: 5px solid #f98a8c;
          border-radius: 5px;
        }

        .grid-content2_top_item2_status_success {
          height: 30px;
          width: 2px;
          border-right: 5px solid #60daa8;
          border-radius: 5px;
        }
        .grid-content2_top_item2_status_primary {
          height: 30px;
          width: 2px;
          border-right: 5px solid #8bc7f9;
          border-radius: 5px;
        }
        .grid-content2_top_item2_status_warning {
          height: 30px;
          width: 2px;
          border-right: 5px solid #fdd58c;
          border-radius: 5px;
        }
      }
    }
  }
  .grid-content2_bottom {
    flex: 1;
    background: rgba(255, 255, 255, 0.7);
    box-shadow: 0px 2px 15px 1px rgba(0, 26, 52, 0.08);
    padding: 20px;
    box-sizing: border-box;
    .grid-content2_bottom_content {
      width: 100%;
      height: calc(100% - 40px);
      .count_box {
        width: 100%;
        display: flex;
        .title_box {
          margin-right: 50px;
          > div {
            width: 163px;
            height: 36px;
            background: url(../../../../../assets/img/unified-resources/三角箭头.png)
              no-repeat;
            background-size: 100% 100%;
            line-height: 30px;
            text-align: center;
            margin-top: 10px;
            font-family: Alibaba PuHuiTi;
            font-weight: 500;
            font-size: 18px;
            color: #585858;
          }
        }
        .num_box {
          // width: 300px;
          flex: 1;
          .num_box_top {
            width: 100%;
            display: flex;
            justify-content: space-between;
            .num_content {
              margin-top: 10px;
              display: flex;

              .b-num_bg {
                width: 35px;
                height: 41px;
                margin-right: 5px;
                background: url(../../../../../assets/img/unified-resources/数字背景.png)
                  no-repeat;
                background-size: 100% 100%;
                color: #269cfd;
                text-align: center;
                line-height: 41px;
                font-size: 26px;
              }
            }
          }
          .num_box_bottom {
            width: 100%;
            display: flex;
            justify-content: space-between;
            align-items: center;
            .num_box_bottom_item {
              margin-top: 10px;
              display: flex;
              flex-direction: column;
              justify-content: center;
              box-sizing: border-box;
              padding: 20px;
              min-width: 269px;
              // width: 229px;
              height: 102px;

              border-radius: 4px 4px 4px 4px;
              border: 1px dashed #98d4ff;
              // padding: 20px;

              .num_box_bottom_item_t {
                display: flex;
                .num_content {
                  margin-left: 10px;
                  display: flex;

                  .b-num_bg {
                    width: 25px;
                    height: 31px;
                    margin-right: 5px;
                    background: url(../../../../../assets/img/unified-resources/数字背景.png)
                      no-repeat;
                    background-size: 100% 100%;
                    color: #269cfd;
                    text-align: center;
                    line-height: 31px;
                  }
                }
              }
              .num_box_bottom_item_b {
                margin-top: 10px;
                display: flex;
                justify-content: space-between;
                > div {
                  line-height: 24px;
                  > div {
                    font-size: 14px;
                  }
                  > span {
                    font-family: DIN;
                    font-weight: 500;
                    font-size: 20px;
                    color: #008ce6;
                    // text-shadow: 0px 3px 0px rgba(174, 218, 255, 0.53);
                    background: linear-gradient(0deg, #0787ff 0%, #45bcf9 100%);
                    -webkit-background-clip: text;
                    -webkit-text-fill-color: transparent;
                  }
                }
              }
            }
          }
        }
        .bar_chart {
          flex: 1;
          width: 620px;
        }
      }

      .table_box {
        width: 100%;
        .small_title {
          margin-top: 10px;
        }
        .tab_table {
          display: flex;
          width: 100%;
          .tab_img {
            width: 140px;
            height: 30px;
            text-align: center;
            line-height: 30px;
            font-family: Alibaba PuHuiTi;
            font-weight: 500;
            font-size: 20px;
            color: #8b8b8b;
            margin: 10px 0;
          }
          .tab_active {
            background: url(../../../../../assets/img/unified-resources/tab选中.png)
              no-repeat;
            background-size: 100% 100%;
          }
        }
      }
    }
  }
}

// 数字背景
.num_bg {
  width: 25px;
  height: 31px;
  margin-right: 5px;
  background: url(../../../../../assets/img/unified-resources/数字背景.png)
    no-repeat;
  background-size: 100% 100%;
  color: #269cfd;
  text-align: center;
  line-height: 31px;
}

/* 呼吸动画效果，每次初始化时播放 */
// @keyframes breathing {
//   0% {
//     transform: scale(1);
//   }
//   50% {
//     transform: scale(1.2); /* 放大效果 */
//   }
//   100% {
//     transform: scale(1);
//   }
// }

// /* 添加持续的呼吸动画 */
// .node {
//   animation: breathing 2s ease-in-out infinite; /* 无限循环动画 */
// }

// =======================
/* 自定义呼吸动画 */
@keyframes breathe {
  0% {
    transform: scale(1);
    opacity: 0.9;
  }
  50% {
    transform: scale(1.2);
    opacity: 1;
  }
  100% {
    transform: scale(1);
    opacity: 0.9;
  }
}

/* 呼吸动画效果，适用于节点 */
.node {
  animation: breathe 3s infinite ease-in-out;
}

/* 使用渐变颜色边框 */
.node-item {
  border-color: transparent;
  border-style: solid;
  border-width: 20px;
  animation: gradient-border 3s infinite;
}

@keyframes gradient-border {
  0% {
    border-color: #ff4d4f;
  }
  50% {
    border-color: #13c2c2;
  }
  100% {
    border-color: #ff4d4f;
  }
}
</style>
