<template>
  <div class="index-module__NV_5cW__container">
    <!-- 头部区域：标题、副标题、武汉核心数据统计 -->
    <div class="index-module__NV_5cW__header">
      <div class="index-module__NV_5cW__floatingElements">
        <div class="index-module__NV_5cW__floatingElement"></div>
        <div class="index-module__NV_5cW__floatingElement"></div>
        <div class="index-module__NV_5cW__floatingElement"></div>
      </div>
      <StatsGlass />
    </div>

    <!-- 内容区域：ECharts图表模块 + 项目列表 -->
    <div class="index-module__NV_5cW__content">
      <!-- ECharts图表区域 -->
      <div class="index-module__NV_5cW__chartsSection">
<!--        <div class="index-module__NV_5cW__sectionHeader">-->
<!--          <h2 class="index-module__NV_5cW__sectionTitle">-->
<!--            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"-->
<!--                 stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"-->
<!--                 class="lucide lucide-chart-pie" aria-hidden="true">-->
<!--              <path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"></path>-->
<!--              <circle cx="12" cy="10" r="3"></circle>-->
<!--            </svg>-->
<!--            <span>全球开源风险态势感知监控中心数据可视化</span>-->
<!--          </h2>-->
<!--        </div>-->

        <!-- 图表网格布局：新增多个模块 -->
        <div class="index-module__NV_5cW__chartsGrid">

          <!-- 全球威胁情报分析地图 - 移到最上面 -->
          <div class="index-module__NV_5cW__chartCard chartCard__wide">
            <h3 class="chartCard__title">🛡️ 全球威胁情报分析与监测</h3>
            <div class="chartCard__container map-container">
              <ThreatIntelMap />
            </div>
          </div>

          <!-- 行业分布 -->
          <IndustryDistribution />

          <!-- 高危组件Top 10 -->
          <HighRiskComponentRank />

          <!-- 情报流 -->
          <IntelligenceFeed />

          <CveTrendChart />
        </div>
      </div>

      <!-- 编程语言使用趋势堆叠面积图 -->
      <div class="index-module__NV_5cW__chartCard chartCard__wide mb-[1.5rem]">
        <h3 class="chartCard__title">漏洞语言分布</h3>
        <div class="chartCard__container">
          <div class="num-empty" v-if="isEmpty.languageTrend"></div>
          <div v-else id="languageTrendChart" class="chart"></div>
        </div>
      </div>

      <!-- 高危漏洞占比图表 -->
      <div class="index-module__NV_5cW__chartCard mb-[1.5rem]">
        <h3 class="chartCard__title">漏洞等级分布</h3>
        <div class="chartCard__container">
          <div class="num-empty" v-if="isEmpty.vulnerabilitySeverity"></div>
          <div v-else id="vulnerabilitySeverityChart" class="chart"></div>
        </div>
      </div>

      <!-- 气泡图 -->
      <div class="index-module__NV_5cW__chartCard mb-[1.5rem]">
        <h3 class="chartCard__title">编程语言安全态势</h3>
        <div class="chartCard__container">
          <div class="num-empty" v-if="isEmpty.scatterData"></div>
          <div v-else id="scatterChart" class="chart"></div>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { onMounted, ref, nextTick, watch, onUnmounted } from 'vue';
import * as echarts from 'echarts';
import { usePageResize } from '@/utils/hooks/usePageResize';
import ThreatIntelMap from './components/ThreatIntelMap.vue';
import IndustryDistribution from './components/IndustryDistribution.vue';
import HighRiskComponentRank from './components/HighRiskComponentRank.vue';
import IntelligenceFeed from './components/IntelligenceFeed.vue';
import CveTrendChart from './components/CveTrendChart.vue';
import StatsGlass from '@/views/Jyh/security/StatsGlass.vue';

// 页面尺寸响应式
const { widthType } = usePageResize();

// 1. 武汉优秀开源项目数据
const excellentProjects = ref([
  { name: '调问（DWSurvey）', desc: '问卷表单', org: '极推科技（武汉）有限公司' },
  { name: 'Eova', desc: '低代码开发平台', org: '武汉简码科技有限公司' },
  { name: 'ClickVisual', desc: '轻量级日志查询、分析、报警可视化平台', org: '武汉初心科技有限公司' },
  { name: 'meta2d.js', desc: '2D图元组成的可视化引擎', org: '武汉乐吾乐科技有限责任公司' },
  { name: 'Juno', desc: '分布式微服务管理系统', org: '武汉斗鱼鱼乐网络科技有限公司' },
  { name: 'Opentalent 开源北极星', desc: '开源人才评价系统', org: '湖北大学' },
  { name: 'fountain', desc: '仓颉编程语言实现的JAVA Spring框架的国产替代', org: '江汉大学' },
  { name: 'deepin', desc: '深度操作系统', org: '武汉深之度科技有限公司' },
  { name: 'RustSBI', desc: '安全引导程序', org: '华中科技大学' },
  { name: 'NextDenovo', desc: '高效且精确的长读长纠错与组装工具', org: '武汉希望组生物科技有限公司' }
]);



