diff --git a/src/views/Jyh/ecosystem/components/InfrastructureCoverageChart.vue b/src/views/Jyh/ecosystem/components/InfrastructureCoverageChart.vue new file mode 100644 index 0000000..f61f212 --- /dev/null +++ b/src/views/Jyh/ecosystem/components/InfrastructureCoverageChart.vue @@ -0,0 +1,330 @@ + + + + + \ No newline at end of file diff --git a/src/views/Jyh/ecosystem/index.vue b/src/views/Jyh/ecosystem/index.vue index a373b71..76e546f 100644 --- a/src/views/Jyh/ecosystem/index.vue +++ b/src/views/Jyh/ecosystem/index.vue @@ -131,13 +131,7 @@ -
-

基础设施覆盖率

-
-
-
-
-
+
@@ -291,6 +285,7 @@ import { onMounted, ref, nextTick, watch, onUnmounted, computed } from 'vue'; import * as echarts from 'echarts'; import TalentMapChart from './TalentMapChart.vue' +import InfrastructureCoverageChart from './components/InfrastructureCoverageChart.vue' import { usePageResize } from '@/utils/hooks/usePageResize'; // 页面尺寸响应式 @@ -578,7 +573,6 @@ const communityData = computed(() => processUniversityClubsData()); // 空数据标识 const isEmpty = ref({ - infrastructure: false, community: false, communityHealth: false, languageTech: false @@ -648,7 +642,6 @@ const getTalentLevel = (density: number) => { // 图表实例存储(用于resize时销毁重绘) const chartInstances = ref<{ [key: string]: echarts.ECharts | null }>({ - infrastructureChart: null, communityChart: null, communityHealthChart: null, languageTechChart: null, @@ -801,154 +794,7 @@ const formatDevs = (num: number) => { }; // ===================== 新增结束 ===================== -// 初始化基础设施覆盖率图表(多层环形图) -const initInfrastructureChart = () => { - const el = document.getElementById('infrastructureChart'); - if (!el) return; - if (chartInstances.value.infrastructureChart) { - chartInstances.value.infrastructureChart.dispose(); - } - - const myChart = echarts.init(el); - chartInstances.value.infrastructureChart = myChart; - - const seriesData: any[] = []; - const center = ['50%', '50%']; - - chartData.value.infrastructure.forEach(item => { - const completeValue = item.value; - const remainingValue = 100 - item.value; - - seriesData.push({ - name: item.name, - type: 'pie', - radius: item.radius, - center: center, - avoidLabelOverlap: false, - startAngle: 90, - hoverAnimation: true, - label: { - show: false - }, - labelLine: { - show: false - }, - emphasis: { - scale: true, - scaleSize: 5 - }, - data: [ - { - value: completeValue, - name: item.name, - itemStyle: { - color: new echarts.graphic.LinearGradient( - 0, 0, 0, 1, - [ - { offset: 0, color: item.color }, - { offset: 1, color: item.color + '80' } - ] - ), - shadowBlur: 10, - shadowColor: item.color + '40' - } - }, - { - value: remainingValue, - name: '未覆盖', - itemStyle: { - color: 'rgba(255, 255, 255, 0.08)' - }, - tooltip: { - show: false - }, - emphasis: { - disabled: true - } - } - ] - }); - }); - - // 计算平均覆盖率 - const avgCoverage = Math.round( - chartData.value.infrastructure.reduce((sum, d) => sum + d.value, 0) / - chartData.value.infrastructure.length - ); - - myChart.setOption({ - tooltip: { - trigger: 'item', - backgroundColor: 'rgba(255, 255, 255, 0.95)', - borderColor: '#3b82f6', - borderWidth: 1, - borderRadius: 6, - padding: 12, - textStyle: { color: '#333', fontSize: 13 }, - formatter: (params: any) => { - if (params.name === '未覆盖') return ''; - const remaining = 100 - params.value; - return ` -
-
${params.name}
-
- - 已覆盖:${params.value}% -
-
- - 未覆盖:${remaining}% -
-
- `; - } - }, - legend: { - data: chartData.value.infrastructure.map(d => d.name), - orient: 'vertical', - right: '5%', - top: 'center', - itemWidth: 12, // 图例方块宽度 - itemHeight: 12, // 图例方块高度 - itemGap: 15, // 图例项之间的间距 - icon: 'circle', // 图例形状:'circle'圆形, 'rect'方形, 'roundRect'圆角方形 - textStyle: { - color: '#333', - fontSize: 12, - padding: [0, 0, 0, 8] // 文字与图标的间距 - } - }, - graphic: [ - { - type: 'text', - left: 'center', - top: '45%', - style: { - text: '总覆盖度', - fill: '#666', - fontSize: 13, - fontWeight: '500' - } - }, - { - type: 'text', - left: 'center', - top: '52%', - style: { - text: `${avgCoverage}%`, - fill: '#3b82f6', - fontSize: 28, - fontWeight: 'bold' - } - } - ], - series: seriesData, - animationDuration: 1000, - animationEasing: 'cubicOut', - animationDelay: (idx: number) => idx * 100 - }); -}; // 初始化高校开源社团/俱乐部数量图表(纵向柱状图) const initCommunityChart = () => { @@ -2082,14 +1928,12 @@ const initHeatmapChart = () => { const initCharts = () => { // 空数据判断 isEmpty.value = { - infrastructure: chartData.value.infrastructure.length === 0, community: chartData.value.universityClubs.length === 0, communityHealth: chartData.value.communityHealth.github.every(item => item === 0), languageTech: chartData.value.languageTech.mainstream.length === 0 && chartData.value.languageTech.emerging.length === 0 }; // 初始化各图表 - if (!isEmpty.value.infrastructure) nextTick(() => initInfrastructureChart()); if (!isEmpty.value.community) nextTick(() => initCommunityChart()); if (!isEmpty.value.communityHealth) nextTick(() => initCommunityHealthChart()); if (!isEmpty.value.languageTech) nextTick(() => initLanguageTechChart()); diff --git a/src/views/Jyh/security/index.vue b/src/views/Jyh/security/index.vue index fbddea3..8328561 100644 --- a/src/views/Jyh/security/index.vue +++ b/src/views/Jyh/security/index.vue @@ -94,8 +94,6 @@ const excellentProjects = ref([ { name: 'NextDenovo', desc: '高效且精确的长读长纠错与组装工具', org: '武汉希望组生物科技有限公司' } ]); - - // 2. 2025武汉市优秀开源软件项目 const excellentProjects2025 = ref([ { name: '调问(DWSurvey)', desc: '问卷表单', org: '极推科技(武汉)有限公司' }, @@ -170,10 +168,8 @@ const chartData = ref({ ] }, - }); - // 空数据标识 const isEmpty = ref({ university: false, @@ -193,10 +189,6 @@ const chartInstances = ref<{ [key: string]: echarts.ECharts | null }>({ cweAttackSurfaceRadar: null }); - - - - // ===================== 新增结束 ===================== // 初始化高校参与分布饼图 @@ -404,12 +396,6 @@ const initDeveloperChart = () => { }); }; - - - - - - // 初始化武汉市语言与技术竞争趋势(折线图) const initLanguageTechChart = () => { const el = document.getElementById('languageTechChart'); @@ -480,8 +466,6 @@ const initCharts = () => { 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)), - - }; // 初始化各图表 @@ -490,7 +474,6 @@ const initCharts = () => { if (!isEmpty.value.ossCompass) nextTick(() => initOssCompassChart()); if (!isEmpty.value.developer) nextTick(() => initDeveloperChart()); if (!isEmpty.value.languageTech) nextTick(() => initLanguageTechChart()); - }; // 页面resize时重绘图表