diff --git a/src/views/Jyh/ecosystem/components/VitalityWaveChart.vue b/src/views/Jyh/ecosystem/components/VitalityWaveChart.vue new file mode 100644 index 0000000..6f5ea91 --- /dev/null +++ b/src/views/Jyh/ecosystem/components/VitalityWaveChart.vue @@ -0,0 +1,371 @@ + + + + + \ No newline at end of file diff --git a/src/views/Jyh/ecosystem/index.vue b/src/views/Jyh/ecosystem/index.vue index b644624..68bc067 100644 --- a/src/views/Jyh/ecosystem/index.vue +++ b/src/views/Jyh/ecosystem/index.vue @@ -186,18 +186,7 @@ -
-

- - - - 开发者活力波形图 -

-
-
-
-
+
@@ -276,6 +265,7 @@ import TalentMapChart from './TalentMapChart.vue' import InfrastructureCoverageChart from './components/InfrastructureCoverageChart.vue' import UniversityClubStatsChart from './components/UniversityClubStatsChart.vue' import CommunityGovernanceHealthChart from './components/CommunityGovernanceHealthChart.vue' +import VitalityWaveChart from './components/VitalityWaveChart.vue' import { usePageResize } from '@/utils/hooks/usePageResize'; // 页面尺寸响应式 @@ -477,12 +467,7 @@ const isEmpty = ref({ // 语言图表Tab状态 const languageTab = ref<'mainstream' | 'emerging'>('mainstream'); -// 开发者活力数据 -const vitalityData = ref({ - timeData: ["2014", "2015", "2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024"], - total: [20, 50, 100, 200, 300, 400, 600, 800, 1000, 1200, 1350], - new: [20, 30, 50, 100, 100, 100, 200, 200, 200, 200, 150] -}); + // 开源项目热力图数据 [OpenRank, 活跃仓库数, 活跃开发者数, 项目名称, 所属组织] const heatmapData = ref([ @@ -539,7 +524,6 @@ const getTalentLevel = (density: number) => { // 图表实例存储(用于resize时销毁重绘) const chartInstances = ref<{ [key: string]: echarts.ECharts | null }>({ languageTechChart: null, - vitalityChart: null, heatmapChart: null }); @@ -987,232 +971,7 @@ const changeLanguageTab = () => { initLanguageTechChart(); }; -// 初始化开发者活力波形图 -const initVitalityChart = () => { - const el = document.getElementById('vitalityChart'); - if (!el) return; - if (chartInstances.value.vitalityChart) { - chartInstances.value.vitalityChart.dispose(); - } - - const myChart = echarts.init(el); - chartInstances.value.vitalityChart = myChart; - - myChart.setOption({ - tooltip: { - trigger: 'axis', - axisPointer: { - type: 'cross', - crossStyle: { - color: '#999', - width: 1, - type: 'dashed' - }, - lineStyle: { - color: '#3b82f6', - width: 1, - type: 'dashed' - } - }, - backgroundColor: 'rgba(255, 255, 255, 0.98)', - borderColor: '#10b981', - borderWidth: 2, - borderRadius: 8, - padding: 16, - textStyle: { color: '#333', fontSize: 14 }, - extraCssText: 'box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);', - formatter: (params: any) => { - if (!Array.isArray(params) || params.length === 0) { - return '
暂无数据
'; - } - const totalItem = params.find((item: any) => item.seriesName === '累计开发者'); - const newItem = params.find((item: any) => item.seriesName === '年度新增'); - const totalValue = totalItem?.value || 0; - const newValue = newItem?.value || 0; - const time = totalItem?.axisValue || newItem?.axisValue || '未知时间'; - - // 计算增长率 - const prevIndex = vitalityData.value.timeData.indexOf(time) - 1; - let growthRate = 0; - if (prevIndex >= 0) { - const prevTotal = vitalityData.value.total[prevIndex]; - growthRate = ((totalValue - prevTotal) / prevTotal * 100).toFixed(1); - } - - return ` -
-
📅 ${time}年
-
- - 累计开发者:${totalValue} 万人 -
-
- - 年度新增:${newValue} 万人 -
- ${growthRate > 0 ? `
📈 同比增长 ${growthRate}%
` : ''} -
- `; - } - }, - legend: { - left: 'center', - top: '0%', - itemWidth: 16, - itemHeight: 16, - itemGap: 20, - textStyle: { color: '#333', fontSize: 14, fontWeight: '600' }, - data: ['累计开发者', '年度新增'], - icon: 'roundRect', - borderRadius: 4 - }, - grid: { - top: '18%', - left: '3%', - right: '4%', - bottom: '8%', - containLabel: true - }, - xAxis: { - type: 'category', - boundaryGap: false, - axisTick: { show: false }, - axisLine: { - lineStyle: { color: '#e5e7eb', width: 2 }, - onZero: false - }, - axisLabel: { - color: '#666', - fontSize: 13, - fontWeight: '500', - interval: 0, - margin: 12 - }, - data: vitalityData.value.timeData - }, - yAxis: { - type: 'value', - name: '开发者数量(万人)', - nameTextStyle: { color: '#666', fontSize: 12 }, - axisLabel: { color: '#666', fontSize: 12 }, - splitLine: { - show: true, - lineStyle: { color: 'rgba(0, 0, 0, 0.06)', type: 'dashed' } - } - }, - series: [ - { - name: '累计开发者', - type: 'line', - smooth: true, - symbol: 'circle', - symbolSize: 8, - lineStyle: { color: '#10b981', width: 3 }, - itemStyle: { - color: '#10b981', - borderWidth: 2, - borderColor: '#fff' - }, - areaStyle: { - color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ - { offset: 0, color: 'rgba(16, 185, 129, 0.4)' }, - { offset: 1, color: 'rgba(16, 185, 129, 0.05)' } - ]), - shadowBlur: 10, - shadowColor: 'rgba(16, 185, 129, 0.2)' - }, - data: vitalityData.value.total, - emphasis: { - itemStyle: { - shadowBlur: 20, - shadowColor: 'rgba(16, 185, 129, 0.6)', - scale: 1.2 - }, - label: { - show: true, - formatter: '{c} 万', - position: 'top', - color: '#10b981', - fontSize: 13, - fontWeight: 'bold' - } - }, - markPoint: { - data: [ - { - type: 'max', name: '最大值', - itemStyle: { color: '#10b981' }, - label: { - color: '#fff', - fontSize: 12, - fontWeight: 'bold' - } - } - ], - symbolSize: 60 - }, - markLine: { - silent: true, - lineStyle: { - color: '#10b981', - type: 'dashed', - width: 1 - }, - label: { - color: '#10b981', - fontSize: 11 - }, - data: [{ type: 'average', name: '平均值' }] - } - }, - { - name: '年度新增', - type: 'bar', - barWidth: '40%', - itemStyle: { - color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ - { offset: 0, color: '#f59e0b' }, - { offset: 1, color: '#fbbf24' } - ]), - borderRadius: [4, 4, 0, 0], - shadowBlur: 8, - shadowColor: 'rgba(245, 158, 11, 0.3)' - }, - data: vitalityData.value.new, - emphasis: { - itemStyle: { - shadowBlur: 20, - shadowColor: 'rgba(245, 158, 11, 0.6)' - }, - label: { - show: true, - formatter: '{c} 万', - position: 'top', - color: '#f59e0b', - fontSize: 12, - fontWeight: 'bold' - } - }, - markPoint: { - data: [ - { - type: 'max', name: '峰值', - itemStyle: { color: '#f59e0b' }, - label: { - color: '#fff', - fontSize: 12, - fontWeight: 'bold' - } - } - ], - symbolSize: 60 - }, - animationDelay: (idx: number) => idx * 50 - } - ] - }); -}; // 初始化开源项目热力图 const initHeatmapChart = () => { @@ -1514,7 +1273,6 @@ const initCharts = () => { // 初始化各图表 if (!isEmpty.value.languageTech) nextTick(() => initLanguageTechChart()); - nextTick(() => initVitalityChart()); nextTick(() => initHeatmapChart()); };