379 lines
10 KiB
Vue
379 lines
10 KiB
Vue
|
<template>
|
|||
|
<view class="container">
|
|||
|
<scroll-view scroll-y="true" class="scroll">
|
|||
|
<view class="tourist-box">
|
|||
|
<image class="bgImg" src="../../static/img/rectangle.png" mode=""></image>
|
|||
|
<image class="img" src="../../static/img/yksl.png" mode=""></image>
|
|||
|
<view style="position: relative;">
|
|||
|
<view class="title">累计游客数量(人)</view>
|
|||
|
<view class="num">{{accumulatedTouristsVo.totalNum}}</view>
|
|||
|
<view class="bar-box">
|
|||
|
<view class="row">
|
|||
|
<view class="label">
|
|||
|
<view class="icon">
|
|||
|
<view>
|
|||
|
<u-icon name="man" color="#2B75E9" size="32rpx" bold></u-icon>
|
|||
|
</view>
|
|||
|
<text>男生人数(人)</text>
|
|||
|
</view>
|
|||
|
<view class="num">{{accumulatedTouristsVo.manNum}}</view>
|
|||
|
</view>
|
|||
|
<view class="manProgress">
|
|||
|
<u-line-progress :percentage="(accumulatedTouristsVo.manNum / accumulatedTouristsVo.totalNum) * 100" activeColor="#2B75E9" :showText="false" height="15rpx"></u-line-progress>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<view class="row">
|
|||
|
<view class="label">
|
|||
|
<view class="icon">
|
|||
|
<view class="woman">
|
|||
|
<u-icon name="woman" color="#FF5EA4" size="32rpx" bold></u-icon>
|
|||
|
</view>
|
|||
|
<text>女生人数(人)</text>
|
|||
|
</view>
|
|||
|
<view class="num">{{accumulatedTouristsVo.womenNum}}</view>
|
|||
|
</view>
|
|||
|
<u-line-progress :percentage="(accumulatedTouristsVo.womenNum / accumulatedTouristsVo.totalNum) * 100" activeColor="#03AE80" :showText="false" height="15rpx"></u-line-progress>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<view class="card age-box">
|
|||
|
<view class="title-box">
|
|||
|
<image class="headline" src="../../static/img/nltj.png" mode=""></image>
|
|||
|
<view class="label">年龄统计</view>
|
|||
|
</view>
|
|||
|
<view class="chart1-box">
|
|||
|
<view class="left">
|
|||
|
<qiun-data-charts type="ring" canvas2d :opts="ringOpts" :chartData="ringChartData" />
|
|||
|
</view>
|
|||
|
<view class="right">
|
|||
|
<view class="row" v-for="(item, index) in ageStatisticsVo">
|
|||
|
<view class="col1">
|
|||
|
<view class="dot"></view>
|
|||
|
<view class="label">{{item.name}}</view>
|
|||
|
</view>
|
|||
|
<view class="col2">{{item.value}}</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<view class="card source-box">
|
|||
|
<view class="title-box">
|
|||
|
<image class="headline" src="../../static/img/yklyd.png" mode=""></image>
|
|||
|
<view class="label">游客来源地</view>
|
|||
|
</view>
|
|||
|
<view class="chart2-box">
|
|||
|
<view class="unit">单位:人</view>
|
|||
|
<view class="plan-list">
|
|||
|
<view class="plan-item" v-for="(item, index) in touristSourcesStatisticsVO" :key="index">
|
|||
|
<view class="icon1">
|
|||
|
<image v-if="index == 0" class="ranking" src="../../static/img/No1.png" mode=""></image>
|
|||
|
<image v-else-if="index == 1" class="ranking" src="../../static/img/No2.png" mode=""></image>
|
|||
|
<image v-else-if="index == 2" class="ranking" src="../../static/img/No3.png" mode=""></image>
|
|||
|
<view v-else class="sort">{{index + 1}}</view>
|
|||
|
</view>
|
|||
|
<view class="row">
|
|||
|
<view class="label">
|
|||
|
<view class="text">{{item.name}}</view>
|
|||
|
<view class="num">{{item.value}}</view>
|
|||
|
</view>
|
|||
|
<u-line-progress :percentage="(item.value / yklydTotal) * 100" activeColor="#03AE80" :showText="false" height="15rpx"></u-line-progress>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<view class="card classify-box">
|
|||
|
<view class="title-box">
|
|||
|
<image class="headline" src="../../static/img/ykfxtj.png" mode=""></image>
|
|||
|
<view class="label">游客分类统计</view>
|
|||
|
</view>
|
|||
|
<view class="chart3-box">
|
|||
|
<view class="unit">单位:人</view>
|
|||
|
<qiun-data-charts type="funnel" canvas2d :opts="funnelOpts" :chartData="funnelChartData" />
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</scroll-view>
|
|||
|
</view>
|
|||
|
</template>
|
|||
|
<script>
|
|||
|
export default {
|
|||
|
data() {
|
|||
|
return {
|
|||
|
accumulatedTouristsVo: {},
|
|||
|
ageStatisticsVo: [],
|
|||
|
touristSourcesStatisticsVO: [],
|
|||
|
yklydTotal: 0,
|
|||
|
touristCategorizeVo: [],
|
|||
|
ringOpts: {
|
|||
|
rotate: false,
|
|||
|
rotateLock: false,
|
|||
|
color: ["#03AE80","#347BEA","#FE7D51","#6E34EA"],
|
|||
|
padding: [0,0,0,0],
|
|||
|
dataLabel: true,
|
|||
|
enableScroll: false,
|
|||
|
legend: {
|
|||
|
show: false,
|
|||
|
position: "right",
|
|||
|
lineHeight: 30
|
|||
|
},
|
|||
|
title: {
|
|||
|
name: "",
|
|||
|
fontSize: 0,
|
|||
|
color: "#666666"
|
|||
|
},
|
|||
|
subtitle: {
|
|||
|
name: "",
|
|||
|
fontSize: 0,
|
|||
|
color: "#7cb5ec"
|
|||
|
},
|
|||
|
extra: {
|
|||
|
ring: {
|
|||
|
ringWidth: 20,
|
|||
|
activeOpacity: 0.5,
|
|||
|
activeRadius: 10,
|
|||
|
offsetAngle: -90,
|
|||
|
labelWidth: 15,
|
|||
|
border: true,
|
|||
|
borderWidth: 3,
|
|||
|
borderColor: "#FFFFFF",
|
|||
|
customRadius: 70
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
funnelOpts: {
|
|||
|
color: ["#03AE80", "#347BEA", "#FE7D51", ],
|
|||
|
legend: {
|
|||
|
show: true,
|
|||
|
},
|
|||
|
padding: [10, 0, 10, 0],
|
|||
|
enableScroll: false,
|
|||
|
extra: {
|
|||
|
funnel: {
|
|||
|
activeOpacity: 0.3,
|
|||
|
activeWidth: 10,
|
|||
|
border: false,
|
|||
|
borderWidth: 2,
|
|||
|
borderColor: "#FFFFFF",
|
|||
|
fillOpacity: 1,
|
|||
|
labelAlign: "right",
|
|||
|
type: "pyramid"
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
ringChartData: {},
|
|||
|
funnelChartData: {}
|
|||
|
};
|
|||
|
},
|
|||
|
mounted() {
|
|||
|
this.getTouristPortrait();
|
|||
|
},
|
|||
|
methods: {
|
|||
|
async getTouristPortrait() {
|
|||
|
let info = await this.$http.getTouristPortrait();
|
|||
|
this.accumulatedTouristsVo = info.data.accumulatedTouristsVo;
|
|||
|
this.ageStatisticsVo = info.data.ageStatisticsVo;
|
|||
|
this.touristSourcesStatisticsVO = info.data.touristSourcesStatisticsVO;
|
|||
|
this.touristSourcesStatisticsVO.forEach(m => {
|
|||
|
this.yklydTotal += m.value;
|
|||
|
})
|
|||
|
this.touristCategorizeVo = info.data.touristCategorizeVo;
|
|||
|
|
|||
|
this.ageStatisticsVo.forEach(m => {
|
|||
|
m.labelShow = false;
|
|||
|
})
|
|||
|
let res1 = {
|
|||
|
series: [
|
|||
|
{
|
|||
|
data: this.ageStatisticsVo
|
|||
|
}
|
|||
|
]
|
|||
|
};
|
|||
|
this.ringChartData = JSON.parse(JSON.stringify(res1));
|
|||
|
|
|||
|
this.touristCategorizeVo.forEach(e => {
|
|||
|
e.centerText = e.value;
|
|||
|
e.labelText = e.name + ' ' + e.value;
|
|||
|
e.centerText = '';
|
|||
|
})
|
|||
|
let res2 = {
|
|||
|
series: [
|
|||
|
{
|
|||
|
data: this.touristCategorizeVo
|
|||
|
}
|
|||
|
]
|
|||
|
};
|
|||
|
this.funnelChartData = JSON.parse(JSON.stringify(res2));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
</script>
|
|||
|
|
|||
|
<style lang="scss" scoped>
|
|||
|
.container {
|
|||
|
height: 100%;
|
|||
|
.scroll {
|
|||
|
height: 100%;
|
|||
|
}
|
|||
|
.tourist-box {
|
|||
|
width: 686rpx;
|
|||
|
height: 396rpx;
|
|||
|
border-radius: 10rpx;
|
|||
|
box-sizing: border-box;
|
|||
|
padding: 32rpx;
|
|||
|
position: relative;
|
|||
|
.bgImg {
|
|||
|
position: absolute;
|
|||
|
left: 0;
|
|||
|
top: 0;
|
|||
|
width: 686rpx;
|
|||
|
height: 396rpx;
|
|||
|
}
|
|||
|
.img {
|
|||
|
position: absolute;
|
|||
|
width: 240rpx;
|
|||
|
height: 232rpx;
|
|||
|
right: 45rpx;
|
|||
|
top: -24rpx;
|
|||
|
}
|
|||
|
.title {
|
|||
|
font-size: 28rpx;
|
|||
|
color: #333333;
|
|||
|
line-height: 33rpx;
|
|||
|
}
|
|||
|
.num {
|
|||
|
margin-top: 8rpx;
|
|||
|
font-weight: bold;
|
|||
|
font-size: 56rpx;
|
|||
|
color: #333333;
|
|||
|
line-height: 66rpx;
|
|||
|
}
|
|||
|
.bar-box {
|
|||
|
padding-top: 20rpx;
|
|||
|
.row {
|
|||
|
.label {
|
|||
|
display: flex; align-items: center; justify-content: space-between; margin: 28rpx 0 12rpx;
|
|||
|
.icon {
|
|||
|
display: flex; align-items: center; font-size: 28rpx; color: #333333; line-height: 33rpx;
|
|||
|
.woman {
|
|||
|
transform: rotate(45deg);
|
|||
|
}
|
|||
|
text { margin-left: 10rpx; }
|
|||
|
}
|
|||
|
.num { font-weight: bold; font-size: 32rpx; color: #333333; line-height: 38rpx; }
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
.title-box {
|
|||
|
width: 686rpx;
|
|||
|
height: 90rpx;
|
|||
|
box-sizing: border-box;
|
|||
|
border-radius: 10rpx 10rpx 0 0;
|
|||
|
padding: 23rpx 28rpx;
|
|||
|
display: flex;
|
|||
|
align-items: center;
|
|||
|
.headline {
|
|||
|
width: 44rpx;
|
|||
|
height: 44rpx;
|
|||
|
margin-right: 16rpx;
|
|||
|
}
|
|||
|
.label {
|
|||
|
font-weight: 500;
|
|||
|
font-size: 32rpx;
|
|||
|
color: #333333;
|
|||
|
}
|
|||
|
}
|
|||
|
.card {
|
|||
|
width: 100%;
|
|||
|
box-sizing: border-box;
|
|||
|
background: #FFFFFF;
|
|||
|
border-radius: 10rpx;
|
|||
|
margin-top: 20rpx;
|
|||
|
}
|
|||
|
.age-box {
|
|||
|
.title-box { background: linear-gradient( 90deg, rgba(3,174,128,0.2) 0%, rgba(255,255,255,0.05) 100%); }
|
|||
|
.chart1-box {
|
|||
|
display: flex; align-items: center; padding: 0 32rpx;
|
|||
|
.left {
|
|||
|
width: 358rpx; height: 358rpx; position: relative; margin-right: 24rpx;
|
|||
|
}
|
|||
|
.right {
|
|||
|
flex: 1;
|
|||
|
.row {
|
|||
|
margin-top: 37rpx; display: flex; align-items: center; justify-content: space-between;
|
|||
|
&:nth-child(1) {
|
|||
|
margin-top: 0;
|
|||
|
.dot { background: #03AE80; }
|
|||
|
}
|
|||
|
&:nth-child(2) {
|
|||
|
.dot { background: #347BEA; }
|
|||
|
}
|
|||
|
&:nth-child(3) {
|
|||
|
.dot { background: #FE7D51; }
|
|||
|
}
|
|||
|
&:nth-child(4) {
|
|||
|
.dot { background: #6E34EA; }
|
|||
|
}
|
|||
|
.col1 {
|
|||
|
display: flex; align-items: center;
|
|||
|
.dot {
|
|||
|
width: 14rpx; height: 14rpx; border-radius: 50%; margin-right: 12rpx;
|
|||
|
}
|
|||
|
.label { font-size: 28rpx; color: #666666; }
|
|||
|
}
|
|||
|
.col2 { font-weight: 500; font-size: 28rpx; color: #333333; }
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
.source-box {
|
|||
|
.title-box { background: linear-gradient( 90deg, rgba(43,117,233,0.2) 0%, rgba(255,255,255,0.05) 100%); }
|
|||
|
.chart2-box {
|
|||
|
padding: 20rpx 28rpx 40rpx;
|
|||
|
.unit {
|
|||
|
font-weight: 500;
|
|||
|
font-size: 22rpx;
|
|||
|
color: #999999;
|
|||
|
text-align: right;
|
|||
|
}
|
|||
|
.plan-list {
|
|||
|
margin-top: 21rpx;
|
|||
|
.plan-item {
|
|||
|
margin-top: 36rpx;
|
|||
|
display: flex;
|
|||
|
align-items: center;
|
|||
|
&:first-child {
|
|||
|
margin-top: 0;
|
|||
|
}
|
|||
|
.icon1 {
|
|||
|
width: 48rpx; margin-right: 20rpx;
|
|||
|
.ranking { width: 48rpx; height: 48rpx; }
|
|||
|
.sort {
|
|||
|
width: 36rpx; height: 36rpx; line-height: 36rpx; text-align: center; background: #F6F6F6; border-radius: 4rpx; font-weight: 500; font-size: 20rpx; color: #333333; margin-left: 12rpx;
|
|||
|
}
|
|||
|
}
|
|||
|
.row {
|
|||
|
flex: 1;
|
|||
|
.label {
|
|||
|
display: flex; align-items: center; justify-content: space-between; font-weight: 500; font-size: 28rpx; color: #333333; line-height: 33rpx; margin-bottom: 4rpx;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
.classify-box {
|
|||
|
.title-box { background: linear-gradient( 90deg, rgba(254,125,81,0.2) 0%, rgba(255,255,255,0.05) 100%); }
|
|||
|
.chart3-box {
|
|||
|
height: 370rpx; box-sizing: border-box; padding: 20rpx 28rpx 40rpx;
|
|||
|
.unit {
|
|||
|
font-weight: 500;
|
|||
|
font-size: 22rpx;
|
|||
|
color: #999999;
|
|||
|
text-align: right;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
</style>
|