| | |
| | | <PanelHeader title="人员分布" /> |
| | | <div class="main-panel panel-item-customers"> |
| | | <Echarts |
| | | ref="echartsRef" |
| | | :chartStyle="chartStyle" |
| | | :legend="pieLegend" |
| | | :series="pieSeries" |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue' |
| | | import { getProgressStatistics } from '@/api/viewIndex.js' |
| | | import { ref, onMounted, computed } from 'vue' |
| | | import { deptStaffDistribution } from '@/api/viewIndex.js' |
| | | import PanelHeader from '../PanelHeader.vue' |
| | | import Echarts from '@/components/Echarts/echarts.vue' |
| | | |
| | | /** |
| | | * @introduction 把数组中key值相同的那一项提取出来,组成一个对象 |
| | | * @description 详细描述 |
| | | * @param {参数类型} array 传入的数组 [{a:"1",b:"2"},{a:"2",b:"3"}] |
| | | * @param {参数类型} key 属性名 a |
| | | * @return {返回类型说明} |
| | | * @exception [违例类型] [违例类型说明] |
| | | */ |
| | | function array2obj(array, key) { |
| | | const resObj = {} |
| | |
| | | height: '100%', |
| | | } |
| | | |
| | | // 饼图数据(示例) |
| | | const pieDatas = [ |
| | | { value: 335, name: '进入区域', percent: '10' }, |
| | | { value: 310, name: '区域入侵', percent: '40' }, |
| | | { value: 274, name: '人员聚集', percent: '30' }, |
| | | { value: 235, name: '越界侦测', percent: '20' }, |
| | | ] |
| | | const echartsRef = ref(null) |
| | | const pieDatas = ref([]) |
| | | const pieColors = ['#D1E4F5', '#5782F7', '#2F67EF', '#82BAFF', '#43e8fc', '#27EBE7'] |
| | | |
| | | const pieColors = ['#D1E4F5', '#5782F7', '#2F67EF', '#82BAFF'] |
| | | const pieLegendData = pieDatas.map((d, idx) => ({ |
| | | const pieObjData = computed(() => array2obj(pieDatas.value, 'name')) |
| | | |
| | | const pieLegend = computed(() => { |
| | | const data = pieDatas.value.map((d, idx) => ({ |
| | | name: d.name, |
| | | icon: 'circle', |
| | | textStyle: { |
| | | fontSize: 18, |
| | | color: pieColors[idx], |
| | | color: pieColors[idx % pieColors.length], |
| | | }, |
| | | })) |
| | | const pieObjData = array2obj(pieDatas, 'name') |
| | | |
| | | const pieLegend = { |
| | | return { |
| | | orient: 'vertical', |
| | | top: 'center', |
| | | left: '50%', |
| | | itemGap: 30, |
| | | data: pieLegendData, |
| | | data: data, |
| | | formatter: function (name) { |
| | | return `{title|${name}}{value|${pieObjData[name].value}}{unit|人}{percent|${pieObjData[name].percent}}{unit|%}` |
| | | const item = pieObjData.value[name] |
| | | if (!item) return name |
| | | return `{title|${name}}{value|${item.value}}{unit|人}{percent|${item.rate}}{unit|%}` |
| | | }, |
| | | textStyle: { |
| | | rich: { |
| | |
| | | }, |
| | | }, |
| | | } |
| | | }) |
| | | |
| | | const pieTooltip = { |
| | | trigger: 'item', |
| | | formatter: '{a} <br/>{b} : {c} ({d}%)', |
| | | } |
| | | |
| | | const pieSeries = ref([ |
| | | const pieSeries = computed(() => [ |
| | | { |
| | | name: '访问来源', |
| | | name: '人员分布', |
| | | type: 'pie', |
| | | radius: '70%', |
| | | center: ['20%', '50%'], |
| | | itemStyle: { |
| | | // 给每个扇区加分隔缝隙,颜色取深色背景 |
| | | borderColor: '#0a1c3a', |
| | | borderWidth: 4, |
| | | borderWidth: 2, |
| | | }, |
| | | label: { |
| | | show: false |
| | | }, |
| | | data: pieDatas, |
| | | roseType: 'radius', |
| | | minAngle: 15, |
| | | data: pieDatas.value, |
| | | animationType: 'scale', |
| | | animationEasing: 'elasticOut', |
| | | animationDelay: function () { |
| | |
| | | backgroundColor: 'transparent', |
| | | textStyle: { color: '#B8C8E0' }, |
| | | } |
| | | |
| | | const getDeptStaffDistribution = () => { |
| | | deptStaffDistribution().then(res => { |
| | | if (res.code === 200) { |
| | | pieDatas.value = res.data.items.map(item => ({ |
| | | name: item.name, |
| | | value: parseInt(item.value), |
| | | rate: item.rate |
| | | })) |
| | | } |
| | | }).catch(err => { |
| | | console.error('获取部门人员分布数据失败:', err) |
| | | }) |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getDeptStaffDistribution() |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped> |