// 2. 2025武汉市优秀开源软件项目
const excellentProjects2025 = ref([
  { name: '调问（DWSurvey）', desc: '问卷表单', org: '极推科技（武汉）有限公司' },
  { name: 'Eova', desc: '低代码开发平台', org: '武汉简码科技有限公司' },
  { name: 'ClickVisual', desc: '轻量级日志查询、分析、报警可视化平台', org: '武汉初心科技有限公司' },
  { name: 'meta2d.js', desc: '2D图元组成的可视化引擎', org: '武汉乐吾乐科技有限责任公司' },
  { name: 'Juno', desc: '分布式微服务管理系统', org: '武汉斗鱼鱼乐网络科技有限公司' },
  { name: 'Opentalent 开源北极星', desc: '开源人才评价系统', org: '湖北大学' },
  { name: 'fountain', desc: '仓颉编程语言实现的JAVA Spring框架的国产替代', org: '江汉大学' }
]);

// 3. 图表数据定义
const chartData = ref({
  // 高校开源参与分布（包含华中科大、武大、湖北大学、江汉大学等）
  university: [
    { value: 30, name: '华中科技大学' },
    { value: 25, name: '武汉大学' },
    { value: 15, name: '湖北大学' },
    { value: 10, name: '江汉大学' },
    { value: 8, name: '武汉理工大学' },
    { value: 7, name: '华中师范大学' },
    { value: 5, name: '其他高校' }
  ],
  // 开源社区区域分布
  community: {
    xAxis: ['武昌区', '洪山区', '东湖高新区', '江汉区', '汉阳区', '青山区'],
    data: [28, 35, 42, 18, 15, 12]
  },
  // OSS Compass开源项目排行（提取OpenRank总分：左边数值）
  ossCompass: {
    yAxis: [
      'openharmony/docs',
      'mindspore/mindspore',
      'openharmony/arkui_ace_engine',
      'apache/doris',
      'openharmony/interface_sdk-js',
      'anolis-challenge/activity-school',
      'PaddlePaddle/Paddle',
      'StarRocks/starrocks',
      'openharmony/xts_acts',
      'ant-design/ant-design'
    ],
    data: [91.55, 67.35, 62.07, 48.82, 44.06, 39.77, 39.55, 34.2, 30.39, 30.37],
    // 完整分数数据（用于tooltip）
    fullData: [
      { openRank: '91.55 | 30.86', quality: '92.06 | 8.905', wxb: '70.69 | -14.8', score: '84.77 | 8.32' },
      { openRank: '67.35 | 27.41', quality: '96.92 | 7.17', wxb: '98.915 | 7.1', score: '87.73 | 13.89' },
      { openRank: '62.07 | 17.98', quality: '71.69 | 2.885', wxb: '76.06 | 10.9', score: '69.94 | 10.59' },
      { openRank: '48.82 | 10.14', quality: '67.26 | 0.573', wxb: '30.5 | 7.3', score: '48.86 | 6.00' },
      { openRank: '44.06 | 11.49', quality: '32.5 | 3.14', wxb: '67.55 | 16.7', score: '48.04 | 10.44' },
      { openRank: '39.77 | 37.64', quality: '31.05 | 0.215', wxb: '24.798 | -18.9', score: '31.87 | 6.32' },
      { openRank: '39.55 | 7.25', quality: '68.55 | -2.937', wxb: '68.26 | -17.3', score: '58.79 | -4.33' },
      { openRank: '34.2 | 2.08', quality: '49.07 | -0.877', wxb: '47.07 | 9.9', score: '43.45 | 3.70' },
      { openRank: '30.39 | 10.97', quality: '29.8 | 5.633', wxb: '27.045 | 4.3', score: '29.08 | 6.97' },
      { openRank: '30.37 | 8.57', quality: '37.1 | 4.295', wxb: '35.097 | 6.8', score: '34.19 | 6.55' }
    ]
  },
  // 武汉开源开发者排行榜（模拟数据：前10名，按贡献值排序）
  developer: {
    yAxis: ['张XX', '李XX', '王XX', '刘XX', '陈XX', '杨XX', '黄XX', '赵XX', '吴XX', '周XX'],
    data: [980, 850, 720, 650, 580, 520, 480, 420, 380, 350]
  },
  // 武汉市语言与技术竞争趋势（2021-2025，多系列）
  languageTech: {
    xAxis: ['2021', '2022', '2023', '2024', '2025'],
    series: [
      { name: 'Java', data: [85, 82, 78, 75, 72] },
      { name: 'Python', data: [78, 80, 85, 88, 90] },
      { name: 'Rust', data: [20, 35, 45, 60, 75] },
      { name: '仓颉', data: [0, 5, 15, 30, 45] },
      { name: 'Go', data: [60, 65, 70, 72, 75] }
    ]
  },
  // 编程语言使用趋势数据
  languageTrend: {
    years: ['2017', '2018', '2019', '2020', '2021', '2022', '2023', '2024'],
    series: [
      {
        name: 'JavaScript',
        type: 'established',
        color: '#FAC858',
        data: [65, 64, 69, 70, 69, 65, 61, 61]
      },
      {
        name: 'Python',
        type: 'established',
        color: '#5470C6',
        data: [32, 41, 49, 55, 52, 53, 54, 60]
      },
      {
        name: 'HTML/CSS',
        type: 'established',
        color: '#91CC75',
        data: [60, 55, 61, 61, 60, 54, 52, 52]
      },
      {
        name: 'SQL',
        type: 'established',
        color: '#9254DE',
        data: [42, 47, 56, 56, 54, 49, 52, 50]
      },
      {
        name: 'Java',
        type: 'established',
        color: '#EE6666',
        data: [47, 51, 50, 54, 49, 48, 49, 49]
      },
      {
        name: 'TypeScript',
        type: 'emerging',
        color: '#73C0DE',
        data: [12, 17, 25, 28, 29, 34, 34, 50]
      },
      {
        name: 'Shell',
        type: 'established',
        color: '#52C41A',
        data: [29, 29, 40, 39, 37, 34, 34, 41]
      },
      {
        name: 'C++',
        type: 'established',
        color: '#FF6E00',
        data: [17, 18, 20, 27, 23, 25, 25, 21]
      },
      {
        name: 'C#',
        type: 'established',
        color: '#722ED1',
        data: [20, 22, 24, 22, 21, 23, 21, 19]
      },
      {
        name: 'Go',
        type: 'emerging',
        color: '#00DDFF',
        data: [8, 12, 18, 19, 17, 19, 17, 14]
      },
      {
        name: 'PHP',
        type: 'declining',
        color: '#F5222D',
        data: [30, 26, 29, 27, 32, 20, 18, 15]
      },
      {
        name: 'Rust',
        type: 'emerging',
        color: '#FC8452',
        data: [2, 2, 5, 7, 6, 9, 10, 10]
      }
    ]
  },

  // 漏洞占比数据
  vulnerabilitySeverity: {
    categories: ['2024Q1', '2024Q2', '2024Q3', '2024Q4', '2025Q1', '2025Q2', '2025Q3', '2025Q4'],
    series: [
      {
        name: '高危漏洞',
        type: 'bar',
        stack: 'total',
        itemStyle: { color: '#FF4D4F' },
        barWidth: 16,
        data: [35, 42, 58, 45, 67, 78, 62, 85, 92]
      },
      {
        name: '中危漏洞',
        type: 'bar',
        stack: 'total',
        itemStyle: { color: '#FAAD14' },
        barWidth: 16,
        data: [65, 72, 88, 95, 112, 105, 120, 135, 128]
      },
      {
        name: '低危漏洞',
        type: 'bar',
        stack: 'total',
        itemStyle: { color: '#36CFC9' },
        barWidth: 16,
        data: [120, 135, 150, 142, 165, 180, 175, 190, 210]
      }
    ]
  },



  // 气泡图数据
  // 基于真实数据：[代码活跃度(X), 漏洞密度(Y), 漏洞总数(Size), 语言名称(Name)]
  // 活跃度基于新增项目数量，漏洞密度基于CWE分布统计
  scatterData: [
    [95, 75, 450, 'JavaScript'], // 最高活跃度：9,345,046个项目
    [90, 70, 380, 'Python'],     // 高活跃度：9,261,587个项目
    [85, 65, 320, 'TypeScript'], // 高增长：78.1%增长率
    [75, 80, 420, 'Java'],       // 传统强势：3,520,215个项目
    [45, 60, 280, 'C++'],        // 中等活跃：1,701,552个项目
    [40, 55, 250, 'C#'],         // 中等活跃：1,478,463个项目
    [35, 45, 180, 'PHP'],        // 传统Web语言
    [25, 25, 80, 'Go'],          // 新兴语言，低漏洞密度
    [15, 20, 45, 'Rust'],        // 安全性较好的新语言
    [60, 50, 200, 'Shell'],      // 脚本语言
  ],
  // 四象限分割点
  midX: 50,
  midY: 50,

  // 四象限颜色定义
  quadrantColors: {
    // [高密度, 低活跃度] - 极高风险
    Q1: '#BF232A',
    // [高密度, 高活跃度] - 高风险，需密切关注
    Q2: '#FF4900',
    // [低密度, 低活跃度] - 低风险，但维护成本高
    Q3: '#00B43E',
    // [低密度, 高活跃度] - 健康生态
    Q4: '#0063D0'
  }
});



