forked from Gitlink/forgeplus-react
个人中心整体上线
This commit is contained in:
parent
a9285f37e7
commit
1432afebfd
|
@ -5075,6 +5075,11 @@
|
|||
"zrender": "4.3.2"
|
||||
}
|
||||
},
|
||||
"echarts-wordcloud": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npm.taobao.org/echarts-wordcloud/download/echarts-wordcloud-2.0.0.tgz?cache=0&sync_timestamp=1610779172014&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fecharts-wordcloud%2Fdownload%2Fecharts-wordcloud-2.0.0.tgz",
|
||||
"integrity": "sha1-Uu+BeJWAH/6emd0brKt2hrLewEo="
|
||||
},
|
||||
"editor.md": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/editor.md/-/editor.md-1.5.0.tgz",
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
"dotenv": "4.0.0",
|
||||
"dotenv-expand": "4.2.0",
|
||||
"echarts": "^4.9.0",
|
||||
"echarts-wordcloud": "^2.0.0",
|
||||
"editor.md": "^1.5.0",
|
||||
"eslint": "4.10.0",
|
||||
"eslint-config-react-app": "^2.1.0",
|
||||
|
|
|
@ -161,9 +161,7 @@
|
|||
height: 7px;
|
||||
margin-top: 12px;
|
||||
span{
|
||||
border-left: 1px solid #fff;
|
||||
&:first-child{
|
||||
border-left: none;
|
||||
border-radius: 10px 0px 0px 10px;
|
||||
}
|
||||
&:last-child{
|
||||
|
|
|
@ -4,12 +4,14 @@ import Js2WordCloud from 'js2wordcloud/dist/js2wordcloud.js'
|
|||
function Cloud({data}) {
|
||||
|
||||
useEffect(()=>{
|
||||
optionChart1();
|
||||
},[])
|
||||
if(data){
|
||||
optionChart1(data);
|
||||
}
|
||||
},[data])
|
||||
|
||||
function optionChart1(){
|
||||
function optionChart1(d){
|
||||
var div = new Js2WordCloud(document.getElementById('cloud'))
|
||||
let textList=['服务', '细致', '意识', '踏实','开发', '反馈']
|
||||
let textList= d.categories;
|
||||
let cyList=[]
|
||||
for(let i=0;i<textList.length;i++){
|
||||
cyList.push([textList[i],textList.length-i])
|
||||
|
@ -21,7 +23,7 @@ function Cloud({data}) {
|
|||
maxFontSize: 21,//最大字号
|
||||
minFontSize: 16,//最小字号
|
||||
tooltip: {
|
||||
show: true
|
||||
show: false
|
||||
},
|
||||
list: cyList,
|
||||
color(word, weight, fontSize, distance, theta) { //自定义颜色、透明度
|
||||
|
@ -43,7 +45,7 @@ function Cloud({data}) {
|
|||
})
|
||||
}
|
||||
return(
|
||||
<div id="cloud" style={{height:"200px"}}></div>
|
||||
<div id="cloud" style={{height:"120px"}}></div>
|
||||
)
|
||||
}
|
||||
export default Cloud;
|
|
@ -3,32 +3,27 @@ import echarts from 'echarts/lib/echarts';
|
|||
import 'echarts/lib/chart/pie';
|
||||
|
||||
function Pie({data}) {
|
||||
useEffect(()=>{
|
||||
Init();
|
||||
},[])
|
||||
|
||||
useEffect(()=>{
|
||||
if(data){
|
||||
Init();
|
||||
Init(data);
|
||||
}
|
||||
},[data])
|
||||
|
||||
function Init() {
|
||||
function Init(d) {
|
||||
var huan_val = document.getElementById("Pie");
|
||||
var chart = echarts.init(huan_val);
|
||||
let option = {
|
||||
color: ["#f8e367", "#99dfff", "#58c0f0", "#5ea6ff", "#ff9e48", "#bcbcbc"],
|
||||
color: ["#f8e367", "#5ea6ff", "#ff9e48", "#99dfff"],
|
||||
title: {
|
||||
text: '角色定位',
|
||||
top:"5%",
|
||||
left:"3%"
|
||||
show:false
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
legend: {
|
||||
top: '5%',
|
||||
right: '3%'
|
||||
right: 'center'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
|
@ -56,11 +51,10 @@ function Pie({data}) {
|
|||
show: false
|
||||
},
|
||||
data: [
|
||||
{value: 1048, name: '搜索引擎'},
|
||||
{value: 735, name: '直接访问'},
|
||||
{value: 580, name: '邮件营销'},
|
||||
{value: 484, name: '联盟广告'},
|
||||
{value: 300, name: '视频广告'}
|
||||
{value: d.developer && d.developer.count, name: '开发者'},
|
||||
{value: d.manager && d.manager.count, name: '管理员'},
|
||||
{value: d.owner && d.owner.count, name: '创建者'},
|
||||
{value: d.reporter && d.reporter.count, name: '报告者'}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
@ -3,54 +3,51 @@ import echarts from 'echarts/lib/echarts'
|
|||
import 'echarts/lib/chart/radar';
|
||||
|
||||
function Radar({data}) {
|
||||
useEffect(()=>{
|
||||
Init();
|
||||
},[])
|
||||
|
||||
useEffect(()=>{
|
||||
if(data){
|
||||
Init();
|
||||
Init(data);
|
||||
}
|
||||
},[data])
|
||||
|
||||
function Init() {
|
||||
function Init(d) {
|
||||
var huan_val = document.getElementById("radar");
|
||||
var myEcharts = echarts.init(huan_val);
|
||||
let option = {
|
||||
color: ["#f8e367", "#99dfff", "#58c0f0", "#5ea6ff", "#ff9e48", "#bcbcbc"],
|
||||
title: {
|
||||
text: '开发能力',
|
||||
top:"0",
|
||||
left:"3%"
|
||||
show:false
|
||||
},
|
||||
legend: {
|
||||
data: ['预算分配', '实际开销'],
|
||||
top:"0",
|
||||
data: ['个人能力(personal)', '社区平均(average)'],
|
||||
top:"3%",
|
||||
right:"center"
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
radar: {
|
||||
// shape: 'circle',
|
||||
indicator: [
|
||||
{ name: '销售', max: 6500},
|
||||
{ name: '管理', max: 16000},
|
||||
{ name: '信息技术', max: 30000},
|
||||
{ name: '客服', max: 38000},
|
||||
{ name: '研发', max: 52000},
|
||||
{ name: '市场', max: 25000}
|
||||
{ name: '影响力', max: 100},
|
||||
{ name: '贡献度', max: 100},
|
||||
{ name: '活跃度', max: 100},
|
||||
{ name: '项目经验', max: 100},
|
||||
{ name: '语言能力', max: 100},
|
||||
],
|
||||
center:["50%","55%"]
|
||||
},
|
||||
series: [{
|
||||
name: '预算 vs 开销',
|
||||
name: '',
|
||||
type: 'radar',
|
||||
data: [
|
||||
{
|
||||
value: [4200, 3000, 20000, 35000, 50000, 18000],
|
||||
name: '预算分配'
|
||||
value: d.user && [d.user.influence, d.user.contribution, d.user.activity, d.user.experience, d.user.language],
|
||||
name: '个人能力(personal)'
|
||||
},
|
||||
{
|
||||
value: [5000, 14000, 28000, 26000, 42000, 21000],
|
||||
name: '实际开销'
|
||||
value: d.platform && [d.platform.influence, d.platform.contribution, d.platform.activity, d.platform.experience, d.platform.language],
|
||||
name: '社区平均(average)'
|
||||
}
|
||||
]
|
||||
}]
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
import React from 'react';
|
||||
import './style.scss';
|
||||
|
||||
|
||||
function Round({num,color,name}) {
|
||||
return(
|
||||
<div className={"annulusBasics"}>
|
||||
<div className={"centerCircle"} style={{color:`${color}`}}>
|
||||
<span><span className="score">{num}</span>分</span>
|
||||
<span>{name}</span>
|
||||
</div>
|
||||
<div className={"annulusOuter"} style={{border:`7px solid ${color}`}}></div>
|
||||
{num > 50 ?
|
||||
<div className={"leftRectangle"} style={{ transform: `rotate(${180/50 *(num - 50)}deg)` }}></div>
|
||||
:
|
||||
<div className={"leftRectangle"} ></div>
|
||||
}
|
||||
{num < 50 ?
|
||||
<div className={"rightRectangle"} style={{ transform: `rotate(${180/50 * num}deg)` }}></div>
|
||||
:
|
||||
<div className={"rightRectangle"} style={{ background: color }}></div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Round;
|
|
@ -0,0 +1,69 @@
|
|||
.annulusBasics {
|
||||
width : 74px;
|
||||
height : 74px;
|
||||
position : relative;
|
||||
overflow : hidden;
|
||||
border-radius: 50%;
|
||||
text-align : center;
|
||||
z-index : 1;
|
||||
}
|
||||
//圆环中间的白色
|
||||
.centerCircle {
|
||||
position : absolute;
|
||||
z-index : 10;
|
||||
border-radius: 50%;
|
||||
width : 60px;
|
||||
height : 60px;
|
||||
background : #fff;
|
||||
transform : translate(7px, 7px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
line-height: 20px;
|
||||
font-size: 12px;
|
||||
.score{
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
//圆环百分比时出现圆环边框的颜色
|
||||
.annulusOuter {
|
||||
position : absolute;
|
||||
top : 0;
|
||||
left : 0;
|
||||
width : 74px;
|
||||
height : 74px;
|
||||
border : 12px solid #FF7F69;
|
||||
border-radius: 50%;
|
||||
}
|
||||
//左边遮住圆环颜色的长方形
|
||||
.leftRectangle {
|
||||
position : absolute;
|
||||
background : #EBEEF5;
|
||||
width : 37px;
|
||||
height : 74px;
|
||||
transform-origin: right;
|
||||
}
|
||||
//右边遮住圆环颜色的长方形
|
||||
.rightRectangle {
|
||||
position : absolute;
|
||||
background : #EBEEF5;
|
||||
transform-origin: left;
|
||||
left : 37px;
|
||||
width : 37px;
|
||||
height : 74px;
|
||||
transform : rotate(0deg);
|
||||
}
|
||||
//弥补hidde在移动端失效的圆环
|
||||
.repairAnnulus{
|
||||
position : absolute;
|
||||
width : 74px;
|
||||
height : 74px;
|
||||
z-index : 20;
|
||||
border-radius: 50%;
|
||||
box-sizing : content-box;
|
||||
//改外边框的时候,位置也要改下
|
||||
border : 20px solid #ffffff;
|
||||
top : -20px;
|
||||
left : -20px;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React , {useEffect, useState} from 'react';
|
||||
import './Index.scss';
|
||||
import 'echarts/lib/component/tooltip';
|
||||
import 'echarts/lib/component/title';
|
||||
|
@ -8,13 +8,184 @@ import 'echarts/lib/component/markPoint';
|
|||
import Pie from '../Echart/Pie';
|
||||
import Cloud from '../Echart/Cloud';
|
||||
import Radar from '../Echart/Radar';
|
||||
import Round from '../Echart/Round';
|
||||
import { DatePicker } from 'antd';
|
||||
import moment from 'moment';
|
||||
|
||||
import { FlexAJ } from '../../Component/layout';
|
||||
import Axios from 'axios';
|
||||
|
||||
const { RangePicker } = DatePicker;
|
||||
const dateFormat = 'YYYY-MM-DD';
|
||||
function Index(props) {
|
||||
const username = props.match.params.username;
|
||||
const [ dates, setDates] = useState(undefined);
|
||||
const [ pieData, setPieData ] = useState([]);
|
||||
const [ rDates, setRDates ] = useState(undefined);
|
||||
const [ radarData, setRadarData ] = useState([]);
|
||||
|
||||
const [ topThree , setTopThree] = useState(undefined);
|
||||
const [ percentData , setPercentData ] = useState(undefined);
|
||||
|
||||
const [ cData, setCData ] = useState(undefined);
|
||||
const [ cloudData, setCloudData ] = useState(undefined);
|
||||
|
||||
const disabledDate = current => {
|
||||
return current && current > moment().endOf('day');
|
||||
};
|
||||
|
||||
// 获取角色定位接口数据
|
||||
useEffect(()=>{
|
||||
getRoleSta();
|
||||
},[dates])
|
||||
|
||||
function getRoleSta() {
|
||||
const url = `/users/${username}/statistics/role.json`;
|
||||
Axios.get(url,{
|
||||
params:{
|
||||
start_time:dates && dates[0],
|
||||
end_time:dates && dates[1]
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
setPieData(result.data.role);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
|
||||
// 获取开发能力接口数据
|
||||
useEffect(()=>{
|
||||
getRadarSta();
|
||||
},[rDates])
|
||||
|
||||
function getRadarSta() {
|
||||
const url = `/users/${username}/statistics/develop.json`;
|
||||
Axios.get(url,{
|
||||
params:{
|
||||
start_time:rDates && rDates[0],
|
||||
end_time:rDates && rDates[1]
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
setRadarData(result.data);
|
||||
let score = result.data.user && result.data.user.each_language_score;
|
||||
var sortData = []
|
||||
for (var item in score) {
|
||||
sortData.push([item, score[item]])
|
||||
}
|
||||
sortData.sort(function(a, b) {
|
||||
return b[1] - a[1];
|
||||
});
|
||||
setTopThree(sortData.slice(0,3));
|
||||
|
||||
let percent = result.data.user && result.data.user.languages_percent;
|
||||
let arr = [];
|
||||
Object.keys(percent).map((item,key)=>{
|
||||
arr.push({name:item,p:percent[item]*100,color:getColor()});
|
||||
})
|
||||
setPercentData(arr);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
function getColor(){
|
||||
let str = "#";
|
||||
let arr = ["1","2","3","4","4","5","6","7","8","9","a","b","c","d","e","f"];
|
||||
for(var i=0;i<6;i++){
|
||||
let num = parseInt(Math.random() * 16,0);
|
||||
str+=arr[num];
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
//用户专业定位
|
||||
useEffect(()=>{
|
||||
getCloudSta();
|
||||
},[cData])
|
||||
|
||||
function getCloudSta() {
|
||||
const url = `/users/${username}/statistics/major.json`;
|
||||
Axios.get(url,{
|
||||
params:{
|
||||
start_time:rDates && rDates[0],
|
||||
end_time:rDates && rDates[1]
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
setCloudData(result.data);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
function Index() {
|
||||
return(
|
||||
<div>
|
||||
<Pie />
|
||||
<Cloud />
|
||||
<Radar />
|
||||
<div className="boxes">
|
||||
<FlexAJ>
|
||||
<span className="font-18">开发能力</span>
|
||||
<RangePicker
|
||||
disabledDate={disabledDate}
|
||||
onChange={(val,dateString) => {setRDates(dateString)}}
|
||||
format={dateFormat}
|
||||
/>
|
||||
</FlexAJ>
|
||||
<Radar data={radarData}/>
|
||||
{
|
||||
topThree &&
|
||||
<div className="roundBox">
|
||||
<Round num={topThree[0][1]} color="#FF7F69" name={topThree[0][0]}/>
|
||||
<Round num={topThree[1][1]} color="#99dfff" name={topThree[1][0]}/>
|
||||
<Round num={topThree[2][1]} color="#ff9e48" name={topThree[2][0]}/>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
percentData &&
|
||||
<div className="pBox">
|
||||
<div class="progress">
|
||||
{
|
||||
percentData.map((i,k)=>{
|
||||
return(
|
||||
<span style={{width: `${i.p}%`, backgroundColor:`${i.color}`}}></span>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
<div className="progresstip">
|
||||
{
|
||||
percentData.map((i,k)=>{
|
||||
return(
|
||||
<span>
|
||||
<i class="zero" style={{backgroundColor: `${i.color}`}}></i><span>{i.name}</span>
|
||||
<span>{`${i.p}%`}</span>
|
||||
</span>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div className="boxes">
|
||||
<FlexAJ>
|
||||
<span className="font-18">角色定位</span>
|
||||
<RangePicker
|
||||
disabledDate={disabledDate}
|
||||
onChange={(val,dateString) => {setDates(dateString)}}
|
||||
format={dateFormat}
|
||||
/>
|
||||
</FlexAJ>
|
||||
<Pie data={pieData}/>
|
||||
</div>
|
||||
<div className="boxes">
|
||||
<FlexAJ>
|
||||
<span className="font-18">专业定位</span>
|
||||
<RangePicker
|
||||
disabledDate={disabledDate}
|
||||
onChange={(val,dateString) => {setCData(dateString)}}
|
||||
format={dateFormat}
|
||||
/>
|
||||
</FlexAJ>
|
||||
<Cloud data={cloudData}/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
.boxes{
|
||||
padding:20px 30px;
|
||||
.roundBox{
|
||||
margin:20px auto;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
& >div{
|
||||
margin:0px 30px;
|
||||
}
|
||||
}
|
||||
.pBox{
|
||||
width: 400px;
|
||||
margin:40px auto 20px;
|
||||
.progress{
|
||||
width: 360px;
|
||||
margin:0px auto;
|
||||
display: flex;
|
||||
background-color: #fafafa;
|
||||
border-radius: 10px;
|
||||
height: 7px;
|
||||
span:first-child {
|
||||
border-radius: 10px 0px 0px 10px;
|
||||
}
|
||||
span:last-child {
|
||||
border-radius: 0px 10px 10px 0px;
|
||||
}
|
||||
}
|
||||
.progresstip {
|
||||
margin-top: 15px;
|
||||
flex-wrap: wrap;
|
||||
display: flex;
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
-webkit-box-pack: justify;
|
||||
-webkit-justify-content: space-between;
|
||||
-ms-flex-pack: justify;
|
||||
justify-content: space-between;
|
||||
& > span {
|
||||
padding-left: 15px;
|
||||
position: relative;
|
||||
min-width: 33%;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
i.zero {
|
||||
display: block;
|
||||
border-radius: 50%;
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
margin-top:10px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
span {
|
||||
color: #666;
|
||||
}
|
||||
span:last-child {
|
||||
color: #999;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue