态势感知平台-开源生态与贡献价值全景-社区治理健康度对比组件抽离
This commit is contained in:
@@ -0,0 +1,353 @@
|
||||
<template>
|
||||
<div class="index-module__NV_5cW__chartCard">
|
||||
<h3 class="chartCard__title">社区治理健康度对比</h3>
|
||||
<div class="chartCard__container">
|
||||
<div class="num-empty" v-if="isEmpty"></div>
|
||||
<div v-else id="ossCompassChart" class="chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref, nextTick, watch, onUnmounted, computed } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { usePageResize } from '@/utils/hooks/usePageResize';
|
||||
|
||||
// 不再接收外部数据,组件内部管理数据
|
||||
const communityHealthData = ref({
|
||||
indicators: ['PR 合并率', 'Issue 响应时间', 'CI/CD 使用率', '平均代码质量得分', '安全审计频率', '贡献者多样性'],
|
||||
github: [82, 88, 78, 85, 75, 80],
|
||||
gitcode: [68, 75, 55, 72, 60, 65]
|
||||
});
|
||||
|
||||
// 未来用于API调用的方法
|
||||
const fetchDataFromApi = async () => {
|
||||
try {
|
||||
// 这里是预留的API调用位置,例如:
|
||||
// const response = await fetch('/api/community-health-data');
|
||||
// const apiData = await response.json();
|
||||
// communityHealthData.value = apiData;
|
||||
|
||||
// 暂时保留默认数据,实际使用时替换为API返回的数据
|
||||
console.log('Fetching community health data from API...');
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch community health data:', error);
|
||||
}
|
||||
};
|
||||
|
||||
// 组件挂载时获取数据
|
||||
onMounted(() => {
|
||||
fetchDataFromApi();
|
||||
});
|
||||
|
||||
// 页面尺寸响应式
|
||||
const { widthType } = usePageResize();
|
||||
|
||||
// 空数据标识
|
||||
const isEmpty = computed(() => {
|
||||
return communityHealthData.value.indicators.length === 0 ||
|
||||
communityHealthData.value.github.length === 0 ||
|
||||
communityHealthData.value.gitcode.length === 0;
|
||||
});
|
||||
|
||||
// 图表实例存储(用于resize时销毁重绘)
|
||||
const chartInstances = ref<{ [key: string]: echarts.ECharts | null }>({
|
||||
communityHealthChart: null
|
||||
});
|
||||
|
||||
// 初始化社区治理健康度对比(纵向柱状图)
|
||||
const initCommunityHealthChart = () => {
|
||||
const el = document.getElementById('ossCompassChart');
|
||||
if (!el) return;
|
||||
|
||||
if (chartInstances.value.communityHealthChart) {
|
||||
chartInstances.value.communityHealthChart.dispose();
|
||||
}
|
||||
|
||||
const myChart = echarts.init(el);
|
||||
chartInstances.value.communityHealthChart = myChart;
|
||||
|
||||
const data = communityHealthData.value;
|
||||
|
||||
myChart.setOption({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
shadowStyle: {
|
||||
color: 'rgba(59, 130, 246, 0.1)'
|
||||
}
|
||||
},
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.98)',
|
||||
borderColor: '#3b82f6',
|
||||
borderWidth: 2,
|
||||
borderRadius: 8,
|
||||
padding: 16,
|
||||
textStyle: { color: '#333', fontSize: 13 },
|
||||
extraCssText: 'box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);',
|
||||
formatter: (params: any) => {
|
||||
const indicator = params[0].name;
|
||||
const githubValue = params[0].value;
|
||||
const gitcodeValue = params[1].value;
|
||||
const diff = githubValue - gitcodeValue;
|
||||
const diffPercent = ((diff / githubValue) * 100).toFixed(1);
|
||||
|
||||
return `
|
||||
<div style="line-height: 2.2;">
|
||||
<div style="font-weight: bold; color: #3b82f6; font-size: 15px; margin-bottom: 8px; border-bottom: 2px solid #3b82f6; padding-bottom: 4px;">${indicator}</div>
|
||||
<div style="display: flex; align-items: center; gap: 10px; margin-bottom: 6px;">
|
||||
<span style="display: inline-block; width: 10px; height: 10px; background: linear-gradient(135deg, #BF232A, #FF4900); border-radius: 50%; box-shadow: 0 2px 4px rgba(191, 35, 42, 0.3);"></span>
|
||||
<span style="color: #666; min-width: 100px;">GitHub 社区</span>
|
||||
<span style="color: #BF232A; font-weight: 700; font-size: 15px;">${githubValue}</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<span style="display: inline-block; width: 10px; height: 10px; background: linear-gradient(135deg, #FF4900, #FFAB00); border-radius: 50%; box-shadow: 0 2px 4px rgba(255, 73, 0, 0.3);"></span>
|
||||
<span style="color: #666; min-width: 100px;">GitCode 社区</span>
|
||||
<span style="color: #FF4900; font-weight: 700; font-size: 15px;">${gitcodeValue}</span>
|
||||
</div>
|
||||
${diff > 0 ? `<div style="margin-top: 8px; padding: 4px 8px; background: rgba(59, 130, 246, 0.1); border-radius: 4px; color: #3b82f6; font-size: 11px;">📊 GitHub 领先 ${diffPercent}%</div>` : ''}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: ['GitHub 社区', 'GitCode 社区'],
|
||||
top: '2%',
|
||||
right: '5%',
|
||||
itemWidth: 14,
|
||||
itemHeight: 14,
|
||||
itemGap: 15,
|
||||
textStyle: {
|
||||
color: '#333',
|
||||
fontSize: 12,
|
||||
fontWeight: '600'
|
||||
},
|
||||
icon: 'roundRect'
|
||||
},
|
||||
grid: {
|
||||
left: '5%',
|
||||
right: '5%',
|
||||
bottom: '8%',
|
||||
top: '15%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: data.indicators,
|
||||
axisLabel: {
|
||||
fontSize: 11,
|
||||
color: '#666',
|
||||
fontWeight: '500',
|
||||
interval: 0,
|
||||
rotate: 20,
|
||||
margin: 12
|
||||
},
|
||||
axisTick: {
|
||||
alignWithLabel: true,
|
||||
length: 5
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: { color: '#e5e7eb', width: 2 }
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
name: '健康度得分',
|
||||
nameTextStyle: {
|
||||
fontSize: 13,
|
||||
color: '#666',
|
||||
fontWeight: '600',
|
||||
padding: [0, 0, 0, 10]
|
||||
},
|
||||
max: 100,
|
||||
axisLabel: {
|
||||
fontSize: 12,
|
||||
color: '#666',
|
||||
formatter: '{value}'
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(0, 0, 0, 0.06)',
|
||||
type: 'dashed'
|
||||
}
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'GitHub 社区',
|
||||
type: 'bar',
|
||||
data: data.github,
|
||||
barWidth: '35%',
|
||||
itemStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
|
||||
{ offset: 0, color: '#FF4900' },
|
||||
{ offset: 0.5, color: '#BF232A' },
|
||||
{ offset: 1, color: '#BF232A' }
|
||||
]),
|
||||
borderRadius: [6, 6, 0, 0],
|
||||
shadowBlur: 10,
|
||||
shadowColor: 'rgba(191, 35, 42, 0.3)'
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
formatter: '{c}',
|
||||
fontSize: 11,
|
||||
color: '#BF232A',
|
||||
fontWeight: 'bold'
|
||||
},
|
||||
emphasis: {
|
||||
itemStyle: {
|
||||
shadowBlur: 20,
|
||||
shadowColor: 'rgba(191, 35, 42, 0.6)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'GitCode 社区',
|
||||
type: 'bar',
|
||||
data: data.gitcode,
|
||||
barWidth: '35%',
|
||||
itemStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
|
||||
{ offset: 0, color: '#FFAB00' },
|
||||
{ offset: 0.5, color: '#FF4900' },
|
||||
{ offset: 1, color: '#FF4900' }
|
||||
]),
|
||||
borderRadius: [6, 6, 0, 0],
|
||||
shadowBlur: 10,
|
||||
shadowColor: 'rgba(255, 73, 0, 0.3)'
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
formatter: '{c}',
|
||||
fontSize: 11,
|
||||
color: '#FF4900',
|
||||
fontWeight: 'bold'
|
||||
},
|
||||
emphasis: {
|
||||
itemStyle: {
|
||||
shadowBlur: 20,
|
||||
shadowColor: 'rgba(255, 73, 0, 0.6)'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
animationDuration: 1000,
|
||||
animationEasing: 'cubicOut',
|
||||
animationDelay: (idx: number) => idx * 80
|
||||
});
|
||||
};
|
||||
|
||||
// 监听数据变化,重新渲染图表
|
||||
watch(communityHealthData, () => {
|
||||
if (!isEmpty.value) {
|
||||
nextTick(() => {
|
||||
initCommunityHealthChart();
|
||||
});
|
||||
}
|
||||
}, { deep: true });
|
||||
|
||||
// 页面resize时重绘图表
|
||||
watch(widthType, () => {
|
||||
nextTick(() => {
|
||||
if (!isEmpty.value) {
|
||||
initCommunityHealthChart();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 挂载时初始化
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
if (!isEmpty.value) {
|
||||
initCommunityHealthChart();
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
|
||||
// 组件卸载时销毁图表实例
|
||||
onUnmounted(() => {
|
||||
if (chartInstances.value.communityHealthChart) {
|
||||
chartInstances.value.communityHealthChart.dispose();
|
||||
chartInstances.value.communityHealthChart = null;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 社区治理健康度对比图表卡片样式 - 从主页面复制 */
|
||||
.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.25rem;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.index-module__NV_5cW__chartCard::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(59, 130, 246, 0.05), transparent);
|
||||
transition: left 0.6s;
|
||||
}
|
||||
|
||||
.index-module__NV_5cW__chartCard:hover::before {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.index-module__NV_5cW__chartCard:hover {
|
||||
border-color: #3b82f64d;
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 8px 24px #0000001f;
|
||||
}
|
||||
|
||||
.index-module__NV_5cW__chartCard:hover .chartCard__title {
|
||||
color: #3b82f6;
|
||||
transform: scale(1.02);
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
/* 标题样式 - 从主页面复制 */
|
||||
.chartCard__title {
|
||||
color: #333;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 容器样式 - 从主页面复制 */
|
||||
.chartCard__container {
|
||||
width: 100%;
|
||||
height: 390px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 空数据显示样式 - 从主页面复制 */
|
||||
.num-empty {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 图表容器样式 */
|
||||
.chart {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -137,13 +137,7 @@
|
||||
<UniversityClubStatsChart />
|
||||
|
||||
<!-- 4. 社区治理健康度对比-->
|
||||
<div class="index-module__NV_5cW__chartCard">
|
||||
<h3 class="chartCard__title">社区治理健康度对比</h3>
|
||||
<div class="chartCard__container">
|
||||
<div class="num-empty" v-if="isEmpty.ossCompass"></div>
|
||||
<div v-else id="ossCompassChart" class="chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
<CommunityGovernanceHealthChart />
|
||||
|
||||
<!-- 5. 语言与技术竞争-->
|
||||
<div class="index-module__NV_5cW__chartCard">
|
||||
@@ -281,6 +275,7 @@ import * as echarts from 'echarts';
|
||||
import TalentMapChart from './TalentMapChart.vue'
|
||||
import InfrastructureCoverageChart from './components/InfrastructureCoverageChart.vue'
|
||||
import UniversityClubStatsChart from './components/UniversityClubStatsChart.vue'
|
||||
import CommunityGovernanceHealthChart from './components/CommunityGovernanceHealthChart.vue'
|
||||
import { usePageResize } from '@/utils/hooks/usePageResize';
|
||||
|
||||
// 页面尺寸响应式
|
||||
@@ -445,71 +440,8 @@ const chartData = ref({
|
||||
radius: ['30%', '40%']
|
||||
}
|
||||
],
|
||||
// 高校开源社团/俱乐部数据(来自 UniversityClubStatsChart.vue)
|
||||
universityClubs: [
|
||||
// 华东地区
|
||||
{ university: '上海交通大学', club: 'SJTU-LUG (Linux User Group)' },
|
||||
{ university: '上海交通大学', club: '开放原子开源俱乐部' },
|
||||
{ university: '复旦大学', club: 'Fudan LUG' },
|
||||
{ university: '复旦大学', club: '开放原子开源俱乐部' },
|
||||
{ university: '浙江大学', club: 'ZJU-LUG' },
|
||||
{ university: '浙江大学', club: 'AAA (Azure Availability Association)' },
|
||||
{ university: '浙江大学', club: '开放原子开源俱乐部' },
|
||||
{ university: '南京大学', club: 'NJU-LUG' },
|
||||
{ university: '南京大学', club: 'eScience 协会' },
|
||||
{ university: '南京大学', club: '开放原子开源俱乐部' },
|
||||
{ university: '中国科学技术大学', club: 'USTC-LUG' },
|
||||
{ university: '中国科学技术大学', club: 'VLAB' },
|
||||
{ university: '同济大学', club: 'Tongji LUG' },
|
||||
{ university: '同济大学', club: '开放原子开源俱乐部' },
|
||||
{ university: '华东师范大学', club: 'ECNU LUG' },
|
||||
// 华北地区
|
||||
{ university: '清华大学', club: 'TUNA (清华大学学生网络与开源软件协会)' },
|
||||
{ university: '清华大学', club: '开放原子开源俱乐部' },
|
||||
{ university: '北京大学', club: 'PKUOSC (北京大学开源软件协会)' },
|
||||
{ university: '北京大学', club: 'PKU-LUG' },
|
||||
{ university: '北京邮电大学', club: 'BYR Team' },
|
||||
{ university: '北京邮电大学', club: '开放原子开源俱乐部' },
|
||||
{ university: '北京航空航天大学', club: 'BUAA LUG' },
|
||||
{ university: '北京航空航天大学', club: '开放原子开源俱乐部' },
|
||||
{ university: '中国科学院大学', club: 'UCAS LUG' },
|
||||
{ university: '天津大学', club: 'TJU LUG' },
|
||||
{ university: '南开大学', club: 'NKU LUG' },
|
||||
{ university: '哈尔滨工业大学', club: 'HIT LUG' },
|
||||
{ university: '哈尔滨工业大学', club: '开放原子开源俱乐部' },
|
||||
// 华中/华南地区
|
||||
{ university: '华中科技大学', club: 'HUST LUG' },
|
||||
{ university: '华中科技大学', club: '联创团队' },
|
||||
{ university: '华中科技大学', club: '开放原子开源俱乐部' },
|
||||
{ university: '武汉大学', club: 'WHU LUG' },
|
||||
{ university: '武汉大学', club: '网络安全协会' },
|
||||
{ university: '中山大学', club: 'SYSU LUG' },
|
||||
{ university: '南方科技大学', club: 'SUSTech CRA' },
|
||||
{ university: '南方科技大学', club: '开放原子开源俱乐部' },
|
||||
{ university: '深圳大学', club: 'SZU LUG' },
|
||||
{ university: '深圳大学', club: '开放原子开源俱乐部' },
|
||||
// 西部/其他地区
|
||||
{ university: '电子科技大学', club: 'UESTC LUG' },
|
||||
{ university: '电子科技大学', club: '星辰工作室' },
|
||||
{ university: '电子科技大学', club: '开放原子开源俱乐部' },
|
||||
{ university: '四川大学', club: 'SCU LUG' },
|
||||
{ university: '西安电子科技大学', club: 'XDU LUG' },
|
||||
{ university: '西安电子科技大学', club: '开放原子开源俱乐部' },
|
||||
{ university: '兰州大学', club: 'LZU LUG' },
|
||||
{ university: '兰州大学', club: '开放原子开源俱乐部' },
|
||||
{ university: '重庆邮电大学', club: 'Redrock 团队' },
|
||||
{ university: '重庆邮电大学', club: 'LUG' },
|
||||
{ university: '湖南大学', club: 'HNU LUG' },
|
||||
{ university: '中南大学', club: 'CSU LUG' },
|
||||
{ university: '山东大学', club: 'SDU LUG' },
|
||||
{ university: '厦门大学', club: 'XMU LUG' }
|
||||
],
|
||||
// 社区治理健康度对比(来自 CommunityGovernanceHealth.vue)
|
||||
communityHealth: {
|
||||
indicators: ['PR 合并率', 'Issue 响应时间', 'CI/CD 使用率', '平均代码质量得分', '安全审计频率', '贡献者多样性'],
|
||||
github: [82, 88, 78, 85, 75, 80],
|
||||
gitcode: [68, 75, 55, 72, 60, 65]
|
||||
},
|
||||
|
||||
|
||||
// 语言与技术竞争(南丁格尔玫瑰图数据)
|
||||
languageTech: {
|
||||
// 主流语言数据(基于2025年数据,增长率为2024→2025的变化)
|
||||
@@ -539,7 +471,6 @@ const chartData = ref({
|
||||
|
||||
// 空数据标识
|
||||
const isEmpty = ref({
|
||||
communityHealth: false,
|
||||
languageTech: false
|
||||
});
|
||||
|
||||
@@ -607,7 +538,6 @@ const getTalentLevel = (density: number) => {
|
||||
|
||||
// 图表实例存储(用于resize时销毁重绘)
|
||||
const chartInstances = ref<{ [key: string]: echarts.ECharts | null }>({
|
||||
communityHealthChart: null,
|
||||
languageTechChart: null,
|
||||
vitalityChart: null,
|
||||
heatmapChart: null
|
||||
@@ -758,195 +688,6 @@ const formatDevs = (num: number) => {
|
||||
};
|
||||
// ===================== 新增结束 =====================
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 初始化社区治理健康度对比(纵向柱状图)
|
||||
const initCommunityHealthChart = () => {
|
||||
const el = document.getElementById('ossCompassChart');
|
||||
if (!el) return;
|
||||
|
||||
if (chartInstances.value.communityHealthChart) {
|
||||
chartInstances.value.communityHealthChart.dispose();
|
||||
}
|
||||
|
||||
const myChart = echarts.init(el);
|
||||
chartInstances.value.communityHealthChart = myChart;
|
||||
|
||||
const data = chartData.value.communityHealth;
|
||||
|
||||
myChart.setOption({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
shadowStyle: {
|
||||
color: 'rgba(59, 130, 246, 0.1)'
|
||||
}
|
||||
},
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.98)',
|
||||
borderColor: '#3b82f6',
|
||||
borderWidth: 2,
|
||||
borderRadius: 8,
|
||||
padding: 16,
|
||||
textStyle: { color: '#333', fontSize: 13 },
|
||||
extraCssText: 'box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);',
|
||||
formatter: (params: any) => {
|
||||
const indicator = params[0].name;
|
||||
const githubValue = params[0].value;
|
||||
const gitcodeValue = params[1].value;
|
||||
const diff = githubValue - gitcodeValue;
|
||||
const diffPercent = ((diff / githubValue) * 100).toFixed(1);
|
||||
|
||||
return `
|
||||
<div style="line-height: 2.2;">
|
||||
<div style="font-weight: bold; color: #3b82f6; font-size: 15px; margin-bottom: 8px; border-bottom: 2px solid #3b82f6; padding-bottom: 4px;">${indicator}</div>
|
||||
<div style="display: flex; align-items: center; gap: 10px; margin-bottom: 6px;">
|
||||
<span style="display: inline-block; width: 10px; height: 10px; background: linear-gradient(135deg, #BF232A, #FF4900); border-radius: 50%; box-shadow: 0 2px 4px rgba(191, 35, 42, 0.3);"></span>
|
||||
<span style="color: #666; min-width: 100px;">GitHub 社区</span>
|
||||
<span style="color: #BF232A; font-weight: 700; font-size: 15px;">${githubValue}</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<span style="display: inline-block; width: 10px; height: 10px; background: linear-gradient(135deg, #FF4900, #FFAB00); border-radius: 50%; box-shadow: 0 2px 4px rgba(255, 73, 0, 0.3);"></span>
|
||||
<span style="color: #666; min-width: 100px;">GitCode 社区</span>
|
||||
<span style="color: #FF4900; font-weight: 700; font-size: 15px;">${gitcodeValue}</span>
|
||||
</div>
|
||||
${diff > 0 ? `<div style="margin-top: 8px; padding: 4px 8px; background: rgba(59, 130, 246, 0.1); border-radius: 4px; color: #3b82f6; font-size: 11px;">📊 GitHub 领先 ${diffPercent}%</div>` : ''}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: ['GitHub 社区', 'GitCode 社区'],
|
||||
top: '2%',
|
||||
right: '5%',
|
||||
itemWidth: 14,
|
||||
itemHeight: 14,
|
||||
itemGap: 15,
|
||||
textStyle: {
|
||||
color: '#333',
|
||||
fontSize: 12,
|
||||
fontWeight: '600'
|
||||
},
|
||||
icon: 'roundRect'
|
||||
},
|
||||
grid: {
|
||||
left: '5%',
|
||||
right: '5%',
|
||||
bottom: '8%',
|
||||
top: '15%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: data.indicators,
|
||||
axisLabel: {
|
||||
fontSize: 11,
|
||||
color: '#666',
|
||||
fontWeight: '500',
|
||||
interval: 0,
|
||||
rotate: 20,
|
||||
margin: 12
|
||||
},
|
||||
axisTick: {
|
||||
alignWithLabel: true,
|
||||
length: 5
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: { color: '#e5e7eb', width: 2 }
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
name: '健康度得分',
|
||||
nameTextStyle: {
|
||||
fontSize: 13,
|
||||
color: '#666',
|
||||
fontWeight: '600',
|
||||
padding: [0, 0, 0, 10]
|
||||
},
|
||||
max: 100,
|
||||
axisLabel: {
|
||||
fontSize: 12,
|
||||
color: '#666',
|
||||
formatter: '{value}'
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(0, 0, 0, 0.06)',
|
||||
type: 'dashed'
|
||||
}
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'GitHub 社区',
|
||||
type: 'bar',
|
||||
data: data.github,
|
||||
barWidth: '35%',
|
||||
itemStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
|
||||
{ offset: 0, color: '#FF4900' },
|
||||
{ offset: 0.5, color: '#BF232A' },
|
||||
{ offset: 1, color: '#BF232A' }
|
||||
]),
|
||||
borderRadius: [6, 6, 0, 0],
|
||||
shadowBlur: 10,
|
||||
shadowColor: 'rgba(191, 35, 42, 0.3)'
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
formatter: '{c}',
|
||||
fontSize: 11,
|
||||
color: '#BF232A',
|
||||
fontWeight: 'bold'
|
||||
},
|
||||
emphasis: {
|
||||
itemStyle: {
|
||||
shadowBlur: 20,
|
||||
shadowColor: 'rgba(191, 35, 42, 0.6)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'GitCode 社区',
|
||||
type: 'bar',
|
||||
data: data.gitcode,
|
||||
barWidth: '35%',
|
||||
itemStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
|
||||
{ offset: 0, color: '#FFAB00' },
|
||||
{ offset: 0.5, color: '#FF4900' },
|
||||
{ offset: 1, color: '#FF4900' }
|
||||
]),
|
||||
borderRadius: [6, 6, 0, 0],
|
||||
shadowBlur: 10,
|
||||
shadowColor: 'rgba(255, 73, 0, 0.3)'
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
formatter: '{c}',
|
||||
fontSize: 11,
|
||||
color: '#FF4900',
|
||||
fontWeight: 'bold'
|
||||
},
|
||||
emphasis: {
|
||||
itemStyle: {
|
||||
shadowBlur: 20,
|
||||
shadowColor: 'rgba(255, 73, 0, 0.6)'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
animationDuration: 1000,
|
||||
animationEasing: 'cubicOut',
|
||||
animationDelay: (idx: number) => idx * 80
|
||||
});
|
||||
};
|
||||
|
||||
// 根据增长率动态生成颜色的函数
|
||||
const getColorByGrowth = (growth: number, tab: string) => {
|
||||
const minGrowth = -5;
|
||||
@@ -1768,12 +1509,10 @@ const initHeatmapChart = () => {
|
||||
const initCharts = () => {
|
||||
// 空数据判断
|
||||
isEmpty.value = {
|
||||
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.communityHealth) nextTick(() => initCommunityHealthChart());
|
||||
if (!isEmpty.value.languageTech) nextTick(() => initLanguageTechChart());
|
||||
nextTick(() => initVitalityChart());
|
||||
nextTick(() => initHeatmapChart());
|
||||
@@ -2807,8 +2546,6 @@ onMounted(() => {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 热力图特殊样式 */
|
||||
.heatmap-section {
|
||||
position: relative;
|
||||
|
||||
Reference in New Issue
Block a user