// 空数据标识
const isEmpty = ref({
  university: false,
  community: false,
  ossCompass: false,
  developer: false,
  languageTech: false
});

// 图表实例存储（用于resize时销毁重绘）
const chartInstances = ref<{ [key: string]: echarts.ECharts | null }>({
  universityChart: null,
  communityChart: null,
  ossCompassChart: null,
  developerChart: null,
  languageTechChart: null,
  cweAttackSurfaceRadar: null
});





// ===================== 新增结束 =====================

// 初始化高校参与分布饼图
const initUniversityChart = () => {
  const el = document.getElementById('universityChart');
  if (!el) return;

  if (chartInstances.value.universityChart) {
    chartInstances.value.universityChart.dispose();
  }

  const myChart = echarts.init(el);
  chartInstances.value.universityChart = myChart;

  myChart.setOption({
    tooltip: {
      trigger: 'item',
      formatter: (params: any) => `${params.name}: ${params.value}%`
    },
    legend: {
      // orient: 'vertical',
      // left: 'left',
      bottom: '0',
      textStyle: { fontSize: 12 },
      itemWidth: 10,
      itemHeight: 10
    },
    series: [
      {
        name: '参与度',
        type: 'pie',
        radius: ['40%', '70%'],
        data: chartData.value.university,
        label: {
          show: true,
          formatter: '{b}: {c}%',
          fontSize: 10
        },
        color: ['#3b82f6', '#8b5cf6', '#ec4899', '#10b981', '#f59e0b', '#6366f1', '#14b8a6']
      }
    ],
    grid: { left: 0, bottom: 0, top: 0, right: 0 }
  });
};

