diff --git a/src/views/Jyh/security/components/CveTrendChart.vue b/src/views/Jyh/security/components/CveTrendChart.vue
new file mode 100644
index 0000000..a8d3e3a
--- /dev/null
+++ b/src/views/Jyh/security/components/CveTrendChart.vue
@@ -0,0 +1,324 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/Jyh/security/index.vue b/src/views/Jyh/security/index.vue
index 66eb17f..5d8c5ba 100644
--- a/src/views/Jyh/security/index.vue
+++ b/src/views/Jyh/security/index.vue
@@ -46,32 +46,7 @@
-
+
@@ -113,6 +88,7 @@ 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';
// 页面尺寸响应式
@@ -317,19 +293,7 @@ const chartData = ref({
]
},
- // CVE图表数据
- cveData: {
- // 全球CVE:2024年实际数据(基于Excel数据)
- global: {
- cveCount: [98402, 418, 7025, 3711, 5115, 3228, 3044, 2957, 2592, 1455, 4826, 4661],
- acceleration: [0, -99.58, 1580.62, -47.17, 37.83, -36.89, -5.70, -2.86, -12.34, -43.87, 231.68, -3.42] // 环比增长率(%)
- },
- // 中国区域CVE:2024年数据(约占全球30%)
- regional: {
- cveCount: [29521, 125, 2108, 1113, 1535, 968, 913, 887, 778, 437, 1448, 1398],
- acceleration: [0, -99.58, 1580.62, -47.17, 37.83, -36.89, -5.70, -2.86, -12.34, -43.87, 231.68, -3.42] // 环比增长率(%)
- }
- },
+
// 气泡图数据
// 基于真实数据:[代码活跃度(X), 漏洞密度(Y), 漏洞总数(Size), 语言名称(Name)]
@@ -363,8 +327,7 @@ const chartData = ref({
}
});
-// 视图切换状态变量(global: 全球, regional: 区域)
-const cveView = ref('global');
+
// 空数据标识
const isEmpty = ref({
@@ -372,9 +335,7 @@ const isEmpty = ref({
community: false,
ossCompass: false,
developer: false,
- languageTech: false,
-
- cveData: false
+ languageTech: false
});
// 图表实例存储(用于resize时销毁重绘)
@@ -384,149 +345,12 @@ const chartInstances = ref<{ [key: string]: echarts.ECharts | null }>({
ossCompassChart: null,
developerChart: null,
languageTechChart: null,
- cweAttackSurfaceRadar: null,
- CVEChart: null
+ cweAttackSurfaceRadar: null
});
-// CVE视图切换方法
-const switchCveView = (view: 'global' | 'regional') => {
- cveView.value = view;
- nextTick(() => {
- initCVEChart();
- });
-};
-// 初始化CVE图表(柱状图+折线图)
-const initCVEChart = () => {
- const el = document.getElementById('CVEChart');
- if (!el) return;
-
- if (chartInstances.value.CVEChart) {
- chartInstances.value.CVEChart.dispose();
- }
-
- const myChart = echarts.init(el);
- chartInstances.value.CVEChart = myChart;
-
- // 获取当前视图的数据
- const currentData = chartData.value.cveData[cveView.value === 'global' ? 'global' : 'regional'];
- const cveCount = currentData.cveCount;
- const acceleration = currentData.acceleration;
-
- // 月份数据
- const months = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'];
-
- myChart.setOption({
- tooltip: {
- trigger: 'axis',
- axisPointer: {
- type: 'cross',
- crossStyle: {
- color: '#999'
- }
- },
- formatter: (params: any) => {
- let res = `${params[0].name}
`;
- params.forEach((p: any) => {
- if (p.seriesName === 'CVE数量') {
- res += `${p.marker}${p.seriesName}: ${p.value}
`;
- } else {
- res += `${p.marker}${p.seriesName}: ${p.value}%
`;
- }
- });
- return res;
- }
- },
- legend: {
- top: 0,
- textStyle: { fontSize: 12 },
- data: ['CVE数量', '环比增长率']
- },
- grid: { left: '3%', right: '4%', bottom: '3%', top: '15%', containLabel: true },
- xAxis: [
- {
- type: 'category',
- data: months,
- axisPointer: {
- type: 'shadow'
- },
- axisLabel: { fontSize: 12 }
- }
- ],
- yAxis: [
- {
- type: 'value',
- name: 'CVE数量',
- nameTextStyle: { fontSize: 12, color: '#333' },
- axisLabel: { fontSize: 12, color: '#666' },
- position: 'left',
- splitLine: {
- show: true,
- lineStyle: {
- type: 'dashed'
- }
- }
- },
- {
- type: 'value',
- name: '环比增长率(%)',
- nameTextStyle: { fontSize: 12, color: '#333' },
- axisLabel: { fontSize: 12, color: '#666' },
- position: 'right',
- splitLine: {
- show: false
- }
- }
- ],
- series: [
- {
- name: 'CVE数量',
- type: 'bar',
- data: cveCount,
- itemStyle: {
- color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
- { offset: 0, color: '#3b82f6' },
- { offset: 1, color: '#60a5fa' }
- ])
- },
- barWidth: 20,
- label: {
- show: true,
- position: 'top',
- formatter: '{c}',
- fontSize: 10,
- color: '#333'
- }
- },
- {
- name: '环比增长率',
- type: 'line',
- yAxisIndex: 1,
- data: acceleration,
- itemStyle: {
- color: '#ef4444',
- borderWidth: 2
- },
- lineStyle: {
- width: 2,
- color: '#ef4444'
- },
- symbol: 'circle',
- symbolSize: 6,
- smooth: true,
- label: {
- show: true,
- position: 'top',
- formatter: (params: any) => `${params.value}%`,
- fontSize: 10,
- color: '#333'
- }
- }
- ]
- });
-};
// ===================== 新增结束 =====================
@@ -735,10 +559,6 @@ const initDeveloperChart = () => {
});
};
-
-
-
-
// 初始化编程语言使用趋势堆叠面积图
const initLanguageTrendChart = () => {
const el = document.getElementById('languageTrendChart');
@@ -1009,8 +829,7 @@ const initCharts = () => {
languageTech: chartData.value.languageTech.series.every(s => s.data.every(d => d === 0)),
- cveData: chartData.value.cveData.global.cveCount.every(item => item === 0) &&
- chartData.value.cveData.regional.cveCount.every(item => item === 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
@@ -1024,7 +843,7 @@ const initCharts = () => {
if (!isEmpty.value.languageTech) nextTick(() => initLanguageTechChart());
- if (!isEmpty.value.cveData) nextTick(() => initCVEChart());
+
if (!isEmpty.value.languageTrend) nextTick(() => initLanguageTrendChart());
if (!isEmpty.value.vulnerabilitySeverity) nextTick(() => initVulnerabilitySeverityChart());
if (!isEmpty.value.scatterData) nextTick(() => initScatterChart());