From 1432afebfd1e2e8fc5df3cb9e0d2b808995b6a4a Mon Sep 17 00:00:00 2001 From: caishi <1149225589@qq.com> Date: Mon, 31 May 2021 17:44:30 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=AA=E4=BA=BA=E4=B8=AD=E5=BF=83=E6=95=B4?= =?UTF-8?q?=E4=BD=93=E4=B8=8A=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 5 + package.json | 1 + src/forge/Main/Index.scss | 2 - src/forge/users/Echart/Cloud.jsx | 14 +- src/forge/users/Echart/Pie.jsx | 24 ++-- src/forge/users/Echart/Radar.jsx | 39 +++--- src/forge/users/Echart/Round.jsx | 26 ++++ src/forge/users/Echart/style.scss | 69 ++++++++++ src/forge/users/Statistics/Index.jsx | 181 +++++++++++++++++++++++++- src/forge/users/Statistics/Index.scss | 64 +++++++++ 10 files changed, 376 insertions(+), 49 deletions(-) create mode 100644 src/forge/users/Echart/Round.jsx create mode 100644 src/forge/users/Echart/style.scss diff --git a/package-lock.json b/package-lock.json index 6f4ada7d..267c0020 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index f69e3af9..2e61175b 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/forge/Main/Index.scss b/src/forge/Main/Index.scss index 2a207dfd..ef3cbc0f 100644 --- a/src/forge/Main/Index.scss +++ b/src/forge/Main/Index.scss @@ -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{ diff --git a/src/forge/users/Echart/Cloud.jsx b/src/forge/users/Echart/Cloud.jsx index 3b53108a..778b30e7 100644 --- a/src/forge/users/Echart/Cloud.jsx +++ b/src/forge/users/Echart/Cloud.jsx @@ -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 +
) } export default Cloud; \ No newline at end of file diff --git a/src/forge/users/Echart/Pie.jsx b/src/forge/users/Echart/Pie.jsx index 460d7f00..d5489b98 100644 --- a/src/forge/users/Echart/Pie.jsx +++ b/src/forge/users/Echart/Pie.jsx @@ -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: '报告者'} ] } ] diff --git a/src/forge/users/Echart/Radar.jsx b/src/forge/users/Echart/Radar.jsx index f427442e..35430958 100644 --- a/src/forge/users/Echart/Radar.jsx +++ b/src/forge/users/Echart/Radar.jsx @@ -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)' } ] }] diff --git a/src/forge/users/Echart/Round.jsx b/src/forge/users/Echart/Round.jsx new file mode 100644 index 00000000..ebcb1367 --- /dev/null +++ b/src/forge/users/Echart/Round.jsx @@ -0,0 +1,26 @@ +import React from 'react'; +import './style.scss'; + + +function Round({num,color,name}) { + return( +
+
+ {num} + {name} +
+
+ {num > 50 ? +
+ : +
+ } + {num < 50 ? +
+ : +
+ } +
+ ) +} +export default Round; \ No newline at end of file diff --git a/src/forge/users/Echart/style.scss b/src/forge/users/Echart/style.scss new file mode 100644 index 00000000..5a2aae38 --- /dev/null +++ b/src/forge/users/Echart/style.scss @@ -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; +} \ No newline at end of file diff --git a/src/forge/users/Statistics/Index.jsx b/src/forge/users/Statistics/Index.jsx index 3b20ea1e..ee4e25e2 100644 --- a/src/forge/users/Statistics/Index.jsx +++ b/src/forge/users/Statistics/Index.jsx @@ -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(
- - - +
+ + 开发能力 + {setRDates(dateString)}} + format={dateFormat} + /> + + + { + topThree && +
+ + + +
+ } + { + percentData && +
+
+ { + percentData.map((i,k)=>{ + return( + + ) + }) + } +
+
+ { + percentData.map((i,k)=>{ + return( + + {i.name} + {`${i.p}%`} + + ) + }) + } +
+
+ } +
+
+ + 角色定位 + {setDates(dateString)}} + format={dateFormat} + /> + + +
+
+ + 专业定位 + {setCData(dateString)}} + format={dateFormat} + /> + + +
) } diff --git a/src/forge/users/Statistics/Index.scss b/src/forge/users/Statistics/Index.scss index e69de29b..a2f944b9 100644 --- a/src/forge/users/Statistics/Index.scss +++ b/src/forge/users/Statistics/Index.scss @@ -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; + } + } + } + } +} \ No newline at end of file