// 初始化社区区域分布柱状图
const initCommunityChart = () => {
  const el = document.getElementById('communityChart');
  if (!el) return;

  if (chartInstances.value.communityChart) {
    chartInstances.value.communityChart.dispose();
  }

  const myChart = echarts.init(el);
  chartInstances.value.communityChart = myChart;

  myChart.setOption({
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'shadow' },
      formatter: (params: any) => `${params[0].name}: ${params[0].value}个`
    },
    grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
    xAxis: {
      type: 'category',
      data: chartData.value.community.xAxis,
      axisLabel: { fontSize: 12 }
    },
    yAxis: {
      type: 'value',
      name: '社区数量',
      nameTextStyle: { fontSize: 12 },
      axisLabel: { fontSize: 12 }
    },
    series: [
      {
        name: '开源社区数量',
        type: 'bar',
        data: chartData.value.community.data,
        itemStyle: {
          color: (params: any) => {
            const colorList = ['#3b82f6', '#8b5cf6', '#ec4899', '#10b981', '#f59e0b', '#6366f1'];
            return colorList[params.dataIndex];
          }
        }
      }
    ]
  });
};

// 初始化OSS Compass开源项目排行（横向柱状图）
const initOssCompassChart = () => {
  const el = document.getElementById('ossCompassChart');
  if (!el) return;

  if (chartInstances.value.ossCompassChart) {
    chartInstances.value.ossCompassChart.dispose();
  }

  const myChart = echarts.init(el);
  chartInstances.value.ossCompassChart = myChart;

  myChart.setOption({
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'shadow' },
      formatter: (params: any) => {
        const index = params[0].dataIndex;
        const data = chartData.value.ossCompass.fullData[index];
        return `
          <div>${params[0].name}</div>
          <div>OpenRank: ${data.openRank}</div>
          <div>代码内生质量: ${data.quality}</div>
          <div>WXB分数: ${data.wxb}</div>
          <div>综合分数: ${data.score}</div>
        `;
      }
    },
    grid: { left: '15%', right: '4%', bottom: '3%', top: '3%', containLabel: true },
    xAxis: {
      type: 'value',
      name: 'OpenRank总分',
      nameTextStyle: { fontSize: 12 },
      axisLabel: { fontSize: 12 }
    },
    yAxis: {
      type: 'category',
      data: chartData.value.ossCompass.yAxis,
      axisLabel: { fontSize: 10, overflow: 'truncate', width: 120 }
    },
    series: [
      {
        name: 'OpenRank总分',
        type: 'bar',
        data: chartData.value.ossCompass.data,
        itemStyle: { color: '#2951E0' },
        label: {
          show: true,
          position: 'right',
          formatter: '{c}',
          fontSize: 10
        },
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
            { offset: 0, color: 'rgba(41, 81, 224, 0.24)' },
            { offset: 1, color: 'rgba(41, 81, 224, 0.04)' }
          ])
        }
      }
    ]
  });
};

// 初始化武汉开源开发者排行榜（横向柱状图）
const initDeveloperChart = () => {
  const el = document.getElementById('developerChart');
  if (!el) return;

  if (chartInstances.value.developerChart) {
    chartInstances.value.developerChart.dispose();
  }

  const myChart = echarts.init(el);
  chartInstances.value.developerChart = myChart;

  myChart.setOption({
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'shadow' },
      formatter: (params: any) => `${params[0].name}: ${params[0].value}贡献值`
    },
    grid: { left: '10%', right: '4%', bottom: '3%', top: '3%', containLabel: true },
    xAxis: {
      type: 'value',
      name: '贡献值',
      nameTextStyle: { fontSize: 12 },
      axisLabel: { fontSize: 12 }
    },
    yAxis: {
      type: 'category',
      data: chartData.value.developer.yAxis,
      axisLabel: { fontSize: 12 }
    },
    series: [
      {
        name: '贡献值',
        type: 'bar',
        data: chartData.value.developer.data,
        itemStyle: { color: '#8b5cf6' },
        label: {
          show: true,
          position: 'right',
          formatter: '{c}',
          fontSize: 12
        },
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
            { offset: 0, color: 'rgba(139, 92, 246, 0.24)' },
            { offset: 1, color: 'rgba(139, 92, 246, 0.04)' }
          ])
        }
      }
    ]
  });
};

// 初始化编程语言使用趋势堆叠面积图
const initLanguageTrendChart = () => {
  const el = document.getElementById('languageTrendChart');
  if (!el) return;

  if (chartInstances.value.languageTrendChart) {
    chartInstances.value.languageTrendChart.dispose();
  }

  const myChart = echarts.init(el);
  chartInstances.value.languageTrendChart = myChart;

  // 准备堆叠面积图数据
  const series = chartData.value.languageTrend.series.map(item => ({
    name: item.name,
    type: 'line',
    stack: '总量',
    areaStyle: {
      color: item.color
    },
    lineStyle: {
      width: 1,
      color: item.color
    },
    symbol: 'none',
    data: item.data
  }));

  myChart.setOption({
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross',
        label: {
          backgroundColor: '#6a7985'
        }
      },
      formatter: (params: any) => {
        let res = `<div>${params[0].name}年</div>`;
        params.forEach((p: any) => {
          res += `<div style="display:flex;align-items:center;"><span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${p.color};"></span>${p.seriesName}: ${p.value}%</div>`;
        });
        return res;
      }
    },
    legend: {
      top: 0,
      textStyle: { fontSize: 12 },
      data: chartData.value.languageTrend.series.map(item => item.name)
    },
    grid: { left: '3%', right: '4%', bottom: '3%', top: '15%', containLabel: true },
    xAxis: [
      {
        type: 'category',
        boundaryGap: false,
        data: chartData.value.languageTrend.years,
        axisLabel: { fontSize: 12 }
      }
    ],
    yAxis: [
      {
        type: 'value',
        name: '使用率(%)',
        nameTextStyle: { fontSize: 12 },
        axisLabel: { fontSize: 12 }
      }
    ],
    series: series
  });
};

