<template>
|
<div class='page-header-index-wide'>
|
<a-row :gutter='24'>
|
<a-col class='pointer' @click='cardClick(1)' :sm='24' :md='12' :xl='6' :style="{ marginBottom: '12px' }">
|
<chart-card :loading='loading' title='研发中心' :total='totalUser|| "0"'>
|
<a-tooltip title='指标说明' slot='action'>
|
<a-icon type='info-circle-o' />
|
</a-tooltip>
|
<div>
|
<trend flag='up' style='margin-right: 16px;'>
|
<span slot='term'>较去年</span>
|
-
|
</trend>
|
|
</div>
|
<template slot='footer'>部门总人数<span></span></template>
|
</chart-card>
|
</a-col>
|
<a-col class='pointer' @click='cardClick(2)' :sm='24' :md='12' :xl='6' :style="{ marginBottom: '12px' }">
|
<chart-card :loading='loading' title='正式员工' :total='regularEmployee'>
|
<a-tooltip title='指标说明' slot='action'>
|
<a-icon type='info-circle-o' />
|
</a-tooltip>
|
<div>
|
|
|
</div>
|
<template slot='footer'>正式员工人数<span></span></template>
|
</chart-card>
|
</a-col>
|
<a-col class='pointer' @click='cardClick(3)' :sm='24' :md='12' :xl='6' :style="{ marginBottom: '12px' }">
|
<chart-card :loading='loading' title='试用期员工' :total='probEmployee'>
|
<a-tooltip title='指标说明' slot='action'>
|
<a-icon type='info-circle-o' />
|
</a-tooltip>
|
<div>
|
|
|
</div>
|
<template slot='footer'>试用期员工人数<span></span></template>
|
</chart-card>
|
</a-col>
|
<a-col class='pointer' @click='cardClick(4)' :sm='24' :md='12' :xl='6' :style="{ marginBottom: '12px' }">
|
<chart-card :loading='loading' title='应届生' :total='gradEmployee'>
|
<a-tooltip title='指标说明' slot='action'>
|
<a-icon type='info-circle-o' />
|
</a-tooltip>
|
<div>
|
|
|
</div>
|
<template slot='footer'>应届生人数<span></span></template>
|
</chart-card>
|
</a-col>
|
</a-row>
|
|
|
<div style='width: 100%;height: 600px;'>
|
<a-row justify='space-between'>
|
|
<a-col :xl='12' :lg='12' :md='24' :sm='24' :xs='24'>
|
<a-card style='margin-right: 12px' :loading='loading' :bordered='false' :body-style="{padding: '0'}">
|
<div style='text-align: center;' class='chart-box'>
|
<div style='height: 40px;font-size: 14px;line-height: 40px'> 各部门人员(正式、试用、实习)分布</div>
|
<div id='chart1' />
|
</div>
|
</a-card>
|
</a-col>
|
|
<a-col :xl='12' :lg='12' :md='24' :sm='24' :xs='24'>
|
<a-card style='margin-left: 12px' :loading='loading' :bordered='false' :body-style="{padding: '0'}">
|
<div style='text-align: center;' class='chart-box'>
|
<div style='height: 40px;font-size: 14px'>各部门人员(编制)分布</div>
|
<div id='chart2' />
|
</div>
|
</a-card>
|
</a-col>
|
|
|
</a-row>
|
|
<a-row justify='space-between' style='margin-top: 12px'>
|
<a-col :xl='6' :lg='6' :md='12' :sm='12' :xs='12'>
|
<a-card style='margin-right: 12px' :loading='loading' :bordered='false' :body-style="{padding: '0'}">
|
<div style='text-align: center;' class='chart-box'>
|
<div style='height: 40px;font-size: 14px'>部门人员(性别)</div>
|
<div id='chart3' />
|
</div>
|
</a-card>
|
</a-col>
|
|
<a-col :xl='6' :lg='6' :md='12' :sm='12' :xs='12'>
|
<a-card style='margin-right: 12px' :loading='loading' :bordered='false' :body-style="{padding: '0'}">
|
<div style='text-align: center;' class='chart-box'>
|
<div style='height: 40px;font-size: 14px'>部门人员(学历)</div>
|
<div id='chart4' />
|
</div>
|
</a-card>
|
</a-col>
|
|
|
<a-col :xl='6' :lg='6' :md='12' :sm='12' :xs='12'>
|
<a-card style='margin-left: 12px' :loading='loading' :bordered='false' :body-style="{padding: '0'}">
|
<div style='text-align: center;' class='chart-box'>
|
<div style='height: 40px;font-size: 14px'>部门人员(等阶)</div>
|
<div id='chart5' />
|
</div>
|
</a-card>
|
</a-col>
|
|
<a-col :xl='6' :lg='6' :md='12' :sm='12' :xs='12'>
|
<a-card style='margin-left: 12px' :loading='loading' :bordered='false' :body-style="{padding: '0'}">
|
<div style='text-align: center;' class='chart-box'>
|
<div style='height: 40px;font-size: 14px'>部门人员(构成)</div>
|
<div id='chart6' />
|
</div>
|
</a-card>
|
</a-col>
|
</a-row>
|
</div>
|
|
|
</div>
|
</template>
|
|
<script>
|
import ChartCard from '@/components/ChartCard'
|
import Trend from '@/components/Trend'
|
import MiniProgress from '@/components/chart/MiniProgress'
|
import MiniArea from '@/components/chart/MiniArea'
|
import MiniBar from '@/components/chart/MiniBar'
|
import { getAction } from '@api/manage'
|
import get from 'lodash.get'
|
import { Chart, registerInteraction } from '@antv/g2'
|
import DataSet from '@antv/data-set';
|
|
export default {
|
name: 'home',
|
components: {
|
ChartCard,
|
Trend,
|
MiniProgress,
|
MiniArea,
|
MiniBar
|
},
|
data() {
|
return {
|
loading: false,
|
model: {
|
departList: []
|
}
|
}
|
},
|
mounted() {
|
this.loadData()
|
},
|
methods: {
|
//查询所有部门数据,树形结构
|
loadData() {
|
getAction('/hrm/board/departUserList', { departName: '研发中心' }).then(res => {
|
if (res.success) {
|
console.info(res.result)
|
this.model.departList = res.result || []
|
this.createData()
|
}
|
|
})
|
},
|
createData() {
|
let chartData1 = []
|
let chartData2 = []
|
let chartData3 = []
|
let chartData4 = []
|
let chartData5 = []
|
let chartData6 = {
|
name: 'root',
|
children: []
|
}
|
this.model.departList.forEach(i => {
|
|
const userList = i.userList || []
|
//统计各类型用户
|
//未分配
|
let blankUserList = userList.filter(u => u.employ == null)
|
let item1 = { year: i.departName, type: '未分配', sales: blankUserList.length }
|
//正式
|
let zsUserList = userList.filter(u => u.employ == 1)
|
let item2 = { year: i.departName, type: '正式', sales: zsUserList.length }
|
//试用
|
let syUserList = userList.filter(u => u.employ == 2)
|
let item3 = { year: i.departName, type: '试用', sales: syUserList.length }
|
//实习
|
let sxUserList = userList.filter(u => u.employ == 3)
|
let item4 = { year: i.departName, type: '实习', sales: sxUserList.length }
|
chartData1.push(item1)
|
|
chartData1.push(item2)
|
chartData1.push(item3)
|
chartData1.push(item4)
|
|
|
let wUserList = userList.filter(u => u.staffing == null)
|
let bzUserList = userList.filter(u => u.staffing == 1)
|
let mbzUserList = userList.filter(u => u.staffing == 0)
|
|
let item21 = { company: '未分配', type: i.departName, value: wUserList.length }
|
let item22 = { company: '有编制', type: i.departName, value: bzUserList.length }
|
let item23 = { company: '无编制', type: i.departName, value: mbzUserList.length }
|
chartData2.push(item21)
|
chartData2.push(item22)
|
chartData2.push(item23)
|
if( i.departName != '研发中心' && userList.length > 0){
|
const item61 = { name: i.departName, value: userList.length }
|
chartData6.children.push(item61)
|
}
|
|
|
|
})
|
|
|
this.initChart1(chartData1)
|
this.initChart2(chartData2)
|
this.initChart6(chartData6)
|
|
if (this.model.departList.length == 0) {
|
return false
|
}
|
|
//不需要分部门计算
|
const userList = this.model.departList[0].userList
|
const total = userList.length
|
if (total == 0) {
|
return false
|
}
|
let nSexList = userList.filter(u => u.sex == null)
|
let manList = userList.filter(u => u.sex == 1)
|
let womenList = userList.filter(u => u.sex == 2)
|
let nSize = this.fixed2(nSexList.length, total)
|
let manSize = this.fixed2(manList.length, total)
|
let womenSize = this.fixed2(womenList.length, total)
|
|
let item31 = { type: '未分配', value: nSexList.length, percent: Number(nSize) }
|
let item32 = { type: '男', value: manList.length, percent: Number(manSize) }
|
let item33 = { type: '女', value: womenList.length, percent: Number(womenSize) }
|
if (nSexList.length > 0) {
|
chartData3.push(item31)
|
}
|
if (manList.length > 0) {
|
chartData3.push(item32)
|
}
|
if (womenList.length > 0) {
|
chartData3.push(item33)
|
}
|
|
this.initChart3(chartData3)
|
|
const wxlList = userList.filter(item => item.education == null)
|
const dxlList = userList.filter(item => item.education == 1)
|
const bxlList = userList.filter(item => item.education == 2)
|
const sxlList = userList.filter(item => item.education == 3)
|
const oxlList = userList.filter(item => item.education == 10)
|
let wxlSize = this.fixed2(wxlList.length, total)
|
let dxlSize = this.fixed2(dxlList.length, total)
|
let bxlSize = this.fixed2(bxlList.length, total)
|
let sxlSize = this.fixed2(sxlList.length, total)
|
let oxlSize = this.fixed2(oxlList.length, total)
|
|
let item41 = { type: '未分配', value: wxlList.length, percent: Number(wxlSize) }
|
let item42 = { type: '大专', value: dxlList.length, percent: Number(dxlSize) }
|
let item43 = { type: '本科', value: bxlList.length, percent: Number(bxlSize) }
|
let item44 = { type: '硕士', value: sxlList.length, percent: Number(sxlSize) }
|
let item45 = { type: '其它', value: oxlList.length, percent: Number(oxlSize) }
|
if (wxlSize.length > 0) {
|
chartData4.push(item41)
|
}
|
if (dxlSize.length > 0) {
|
chartData4.push(item42)
|
}
|
if (bxlSize.length > 0) {
|
chartData4.push(item43)
|
}
|
if (sxlSize.length > 0) {
|
chartData4.push(item44)
|
}
|
if (oxlSize.length > 0) {
|
chartData4.push(item45)
|
}
|
this.initChart4(chartData4)
|
|
const wdjList = userList.filter(item => item.level == null)
|
const djList1 = userList.filter(item => item.level >= 11 && item.level <= 14)
|
const djList2 = userList.filter(item => item.level >= 21 && item.level <= 24)
|
const djList3 = userList.filter(item => item.level >= 31 && item.level <= 34)
|
const djList4 = userList.filter(item => item.level >= 41 && item.level <= 44)
|
const djList5 = userList.filter(item => item.level >= 51 && item.level <= 54)
|
let wdjSize = this.fixed2(wdjList.length, total)
|
let djSize1 = this.fixed2(djList1.length, total)
|
let djSize2 = this.fixed2(djList2.length, total)
|
let djSize3 = this.fixed2(djList3.length, total)
|
let djSize4 = this.fixed2(djList4.length, total)
|
let djSize5 = this.fixed2(djList5.length, total)
|
|
let item51 = { type: '未分配', value: wdjList.length, percent: Number(wdjSize) }
|
let item52 = { type: '一等阶', value: djList1.length, percent: Number(djSize1) }
|
let item53 = { type: '二等阶', value: djList2.length, percent: Number(djSize2) }
|
let item54 = { type: '三等阶', value: djList3.length, percent: Number(djSize3) }
|
let item55 = { type: '四等阶', value: djList4.length, percent: Number(djSize4) }
|
let item56 = { type: '五等阶', value: djList5.length, percent: Number(djSize5) }
|
if (wdjSize.length > 0) {
|
chartData5.push(item51)
|
}
|
if (djSize1.length > 0) {
|
chartData5.push(item52)
|
}
|
if (djSize2.length > 0) {
|
chartData5.push(item53)
|
}
|
if (djSize3.length > 0) {
|
chartData5.push(item54)
|
}
|
if (djSize4.length > 0) {
|
chartData5.push(item55)
|
}
|
if (djSize5.length > 0) {
|
chartData5.push(item56)
|
}
|
|
this.initChart5(chartData5)
|
|
},
|
/**
|
* 保留2位小数
|
* @param value
|
* @param total
|
* @returns {string|number}
|
*/
|
fixed2(value, total) {
|
if (value > 0) {
|
value = value / total
|
value = value.toFixed(2)
|
return value
|
}
|
return 0
|
},
|
|
|
initChart1(chartData1) {
|
console.info(chartData1)
|
registerInteraction('element-link', {
|
start: [
|
{ trigger: 'interval:mouseenter', action: 'element-link-by-color:link' }
|
],
|
end: [
|
{ trigger: 'interval:mouseleave', action: 'element-link-by-color:unlink' }
|
]
|
})
|
|
|
const chart = new Chart({
|
container: 'chart1',
|
autoFit: true,
|
height: 300
|
})
|
|
chart.data(chartData1)
|
/* chart.scale({
|
sales: {
|
max: 2400,
|
tickInterval: 600,
|
nice: true
|
}
|
})*/
|
|
chart.tooltip({
|
showMarkers: false
|
})
|
|
chart
|
.interval()
|
.position('year*sales')
|
.color('type')
|
.adjust('stack')
|
|
chart.interaction('element-highlight-by-color')
|
chart.interaction('element-link')
|
chart.render()
|
|
},
|
initChart2(chartData2) {
|
|
|
const chart = new Chart({
|
container: 'chart2',
|
autoFit: true,
|
height: 300
|
})
|
|
chart.data(chartData2)
|
|
chart.scale('value', { nice: true })
|
|
/* chart.legend({
|
position: 'top'
|
});*/
|
|
chart.tooltip({
|
showMarkers: false
|
})
|
|
chart
|
.interval()
|
.position('type*value').color('company')
|
.label('value', {
|
position: 'top', // 在柱子中间显示标签
|
style: {
|
fill: 'gray'
|
},
|
formatter: (text, item) => {
|
// 当值为 0 时不显示标签
|
return item.value !== 0 ? text : ''
|
}
|
})
|
.adjust([{
|
type: 'dodge',
|
marginRatio: 0
|
}])
|
|
chart.interaction('element-list-highlight')
|
|
|
chart.render()
|
},
|
initChart3(chartData3) {
|
|
|
const chart = new Chart({
|
container: 'chart3',
|
autoFit: true,
|
height: 300
|
})
|
chart.coordinate('theta', {
|
radius: 0.75
|
})
|
|
chart.data(chartData3)
|
|
chart.scale('percent', {
|
formatter: (val) => {
|
if (!val) return val
|
val = val * 100
|
val = val.toFixed(2)
|
val = val + '%'
|
return val
|
}
|
})
|
|
chart.tooltip({
|
showTitle: false,
|
showMarkers: false
|
})
|
|
chart
|
.interval()
|
.position('percent')
|
.color('type')
|
.label('percent', {
|
layout: [{ type: 'limit-in-plot', cfg: { action: 'ellipsis'/** 或 translate */ } }],
|
content: (data) => {
|
/* var percent = data.percent * 100
|
console.info(percent)
|
percent = percent.toFixed(2)
|
percent = percent + '%'*/
|
return `${data.type}: ${data.value} `
|
}
|
})
|
.adjust('stack')
|
|
chart.interaction('element-active')
|
|
chart.render()
|
},
|
initChart4(chartData4) {
|
|
|
const chart = new Chart({
|
container: 'chart4',
|
autoFit: true,
|
height: 300
|
})
|
chart.coordinate('theta', {
|
radius: 0.75
|
})
|
|
chart.data(chartData4)
|
|
chart.scale('percent', {
|
formatter: (val) => {
|
if (!val) return val
|
val = val * 100
|
val = val.toFixed(2)
|
val = val + '%'
|
return val
|
}
|
})
|
|
chart.tooltip({
|
showTitle: false,
|
showMarkers: false
|
})
|
|
chart
|
.interval()
|
.position('percent')
|
.color('type')
|
.label('percent', {
|
layout: [{ type: 'limit-in-plot', cfg: { action: 'ellipsis'/** 或 translate */ } }],
|
content: (data) => {
|
/* var percent = data.percent * 100
|
console.info(percent)
|
percent = percent.toFixed(2)
|
percent = percent + '%'*/
|
return `${data.type}: ${data.value} `
|
}
|
})
|
.adjust('stack')
|
|
chart.interaction('element-active')
|
|
chart.render()
|
},
|
initChart5(chartData5) {
|
|
|
const chart = new Chart({
|
container: 'chart5',
|
autoFit: true,
|
height: 300
|
})
|
chart.coordinate('theta', {
|
radius: 0.75
|
})
|
|
chart.data(chartData5)
|
|
chart.scale('percent', {
|
formatter: (val) => {
|
if (!val) return val
|
val = val * 100
|
val = val.toFixed(2)
|
val = val + '%'
|
return val
|
}
|
})
|
|
chart.tooltip({
|
showTitle: false,
|
showMarkers: false
|
})
|
|
chart
|
.interval()
|
.position('percent')
|
.color('type')
|
.label('percent', {
|
layout: [{ type: 'limit-in-plot', cfg: { action: 'ellipsis'/** 或 translate */ } }],
|
content: (data) => {
|
/* var percent = data.percent * 100
|
console.info(percent)
|
percent = percent.toFixed(2)
|
percent = percent + '%'*/
|
return `${data.type}: ${data.value} `
|
}
|
})
|
.adjust('stack')
|
|
chart.interaction('element-active')
|
|
chart.render()
|
},
|
initChart6(chartData6){
|
const { DataView } = DataSet;
|
|
const dv = new DataView();
|
dv.source(chartData6, {
|
type: 'hierarchy',
|
}).transform({
|
field: 'value',
|
type: 'hierarchy.treemap',
|
tile: 'treemapResquarify',
|
as: ['x', 'y'],
|
});
|
|
// 将 DataSet 处理后的结果转换为 G2 接受的数据
|
const nodes = [];
|
for (const node of dv.getAllNodes()) {
|
if (node.data.name === 'root') {
|
continue;
|
}
|
const eachNode = {
|
name: node.data.name,
|
x: node.x,
|
y: node.y,
|
value: node.data.value,
|
};
|
|
nodes.push(eachNode);
|
}
|
const chart = new Chart({
|
container: 'chart6',
|
autoFit: true,
|
height: 300,
|
});
|
chart.data(nodes);
|
chart.scale({
|
x: {
|
nice: true,
|
},
|
y: {
|
nice: true,
|
},
|
});
|
|
chart.axis(false);
|
chart.legend(false);
|
chart.tooltip({
|
showTitle: false,
|
showMarkers: false,
|
itemTpl:
|
'<li style="list-style: none;">' +
|
'<span style="background-color:{color};" class="g2-tooltip-marker"></span>' +
|
'{name}<br/>' +
|
'<span style="padding-left: 16px">览数:{count}</span><br/>' +
|
'</li>',
|
});
|
chart
|
.polygon()
|
.position('x*y')
|
.color('name')
|
.tooltip('name*value', (name, count) => {
|
return {
|
name,
|
count,
|
};
|
})
|
.style({
|
lineWidth: 1,
|
stroke: '#fff'
|
})
|
.label('name', {
|
offset: 0,
|
style: {
|
textBaseline: 'middle',
|
},
|
content: (obj) => {
|
if (obj.name !== 'root') {
|
return obj.name + "(" +obj.value+ ")";
|
}
|
},
|
});
|
chart.interaction('element-active');
|
|
chart.render();
|
|
},
|
cardClick(index) {
|
console.info(index)
|
}
|
},
|
computed: {
|
totalUser() {
|
let total = get(this.model, 'departList[0].userList.length') || 0
|
return total + ''
|
},
|
regularEmployee() {
|
let departList = get(this.model, 'departList')
|
if (departList.length > 0) {
|
if (departList[0].userList) {
|
let userList = departList[0].userList
|
userList = userList.filter(item => item.staffing == 1)
|
return userList.length + ''
|
}
|
|
}
|
return '0'
|
},
|
probEmployee() {
|
let departList = get(this.model, 'departList')
|
if (departList.length > 0) {
|
if (departList[0].userList) {
|
let userList = departList[0].userList
|
userList = userList.filter(item => item.employ == 2)
|
return userList.length + ''
|
}
|
|
}
|
return '0'
|
},
|
gradEmployee() {
|
let departList = get(this.model, 'departList')
|
if (departList.length > 0) {
|
if (departList[0].userList) {
|
let userList = departList[0].userList
|
userList = userList.filter(item => item.grad == 1)
|
return userList.length + ''
|
}
|
|
}
|
return '0'
|
}
|
|
}
|
|
}
|
</script>
|
|
<style lang='less' scoped>
|
.chart-box {
|
padding: 10px;
|
}
|
|
.pointer {
|
cursor: pointer;
|
}
|
|
</style>
|