人员缴费分析
This commit is contained in:
@@ -1,12 +1,515 @@
|
||||
<template>
|
||||
<div class="p-2 h-full flex flex-col">
|
||||
<Pageheader></Pageheader>
|
||||
<div class="flex-1 color-gray flex h-full font-size-6 flex-center">系统还在维护中,敬请期待...</div>
|
||||
<div class="personnel p-2 h-full flex flex-col">
|
||||
<div class="flex flex-items-center searchBox">
|
||||
<div class="searchLabel">选择日期</div>
|
||||
<el-date-picker
|
||||
v-model="date"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
value-format="yyyy-MM-dd"
|
||||
style="width: 400px; margin-right: 10px"
|
||||
></el-date-picker>
|
||||
<el-button type="primary">查询</el-button>
|
||||
<el-button>重置</el-button>
|
||||
</div>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="16">
|
||||
<div class="cardbox">
|
||||
<div>收入来源</div>
|
||||
<div class="cardbody" style="height: 200px">
|
||||
<div class="flex flex-col flex-items-center flex-1">
|
||||
<Echarts :options="options"></Echarts>
|
||||
<div>停车费</div>
|
||||
</div>
|
||||
<div class="flex flex-col flex-items-center flex-1">
|
||||
<Echarts :options="options"></Echarts>
|
||||
<div>物业费</div>
|
||||
</div>
|
||||
<div class="flex flex-col flex-items-center flex-1">
|
||||
<Echarts :options="options"></Echarts>
|
||||
<div>商铺租金</div>
|
||||
</div>
|
||||
<div class="flex flex-col flex-items-center flex-1">
|
||||
<Echarts :options="options"></Echarts>
|
||||
<div>水电费</div>
|
||||
</div>
|
||||
<div class="flex flex-col flex-items-center flex-1">
|
||||
<Echarts :options="options"></Echarts>
|
||||
<div>维修费</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="cardbox">
|
||||
<div>缴费方式</div>
|
||||
<div class="cardbody w-full" style="height: 150px">
|
||||
<Echarts :options="options2"></Echarts>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div class="" style="height: 20px"></div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="16">
|
||||
<div class="cardbox w-full" style="height: 400px">
|
||||
<Echarts :options="options3"></Echarts>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="cardbox w-full" style="height: 400px">
|
||||
<div class="" style="height: 50px; margin-bottom: 20px">缴费方式</div>
|
||||
<div flex flex-items-center justify-center>
|
||||
<ul class="legendbox">
|
||||
<li>小程序</li>
|
||||
<li>物业缴费</li>
|
||||
<li>手机APP</li>
|
||||
</ul>
|
||||
<ul class="circlebox">
|
||||
<li>70%</li>
|
||||
<li>20%</li>
|
||||
<li>10%</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div class="" style="height: 20px"></div>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<div class="cardbox w-full" style="height: 450px">
|
||||
<Echarts :options="flowLineOption"></Echarts>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import Echarts from '@/components/Echarts/index.vue';
|
||||
import { EChartsOption } from 'echarts';
|
||||
import { getLast7Days, getLastNDays } from '@/utils/time';
|
||||
|
||||
/** 入住情况 */
|
||||
const options = shallowRef<EChartsOption>({
|
||||
tooltip: { show: false },
|
||||
series: [
|
||||
// 1. 底层细圆环(灰色底色)
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['60%', '80%'], // 细一点
|
||||
clockwise: true,
|
||||
data: [100],
|
||||
itemStyle: { color: '#ebeef5' },
|
||||
emphasis: { disabled: true },
|
||||
label: { show: false }
|
||||
},
|
||||
// 2. 上层粗圆环(进度条)
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['60%', '85%'], // 粗一点
|
||||
clockwise: true,
|
||||
itemStyle: {
|
||||
color: '#409eff',
|
||||
borderRadius: 10
|
||||
},
|
||||
emphasis: { disabled: true },
|
||||
label: {
|
||||
show: true,
|
||||
position: 'center',
|
||||
fontSize: 20,
|
||||
fontWeight: 'bold',
|
||||
formatter: '85%'
|
||||
},
|
||||
data: [{ value: 85 }, { value: 15, itemStyle: { color: 'transparent' } }]
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
/** 入住类型 */
|
||||
const options1 = shallowRef<EChartsOption>({
|
||||
legend: {
|
||||
top: 'center',
|
||||
left: '0',
|
||||
orient: 'vertical',
|
||||
itemGap: 50
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'Access From',
|
||||
type: 'pie',
|
||||
radius: ['50%', '100%'],
|
||||
avoidLabelOverlap: false,
|
||||
left: '50%',
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center'
|
||||
},
|
||||
tooltip: {
|
||||
show: false
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: false,
|
||||
fontSize: 20,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{ value: 25, name: '业主', itemStyle: { color: '#0a74fe' } },
|
||||
{ value: 25, name: '租户', itemStyle: { color: '#fe3d4e' } },
|
||||
{ value: 25, name: '亲属', itemStyle: { color: '#00cf7f' } },
|
||||
{ value: 25, name: '其他', itemStyle: { color: '#f48e3b' } }
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
/** 缴费方式 */
|
||||
const options2 = shallowRef<EChartsOption>({
|
||||
legend: {
|
||||
top: 'center',
|
||||
left: '0',
|
||||
orient: 'vertical',
|
||||
itemGap: 50
|
||||
},
|
||||
clockwise: true,
|
||||
series: [
|
||||
{
|
||||
name: 'Access From',
|
||||
type: 'pie',
|
||||
startAngle: 280,
|
||||
radius: ['50%', '100%'],
|
||||
avoidLabelOverlap: false,
|
||||
left: '50%',
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center'
|
||||
},
|
||||
tooltip: {
|
||||
show: false
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: false,
|
||||
fontSize: 20,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{ value: 50, name: '支付宝', itemStyle: { color: '#0a74fe' } },
|
||||
{ value: 30, name: '微信', itemStyle: { color: '#f74043' } },
|
||||
{ value: 20, name: '线下', itemStyle: { color: '#fcd152' } }
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// ! 年龄分布 -------------------------------------------------------------------------------------
|
||||
const agesX = ['6岁以下', '6-11岁', '11-14岁', '15-24岁', '25-30岁', '31-40岁', '41-50岁', '51-61岁', '61-65岁', '65-70岁', '70岁以上'];
|
||||
const agesData = [520, 680, 460, 750, 1350, 1860, 1420, 960, 630, 380, 210];
|
||||
// 🔥 关键:灰色背景数据 = 最大值 - 真实数据(互补100%)
|
||||
const maxValue = 2000; // 设定总高度(可自行调整)
|
||||
const middleHeight = 20;
|
||||
const barwidth = '10%';
|
||||
const bgData = agesData.map((item) => maxValue - item - middleHeight);
|
||||
const bgData2 = agesData.map((item) => middleHeight);
|
||||
/** 年龄分布 */
|
||||
const options3 = shallowRef<EChartsOption>({
|
||||
title: {
|
||||
text: '住户年龄分布',
|
||||
left: '0',
|
||||
top: '0',
|
||||
textStyle: { fontSize: 16, fontWeight: 'bold' }
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
top: '12%',
|
||||
bottom: '8%',
|
||||
containLabel: true
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
confine: true,
|
||||
axisPointer: { type: 'shadow' }
|
||||
},
|
||||
// 鼠标悬浮高亮当前,其他隐藏
|
||||
|
||||
xAxis: { type: 'category', data: agesX, axisLabel: { interval: 0 } },
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
splitLine: { show: true, lineStyle: { color: '#eee' } }
|
||||
},
|
||||
series: [
|
||||
// 蓝色真实数据
|
||||
{
|
||||
type: 'bar',
|
||||
barWidth: barwidth,
|
||||
data: agesData,
|
||||
itemStyle: {
|
||||
color: '#409eff',
|
||||
borderRadius: [4, 4, 0, 0]
|
||||
},
|
||||
stack: 'total'
|
||||
},
|
||||
{
|
||||
type: 'bar',
|
||||
barWidth: barwidth,
|
||||
data: bgData2,
|
||||
tooltip: { show: false }, // 关键:不显示提示
|
||||
itemStyle: {
|
||||
color: '#fff'
|
||||
},
|
||||
stack: 'total'
|
||||
},
|
||||
{
|
||||
type: 'bar',
|
||||
barWidth: barwidth,
|
||||
data: bgData,
|
||||
tooltip: { show: false }, // 关键:不显示提示
|
||||
itemStyle: {
|
||||
color: 'rgba(180, 180, 180, 0.2)'
|
||||
},
|
||||
stack: 'total'
|
||||
}
|
||||
]
|
||||
});
|
||||
// ! 年龄分布 -------------------------------------------------------------------------------------
|
||||
|
||||
// ! 职业分布比例 -------------------------------------------------------------------------------------
|
||||
|
||||
// ! 职业分布比例 -------------------------------------------------------------------------------------
|
||||
|
||||
// ! 人员流动情况 -------------------------------------------------------------------------------------
|
||||
// 近10天日期
|
||||
const dayX = getLast7Days(10);
|
||||
|
||||
// 小区真实规模:人员流入 / 流出 数据
|
||||
const inData = [97, 145, 63, 112, 88, 156, 74, 131, 102, 59];
|
||||
const outData = [121, 85, 142, 71, 135, 93, 116, 66, 148, 104];
|
||||
|
||||
/** 进十日缴费数量情况 - 平滑折线图 */
|
||||
const flowLineOption = shallowRef<EChartsOption>({
|
||||
title: {
|
||||
text: '进十日缴费数量趋势',
|
||||
left: 0,
|
||||
top: 0,
|
||||
textStyle: { fontSize: 14, fontWeight: 'normal' }
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
confine: true
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
top: '12%',
|
||||
bottom: '8%',
|
||||
containLabel: true
|
||||
},
|
||||
legend: {
|
||||
data: ['已缴费', '未缴费'],
|
||||
right: 10,
|
||||
top: 0
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: dayX,
|
||||
boundaryGap: false,
|
||||
axisLine: { lineStyle: { color: '#eee' } }
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: { color: '#eee' }
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '已缴费',
|
||||
type: 'line',
|
||||
smooth: true, // 平滑折线 核心
|
||||
data: inData,
|
||||
symbol: 'circle',
|
||||
symbolSize: 6,
|
||||
itemStyle: { color: '#f94144' },
|
||||
lineStyle: { width: 4 },
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: '#fbd7d9' },
|
||||
{ offset: 1, color: '#fbd7d9' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '未缴费',
|
||||
type: 'line',
|
||||
smooth: true, // 平滑折线 核心
|
||||
data: outData,
|
||||
symbol: 'circle',
|
||||
symbolSize: 6,
|
||||
itemStyle: { color: '#f9c74f' },
|
||||
lineStyle: { width: 4 },
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: '#fcf2dc' },
|
||||
{ offset: 1, color: '#fcf2dc' }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
// ! 人员流动情况 -------------------------------------------------------------------------------------
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
<style scoped lang="scss">
|
||||
.personnel {
|
||||
background: linear-gradient(180deg, #deedff 0%, #f8f9fe 50%);
|
||||
.el-button {
|
||||
width: 80px;
|
||||
height: 32px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.searchBox {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.searchLabel {
|
||||
width: 100px;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
// 入住清空
|
||||
.cardbox {
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.2) 0%, #ffffff 70%);
|
||||
border-radius: 16px 16px 16px 16px;
|
||||
border: 2px solid #ffffff;
|
||||
font-size: 20px;
|
||||
padding: 20px;
|
||||
min-height: 275px;
|
||||
.cardbody {
|
||||
padding: 0 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
.card_leftbox {
|
||||
text-align: center;
|
||||
.labelbox {
|
||||
font-size: 16px;
|
||||
}
|
||||
.valuebox {
|
||||
font-weight: 600;
|
||||
font-size: 36px;
|
||||
color: #222222;
|
||||
}
|
||||
}
|
||||
.echartsbox {
|
||||
width: 400px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.legendbox {
|
||||
font-size: 0.8rem;
|
||||
li {
|
||||
margin-bottom: 20px;
|
||||
position: relative;
|
||||
width: 100px;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
text-align: left;
|
||||
padding-left: 30px;
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
display: block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
background: #c893fd;
|
||||
}
|
||||
|
||||
&:first-of-type {
|
||||
&::after {
|
||||
background: #4a3aff;
|
||||
}
|
||||
}
|
||||
&:last-of-type {
|
||||
&::after {
|
||||
background: #1e1b39;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.circlebox {
|
||||
margin-left: 60px;
|
||||
position: relative;
|
||||
width: 300px;
|
||||
height: 200px;
|
||||
transform: translateY(-40px);
|
||||
li {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
border-radius: 50%;
|
||||
background-color: #c893fd;
|
||||
border: 3px solid white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #fff;
|
||||
font-size: 1.4rem;
|
||||
font-weight: 450;
|
||||
z-index: 10;
|
||||
&:nth-child(1) {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
right: inherit;
|
||||
left: 0px;
|
||||
font-size: 2rem;
|
||||
top: 30px;
|
||||
z-index: 9;
|
||||
background-color: #4a3aff;
|
||||
}
|
||||
&:nth-child(3) {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
left: inherit;
|
||||
top: inherit;
|
||||
right: 50px;
|
||||
font-size: 1.1rem;
|
||||
bottom: -20px;
|
||||
z-index: 11;
|
||||
background-color: #1e1b39;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,12 +1,477 @@
|
||||
<template>
|
||||
<div class="p-2 h-full flex flex-col">
|
||||
<Pageheader></Pageheader>
|
||||
<div class="flex-1 color-gray flex h-full font-size-6 flex-center">系统还在维护中,敬请期待...</div>
|
||||
<div class="personnel p-2 h-full flex flex-col">
|
||||
<div class="flex flex-items-center searchBox">
|
||||
<div class="searchLabel">选择日期</div>
|
||||
<el-date-picker
|
||||
v-model="date"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
value-format="yyyy-MM-dd"
|
||||
style="width: 400px; margin-right: 10px"
|
||||
></el-date-picker>
|
||||
<el-button type="primary">查询</el-button>
|
||||
<el-button>重置</el-button>
|
||||
</div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<div class="cardbox">
|
||||
<div>入住情况</div>
|
||||
<div class="cardbody" style="height: 200px">
|
||||
<div class="card_leftbox">
|
||||
<div class="valuebox">4889</div>
|
||||
<div class="labelbox">入住人数</div>
|
||||
</div>
|
||||
<div class="echartsbox h-full">
|
||||
<Echarts :options="options"></Echarts>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="cardbox">
|
||||
<div>住户分析情况</div>
|
||||
<div class="cardbody w-full" style="height: 150px">
|
||||
<Echarts :options="options1"></Echarts>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="cardbox">
|
||||
<div>男女比例</div>
|
||||
<div class="cardbody w-full" style="height: 150px">
|
||||
<Echarts :options="options2"></Echarts>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div class="" style="height: 20px"></div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="16">
|
||||
<div class="cardbox w-full" style="height: 400px">
|
||||
<Echarts :options="options3"></Echarts>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="cardbox w-full" style="height: 400px">
|
||||
<Echarts :options="options4"></Echarts>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div class="" style="height: 20px"></div>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<div class="cardbox w-full" style="height: 450px">
|
||||
<Echarts :options="flowLineOption"></Echarts>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import Echarts from '@/components/Echarts/index.vue';
|
||||
import { EChartsOption } from 'echarts';
|
||||
import { getLast7Days, getLastNDays } from '@/utils/time';
|
||||
|
||||
/** 入住情况 */
|
||||
const options = shallowRef<EChartsOption>({
|
||||
tooltip: { show: false },
|
||||
series: [
|
||||
// 1. 底层细圆环(灰色底色)
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['68%', '90%'], // 细一点
|
||||
clockwise: true,
|
||||
data: [100],
|
||||
itemStyle: { color: '#ebeef5' },
|
||||
emphasis: { disabled: true },
|
||||
label: { show: false }
|
||||
},
|
||||
// 2. 上层粗圆环(进度条)
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['65%', '98%'], // 粗一点
|
||||
clockwise: true,
|
||||
itemStyle: {
|
||||
color: '#409eff',
|
||||
borderRadius: 10
|
||||
},
|
||||
emphasis: { disabled: true },
|
||||
label: {
|
||||
show: true,
|
||||
position: 'center',
|
||||
fontSize: 20,
|
||||
fontWeight: 'bold',
|
||||
formatter: ' 85% \n\n 入住率'
|
||||
},
|
||||
data: [{ value: 85 }, { value: 15, itemStyle: { color: 'transparent' } }]
|
||||
}
|
||||
]
|
||||
});
|
||||
function getRingOption(percent) {
|
||||
return {
|
||||
tooltip: { show: false },
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['78%', '88%'],
|
||||
data: [100],
|
||||
itemStyle: { color: '#ebeef5' },
|
||||
emphasis: { disabled: true },
|
||||
label: { show: false }
|
||||
},
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['75%', '90%'],
|
||||
itemStyle: { color: '#409eff', borderRadius: 10 },
|
||||
emphasis: { disabled: true },
|
||||
label: {
|
||||
show: true,
|
||||
position: 'center',
|
||||
fontSize: 18,
|
||||
fontWeight: 'bold',
|
||||
formatter: percent + '%'
|
||||
},
|
||||
data: [{ value: percent }, { value: 100 - percent, itemStyle: { color: 'transparent' } }]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
/** 入住类型 */
|
||||
const options1 = shallowRef<EChartsOption>({
|
||||
legend: {
|
||||
top: 'center',
|
||||
left: '0',
|
||||
orient: 'vertical',
|
||||
itemGap: 50
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'Access From',
|
||||
type: 'pie',
|
||||
radius: ['50%', '100%'],
|
||||
avoidLabelOverlap: false,
|
||||
left: '50%',
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center'
|
||||
},
|
||||
tooltip: {
|
||||
show: false
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: false,
|
||||
fontSize: 20,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{ value: 25, name: '业主', itemStyle: { color: '#0a74fe' } },
|
||||
{ value: 25, name: '租户', itemStyle: { color: '#fe3d4e' } },
|
||||
{ value: 25, name: '亲属', itemStyle: { color: '#00cf7f' } },
|
||||
{ value: 25, name: '其他', itemStyle: { color: '#f48e3b' } }
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
/** 男女比例 */
|
||||
const options2 = shallowRef<EChartsOption>({
|
||||
legend: {
|
||||
top: 'center',
|
||||
left: '0',
|
||||
orient: 'vertical',
|
||||
itemGap: 50
|
||||
},
|
||||
clockwise: true,
|
||||
series: [
|
||||
{
|
||||
name: 'Access From',
|
||||
type: 'pie',
|
||||
startAngle: 280,
|
||||
radius: ['50%', '100%'],
|
||||
avoidLabelOverlap: false,
|
||||
left: '50%',
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center'
|
||||
},
|
||||
tooltip: {
|
||||
show: false
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: false,
|
||||
fontSize: 20,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{ value: 60, name: '男', itemStyle: { color: '#0a74fe' } },
|
||||
{ value: 40, name: '女', itemStyle: { color: '#f74043' } }
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// ! 年龄分布 -------------------------------------------------------------------------------------
|
||||
const agesX = ['6岁以下', '6-11岁', '11-14岁', '15-24岁', '25-30岁', '31-40岁', '41-50岁', '51-61岁', '61-65岁', '65-70岁', '70岁以上'];
|
||||
const agesData = [520, 680, 460, 750, 1350, 1860, 1420, 960, 630, 380, 210];
|
||||
// 🔥 关键:灰色背景数据 = 最大值 - 真实数据(互补100%)
|
||||
const maxValue = 2000; // 设定总高度(可自行调整)
|
||||
const middleHeight = 20;
|
||||
const barwidth = '10%';
|
||||
const bgData = agesData.map((item) => maxValue - item - middleHeight);
|
||||
const bgData2 = agesData.map((item) => middleHeight);
|
||||
/** 年龄分布 */
|
||||
const options3 = shallowRef<EChartsOption>({
|
||||
title: {
|
||||
text: '住户年龄分布',
|
||||
left: '0',
|
||||
top: '0',
|
||||
textStyle: { fontSize: 16, fontWeight: 'bold' }
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
top: '12%',
|
||||
bottom: '8%',
|
||||
containLabel: true
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
confine: true,
|
||||
axisPointer: { type: 'shadow' }
|
||||
},
|
||||
// 鼠标悬浮高亮当前,其他隐藏
|
||||
|
||||
xAxis: { type: 'category', data: agesX, axisLabel: { interval: 0 } },
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
splitLine: { show: true, lineStyle: { color: '#eee' } }
|
||||
},
|
||||
series: [
|
||||
// 蓝色真实数据
|
||||
{
|
||||
type: 'bar',
|
||||
barWidth: barwidth,
|
||||
data: agesData,
|
||||
itemStyle: {
|
||||
color: '#409eff',
|
||||
borderRadius: [4, 4, 0, 0]
|
||||
},
|
||||
stack: 'total'
|
||||
},
|
||||
{
|
||||
type: 'bar',
|
||||
barWidth: barwidth,
|
||||
data: bgData2,
|
||||
tooltip: { show: false }, // 关键:不显示提示
|
||||
itemStyle: {
|
||||
color: '#fff'
|
||||
},
|
||||
stack: 'total'
|
||||
},
|
||||
{
|
||||
type: 'bar',
|
||||
barWidth: barwidth,
|
||||
data: bgData,
|
||||
tooltip: { show: false }, // 关键:不显示提示
|
||||
itemStyle: {
|
||||
color: 'rgba(180, 180, 180, 0.2)'
|
||||
},
|
||||
stack: 'total'
|
||||
}
|
||||
]
|
||||
});
|
||||
// ! 年龄分布 -------------------------------------------------------------------------------------
|
||||
// ! 职业分布比例 -------------------------------------------------------------------------------------
|
||||
// 真实小区职业分布数据(上班族最多,依次递减)
|
||||
const realData = [120, 260, 580, 620, 1480];
|
||||
const options4 = shallowRef<EChartsOption>({
|
||||
title: {
|
||||
text: '职业分布比例',
|
||||
left: '0',
|
||||
top: '0',
|
||||
textStyle: { fontSize: 16, fontWeight: 'bold' }
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
type: 'value',
|
||||
boundaryGap: [0, 0.01]
|
||||
},
|
||||
yAxis: {
|
||||
type: 'category',
|
||||
data: ['其他', '自由职业', '学生', '全职妈妈', '上班族']
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '2011',
|
||||
type: 'bar',
|
||||
itemStyle: {
|
||||
color: '#fe3d4e'
|
||||
},
|
||||
data: realData
|
||||
}
|
||||
]
|
||||
});
|
||||
// ! 职业分布比例 -------------------------------------------------------------------------------------
|
||||
|
||||
// ! 人员流动情况 -------------------------------------------------------------------------------------
|
||||
// 近10天日期
|
||||
const dayX = getLast7Days(10);
|
||||
|
||||
// 小区真实规模:人员流入 / 流出 数据
|
||||
// 【全新打乱随机数据】小区人员流入 / 流出
|
||||
const inData = [132, 76, 158, 91, 125, 68, 143, 84, 107, 162];
|
||||
const outData = [95, 136, 72, 118, 83, 149, 65, 124, 101, 77];
|
||||
|
||||
/** 近十天人员流入流出 - 平滑折线图 */
|
||||
const flowLineOption = shallowRef<EChartsOption>({
|
||||
title: {
|
||||
text: '近十日人员流动趋势',
|
||||
left: 0,
|
||||
top: 0,
|
||||
textStyle: { fontSize: 14, fontWeight: 'normal' }
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
confine: true
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
top: '12%',
|
||||
bottom: '8%',
|
||||
containLabel: true
|
||||
},
|
||||
legend: {
|
||||
data: ['人员流入', '人员流出'],
|
||||
right: 10,
|
||||
top: 0
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: dayX,
|
||||
boundaryGap: false,
|
||||
axisLine: { lineStyle: { color: '#eee' } }
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: { color: '#eee' }
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '人员流入',
|
||||
type: 'line',
|
||||
smooth: true, // 平滑折线 核心
|
||||
data: inData,
|
||||
symbol: 'circle',
|
||||
symbolSize: 6,
|
||||
itemStyle: { color: '#f94144' },
|
||||
lineStyle: { width: 4 },
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: '#fbd7d9' },
|
||||
{ offset: 1, color: '#fbd7d9' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '人员流出',
|
||||
type: 'line',
|
||||
smooth: true, // 平滑折线 核心
|
||||
data: outData,
|
||||
symbol: 'circle',
|
||||
symbolSize: 6,
|
||||
itemStyle: { color: '#f9c74f' },
|
||||
lineStyle: { width: 4 },
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: '#fcf2dc' },
|
||||
{ offset: 1, color: '#fcf2dc' }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
// ! 人员流动情况 -------------------------------------------------------------------------------------
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
<style scoped lang="scss">
|
||||
.personnel {
|
||||
background: linear-gradient(180deg, #deedff 0%, #f8f9fe 50%);
|
||||
.el-button {
|
||||
width: 80px;
|
||||
height: 32px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.searchBox {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.searchLabel {
|
||||
width: 100px;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
// 入住清空
|
||||
.cardbox {
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.2) 0%, #ffffff 70%);
|
||||
border-radius: 16px 16px 16px 16px;
|
||||
border: 2px solid #ffffff;
|
||||
font-size: 20px;
|
||||
padding: 20px;
|
||||
min-height: 275px;
|
||||
.cardbody {
|
||||
padding: 0 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
.card_leftbox {
|
||||
text-align: center;
|
||||
.labelbox {
|
||||
font-size: 16px;
|
||||
}
|
||||
.valuebox {
|
||||
font-weight: 600;
|
||||
font-size: 36px;
|
||||
color: #222222;
|
||||
}
|
||||
}
|
||||
.echartsbox {
|
||||
width: 400px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user