// 初始化高危漏洞占比图表
const initVulnerabilitySeverityChart = () => {
  const el = document.getElementById('vulnerabilitySeverityChart');
  if (!el) return;

  if (chartInstances.value.vulnerabilitySeverityChart) {
    chartInstances.value.vulnerabilitySeverityChart.dispose();
  }

  const myChart = echarts.init(el);
  chartInstances.value.vulnerabilitySeverityChart = myChart;

  myChart.setOption({
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      },
      formatter: (params: any) => {
        let res = `<div>${params[0].name}</div>`;
        let total = 0;
        params.forEach((p: any) => {
          total += p.value;
        });
        params.forEach((p: any) => {
          const percentage = ((p.value / total) * 100).toFixed(1);
          res += `<div style="display:flex;align-items:center;"><span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${p.color};"></span>${p.seriesName}: ${p.value} (${percentage}%)</div>`;
        });
        return res;
      }
    },
    legend: {
      top: 0,
      textStyle: { fontSize: 12 },
      data: chartData.value.vulnerabilitySeverity.series.map(item => item.name)
    },
    grid: { left: '3%', right: '4%', bottom: '3%', top: '15%', containLabel: true },
    xAxis: [
      {
        type: 'category',
        data: chartData.value.vulnerabilitySeverity.categories,
        axisLabel: { fontSize: 12 }
      }
    ],
    yAxis: [
      {
        type: 'value',
        name: '漏洞数量',
        nameTextStyle: { fontSize: 12 },
        axisLabel: { fontSize: 12 }
      }
    ],
    series: chartData.value.vulnerabilitySeverity.series
  });
};

// 初始化气泡图
const initScatterChart = () => {
  const el = document.getElementById('scatterChart');
  if (!el) return;

  if (chartInstances.value.scatterChart) {
    chartInstances.value.scatterChart.dispose();
  }

  const myChart = echarts.init(el);
  chartInstances.value.scatterChart = myChart;

  // 数据处理
  const data = chartData.value.scatterData.map(item => ({
    value: [item[0], item[1], item[2]],
    name: item[3]
  }));

  // 计算四象限颜色
  const getColor = (x: number, y: number) => {
    if (x < chartData.value.midX && y >= chartData.value.midY) return chartData.value.quadrantColors.Q1; // 高密度, 低活跃度 - 极高风险
    if (x >= chartData.value.midX && y >= chartData.value.midY) return chartData.value.quadrantColors.Q2; // 高密度, 高活跃度 - 高风险
    if (x < chartData.value.midX && y < chartData.value.midY) return chartData.value.quadrantColors.Q3; // 低密度, 低活跃度 - 低风险
    return chartData.value.quadrantColors.Q4; // 低密度, 高活跃度 - 健康生态
  };

  myChart.setOption({
    tooltip: {
      trigger: 'item',
      formatter: (params: any) => {
        return `
          <div>${params.data.name}</div>
          <div>代码活跃度: ${params.data.value[0]}</div>
          <div>漏洞密度: ${params.data.value[1]}</div>
          <div>漏洞总数: ${params.data.value[2]}</div>
        `;
      }
    },
    grid: { left: '3%', right: '4%', bottom: '3%', top: '15%', containLabel: true },
    xAxis: {
      type: 'value',
      name: '代码活跃度',
      nameTextStyle: { fontSize: 12 },
      axisLabel: { fontSize: 12 },
      splitLine: { show: true }
    },
    yAxis: {
      type: 'value',
      name: '漏洞密度',
      nameTextStyle: { fontSize: 12 },
      axisLabel: { fontSize: 12 },
      splitLine: { show: true }
    },
    series: [{
      type: 'scatter',
      data: data,
      symbolSize: (val: any) => val[2] / 2, // 根据漏洞总数调整气泡大小
      itemStyle: {
        color: (params: any) => getColor(params.value[0], params.value[1])
      },
      label: {
        show: true,
        formatter: (params: any) => params.data.name,
        position: 'inside',
        fontSize: 10,
        color: '#fff'
      }
    }]
  });
};

// 初始化武汉市语言与技术竞争趋势（折线图）
const initLanguageTechChart = () => {
  const el = document.getElementById('languageTechChart');
  if (!el) return;

  if (chartInstances.value.languageTechChart) {
    chartInstances.value.languageTechChart.dispose();
  }

  const myChart = echarts.init(el);
  chartInstances.value.languageTechChart = myChart;

  // 定义系列颜色
  const colorList = ['#3b82f6', '#10b981', '#f59e0b', '#ec4899', '#8b5cf6'];
  const series = chartData.value.languageTech.series.map((item, index) => ({
    name: item.name,
    type: 'line',
    data: item.data,
    symbol: 'circle',
    symbolSize: 6,
    lineStyle: { color: colorList[index], width: 2 },
    itemStyle: { color: colorList[index] },
    areaStyle: {
      color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
        { offset: 0, color: `${colorList[index]}33` },
        { offset: 1, color: `${colorList[index]}08` }
      ])
    }
  }));

  myChart.setOption({
    tooltip: {
      trigger: 'axis',
      formatter: (params: any) => {
        let res = `<div>${params[0].axisValue}</div>`;
        params.forEach((p: any) => {
          res += `<div>${p.seriesName}: ${p.value}</div>`;
        });
        return res;
      }
    },
    legend: {
      top: 0,
      textStyle: { fontSize: 12 }
    },
    grid: { left: '3%', right: '4%', bottom: '3%', top: '10%', containLabel: true },
    xAxis: {
      type: 'category',
      data: chartData.value.languageTech.xAxis,
      axisLabel: { fontSize: 12 }
    },
    yAxis: {
      type: 'value',
      name: '使用占比/热度',
      nameTextStyle: { fontSize: 12 },
      axisLabel: { fontSize: 12 }
    },
    series
  });
};

