Browse Source

统计分析改版

v3
蟑螂恶霸 2 years ago
parent
commit
b52b27a4e6
  1. BIN
      src/assets/images/bg_count.jpg
  2. 542
      src/views/common/analyse-back.vue
  3. 390
      src/views/common/analyse.vue

BIN
src/assets/images/bg_count.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 17 KiB

542
src/views/common/analyse-back.vue

@ -0,0 +1,542 @@
<template>
<div class="address_edit">
<!-- 导航栏 -->
<!-- <div class="header_body">
<header-nav
:slefBack="true"
@goBack="goBack"
:titelText="`统计分析`"
>
</header-nav>
</div> -->
<!-- 中间 -->
<div class="warp_body">
<div class="countbox">
<span class="count-tit">本月执法</span>
<span class="count-tot"><b>{{ data.allTotal }}</b>件</span>
<span class="count-com"><i>投诉:</i><b>{{ data.complaintCount }}</b>件</span>
</div>
<div class="analybox">
<div class="title">检查类别</div>
<div id="echartRing" class="chartbox"></div>
<div id="echartLine" class="chartbox"></div>
</div>
<div class="analybox">
<div class="title">执法人员</div>
<div id="echartLineUser" class="chartbox" style="height: 10rem;"></div>
</div>
<div class="analybox">
<div class="title">案件数量</div>
<div id="echarCount" class="chartbox"></div>
</div>
<div class="analybox">
<div class="title">企业类型</div>
<div id="echartLineCompany" class="chartbox"></div>
</div>
</div>
</div>
</template>
<script setup name="addressEdit">
import {onBeforeUnmount} from 'vue';
import util from "@/util/area";
import {queryStatisticalData} from '@/api/enforce';
import * as echarts from 'echarts';
const {useCommon, useShopCard} = $globalStore;
const router = useRouter();
const route = useRoute();
let queryaddressId = ref("");
const data = reactive({
searchResult: [],
areaList: util.areaList,
addressInfo: {},
areaColumns: ["请选择", "请选择", "请选择"],
allTotal: 0,
complaintCount: 0
});
// 返回
const goBack = () => {
router.go(-1);
};
onBeforeUnmount(() => {
// 当前路由不是首页,且用户确认离开时
router.replace('/enforceHome'); // 替换到首页
});
onUnmounted(() => {
console.log("=============销毁完毕=============")
const chartEle = document.getElementById("echartRing");
console.log(chartEle)
// chartEle.removeAttribute('_echarts_instance_')
});
// 保存地址操作
const onSave = () => {
router.replace({name: "addressList"});
};
// 删除地址操作
const onDelete = () => {
router.replace({name: "addressList"});
};
// 修改详细地址
const onChangeDetail = () => {
};
const echartInit = (data, targetId) => {
var container = document.getElementById(targetId);
var myChart = echarts.getInstanceByDom(container);
if (myChart) {
myChart.dispose();
}
myChart = echarts.init(document.getElementById(targetId));
// 指定图表的配置项和数据
let option = {
tooltip: {
trigger: 'item'
},
series: [
{
name: '统计图表',
type: 'pie',
silent: true, // 设置所有的点击事件为静默模式
radius: ['33%', '50%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 0,
borderColor: '#fff',
borderWidth: 1
},
emphasis: {
label: {
show: true,
fontSize: '14',
fontWeight: 'bold'
}
},
label: {
normal: {
show: true,
position: 'outside', // 标签显示在外部
formatter: '{b}\n{c} ({d}%)', // 标签格式化,b是数据名,c是数值,d是百分比
textStyle: {
fontSize: 14,
rich: {
a: {
width: 100,
overflow: 'truncate', // 文字超出宽度时截断
textOverflow: 'ellipsis', // 文字超出宽度时显示省略号
},
},
},
},
},
// ... 其他配置项
data: data,
color: ['#0038bb', '#0047eb', '#1c60ff', '#3f78ff', '#6592ff', '#8aadff'],
}
]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
};
const initSchedule = (dataAll, targetId) => {
var container = document.getElementById(targetId);
var myChartLine = echarts.getInstanceByDom(container);
if (myChartLine) {
myChartLine.dispose();
}
myChartLine = echarts.init(document.getElementById(targetId));
let myColor = ['#3C83FF']
var option = {
tooltip: {
trigger: 'item',
},
grid: { // 直角坐标系内绘图网格
top: '-5%',
bottom: '5%',
left: '25%', //grid 组件离容器左侧的距离,
//left的值可以是80这样具体像素值,
//也可以是'80%'这样相对于容器高度的百分比
right: '25%',
//containLabel: true //gid区域是否包含坐标轴的刻度标签。为true的时候,
// left/right/top/bottom/width/height决定的是包括了坐标轴标签在内的
//所有内容所形成的矩形的位置.常用于【防止标签溢出】的场景
},
xAxis: { //直角坐标系grid中的x轴,
//一般情况下单个grid组件最多只能放上下两个x轴,
//多于两个x轴需要通过配置offset属性防止同个位置多个x轴的重叠。
type: 'value', //坐标轴类型,分别有:
//'value'-数值轴;'category'-类目轴;
//'time'-时间轴;'log'-对数轴
splitLine: {
show: false
}, //坐标轴在 grid 区域中的分隔线
axisLabel: {
show: false
}, //坐标轴刻度标签
axisTick: {
show: false
}, //坐标轴刻度
axisLine: {
show: false
}, //坐标轴轴线
},
yAxis: {
type: 'category',
axisTick: {
show: false
},
axisLine: {
show: false
},
axisLabel: {
color: 'rgba(0,0,0,.7)',
fontSize: 14,
formatter: function (data) {
var traceValue;
for (var i = 0; i < dataAll.dataX.length; i++) {
if (data === dataAll.dataX[i]) {
traceValue = dataAll.dataY[i]
break
}
}
var arr = [
'{a|' + data + '}',
'{b|' + traceValue + '}',
'{c|件}'
]
return arr.join('')
},
formatter: function (params) {
var maxLength = 6;
//判断长度,超出使用...代替
if (params && params.length > maxLength) {
return params.substring(0, maxLength - 1) + '.';
} else {
return params;
}
},
textStyle: {
rich: {
a: {
fontSize: 14,
//width: 100
},
b: {
fontSize: 14,
align: 'center',
color: '#3C83FF',
fontWeight: 600,
},
c: {
padding: [0, 0, 0, 5],
fontSize: 14,
align: 'center',
}
}
},
},
data: dataAll.dataX //类目数据,在类目轴(type: 'category')中有效。
//如果没有设置 type,但是设置了axis.data,则认为type 是 'category'。
},
series: [ //系列列表。每个系列通过 type 决定自己的图表类型
{
name: '', //系列名称
type: 'bar', //柱状、条形图
silent: true, // 设置所有柱子的点击事件为静默模式
barWidth: 15, //柱条的宽度,默认自适应
data: dataAll.dataPercent, //系列中数据内容数组
label: { //图形上的文本标签
show: true,
position: 'right', //标签的位置
offset: [0, 40], //标签文字的偏移,此处表示向上偏移40
//formatter: '{c}{a}',//标签内容格式器 {a}-系列名,{b}-数据名,{c}-数据值
formatter: function (data) {
//.toFixed(0)去掉小数位,如果为2就是保留两位小数
//let b = data.percent.toFixed(0) + "%";
//subText = b;
return '';
},
color: 'rgba(0,0,0,.7)', //标签字体颜色
fontSize: 26 //标签字号
},
itemStyle: { //图形样式
normal: { //normal 图形在默认状态下的样式;
//emphasis图形在高亮状态下的样式
barBorderRadius: 10, //柱条圆角半径,单位px.
//此处统一设置4个角的圆角大小;
//也可以分开设置[10,10,10,10]顺时针左上、右上、右下、左下
color: function (params) {
let num = myColor.length; //得到myColor颜色数组的长度
return myColor[params.dataIndex % num]; //返回颜色数组中的一个对应的颜色值
},
}
},
dataZoom: [
{
type: 'inside', // 设置为 inside 类型
orient: 'vertical', // 设置为垂直滚动条
start: 0,
end: 100,
left: "93%",
yAxisIndex: [0],
}
],
zlevel: 1 //柱状图所有图形的 zlevel 值,
//zlevel 大的 Canvas 会放在 zlevel 小的 Canvas 的上面
},
{
name: '',
type: 'bar',
silent: true, // 设置所有柱子的点击事件为静默模式
label: { //图形上的文本标签
show: true,
position: 'right', //标签的位置
offset: [0, 0], //标签文字的偏移,此处表示向上偏移40
//formatter: '{c}{a}',//标签内容格式器 {a}-系列名,{b}-数据名,{c}-数据值
formatter: function (data) {
//.toFixed(0)去掉小数位,如果为2就是保留两位小数
var traceValue;
for (var i = 0; i < dataAll.dataX.length; i++) {
if (data.name === dataAll.dataX[i]) {
traceValue = dataAll.dataPercent[i]
break
}
}
var arr = [
'{a|' + traceValue + '}',
'{b|%}'
]
return arr.join('');
},
textStyle: {
rich: {
a: {
fontSize: 14,
color: 'rgba(0,0,0,0.7)',
fontWeight: 560,
padding: [0, 0, 0, 15],
},
b: {
fontSize: 14,
color: 'rgba(0,0,0,0.7)',
padding: [0, 0, 0, 3],
align: 'center',
},
}
},
},
barGap: '-100%', //不同系列的柱间距离,为百分比。
// 在同一坐标系上,此属性会被多个 'bar' 系列共享。
// 此属性应设置于此坐标系中最后一个 'bar' 系列上才会生效,
//并且是对此坐标系中所有 'bar' 系列生效。
barWidth: 15,
data: dataAll.dataSum,
color: '#DEE0E3', //柱条颜色
itemStyle: {
normal: {
barBorderRadius: 10
}
}
},
]
};
myChartLine.setOption(option, true);
};
const initData = (dataX, dataY, dataPercent, targetId) => {
// var dataX = ['生态环境检查', '卫生健康检查', '商务领域检查', '财务领域检查', '水务领域检查']
// var dataY = ['30', '20', '15', '25', '10'];
// var dataPercent = ['30', '20', '15', '25', '10'];
var dataSum = new Array(dataX.length).fill(100);
var data = {
dataX: dataX,
dataY: dataY,
dataSum: dataSum,
dataPercent: dataPercent,
}
initSchedule(data, targetId);
};
onMounted(() => {
queryStatisticalData({
"dataScopeId": useCommon.userId
}, success => {
var arrData = [];
var arrCompanyData = [];
var countTotal = 0;
var userTotal = 0;
//执法类别参数
var dataX = [];
var dataY = [];
var dataPercent = [];
//执法人员
var userDataX = [];
var userDataY = [];
var userDataPercent = [];
//本月案件数量
var arrCountData = [];
console.log(success.data.item)
success.data.item.forEach(res => {
countTotal += res.total;
})
success.data.lawEnforcer.forEach(res => {
userTotal += res.total;
})
success.data.item.forEach(res => {
console.log(res)
arrData.push({
"name": res.lawEnforcementItem,
"value": res.total
})
dataX.push(res.lawEnforcementItem);
dataY.push(res.total);
dataPercent.push((res.total / countTotal * 100).toFixed(2));
})
success.data.lawEnforcer.forEach(res => {
console.log(res)
userDataX.push(res.lawEnforcer);
userDataY.push(res.total);
userDataPercent.push((res.total / userTotal * 100).toFixed(2));
})
console.log(userDataPercent)
success.data.enterpriseType.forEach(res => {
console.log(res)
arrCompanyData.push({
"name": res.dictLabel,
"value": res.total
})
})
data.allTotal = success.data.mouth.total;
data.complaintCount = success.data.mouth.complaintCount;
arrCountData.push({
"name": "本月执法数量",
"value": data.allTotal
})
arrCountData.push({
"name": "本月执法投诉数量",
"value": data.complaintCount
})
nextTick(() => {
echartInit(arrData, 'echartRing');
//执法类别统计
initData(dataX, dataY, dataPercent, "echartLine");
//执法人员
initData(userDataX, userDataY, userDataPercent, "echartLineUser");
//企业类型统计
echartInit(arrCompanyData, 'echartLineCompany');
//本月案件数量
echartInit(arrCountData, 'echarCount');
});
}, error => {
})
});
</script>
<style lang="less" scoped>
.address_edit {
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
background-color: #ebf3fb;
}
.warp_body {
background-image: linear-gradient(to bottom, #ebf3fb, transparent);
margin-top: 0.15rem;
}
.countbox, .analybox {
position: relative;
margin: 2% 3%;
padding: 2% 0 0;
width: 94%;
height: 3rem;
background: #fff url("../../assets/images/bg_count.jpg") no-repeat right;
background-size: auto 100%;
border-radius: 0.25rem;
}
.countbox span {
display: block;
margin: 1.75% 4.5%;
color: #999;
font-size: 0.3rem;
line-height: 1.25;
}
.countbox span.count-tit {
color: #666;
font-size: 0.40rem;
}
.countbox span.count-tot {
font-size: 0.3rem;
b {
margin-right: 0.15rem;
color: #085dff;
font-size: 0.85rem;
}
}
.countbox span.count-com {
float: right;
margin-top: -0.1rem;
font-size: 0.3rem;
i {
font-size: 0.4rem;
font-style: normal;
}
b {
margin-right: 5px;
color: #f00;
font-size: 0.6rem;
}
}
.analybox {
height: auto;
min-height: 7rem;
background: #fff none;
.title {
margin: 2% 2.5%;
font-size: 0.42rem;
font-weight: 600;
}
}
.chartbox {
margin: 2% 5% 3%;
width: 90%;
height: 7rem;
}
</style>

390
src/views/common/analyse.vue

@ -12,29 +12,126 @@
<!-- 中间 -->
<div class="warp_body">
<div class="countbox">
<span class="count-tit">本月执法</span>
<span class="count-tot"><b>{{ data.allTotal }}</b>件</span>
<span class="count-com"><i>投诉:</i><b>{{ data.complaintCount }}</b>件</span>
<div class="search-button-list">
<van-button plain hairline :class="1==data.checkNum?'search-button active':'search-button'"
@click="searchDateType(1)" round type="primary"
size="mini">月度
</van-button>
<van-button plain hairline :class="2==data.checkNum?'search-button active':'search-button'"
@click="searchDateType(2)" round type="primary"
size="mini">季度
</van-button>
<van-button plain hairline :class="null==data.checkNum?'search-button active':'search-button'"
@click="searchDateType(null)" round type="primary"
size="mini">年度
</van-button>
<van-button plain hairline :class="9==data.checkNum?'search-button active':'search-button'"
@click="selectDate" round type="primary" size="mini">筛选
</van-button>
</div>
<div class="curtime"><div>2024</div> <van-icon name="play" /></div>
<div class="person-data">
<div class="count-tit">个人检查数量</div>
<div class="count-tot"><b>{{ data.allTotal }}</b>件</div>
<div class="percent-tag">
<span class="percent-month">环比:<span class="data-rise"><van-icon name="down" />13件</span></span>
<span class="percent-year">同比:<span class="data-fall"><van-icon name="down" />7件</span></span>
</div>
<div class="count-com"><i>投诉:</i><b>{{ data.complaintCount }}</b>件</div>
</div>
<van-divider />
<div class="depart-data">
<div class="count-tit">部门检查数量</div>
<div class="count-tot"><b>{{ data.allTotal }}</b>件</div>
<div class="percent-tag">
<span class="percent-month">环比:<span class="data-rise"><van-icon name="down" />13件</span></span>
<span class="percent-year">同比:<span class="data-fall"><van-icon name="down" />7件</span></span>
</div>
<div class="count-com"><i>投诉:</i><b>{{ data.complaintCount }}</b>件</div>
</div>
</div>
<div class="analybox">
<div class="title">检查类别</div>
<div id="echartRing" class="chartbox"></div>
<div id="echartLine" class="chartbox"></div>
<div class="tab-tag">
<van-tabs v-model:active="active" type="card">
<van-tab title="个人"></van-tab>
<van-tab title="部门"></van-tab>
</van-tabs>
</div>
<div class="dropdown-box">
<span><label>区域</label><van-icon name="arrow-down" /></span>
<span><label>部门</label><van-icon name="arrow-down" /></span>
<span><label>企业</label><van-icon name="arrow-down" /></span>
<span><label>检查</label><van-icon name="arrow-down" /></span>
<span><label>投诉</label><van-icon name="arrow-down" /></span>
</div>
<div class="selected-box">
<div><label>执法部门:</label><div><span>深圳市司法局</span>,<span>深圳市公安局</span><span>深圳市司法局</span>,<span>深圳市公安局</span></div></div>
<div><label>企业类型:</label><div><span>内资企业</span></div></div>
<div><label>检查类别:</label><div><span>日常检查</span></div></div>
</div>
<div class="stat-box">
<div class="stat-item">
<div class="count-tit">部门数量</div>
<div class="count-tot"><b>2</b>个</div>
<div class="percent-tag">
<span class="time-last"><span class="data-rise">--</span><label>较上年</label></span>
</div>
</div>
<div class="analybox">
<div class="title">执法人员</div>
<div id="echartLineUser" class="chartbox" style="height: 10rem;"></div>
<div class="stat-item">
<div class="count-tit">企业数量</div>
<div class="count-tot"><b>156.85</b>万</div>
<div class="percent-tag">
<span class="time-last"><span class="data-rise"><van-icon name="down" />1.26</span><label>较上年</label></span>
</div>
</div>
<div class="analybox">
<div class="title">案件数量</div>
<div id="echarCount" class="chartbox"></div>
<div class="stat-item">
<div class="count-tit">检查数量</div>
<div class="count-tot"><b>5233</b>件</div>
<div class="percent-tag">
<span class="time-last"><span class="data-rise"><van-icon name="down" />32</span><label>较上年</label></span>
</div>
</div>
<div class="analybox">
<div class="title">企业类型</div>
<div id="echartLineCompany" class="chartbox"></div>
<div class="stat-item">
<div class="count-tit">投诉数量</div>
<div class="count-tot"><b>65</b>件</div>
<div class="percent-tag">
<span class="time-last"><span class="data-fall"><van-icon name="down" />3</span><label>较上年</label></span>
</div>
</div>
</div>
<!-- <div class="analybox">
<div class="title">检查类别</div>
<div id="echartRing" class="chartbox"></div>
<div id="echartLine" class="chartbox"></div>
</div>
<div class="analybox">
<div class="title">执法人员</div>
<div id="echartLineUser" class="chartbox" style="height: 10rem;"></div>
</div>
<div class="analybox">
<div class="title">案件数量</div>
<div id="echarCount" class="chartbox"></div>
</div>
<div class="analybox">
<div class="title">企业类型</div>
<div id="echartLineCompany" class="chartbox"></div>
</div>-->
</div>
</div>
@ -466,49 +563,56 @@
.warp_body {
background-image: linear-gradient(to bottom, #ebf3fb, transparent);
background: #ebf3fb;
margin-top: 0.15rem;
}
.countbox, .analybox {
position: relative;
margin: 2% 3%;
padding: 2% 0 0;
width: 94%;
height: 3rem;
background: #fff url("../../assets/images/bg_count.jpg") no-repeat right;
background-size: auto 100%;
border-radius: 0.25rem;
position: relative;
margin: 2% 3%;
padding: 2% 0;
width: 94%;
/* height: 7rem; */
background: #fff url(/src/assets/images/bg_count.jpg) no-repeat right;
background-size: auto 100%;
border-radius: 0.25rem;
color: #999;
box-shadow: 0 0 5px #b4cbd9;
}
.countbox span {
display: block;
margin: 1.75% 4.5%;
color: #999;
font-size: 0.3rem;
line-height: 1.25;
}
.countbox span.count-tit {
color: #666;
font-size: 0.40rem;
.count-tit {
margin: 2% 4%;
color: #333;
font-size: 0.4rem;
}
.countbox span.count-tot {
.count-tot {
margin: 2% 4%;
font-size: 0.3rem;
b {
margin-right: 0.15rem;
color: #085dff;
font-size: 0.85rem;
font-size: 0.95rem;
}
}
.countbox span.count-com {
float: right;
margin-top: -0.1rem;
font-size: 0.3rem;
.count-com {
float: right;
display: flex;
align-items: center;
margin: -0.1rem 0.5rem 0;
font-size: 0.3rem;
i {
color: #666;
font-size: 0.4rem;
font-style: normal;
}
@ -538,5 +642,223 @@
height: 7rem;
}
.search-button-list {
height: 0.7rem;
display: flex;
flex-direction: row;
padding-left: 0.27rem;
margin-top: 0.27rem;
align-items: end;
.search-button {
/*width: 15%;
height: 90%;*/
background: transparent;
border-color: transparent;
color: #666;
font-size: 0.35rem;
line-height: 1.5;
}
.search-button.active {
padding: 0 0.3rem;
background-color: #fff;
border-color: #75a5fb;
color: #1367fe;
}
}
.countbox .search-button-list {
position: absolute;
top: -0.1rem;
right: 3%;
display: flex;
white-space: normal;
background: #ebebeb;
border-radius: 0.15rem;
}
.curtime {
display: flex;
align-items: center;
margin: 1% 0 4% 4%;
font-size: 0.45rem;
color: #085dff;
}
.curtime i {
margin: 0 0 0 0.1rem;
transform: rotate(90deg);
font-size: 0.3rem;
}
.person-data, .depart-data {
position: relative;
display: table;
width: 100%;
}
.depart-data {
margin: -2% 0 3%;
}
.percent-tag {
margin: -3% 3% 0;
}
.percent-tag > span {
margin: 0 2%;
font-size: 0.35rem;
}
.percent-tag > span > span {
margin: 0;
}
.percent-tag > span > span > i {
margin-right: 1%;
}
span.data-fall {
color: #ff0000;
font-size: 0.4rem;
}
span.data-rise {
color: #03a159;
font-size: 0.4rem;
}
span.data-rise i {
transform: rotate(180deg);
}
.countbox .van-divider {
margin-left: 4%;
width: 92%;
border-color: #e3e3e3;
}
.tab-tag {
position: relative;
}
/deep/ .tab-tag .van-tabs {
float: right;
margin: 2% 0;
width: 35%;
}
/deep/ .tab-tag .van-tabs__nav--card {
height: 0.65rem;
border-radius: 0.3rem;
}
/deep/ .van-tab--card.van-tab--active {
border-radius: 0.3rem;
}
/deep/ .tab-tag .van-tab--card {
border-right: 0;
font-size: 0.35rem;
}
.dropdown-box {
display: flex;
justify-content: space-around;
align-items: center;
clear: both;
position: relative;
margin: 2% 3%;
padding: 2% 0;
width: 94%;
height: 0.6rem;
background: #fafcfd;
border: 0.02667rem solid #e2ebf7;
border-radius: 0.25rem;
color: #666;
font-size: 0.4rem;
box-shadow: 0 0 0.06rem #c1dbeb;
}
.dropdown-box > span > i {
margin: 0 0 0 0.15rem;
font-size: 0.3rem;
}
.selected-box {
position: relative;
margin: 0 5%;
width: 90%;
color: #c0c0c0;
font-size: 0.35rem;
}
.selected-box > div {
display: flex;
margin: 2% 0;
}
.selected-box label {
white-space: nowrap;
}
.selected-box > div > div {
display: inline-block;
width: calc(100% - 2.0rem);
color: #666;
}
.selected-box > div > div > span {
margin-left: 0.15rem;
}
.stat-box {
position: relative;
margin: 0 3%;
padding: 1%;
width: 94%;
background: #fff;
color: #c0c0c0;
font-size: 0.35rem;
box-sizing: border-box;
border-radius: 0.25rem;
}
.stat-item {
display: inline-block;
margin: 2%;
padding: 3%;
width: 40%;
background: #e7f9f3;
border-radius: 0.25rem;
}
.stat-item:nth-child(2) {
background: #f7f8f9;
}
.stat-item:nth-child(3) {
background: #ebf4fd;
}
.stat-item:nth-child(4) {
background: #ffeded;
}
.stat-item .count-tot b {
color: #333;
font-size: 0.8rem;
font-weight: 500;
line-height: 1.75;
}
.stat-item .percent-tag label {
margin-left: 0.5rem;
font-size: 0.3rem;
}
</style>

Loading…
Cancel
Save