员工统计

master
wangyunfei 2 weeks ago
parent 9c96ab638b
commit f441f969ca

@ -29,7 +29,7 @@ export default [
path: '/topnavbar00/multidstatistics/staffstatistics', path: '/topnavbar00/multidstatistics/staffstatistics',
// icon: 'bank', // icon: 'bank',
name: 'staffstatistics', name: 'staffstatistics',
component: './multi-d-statistics/multiDStatistics', component: './multi-d-statistics/MultiDStatistics',
}, },
], ],
}, },

@ -1,14 +1,452 @@
import React, {Fragment, PureComponent} from 'react'; import React, { useEffect, useRef } from 'react';
import styles from './multiDStatistics.less'; import * as echarts from "echarts";
class multiDStatistics extends PureComponent {
render() { import styles from './MultiDStatistics.less';
// 图片
import arrow_up from '@/assets/multiDStaistics/arrow_up.png';
import arrow_down from '@/assets/multiDStaistics/arrow_down.png';
const MultiDStatistics = () => {
const chartRefDepartment = useRef(null);
const chartRefPosition = useRef(null);
const chartRefAge = useRef(null);
const chartRefworkingyears = useRef(null);
const chartRefPerformance = useRef(null);
const chartRefRecruitment = useRef(null);
useEffect(() => {
const departmentChart = chartRefDepartment.current;
if (!departmentChart) return;
const myChart = echarts.init(chartRefDepartment.current);
const option = {
color: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452'],
tooltip: { trigger: 'item' },
legend: {
orient: 'vertical',
right: 10,
top: 'center',
data: ['技术部', '产品部', '市场部', '销售部', '人力资源', '财务部', '行政部']
},
series: [{
name: '部门分布',
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 4,
borderColor: '#fff',
borderWidth: 2
},
label: { show: false, position: 'center' },
emphasis: {
label: { show: true, fontSize: 18, fontWeight: 'bold' }
},
labelLine: { show: false },
data: [
{ value: 320, name: '技术部' },
{ value: 240, name: '产品部' },
{ value: 149, name: '市场部' },
{ value: 180, name: '销售部' },
{ value: 98, name: '人力资源' },
{ value: 56, name: '财务部' },
{ value: 105, name: '行政部' }
]
}]
};
myChart.setOption(option);
return () => { myChart.dispose(); };
}, []);
useEffect(() => {
const positionChart = chartRefPosition.current;
if (!positionChart) return;
const myChart = echarts.init(chartRefPosition.current);
const option = {
color: ['#6C5CE7', '#74B9FF', '#00B894', '#FDCB6E', '#E17055', '#FD79A8', '#A29BFE', '#81ECEC'],
animation: false,
tooltip: { trigger: 'item' },
legend: {
orient: 'vertical',
right: 10,
top: 'center',
data: ['工程师', '产品经理', '设计师', '市场专员', '销售代表', 'HRBP', '财务专员', '行政专员']
},
series: [{
name: '职位分布',
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 4,
borderColor: '#fff',
borderWidth: 2
},
label: { show: false, position: 'center' },
emphasis: {
label: { show: true, fontSize: 18, fontWeight: 'bold' }
},
labelLine: { show: false },
data: [
{ value: 280, name: '工程师' },
{ value: 120, name: '产品经理' },
{ value: 90, name: '设计师' },
{ value: 80, name: '市场专员' },
{ value: 150, name: '销售代表' },
{ value: 60, name: 'HRBP' },
{ value: 40, name: '财务专员' },
{ value: 80, name: '行政专员' }
]
}]
};
myChart.setOption(option);
return () => { myChart.dispose(); };
}, []);
useEffect(() => {
const ageChart = chartRefAge.current;
if (!ageChart) return;
const myChart = echarts.init(chartRefAge.current);
const option = {
animation: false,
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
data: ['20-25岁', '26-30岁', '31-35岁', '36-40岁', '41岁以上'],
axisTick: {
alignWithLabel: true
}
},
yAxis: {
type: 'value'
},
series: [
{
name: '人数',
type: 'bar',
barWidth: '60%',
itemStyle: {
color: '#2D5CF6'
},
data: [120, 480, 360, 180, 108]
}
]
};
myChart.setOption(option);
return () => { myChart.dispose(); };
}, []);
useEffect(() => {
const seniorityChart = chartRefworkingyears.current;
if (!seniorityChart) return;
const myChart = echarts.init(seniorityChart);
const option = {
color: ['#667EEA', '#764BA2', '#F093FB', '#F5576C', '#4FACFE'],
animation: true,
animationDuration: 1000,
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
legend: {
orient: 'vertical',
right: 10,
top: 'center',
data: ['1年以内', '1-3年', '3-5年', '5-10年', '10年以上'],
textStyle: {
fontSize: 12,
color: '#333'
}
},
series: [{
name: '工龄分布',
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 8,
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.1)'
},
label: { show: false, position: 'center' },
emphasis: {
label: {
show: true,
fontSize: 20,
fontWeight: 'bold',
color: '#333'
},
itemStyle: {
shadowBlur: 20,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.3)'
}
},
labelLine: { show: false },
data: [
{ value: 280, name: '1年以内', itemStyle: { color: '#667EEA' } },
{ value: 420, name: '1-3年', itemStyle: { color: '#764BA2' } },
{ value: 300, name: '3-5年', itemStyle: { color: '#F093FB' } },
{ value: 180, name: '5-10年', itemStyle: { color: '#F5576C' } },
{ value: 68, name: '10年以上', itemStyle: { color: '#4FACFE' } }
]
}]
};
myChart.setOption(option);
return () => { myChart.dispose(); };
}, []);
useEffect(() => {
const performanceChart = chartRefPerformance.current;
if (!performanceChart) return;
const myChart = echarts.init(performanceChart);
const option = {
color: ['#4CAF50', '#2196F3', '#FF9800', '#F44336'],
animation: true,
animationDuration: 1200,
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
legend: {
orient: 'vertical',
right: 10,
top: 'center',
data: ['A(优秀)', 'B(良好)', 'C(合格)', 'D(待改进)'],
textStyle: {
fontSize: 12,
color: '#333'
}
},
series: [{
name: '绩效分布',
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 8,
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.1)'
},
label: { show: false, position: 'center' },
emphasis: {
label: {
show: true,
fontSize: 20,
fontWeight: 'bold',
color: '#333'
},
itemStyle: {
shadowBlur: 20,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.3)'
}
},
labelLine: { show: false },
data: [
{ value: 180, name: 'A(优秀)', itemStyle: { color: '#4CAF50' } },
{ value: 420, name: 'B(良好)', itemStyle: { color: '#2196F3' } },
{ value: 480, name: 'C(合格)', itemStyle: { color: '#FF9800' } },
{ value: 68, name: 'D(待改进)', itemStyle: { color: '#F44336' } }
]
}]
};
myChart.setOption(option);
return () => { myChart.dispose(); };
}, []);
useEffect(() => {
const recruitmentChart = chartRefRecruitment.current;
if (!recruitmentChart) return;
const myChart = echarts.init(recruitmentChart);
const option = {
color: ['#B19CD9', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7'],
animation: false,
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' }
},
legend: {
data: ['猎头', '招聘网站', '内部推荐', '校园招聘', '社交媒体']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: { type: 'value' },
yAxis: {
type: 'category',
data: ['1月', '2月', '3月', '4月', '5月', '6月']
},
series: [
{
name: '猎头',
type: 'bar',
stack: 'total',
label: { show: true },
emphasis: { focus: 'series' },
itemStyle: {
color: '#B19CD9',
borderRadius: [2, 2, 2, 2]
},
data: [5, 3, 7, 4, 6, 8]
},
{
name: '招聘网站',
type: 'bar',
stack: 'total',
label: { show: true },
emphasis: { focus: 'series' },
itemStyle: {
color: '#4ECDC4',
borderRadius: [2, 2, 2, 2]
},
data: [12, 10, 15, 18, 14, 16]
},
{
name: '内部推荐',
type: 'bar',
stack: 'total',
label: { show: true },
emphasis: { focus: 'series' },
itemStyle: {
color: '#45B7D1',
borderRadius: [2, 2, 2, 2]
},
data: [8, 6, 10, 7, 9, 11]
},
{
name: '校园招聘',
type: 'bar',
stack: 'total',
label: { show: true },
emphasis: { focus: 'series' },
itemStyle: {
color: '#96CEB4',
borderRadius: [2, 2, 2, 2]
},
data: [0, 0, 0, 15, 12, 10]
},
{
name: '社交媒体',
type: 'bar',
stack: 'total',
label: { show: true },
emphasis: { focus: 'series' },
itemStyle: {
color: '#FFEAA7',
borderRadius: [2, 2, 2, 2]
},
data: [3, 5, 4, 6, 5, 7]
}
]
};
myChart.setOption(option);
return () => { myChart.dispose(); };
}, []);
return ( return (
<> <div className={styles.frameContent}>
<iframe title="人员多维统计" className={styles.frameContent} src="/人员多维统计.html"/> <div className={styles.top}>
</> <div className={styles.staff}>
<span className={styles.staff_1} >员工总数</span>
<div className={styles.staff_2}>
<span className={styles.staff_21}>1,278</span>
<img src={arrow_up} alt="箭头" className={styles.staff_22} ></img>
<span className={styles.staff_23}>5.2%</span></div>
<span className={styles.staff_3}>较上月增加64人</span>
</div>
<div className={styles.entry}>
<span className={styles.entry_1} >本月入职</span>
<div className={styles.entry_2}>
<span className={styles.entry_21}>48</span>
</div>
<span className={styles.entry_3}>其中社招25人校招23人</span>
</div>
<div className={styles.dimission}>
<span className={styles.dimission_1} >本月离职</span>
<div className={styles.dimission_2}>
<span className={styles.dimission_21}>18</span>
<img src={arrow_down} alt="箭头" className={styles.dimission_22} ></img>
<span className={styles.dimission_23}>5.2%</span>
</div>
<span className={styles.dimission_3}>主动离职13人被动5离职</span>
</div>
<div className={styles.workingYears}>
<span className={styles.workingYears_1} >平均工龄</span>
<div className={styles.workingYears_2}>
<span className={styles.workingYears_21}>4.2</span>
</div>
<span className={styles.workingYears_3}>较行业平均高0.8</span>
</div>
</div>
<div className={styles.pieChart1}>
<div className={styles.department}>
<span className={styles.department_1} >部门人员分布</span>
<div ref={chartRefDepartment} style={{ width: '100%', height: '100%' }} />
</div>
<div className={styles.position}>
<span className={styles.position_1} >职位分布</span>
<div ref={chartRefPosition} style={{ width: '100%', height: '100%' }} />
</div>
</div>
<div className={styles.pieChart2}>
<div className={styles.age}>
<span className={styles.age_1} >员工年龄分布</span>
<div ref={chartRefAge} style={{ width: '100%', height: '100%' }} />
</div>
<div className={styles.workingYears}>
<span className={styles.workingYears_1} >员工工龄分布</span>
<div ref={chartRefworkingyears} style={{ width: '100%', height: '100%' }} />
</div>
</div>
<div className={styles.pieChart3}>
<div className={styles.performance}>
<span className={styles.performance_1} >员工绩效分布</span>
<div ref={chartRefPerformance} style={{ width: '100%', height: '100%' }} />
</div>
<div className={styles.department}>
<span className={styles.department_1} >招聘渠道分布</span>
<div ref={chartRefRecruitment} style={{ width: '100%', height: '100%' }} />
</div>
</div>
<div className={styles.kong}></div>
</div>
) )
}
} }
export default multiDStatistics export default MultiDStatistics;