// 统一初始化图表
const initCharts = () => {
  // 空数据判断
  isEmpty.value = {
    university: chartData.value.university.length === 0,
    community: chartData.value.community.data.every(item => item === 0),
    ossCompass: chartData.value.ossCompass.data.every(item => item === 0),
    developer: chartData.value.developer.data.every(item => item === 0),
    languageTech: chartData.value.languageTech.series.every(s => s.data.every(d => d === 0)),



    languageTrend: chartData.value.languageTrend.series.every(s => s.data.every(d => d === 0)),
    vulnerabilitySeverity: chartData.value.vulnerabilitySeverity.series.every(s => s.data.every(d => d === 0)),
    scatterData: chartData.value.scatterData.length === 0
  };

  // 初始化各图表
  if (!isEmpty.value.university) nextTick(() => initUniversityChart());
  if (!isEmpty.value.community) nextTick(() => initCommunityChart());
  if (!isEmpty.value.ossCompass) nextTick(() => initOssCompassChart());
  if (!isEmpty.value.developer) nextTick(() => initDeveloperChart());
  if (!isEmpty.value.languageTech) nextTick(() => initLanguageTechChart());



  if (!isEmpty.value.languageTrend) nextTick(() => initLanguageTrendChart());
  if (!isEmpty.value.vulnerabilitySeverity) nextTick(() => initVulnerabilitySeverityChart());
  if (!isEmpty.value.scatterData) nextTick(() => initScatterChart());
};

// 页面resize时重绘图表
watch(widthType, () => {
  initCharts();
});

// 挂载时初始化
onMounted(() => {
  setTimeout(() => {
    initCharts();
  }, 100);
});
</script>

<style lang="scss" scoped>
.index-module__NV_5cW__container {
  background: #020617;
  min-height: 100vh;
  padding: 2rem 1rem;
  position: relative;
  overflow-x: hidden;
}

.index-module__NV_5cW__header {
  width: 1400px;
  text-align: center;
  padding: 1rem;
  position: relative;
  margin: 0 auto 3rem;
}

.index-module__NV_5cW__floatingElements {
  pointer-events: none;
  opacity: 0.3;
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.index-module__NV_5cW__floatingElement {
  background: linear-gradient(135deg, #3b82f60d, #9333ea0d);
  border-radius: 50%;
  width: 120px;
  height: 120px;
  animation: 30s linear infinite index-module__NV_5cW__float;
  position: absolute;
}

.index-module__NV_5cW__floatingElement:first-child {
  animation-delay: 0s;
  top: 10%;
  left: 10%;
}

.index-module__NV_5cW__floatingElement:nth-child(2) {
  animation-delay: -7s;
  top: 60%;
  right: 10%;
}

.index-module__NV_5cW__floatingElement:nth-child(3) {
  animation-delay: -14s;
  bottom: 20%;
  left: 50%;
}

@keyframes index-module__NV_5cW__float {
  0% {
    transform: translateY(0) rotate(0);
  }

  33% {
    transform: translateY(-20px) rotate(120deg);
  }

  66% {
    transform: translateY(10px) rotate(240deg);
  }

  to {
    transform: translateY(0) rotate(360deg);
  }
}

.index-module__NV_5cW__titleContainer {
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 1rem;
  display: flex;
}

.index-module__NV_5cW__title {
  background: #333;
  -webkit-text-fill-color: transparent;
  letter-spacing: -0.02em;
  white-space: nowrap;
  -webkit-background-clip: text;
  background-clip: text;
  margin: 0;
  font-size: 2.8rem;
  font-weight: 700;
}

.index-module__NV_5cW__titleBadge {
  color: #fff;
  letter-spacing: 0.05em;
  white-space: nowrap;
  background: #60a5fa;
  border-radius: 1.5rem;
  padding: 0.4rem 1rem;
  font-size: 1rem;
  font-weight: 600;
  box-shadow: 0 2px 10px #3b82f64d;
}

.index-module__NV_5cW__subtitle {
  color: #666;
  text-align: center;
  align-items: center;
  gap: 0.5rem;
  max-width: 500px;
  font-size: 1.1rem;
  font-weight: 400;
  display: flex;
}

.index-module__NV_5cW__statsBar {
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  background: #ffffff1a;
  border: 1px solid #fff3;
  border-radius: 1.5rem;
  align-items: center;
  gap: 1.5rem;
  width: fit-content;
  max-width: 90%;
  margin-top: 0.75rem;
  padding: 0.75rem 1.5rem;
  display: flex;
}

.index-module__NV_5cW__stat {
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
  display: flex;
}

.index-module__NV_5cW__statNumber {
  color: #60a5fa;
  font-size: 1.5rem;
  font-weight: 700;
}

.index-module__NV_5cW__statLabel {
  color: #333;
  font-size: 0.875rem;
  font-weight: 500;
}

.index-module__NV_5cW__statDivider {
  background: #fff3;
  width: 1px;
  height: 2rem;
}

.index-module__NV_5cW__content {
  max-width: 1400px; /* 加宽容器，适配更多图表 */
  margin: 0 auto;
  padding: 0 1rem;
}

/* 图表区域样式（适配示例的num-empty） */
.index-module__NV_5cW__chartsSection {
  margin-bottom: 1.5rem;
}

.index-module__NV_5cW__chartsGrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); /* 调整列宽，适配列表 */
  gap: 1.5rem;
  padding: 0;
}

