|
|
|
@ -1,14 +1,452 @@
|
|
|
|
|
import React, {Fragment, PureComponent} from 'react';
|
|
|
|
|
import styles from './multiDStatistics.less';
|
|
|
|
|
class multiDStatistics extends PureComponent {
|
|
|
|
|
render() {
|
|
|
|
|
import React, { useEffect, useRef } from 'react';
|
|
|
|
|
import * as echarts from "echarts";
|
|
|
|
|
|
|
|
|
|
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 (
|
|
|
|
|
<>
|
|
|
|
|
<iframe title="人员多维统计" className={styles.frameContent} src="/人员多维统计.html"/>
|
|
|
|
|
</>
|
|
|
|
|
<div className={styles.frameContent}>
|
|
|
|
|
<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;
|
|
|
|
|