@ -5,6 +5,423 @@
height: 100vh; height: 100vh;
border: none; border: none;
display: block; display: block;
background-color: #f5f6fa !important;
margin: 0; margin: 0;
padding: 0; padding: 0;
overflow-y: auto;
.top {
display: flex;
width: 100%;
height: 25vh;
.staff {
display: flex;
flex-direction: column;
width: 20%;
height: 17vh;
background-color: #ffffff;
margin-left: 7%;
margin-top: 6vh;
border-radius: 6px;
position: relative;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08), 0 1.5px 6px rgba(0, 0, 0, 0.06);
// 右侧图标图片
&::after {
content: '';
display: block;
position: absolute;
right: 15px;
top: 50%;
transform: translateY(-50%);
width: 60px;
height: 60px;
background: url('@/assets/multiDStaistics/staff_total.png') no-repeat center center;
background-size: contain;
}
.staff_1 {
width: 100%;
font-size: 16px;
color: #777;
margin-left: 15px;
margin-top: 18px;
}
.staff_2 {
width: 100%;
margin: 10px 0 0 15px;
.staff_21 {
font-size: 28px;
color: #1975d0;
font-family: 'Microsoft YaHei';
}
.staff_22 {
width: 26px;
height: 26px;
margin-top: -10px;
}
.staff_23 {
color: #38d57a;
font-size: 16px;
font-weight: bold;
margin-left: -5px;
}
}
.staff_3 {
font-size: 14px;
color: #999;
margin: 10px 0 0 15px;
}
}
.entry {
display: flex;
flex-direction: column;
width: 20%;
height: 17vh;
background-color: #ffffff;
margin-left: 2%;
margin-top: 6vh;
border-radius: 6px;
position: relative;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08), 0 1.5px 6px rgba(0, 0, 0, 0.06);
// 右侧图标图片
&::after {
content: '';
display: block;
position: absolute;
right: 15px;
top: 50%;
transform: translateY(-50%);
width: 55px;
height: 55px;
background: url('@/assets/multiDStaistics/entry.png') no-repeat center center;
background-size: contain;
}
.entry_1 {
width: 100%;
font-size: 16px;
color: #777;
margin-left: 15px;
margin-top: 18px;
}
.entry_2 {
width: 100%;
margin: 10px 0 0 15px;
.entry_21 {
font-size: 28px;
color: #1975d0;
font-family: 'Microsoft YaHei';
}
.entry_22 {
width: 20px;
height: 16px;
margin-top: -7px;
}
.entry_23 {
color: #ff3333;
font-size: 16px;
font-weight: bold;
// margin-left: -5px;
}
}
.entry_3 {
font-size: 14px;
color: #999;
margin: 10px 0 0 15px;
}
}
.dimission {
display: flex;
flex-direction: column;
width: 20%;
height: 17vh;
background-color: #ffffff;
margin-left: 2%;
margin-top: 6vh;
border-radius: 6px;
position: relative;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08), 0 1.5px 6px rgba(0, 0, 0, 0.06);
// 右侧图标图片
&::after {
content: '';
display: block;
position: absolute;
right: 15px;
top: 50%;
transform: translateY(-50%);
width: 55px;
height: 55px;
background: url('@/assets/multiDStaistics/dimission.png') no-repeat center center;
background-size: contain;
}
.dimission_1 {
width: 100%;
font-size: 16px;
color: #777;
margin-left: 15px;
margin-top: 18px;
}
.dimission_2 {
width: 100%;
margin: 10px 0 0 15px;
.dimission_21 {
font-size: 28px;
color: #1975d0;
font-family: 'Microsoft YaHei';
}
.dimission_22 {
width: 20px;
height: 16px;
margin-top: -7px;
}
.dimission_23 {
color: #ff3333;
font-size: 16px;
font-weight: bold;
// margin-left: -5px;
}
}
.dimission_3 {
font-size: 14px;
color: #999;
margin: 10px 0 0 15px;
}
}
.workingYears {
display: flex;
flex-direction: column;
width: 20%;
height: 17vh;
background-color: #ffffff;
margin-left: 2%;
margin-top: 6vh;
border-radius: 6px;
position: relative;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08), 0 1.5px 6px rgba(0, 0, 0, 0.06);
// 右侧图标图片
&::after {
content: '';
display: block;
position: absolute;
right: 15px;
top: 50%;
transform: translateY(-50%);
width: 55px;
height: 55px;
background: url('@/assets/multiDStaistics/workingYears.png') no-repeat center center;
background-size: contain;
}
.workingYears_1 {
width: 100%;
font-size: 16px;
color: #777;
margin-left: 15px;
margin-top: 18px;
}
.workingYears_2 {
width: 100%;
margin: 10px 0 0 15px;
.workingYears_21 {
font-size: 28px;
color: #1975d0;
font-family: 'Microsoft YaHei';
}
.workingYears_22 {
width: 20px;
height: 16px;
margin-top: -7px;
}
.workingYears_23 {
color: #ff3333;
font-size: 16px;
font-weight: bold;
}
}
.workingYears_3 {
font-size: 14px;
color: #999;
margin: 10px 0 0 15px;
}
}
}
.pieChart1 {
display: flex;
width: 100%;
height: 45vh; // 增加高度以容纳 40vh 的子元素
.department {
display: flex;
flex-direction: column;
width: 42%;
height: 40vh;
background-color: #ffffff;
margin-left: 7%;
margin-top: 3vh;
border-radius: 6px;
position: relative;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08), 0 1.5px 6px rgba(0, 0, 0, 0.06);
.department_1 {
margin-top: 2%;
margin-left: 2%;
color: #333;
font-size: 20px;
font-weight: bold;
}
}
.position {
display: flex;
flex-direction: column;
width: 42%;
height: 40vh;
background-color: #ffffff;
margin-left: 2%;
margin-top: 3vh;
border-radius: 6px;
position: relative;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08), 0 1.5px 6px rgba(0, 0, 0, 0.06);
.position_1 {
margin-top: 2%;
margin-left: 2%;
color: #333;
font-size: 20px;
font-weight: bold;
}
}
}
.pieChart2 {
display: flex;
width: 100%;
height: 40vh;
.age {
display: flex;
flex-direction: column;
width: 42%;
height: 40vh;
background-color: #ffffff;
margin-left: 7%;
margin-top: 3vh;
border-radius: 6px;
position: relative;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08), 0 1.5px 6px rgba(0, 0, 0, 0.06);
.age_1 {
margin-top: 2%;
margin-left: 2%;
color: #333;
font-size: 20px;
font-weight: bold;
}
}
.workingYears {
display: flex;
flex-direction: column;
width: 42%;
height: 40vh;
background-color: #ffffff;
margin-left: 2%;
margin-top: 3vh;
border-radius: 6px;
position: relative;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08), 0 1.5px 6px rgba(0, 0, 0, 0.06);
.workingYears_1 {
margin-top: 2%;
margin-left: 2%;
color: #333;
font-size: 20px;
font-weight: bold;
}
}
}
.pieChart3 {
display: flex;
width: 100%;
height: 45vh;
.performance {
display: flex;
flex-direction: column;
width: 42%;
height: 40vh;
background-color: #ffffff;
margin-left: 7%;
margin-top: 8vh;
margin-bottom: 25vh;
border-radius: 6px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08), 0 1.5px 6px rgba(0, 0, 0, 0.06);
.performance_1 {
margin-top: 2%;
margin-left: 2%;
color: #333;
font-size: 20px;
font-weight: bold;
}
}
.department {
display: flex;
flex-direction: column;
width: 42%;
height: 40vh;
background-color: #ffffff;
margin-left: 2%;
margin-top: 8vh;
margin-bottom: 25vh;
border-radius: 6px;
position: relative;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08), 0 1.5px 6px rgba(0, 0, 0, 0.06);
.department_1 {
margin-top: 2%;
margin-left: 2%;
color: #333;
font-size: 20px;
font-weight: bold;
}
}
}
.kong{
height: 20vh;
}
} }
Loading…
Cancel
Save