.index-module__NV_5cW__chartCard {
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  background: #ffffffe6;
  border: 1px solid #ffffff4d;
  border-radius: 1rem;
  padding: 1.5rem;
  box-shadow: 0 4px 16px #00000014;
  transition: all 0.3s;
}

/* 列表卡片特殊样式 */
.index-module__NV_5cW__chartCard.list-card {
  padding: 1.5rem;
}

.index-module__NV_5cW__chartCard:hover {
  border-color: #3b82f64d;
  transform: translateY(-4px);
  box-shadow: 0 8px 24px #0000001f;
}

.chartCard__wide {
  grid-column: 1 / -1; /* 跨列显示 */
}

.chartCard__title {
  color: #333;
  font-size: 1.1rem;
  font-weight: 600;
  margin: 0 0 1rem 0;
  text-align: left;
}

.chartCard__container {
  width: 100%;
  height: 300px; /* 图表高度 */
  position: relative;
}

/* 地图容器特殊样式 */
.chartCard__container.map-container {
  height: 500px; /* 地图需要更大的高度 */
  border-radius: 0.5rem;
  overflow: hidden;
  background: transparent; /* 让地图组件自己控制背景 */
}

/* 地图卡片标题样式优化 */
.index-module__NV_5cW__chartCard:has(.map-container) .chartCard__title {
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(8px);
  border-radius: 20px;
  padding: 8px 16px;
  margin: 0 auto 16px;
  width: fit-content;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  border: 1px solid rgba(59, 130, 246, 0.2);
}

/* 列表容器样式：隐藏原生滚动条（可选，视觉更美观） */
.chartCard__container.list-container {
  height: auto;
  max-height: 300px; /* 限制列表高度，超出滚动 */
  overflow-y: auto;
  padding: 0 0.5rem;
  /* 隐藏滚动条 */
  scrollbar-width: none; /* Firefox */
  -ms-overflow-style: none; /* IE/Edge */
}

/* 隐藏webkit内核浏览器的滚动条 */
.chartCard__container.list-container::-webkit-scrollbar {
  display: none;
}

/* 项目列表样式 */
.project-list {
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
}

.project-item {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.8rem;
  background: #f8f9fa;
  border-radius: 0.5rem;
  border-left: 3px solid #2951E0;
  transition: all 0.2s;
}

/* 鼠标悬停项目项时的样式（可选） */
.project-item:hover {
  background: #f0f4ff;
  transform: translateX(2px);
}

.project-rank {
  min-width: 24px;
  height: 24px;
  border-radius: 4px;
  background: #2951E0;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 600;
  flex-shrink: 0;
  padding: 0 4px;
}

.project-rank.cisa {
  background: #ff0000;
}

.project-rank.poisoning {
  background: #ffa500;
}

.project-rank.cnvd {
  background: #ffff00;
  color: #000;
}

.project-rank.github {
  background: #0000ff;
}

.project-rank.fix {
  background: #008000;
}

.project-rank.supply {
  background: #800080;
}

