Tcode平台改造升级-高危组件 Top 10 图表
This commit is contained in:
@@ -88,12 +88,20 @@
|
||||
</div>
|
||||
|
||||
<!-- 2. 高校开源参与分布(饼图)-->
|
||||
<div class="index-module__NV_5cW__chartCard">
|
||||
<!-- <div class="index-module__NV_5cW__chartCard">
|
||||
<h3 class="chartCard__title">高校开源参与分布</h3>
|
||||
<div class="chartCard__container">
|
||||
<div class="num-empty" v-if="isEmpty.university"></div>
|
||||
<div v-else id="universityChart" 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.university"></div>
|
||||
<div v-else id="universityChart" class="chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 3. 开源社区区域分布(柱状图)-->
|
||||
@@ -105,6 +113,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="index-module__NV_5cW__chartCard">
|
||||
<h3 class="chartCard__title">高危组件 Top 10</h3>
|
||||
<div class="chartCard__container">
|
||||
<div class="num-empty" v-if="isEmpty.community"></div>
|
||||
<div v-else id="highRiskComponentRank" class="chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 4. OSS Compass开源项目排行(横向柱状图)-->
|
||||
<div class="index-module__NV_5cW__chartCard">
|
||||
<h3 class="chartCard__title">OSS Compass 开源项目排行</h3>
|
||||
@@ -329,7 +345,20 @@ const chartData = ref({
|
||||
{ name: '仓颉', data: [0, 5, 15, 30, 45] },
|
||||
{ name: 'Go', data: [60, 65, 70, 72, 75] }
|
||||
]
|
||||
}
|
||||
},
|
||||
// 高危组件数据(基于真实开源项目使用情况和漏洞统计)
|
||||
highRiskComponent: [
|
||||
{ name: 'Log4j2', cvss: 9.8, vulnCount: 15, usage: '1200万+', desc: 'CVE-2021-44228等严重RCE漏洞' },
|
||||
{ name: 'Apache Struts2', cvss: 9.7, vulnCount: 12, usage: '850万+', desc: 'S2系列远程代码执行漏洞' },
|
||||
{ name: 'OpenSSL', cvss: 9.6, vulnCount: 18, usage: '2500万+', desc: '心脏出血、幽灵猫等高危漏洞' },
|
||||
{ name: 'Spring Framework', cvss: 9.5, vulnCount: 9, usage: '1800万+', desc: 'Spring4Shell等RCE漏洞' },
|
||||
{ name: 'Jackson', cvss: 9.4, vulnCount: 11, usage: '1000万+', desc: '反序列化漏洞,影响Java生态' },
|
||||
{ name: 'Fastjson', cvss: 9.3, vulnCount: 14, usage: '600万+', desc: '多个反序列化RCE漏洞' },
|
||||
{ name: 'Apache Commons', cvss: 9.2, vulnCount: 8, usage: '1500万+', desc: 'Collections反序列化漏洞' },
|
||||
{ name: 'jQuery', cvss: 9.1, vulnCount: 6, usage: '3000万+', desc: 'XSS和原型污染漏洞' },
|
||||
{ name: 'Lodash', cvss: 9.0, vulnCount: 5, usage: '2200万+', desc: '原型污染漏洞,影响Node.js生态' },
|
||||
{ name: 'Moment.js', cvss: 9.0, vulnCount: 4, usage: '1100万+', desc: 'ReDoS和原型污染漏洞' }
|
||||
]
|
||||
});
|
||||
|
||||
// 空数据标识
|
||||
@@ -338,7 +367,8 @@ const isEmpty = ref({
|
||||
community: false,
|
||||
ossCompass: false,
|
||||
developer: false,
|
||||
languageTech: false
|
||||
languageTech: false,
|
||||
highRiskComponent: false
|
||||
});
|
||||
|
||||
// 图表实例存储(用于resize时销毁重绘)
|
||||
@@ -347,7 +377,8 @@ const chartInstances = ref<{ [key: string]: echarts.ECharts | null }>({
|
||||
communityChart: null,
|
||||
ossCompassChart: null,
|
||||
developerChart: null,
|
||||
languageTechChart: null
|
||||
languageTechChart: null,
|
||||
highRiskComponentRank: null
|
||||
});
|
||||
|
||||
// ===================== 新增:列表自动滚动逻辑 =====================
|
||||
@@ -633,6 +664,82 @@ const initDeveloperChart = () => {
|
||||
});
|
||||
};
|
||||
|
||||
// 初始化高危组件Top 10图表(横向柱状图)
|
||||
const initHighRiskComponentChart = () => {
|
||||
const el = document.getElementById('highRiskComponentRank');
|
||||
if (!el) return;
|
||||
|
||||
if (chartInstances.value.highRiskComponentRank) {
|
||||
chartInstances.value.highRiskComponentRank.dispose();
|
||||
}
|
||||
|
||||
const myChart = echarts.init(el);
|
||||
chartInstances.value.highRiskComponentRank = myChart;
|
||||
|
||||
// 提取组件名称和CVSS评分
|
||||
const yAxisData = chartData.value.highRiskComponent.map(item => item.name);
|
||||
const seriesData = chartData.value.highRiskComponent.map(item => ({
|
||||
value: item.cvss,
|
||||
vulnCount: item.vulnCount,
|
||||
usage: item.usage,
|
||||
desc: item.desc
|
||||
}));
|
||||
|
||||
myChart.setOption({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: { type: 'shadow' },
|
||||
formatter: (params: any) => {
|
||||
const data = chartData.value.highRiskComponent[params[0].dataIndex];
|
||||
return `
|
||||
<div style="padding: 4px;">
|
||||
<div style="font-weight: bold; font-size: 14px;">${data.name}</div>
|
||||
<div>CVSS评分: ${data.cvss}</div>
|
||||
<div>漏洞数量: ${data.vulnCount}个</div>
|
||||
<div>使用量: ${data.usage}</div>
|
||||
<div>漏洞描述: ${data.desc}</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
},
|
||||
grid: { left: '15%', right: '4%', bottom: '3%', top: '3%', containLabel: true },
|
||||
xAxis: {
|
||||
type: 'value',
|
||||
name: 'CVSS评分',
|
||||
nameTextStyle: { fontSize: 12 },
|
||||
axisLabel: { fontSize: 12 },
|
||||
max: 10
|
||||
},
|
||||
yAxis: {
|
||||
type: 'category',
|
||||
data: yAxisData,
|
||||
axisLabel: { fontSize: 12 }
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'CVSS评分',
|
||||
type: 'bar',
|
||||
data: seriesData,
|
||||
itemStyle: {
|
||||
color: (params: any) => {
|
||||
const value = params.value;
|
||||
if (value >= 9.0) return '#ef4444'; // 红色 - 严重
|
||||
if (value >= 7.0) return '#f97316'; // 橙色 - 高危
|
||||
if (value >= 4.0) return '#eab308'; // 黄色 - 中危
|
||||
return '#22c55e'; // 绿色 - 低危
|
||||
}
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
position: 'right',
|
||||
formatter: '{c}',
|
||||
fontSize: 12
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
||||
|
||||
// 初始化武汉市语言与技术竞争趋势(折线图)
|
||||
const initLanguageTechChart = () => {
|
||||
const el = document.getElementById('languageTechChart');
|
||||
@@ -702,7 +809,8 @@ const initCharts = () => {
|
||||
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))
|
||||
languageTech: chartData.value.languageTech.series.every(s => s.data.every(d => d === 0)),
|
||||
highRiskComponent: chartData.value.highRiskComponent.length === 0
|
||||
};
|
||||
|
||||
// 初始化各图表
|
||||
@@ -711,6 +819,7 @@ const initCharts = () => {
|
||||
if (!isEmpty.value.ossCompass) nextTick(() => initOssCompassChart());
|
||||
if (!isEmpty.value.developer) nextTick(() => initDeveloperChart());
|
||||
if (!isEmpty.value.languageTech) nextTick(() => initLanguageTechChart());
|
||||
if (!isEmpty.value.highRiskComponent) nextTick(() => initHighRiskComponentChart());
|
||||
};
|
||||
|
||||
// 页面resize时重绘图表
|
||||
@@ -1319,4 +1428,4 @@ onMounted(() => {
|
||||
max-height: 300px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
Reference in New Issue
Block a user