Tcode平台改造升级-编程语言安全态势图表

This commit is contained in:
2025-12-18 11:31:18 +08:00
parent e79572cd34
commit 8cab400008

View File

@@ -148,6 +148,15 @@
<div v-else id="vulnerabilitySeverityChart" class="chart"></div>
</div>
</div>
<!-- 气泡图 -->
<div class="index-module__NV_5cW__chartCard">
<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 class="index-module__NV_5cW__actionSection">
@@ -504,6 +513,37 @@ const chartData = ref({
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)]
// 活跃度基于新增项目数量漏洞密度基于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'
}
});
@@ -1200,6 +1240,77 @@ const initVulnerabilitySeverityChart = () => {
});
};
// 初始化气泡图
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');
@@ -1275,7 +1386,8 @@ const initCharts = () => {
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))
vulnerabilitySeverity: chartData.value.vulnerabilitySeverity.series.every(s => s.data.every(d => d === 0)),
scatterData: chartData.value.scatterData.length === 0
};
// 初始化各图表
@@ -1289,6 +1401,7 @@ const initCharts = () => {
if (!isEmpty.value.cveData) nextTick(() => initCVEChart());
if (!isEmpty.value.languageTrend) nextTick(() => initLanguageTrendChart());
if (!isEmpty.value.vulnerabilitySeverity) nextTick(() => initVulnerabilitySeverityChart());
if (!isEmpty.value.scatterData) nextTick(() => initScatterChart());
};
// 页面resize时重绘图表