.project-info {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.project-name {
  font-size: 14px;
  font-weight: 600;
  color: #333;
}

.project-desc {
  font-size: 12px;
  color: #666;
  font-style: italic;
}

.project-org {
  font-size: 12px;
  color: #888;
  flex-shrink: 0;
  white-space: nowrap;
  max-width: 150px;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 与示例一致的空数据样式 */
.num-empty {
  height: 10px;
  border-top: 2px solid #2951E0;
  width: 100%;
  background: linear-gradient(180deg, rgba(41, 81, 224, 0.12) 0%, rgba(41, 81, 224, 0.04) 100%);
  position: absolute;
  top: 50%;
  left: 0;
  transform: translateY(-50%);
}

.chart {
  width: 100%;
  height: 100%;
}

.index-module__NV_5cW__sectionHeader {
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 1rem;
  margin-bottom: 2rem;
  display: flex;
  position: relative;
}

.index-module__NV_5cW__sectionTitle {
  color: #333;
  text-align: center;
  justify-content: center;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  margin: 0;
  font-size: 1.5rem;
  font-weight: 600;
  display: flex;
}

.index-module__NV_5cW__actionSection {
  text-align: center;
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  background: #ffffffe6;
  border: 1px solid #ffffff4d;
  border-radius: 1.5rem;
  margin: 0;
  padding: 2.5rem 2rem;
  position: relative;
  overflow: hidden;
  box-shadow: 0 8px 24px #00000014;
}

.index-module__NV_5cW__actionBackground {
  z-index: 1;
  background: linear-gradient(135deg, #3b82f60d 0%, #9333ea0d 100%);
  position: absolute;
  inset: 0;
}

.index-module__NV_5cW__actionContent {
  z-index: 2;
  max-width: 600px;
  margin: 0 auto;
  position: relative;
}

.index-module__NV_5cW__actionIcon {
  color: #fff;
  background: linear-gradient(135deg, #3b82f6, #8b5cf6);
  border-radius: 50%;
  justify-content: center;
  align-items: center;
  width: 3rem;
  height: 3rem;
  margin: 0 auto 1.5rem;
  display: flex;
  box-shadow: 0 4px 12px #3b82f633;
}

.index-module__NV_5cW__actionTitle {
  background: linear-gradient(135deg, #1e293b 0%, #3b82f6 100%);
  -webkit-text-fill-color: transparent;
  -webkit-background-clip: text;
  background-clip: text;
  margin-bottom: 1rem;
  font-size: 2rem;
  font-weight: 700;
  line-height: 1.2;
}

.index-module__NV_5cW__actionDescription {
  color: #64748b;
  margin-bottom: 2rem;
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.5;
}

.index-module__NV_5cW__actionFeatures {
  flex-wrap: wrap;
  justify-content: center;
  gap: 1.5rem;
  margin-bottom: 2rem;
  display: flex;
}

.index-module__NV_5cW__feature {
  color: #3b82f6;
  background: #3b82f614;
  border: 1px solid #3b82f626;
  border-radius: 1.5rem;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 1rem;
  font-size: 0.85rem;
  font-weight: 500;
  display: flex;
}

.index-module__NV_5cW__createButton {
  background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
  border: none;
  border-radius: 1.5rem;
  align-items: center;
  gap: 0.5rem;
  height: auto;
  margin: 0 auto;
  padding: 0.75rem 2rem;
  font-size: 1rem;
  font-weight: 600;
  transition: all 0.3s;
  display: flex;
  box-shadow: 0 4px 12px #3b82f64d;
}

.index-module__NV_5cW__createButton:hover {
  background: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%);
  transform: translateY(-2px);
  box-shadow: 0 6px 18px #3b82f666;
}

/* 响应式适配 */
@media (max-width: 768px) {
  .index-module__NV_5cW__titleContainer {
    text-align: center;
    flex-direction: column;
    gap: 0.5rem;
  }

  .index-module__NV_5cW__title {
    font-size: 2.5rem;
  }

  .index-module__NV_5cW__titleBadge {
    padding: 0.4rem 1.2rem;
    font-size: 1rem;
  }

  .index-module__NV_5cW__container {
    padding: 1rem;
  }

  .index-module__NV_5cW__header {
    margin-bottom: 2rem;
    padding: 1.5rem 1rem;
  }

  .index-module__NV_5cW__statsBar {
    flex-wrap: nowrap;
    justify-content: space-between;
    gap: 0.8rem;
    width: 100%;
    max-width: 100%;
    padding: 0.8rem 1.2rem;
  }

  .index-module__NV_5cW__stat {
    text-align: center;
    flex: 1;
    min-width: 60px;
  }

  .index-module__NV_5cW__statNumber {
    font-size: 1.1rem;
  }

  .index-module__NV_5cW__statLabel {
    white-space: nowrap;
    font-size: 0.7rem;
  }

  .index-module__NV_5cW__statDivider {
    width: 1px;
    height: 1.2rem;
  }

  .index-module__NV_5cW__sectionTitle {
    text-align: left;
    flex: 1;
    justify-content: flex-start;
    gap: 0.5rem;
    font-size: 1.3rem;
  }

  .index-module__NV_5cW__actionSection {
    border-radius: 1rem;
    margin: 0;
    padding: 2rem 1.5rem;
  }

  .index-module__NV_5cW__actionTitle {
    font-size: 1.6rem;
  }

  .index-module__NV_5cW__actionFeatures {
    flex-direction: column;
    align-items: center;
    gap: 1rem;
  }

  .index-module__NV_5cW__createButton {
    padding: 0.65rem 1.5rem;
    font-size: 0.95rem;
  }

  .chartCard__container {
    height: 250px; /* 移动端图表高度调整 */
  }

  /* 移动端列表样式调整 */
  .project-item {
    flex-wrap: wrap;
    gap: 0.5rem;
  }

  .project-org {
    width: 100%;
    max-width: 100%;
    margin-top: 0.2rem;
  }
}

@media (max-width: 480px) {
  .index-module__NV_5cW__title {
    font-size: 1.8rem;
  }

  .index-module__NV_5cW__actionSection {
    padding: 1.5rem 1rem;
  }

  .index-module__NV_5cW__statsBar {
    gap: 0.6rem;
    padding: 0.6rem 0.8rem;
  }

  .index-module__NV_5cW__statNumber {
    font-size: 1rem;
  }

  .index-module__NV_5cW__statLabel {
    font-size: 0.65rem;
  }

  .index-module__NV_5cW__sectionTitle {
    gap: 0.4rem;
    font-size: 1.2rem;
  }

  .chartCard__container {
    height: 200px; /* 小屏移动端图表高度调整 */
  }

  .index-module__NV_5cW__chartsGrid {
    grid-template-columns: 1fr;
  }

  /* 小屏列表高度调整 */
  .chartCard__container.list-container {
    max-height: 300px;
  }
}

/* 图表卡片头部样式 */
.chartCard__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

/* 图表操作按钮样式 */
.chartCard__actions {
  display: flex;
  gap: 8px;
}

.chartCard__actionBtn {
  padding: 4px 12px;
  border: 1px solid #d1d5db;
  background-color: #c1c7cd;
  border-radius: 4px;
  font-size: 12px;
  cursor: pointer;
  transition: all 0.2s;
}

.chartCard__actionBtn:hover {
  background-color: #f3f4f6;
}

.chartCard__actionBtn--active {
  background-color: #3b82f6;
  color: white;
  border-color: #3b82f6;
}

.chartCard__actionBtn--active:hover {
  background-color: #2563eb;
}
</style>
