Files
hellogithub-vue/src/components/Ranking/Ranking.vue
2023-07-10 10:36:46 +08:00

538 lines
20 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div style="display:flex;flex-direction:row;flex-wrap: nowrap">
<div style="display: flex;flex-direction:column;flex-wrap: nowrap">
<div class="PageHeader">
<br/>
<el-page-header @back="goBack" style="justify-content:left;display: flex;">
<div slot="title" style="font-size:23px;font-weight: 600;"></div>
<div slot="content" class="test" style="font-size:23px;font-weight: 600;">
<div>{{TitleWord}}</div>
</div>
</el-page-header>
</div>
<div class="PageContent" style="display: flex;flex-direction: column;flex-wrap: nowrap">
<el-card class="box-card">
<div style="display: flex;flex-direction: row;flex-wrap: nowrap;justify-content: space-between">
<el-cascader @change="FreshPage(selectedValue,1)" v-model="selectedValue" :options="options" placeholder="选择分类"
:show-all-levels="false" style="width: 10vw"></el-cascader>
<el-image fit="fill" :src="require('@/assets/svg/logo-tiobe.svg')" style="width:8vw;height: 4vh;display: flex;flex-direction: row;justify-content: flex-end"></el-image>
<el-select @change="FreshPage(selectedValue,2)" placeholder="选择年份" v-model="selectedValueByYear" style="width: 7vw" :disabled="ban">
<el-option
v-for="(n,index) in 12"
:key="index"
:label="index + 2012"
:value="index"
>
</el-option>
</el-select>
</div>
</el-card>
<el-card class="box-card" style="margin-top: 20px">
<el-switch
ref="switch"
@change="FreshPage(selectedValue,0)"
style="margin-left:75%"
v-model="value1"
:active-text=activeWord
:inactive-text=inactiveWord>
</el-switch>
<div ref="totalContent" style="margin-top:10px">
<el-row :gutter="24" style="margin-top:20px;">
<el-col :span="20" style="margin-left:10%">
<el-card shadow="always">
<span style="font-size:30px;font-weight:600">GitHub官网数据整理</span>
</el-card>
</el-col>
</el-row>
<el-table
border
class="DataForm"
:data="showData"
style="margin-top:50px;width:500px;margin-left:20%;"
:header-row-style="{height:'15px'}" :cell-style="{padding:'1px'}">
<el-table-column
prop="name"
:label=formName[0]
>
</el-table-column>
<el-table-column
prop="count"
:label=formName[1]
>
</el-table-column>
</el-table>
</div>
<!-- <el-button @click="test()"></el-button>-->
<el-row :gutter="24" style="margin-top:20px;">
<el-col :span="20" style="margin-left:10%">
<el-card shadow="always">
<span style="font-size:30px;font-weight:600">GitHub官网数据统计图</span>
</el-card>
</el-col>
</el-row>
<div ref="EChart" style="margin-left:20px;width: 700px;height:700px;margin-top:20px"></div>
</el-card>
</div>
</div>
<RightTools></RightTools>
</div>
</template>
<script>
import RightTools from "@/components/Home/RightTools.vue";
import axios from 'axios'; // 安装axios后引入
import Vue from "vue";
Vue.prototype.$axios = axios; // 将axios挂载到原型上方便使用
import * as echarts from 'echarts'
Vue.prototype.$echarts = echarts;
export default {
name: "RankingComponent",
components: {RightTools},
data(){
return{
// 标头文字:
TitleWord:'GitHub星数年度排行榜',
// 开关文本:
activeWord:'月度趋势',
inactiveWord:'年度统计',
// 禁用年份选择:
ban:false,
// echart图
manuChart:null,
// Echart图options
MyOption:{},
// 最后展示数据:
showData:[],
// 数据表格表头:
formName:[],
// 星数数据:
starNum:[],
// 项目拉取数:
pullNum:[],
// 推送项目数:
pushNum:[],
// 协议数:
licensesNum:[],
// 榜单分类目录:
options:[{
value: '1',
label: '编程语言',
children:[{
value:'2',
label:'星数',
}, {
value:'3',
label:'推送项目数'
},
{
value:'4',
label:'拉取项目数',
}
]
},{
value:'5',
label:'协议种类'
}
],
value1: false,
// 默认用户选择的分类
selectedValue:['1','2'],
selectedValueByYear:null,
}
},
updated(){
// history.go(0);
},
created() {
// 使用getjson读取数据
var that = this;
this.$axios.get("/gh-star-event.json").then(res => {
that.starNum = res.data;
})
this.$axios.get("/gh-push-event.json").then(res => {
that.pushNum = res.data;
})
this.$axios.get("/gh-pull-request.json").then(res => {
that.pullNum = res.data;
})
this.$axios.get("/github-licenses.json").then(res => {
that.licensesNum = res.data;
})
},
mounted() {
this.initPage();
},
methods: {
goBack() {
window.history.go(-1);
},
test(){
console.log(this.showData);
},
// 用户改变分类榜单时,刷新页面:
initPage(){
var that = this;
that.formName=['语言种类','获得星数'];
that.activeWord='月度趋势';
that.inactiveWord='年度统计';
that.ban=false;
that.showData = [];
this.manuChart = this.$echarts.init(this.$refs.EChart);
// this.getNumData(2023,false);
},
FreshPage(type,index){
var that = this;
that.ban=false;
if(index == 1) {
that.selectedValueByYear = 11;
that.value1 = false;
this.$refs.totalContent.style.display = 'block';
}
if(index == 1 || index == 2 || index == 0 && that.selectedValueByYear != null){
if(that.value1 == false && index == 0) this.$refs.totalContent.style.display = 'block';
type = type[type.length-1] - 1;
let year = that.selectedValueByYear + 2012;
if(type == 1){
// 按星数统计:
this.getNumData(year,that.value1,that.starNum);
that.formName=['语言种类','获得星数']
that.activeWord='月度趋势';
that.inactiveWord='年度统计';
that.TitleWord='GitHub星数年度排行榜';
}else if(type == 2){
this.getNumData(year,that.value1,that.pushNum);
that.formName=['语言种类','推送项目数']
that.activeWord='月度趋势';
that.inactiveWord='年度统计';
that.TitleWord='GitHub推送数年度排行榜';
}else if(type == 3){
this.getNumData(year,that.value1,that.pullNum);
that.formName=['语言种类','用户拉取项目数']
that.activeWord='月度趋势';
that.inactiveWord='年度统计';
that.TitleWord='GitHub拉取数年度排行榜';
}else if(type == 4){
this.getLiscenseData(that.value1);
that.formName=['协议种类','项目数']
that.activeWord='各协议占比';
that.inactiveWord='数据总览';
that.TitleWord='GitHub协议年度排行榜';
that.ban=true;
}
}
if(index == 0 && that.selectedValueByYear == null){
this.$message({
message: '请先选择年份!',
type: 'warning',
offset:100,
duration:500,
});
// 不让修改:
if(that.value1 == false) that.value1 = true;
if(that.value1 == true) that.value1 = false;
}
},
// 语言分类的数据:
getNumData(year,index,Mydata){
function compare(property) {
return function (a, b) {
var value1 = a[property];
var value2 = b[property];
return value2 - value1;
}
}
var that = this;
that.showData = [];
let starNum2 = Mydata.filter(item => item['year'] == year);
if(index == false){
let tmp = [];
// 按年度统计:
for(let i=0;i<starNum2.length;i++){
let tmpObj = {name:starNum2[i].name,count:starNum2[i].count};
let findSignal = tmp.findIndex(item=>item['name'] == tmpObj['name']);
if (findSignal != -1){
tmp[findSignal]['count'] = parseInt(tmp[findSignal]['count']) + parseInt(tmpObj['count']);
}else{
tmp.push(tmpObj);
}
}
that.showData = tmp.slice(0,18);
that.showData = that.showData.sort(compare('count'));
this.getRenderer();
}else{
// 按月度统计:
this.$refs.totalContent.style.display = 'none';
let quarterItems = [];
for(let i=0;i<15;i++){
// 初始化数据模板
let tmpName = starNum2[i].name;
let tmpcount = starNum2[i].count;
let Quarter = parseInt(starNum2[i]['quarter']) - 1;
//对应该四个月的数量
let monthCount = [0,0,0,0];
// 应该存入的对应季度数组下标quarterItems[starNum2[i]['quarter']]
if(that.selectedValueByYear == 11){
monthCount = monthCount.fill(tmpcount);
}else{
monthCount[Quarter] = tmpcount;
}
//创建该折线数据对象
let tmpObj = {'name':tmpName,'type':'line','data':monthCount};
quarterItems.push(tmpObj);
}
for(let j=15;j<starNum2.length;j++){
if(that.selectedValueByYear == 2023) break;
let tmpName = starNum2[j].name;
let tmpcount = starNum2[j].count;
let Quarter = parseInt(starNum2[j]['quarter']) - 1;
let LastQ = parseInt(Quarter) - 1;
let findSignal = quarterItems.findIndex(item=>item['name'] == tmpName);
if(findSignal != -1){
let p = parseInt(quarterItems[findSignal]['data'][parseInt(LastQ)]);
quarterItems[findSignal]['data'][Quarter] = p + parseInt(tmpcount);
}
}
that.showData = quarterItems;
this.getLineChart();
}
},
getLiscenseData(index){
var that = this;
that.showData = that.licensesNum;
that.showData = JSON.parse(JSON.stringify(that.showData).replace(/license/g,"name"));
that.showData = JSON.parse(JSON.stringify(that.showData).replace(/count/g,"count"))
if(index == false){
this.getRendererLiscense();
}if(index == true){
this.$refs.totalContent.style.display = 'none';
this.getPie();
}
},
// 饼图:
getPie(){
var that = this;
let tmp = that.licensesNum;
tmp = JSON.parse(JSON.stringify(tmp).replace(/license/g,"name"));
tmp = JSON.parse(JSON.stringify(tmp).replace(/count/g,"value"))
that.MyOption = {
tooltip: {
trigger: 'item', //item数据项图形触发主要在散点图饼图等无类目轴的图表中使用。
axisPointer: {
// 坐标轴指示器,坐标轴触发有效
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
},
formatter: '{a} <br/>{b} 协议项目 : {c} 个 <br/>百分比 : {d}%' //{a}(系列名称),{b}(数据项名称),{c}(数值), {d}(百分比)
},
series: [{
name:'协议数据',
type: 'pie',
data: tmp,
label: {//饼图文字的显示
show: true, //默认 显示文字
formatter: function (arg) {
return arg.name + ' 项目 ' + arg.value + " 个 " +'\n'+ arg.percent + "%"
}
},
radius: 220 //饼图的半径
}],
grid: {
x: '18%',
y: 0,
x2: '10%',
y2: 0
},
dataZoom: {
yAxisIndex: [0],
type:'inside',
start: 0,
end: 100,
zoomLock:true,
}
};
that.manuChart.setOption(that.MyOption,true);
},
// 横向柱状图(协议种类)
getRendererLiscense() {
var that = this;
let name = [];
let value = [];
for(let i=0;i < that.showData.length;i++){
name.push(that.showData[i]['name']);
value.push(that.showData[i]['count']);
}
that.MyOption = {
tooltip: {
trigger: "axis"
},
xAxis: {
type: 'value',
min: 0,
axisLabel : {
show : false
},
splitLine : {
show : false
}
},
yAxis: {
type: 'category',
inverse: true,
axisTick : {
show : false
},
axisLine:{
show : false
},
data: name,
},
series: [{
name: '项目总数',
type: 'bar',
barWidth:13,
data: value,
label: {
show: true,
position: 'right'
}
}],
grid: {
x: '18%',
y: 0,
x2: '10%',
y2: 0
},
dataZoom: {
yAxisIndex: [0],
type:'inside',
start: 0,
end: 100,
zoomLock:true,
}
};
that.manuChart.setOption(that.MyOption,true);
},
// 横向柱状图(编程语言)
getRenderer() {
var that = this;
let name = [];
let value = [];
for(let i=0;i < that.showData.length;i++){
name.push(that.showData[i]['name']);
value.push(that.showData[i]['count']);
}
that.MyOption = {
tooltip: {
trigger: "axis"
},
xAxis: {
type: 'value',
min: 0,
axisLabel : {
show : false
},
splitLine : {
show : false
}
},
yAxis: {
type: 'category',
inverse: true,
axisTick : {
show : false
},
axisLine:{
show : false
},
data: name,
},
series: [{
name: '获取星数',
type: 'bar',
barWidth:13,
data: value,
label: {
show: true,
position: 'right'
}
}],
grid: {
x: '18%',
y: 0,
x2: '10%',
y2: 0
},
dataZoom: {
yAxisIndex: [0],
type:'inside',
start: 0,
end: 100,
zoomLock:true,
}
};
that.manuChart.setOption(that.MyOption,true);
},
//折线图:
getLineChart(){
var that = this;
let month = ['第一季度','第二季度','第三季度','第四季度'];
let dic = [];
for (let i = 0;i<15;i++){
dic.push(that.showData[i]['name']);
}
that.MyOption={
tooltip: {
trigger: 'axis'
},
legend: {
data: dic//图例
},
grid: {
left: '3%',
right: '4%',
top:'20%',
containLabel: true
},
// toolbox: {
// feature: {
// saveAsImage: {}
// }
// },
xAxis: {//横坐标
name: "季度",
type: 'category',
boundaryGap: false,
data: month
},
yAxis: {
name: "数量",
type: 'value'
},
//三条折线就有三种series可以更改type以改变是否为折线
series: that.showData
};
that.manuChart.setOption(that.MyOption,true);
}
},
}
</script>
<style scoped lang="scss">
::v-deep .el-page-header__left{
left:10px;
}
::v-deep .el-page-header__content{
flex:1;
}
.el-card{
border: none;
}
</style>