2023-04-12 19:06:57 +08:00

614 lines
14 KiB
Vue

<template>
<view v-show="show">
<div class="" v-show="!loading && pageEmpty">
<noFound :nodata="true" :text="'抱歉,服务区采集样本数据过小,无法分析。'" />
</div>
<div v-show="!loading && !pageEmpty">
<div class="customer-content">
<div class="tab-btn" v-if="topData.length>1" @tap="tabChange(canvasTab==1?0:1,opt)">
查看{{topData[canvasTab?0:1].Serverpart_Region}}区数据</div>
<div class="customer-title">入区车流分析</div>
<div class="uni-flex jc-between">
<div style="flex:1;" class="tab-unit">
<div class="tab-title">车流量</div>
<div class="tab-number">{{topData[canvasTab].Vehicle_Count}}</div>
<div class="tab-rate"><span class="tab-desc"></span> <span
:style="topData[canvasTab].Vehicle_GrowthRate>0? 'color: #2CC260;' : 'color: #F54850;'">{{topData[canvasTab].Vehicle_GrowthRate}}%</span>
</div>
</div>
<div style="flex:1;" class="tab-unit">
<div class="tab-title">入区率</div>
<div class="tab-number">{{topData[canvasTab].Entry_Rate}}%</div>
<div class="tab-rate"><span class="tab-desc"></span> <span
:style="topData[canvasTab].Entry_GrowthRate>0? 'color: #2CC260;' : 'color: #F54850;'">{{topData[canvasTab].Entry_GrowthRate}}%</span>
</div>
</div>
</div>
</div>
<!-- <canvas canvas-id="sexCate" id="sexCate" class="operation-cate-content"></canvas> -->
<div class="customer-content">
<div class="customer-title">各车停留时间</div>
<div v-if="chartdata.stayChart[canvasTab] && chartdata.stayChart[canvasTab].data.length>0">
<canvas canvas-id="carStay" id="carStay" class="operation-stock-content" @touchend="tap"></canvas>
</div>
<noFound :nodata="true" :text="'抱歉,服务区采集样本数据过小,无法分析。'" v-else />
</div>
<div class="customer-content">
<div class="customer-title">车辆归属地</div>
<div v-if="chartdata.countChart[canvasTab] && !lodingDetail">
<view class="operation-pie-content">
<!-- <uni-ec-canvas
class="operation-stock-content"
id="carBelong"
ref="carBelong"
canvas-id="carBelong"
:ec="ec"
></uni-ec-canvas> -->
<!-- @inited="inited" -->
<canvas canvas-id="carBelong" id="carBelong" class="operation-pie-content"
@touchend="tap"></canvas>
<!-- <qiun-data-charts
type="radar"
:chartData="radarData"
:opts="radaropts"
background="none"
loadingType="2"
/> -->
</view>
<view class="operation-pie-content">
<canvas canvas-id="carFunnel" id="carFunnel" class="operation-pie-content"
@touchend="tap"></canvas>
<!-- <qiun-data-charts
type="funnel"
:chartData="funnelData"
background="none"
:opts="funnelopts"
loadingType="0"
/> -->
</view>
</div>
<noFound :nodata="true" :text="'抱歉,服务区采集样本数据过小,无法分析。'" v-else />
<!-- <div class="analysis-text" v-if="proportionList[canvasTab]">
<span class="key-text">分析</span><span>{{proportionList[canvasTab][1]}}</span>
</div> -->
</div>
</div>
</view>
</template>
<script>
import uCharts from '@/components/u-charts.js';
import uniEcCanvas from './uni-ec-canvas/uni-ec-canvas.vue';
// import uCharts from '@/uni_modules/qiun-data-charts/js_sdk/u-charts/u-charts.js';
let rincanvas = {}
export default {
props: {
pieId: String,
barId: String,
show: Boolean
},
data() {
return {
funnelData: null,
radarData: [],
topData: [],
canvasTab: 0,
chartdata: {
"stayChart": [],
"countChart": []
},
opt: null,
pageEmpty: false,
loading: true,
lodingDetail: true,
}
},
methods: {
refreshData(data) {
// 刷新数据
rincanvas['carStay'].updateData({
series: data.data,
categories: data.categories
});
this.$forceUpdate()
},
tabChange(name, opt) {
this.canvasTab = name
if (!this.chartdata.stayChart[name]) {
this.lodingDetail = true
this.getProportion(name, opt) // 获取 各车型停留时间
this.getAnalysisDesc(name, opt)
} else {
if (this.chartdata.countChart[name]) {
// 车辆归属地
const list = this.chartdata.countChart[name]
this.showClounm({
id: 'carBelong',
data: [{
name: '归属城市',
data: list.OwnerCityList.map(n => {
return parseInt(n.value)
}),
textColor: '#747474',
textSize: uni.upx2px(20),
formatter: (val) => {
return parseInt(val)+'辆'
}
}],
categories: list.OwnerCity
})
//
this.showPie({
id: 'carFunnel',
data: list.OwnerProvinceList.map(n => {
return {
...n,
data: parseFloat(n.value)
}
}),
categories: list.OwnerProvince,
})
}
if (this.chartdata.stayChart[name]) {
// 车辆停留时间
const {
data,
categories
} = this.chartdata.stayChart[name]
this.showMix({
id: 'carStay', //+type,
data: data,
categories: categories
})
console.log('data123123',data)
}
}
},
// 获取 各车型停留时间
async getProportion(type, params) {
let _this = this
_this.opt = params
const data = await this.$request.$webGet('CommercialApi/Revenue/GetBayonetSTAList', {
Serverpart_Region: this.topData[type].Serverpart_Region,
...params
})
if (data.Result_Code === 100 && data.Result_Data.List.length > 0) {
const [list] = data.Result_Data.List
const showData = [{
name: '车型',
type: "column",
index: 0,
data: list.VehicleCountList.map(n => n.value)
},
{
name: '停留时间(分钟)',
type: "line",
index: 1,
"style": "curve",
dataPointShape: true,
data: list.StayTimesList.map(n => parseInt(n.value) + ''),
}
]
_this.showMix({
id: 'carStay', //+type,
data: showData,
categories: list.Vehicle_Type
})
this.chartdata.stayChart[type] = {
data: showData,
categories: list.Vehicle_Type
}
this.$forceUpdate()
} else {
this.chartdata.stayChart[type] = null
}
},
async getAnalysisDesc(type, params) {
let _this = this
const data = await this.$request.$webGet('CommercialApi/Revenue/GetBayonetOAList', {
Serverpart_Region: this.topData[type].Serverpart_Region,
statisticsMonth: this.$util.cutDate(params.StatisticsDate, 'YYYYMM'),
...params
})
if (data.Result_Code === 100 && data.Result_Data.List.length > 0) {
const [list] = data.Result_Data.List
this.chartdata.countChart[type] = list
this.showClounm({
id: 'carBelong',
data: [{
name: '归属城市',
data: list.OwnerCityList.map(n => {
return parseInt(n.value)
}),
textColor: '#747474',
textSize: uni.upx2px(20),
formatter: (val) => {
return parseInt(val)+'辆'
}
}],
categories: list.OwnerCity
})
this.showPie({
id: 'carFunnel',
data: list.OwnerProvinceList.map(n => {
return {
...n,
data: parseFloat(n.value)
}
}),
categories: list.OwnerProvince,
})
this.$forceUpdate()
} else {
this.chartdata.countChart[type] = null
}
this.lodingDetail = false
},
// 加载头部信息
async getTopData(params) {
const data = await this.$request.$webGet('CommercialApi/Revenue/GetBayonetEntryList', {
...params
})
this.loading = false
if (data.Result_Data.TotalCount == 0) {
this.pageEmpty = true
return
}
this.topData = data.Result_Data.List
this.lodingDetail = true
this.getProportion(this.canvasTab, params)
this.getAnalysisDesc(this.canvasTab, params)
},
tap(e) {
rincanvas[e.target.id].touchLegend(e);
rincanvas[e.target.id].showToolTip(e);
},
showPie(obj) {
let data = {
series: []
}
data.series = data.series.concat(obj.data)
const ctx = uni.createCanvasContext(obj.id, this);
rincanvas[obj.id] = new uCharts({
// padding: [5,5,5,5],
context: ctx,
color: ['#6B96F8', '#F6B760', '#677798', '#6BDBAB', '#7a67f8'],
type: 'rose',
fontSize: 12,
legend: {
show: true,
position: 'bottom',
padding: 5,
lineHeight: 12,
fontSize: uni.upx2px(24),
margin: 0,
},
legendShape: 'square',
background: '#FFFFFF',
pixelRatio: 1,
series: data.series,
animation: true,
width: uni.upx2px(686),
height: uni.upx2px(500),
dataLabel: true,
extra: {
rose: {
type: "area",
minRadius: 70,
activeOpacity: 0.5,
activeRadius: 10,
// offsetAngle: 0,
labelWidth: 15,
border: false,
borderWidth: 2,
borderColor: "#FFFFFF"
}
},
});
},
showClounm(obj) {
const ctx = uni.createCanvasContext(obj.id, this);
rincanvas[obj.id] = new uCharts({
context: ctx,
type: "bar",
legend: {
show: false
},
color: ['#6B96F8'],
fontSize: 12,
background: '#FFFFFF',
padding: [30, 24, 12, 12],
animation: true,
categories: obj.categories,
series: obj.data,
enableScroll: false, //开启图表拖拽功能
xAxis: {
boundaryGap: "justify",
axisLine: false,
// disableGrid: false,
min: 0,
// axisLine: false,
max: 400,
// axisLineColor: "#eee"
fontSize: uni.upx2px(24),
fontColor: '#777777',
gridColor: '#eee'
},
subtitle: {
name: '归属城市',
color: '#e6e6e6',
},
yAxis: {
data: [{
title: '归属城市',
position: "left",
type:'categories',
titleFontSize: uni.upx2px(22),
titleFontColor: '#BABABA',
// titleOffsetX: uni.upx2px(-40),
titleOffsetY: uni.upx2px(-20),
fontSize: uni.upx2px(24),
fontColor: '#777777',
}],
showTitle:true,
axisLineColor: "#eee",
fontSize: uni.upx2px(24),
},
dataLabel: true,
width: uni.upx2px(686),
height: uni.upx2px(500),
extra: {
bar: {
type: 'group',
width: uni.upx2px(48),
meterBorde: 1,
seriesGap: 4,
// meterFillColor: "#FFFFFF",
// activeBgColor: "#000000",
// activeBgOpacity: 0.08,
categoryGap: 4
}
}
});
},
showMix(obj) {
let data = {
series: []
}
console.log('obj21123',obj)
const ctx = uni.createCanvasContext(obj.id, this);
data.series = data.series.concat(obj.data)
rincanvas[obj.id] = new uCharts({
context: ctx,
// canvasId: obj.id,
type: 'mix',
legend: {
show: true,
position: 'bottom',
// float: 'right',
fontSize: 11,
lineHeight: 20,
margin: 5
},
color: ['#667ED5', '#FFAB35'],
fontSize: 12,
background: '#FFFFFF',
padding: [30, 12, 12, 12],
animation: true,
categories: obj.categories,
series: data.series,
enableScroll: false, //开启图表拖拽功能
xAxis: {
disabled: false,
disableGrid: true,
axisLine: false,
fontColor: '#777777',
labelCount: 5,
},
yAxis: {
data: [{
position: "left",
title: '车流量(辆)',
disabled: false,
axisLine: false,
titleFontSize: uni.upx2px(22),
titleFontColor: '#BABABA',
// titleOffsetX: uni.upx2px(-40),
titleOffsetY: uni.upx2px(-20),
fontSize: uni.upx2px(24),
fontColor: '#777777',
min: 0,
formatter: (val) => {
return parseInt(val)
},
},
{
title: '(分钟)',
position: "right",
disabled: false,
axisLine: false,
min: 0,
titleFontSize: uni.upx2px(22),
titleFontColor: '#BABABA',
// titleOffsetX: uni.upx2px(-40),
titleOffsetY: uni.upx2px(-20),
fontSize: uni.upx2px(24),
fontColor: '#777777',
formatter: (val) => {
return parseInt(val)
}
}
],
showTitle:true,
gridType: 'dash',
gridColor: '#eee',
dashLength: 2,
// splitNumber: 3,
},
dataLabel: false,
width: uni.upx2px(686),
height: uni.upx2px(480),
showBox: true,
extra: {
mix: {
column: {
type: 'group',
width: uni.upx2px(50),
dataLabel: true,
},
line: {
dataPointShapeType: 'hollow',
dataPointShape: true,
}
}
}
});
},
}
}
</script>
<style scoped>
.customer-content {
margin: 0 30rpx;
border-radius: 8rpx;
box-shadow: 0 2rpx 10rpx 0 rgba(230, 230, 230, 0.49);
background-color: #fff;
position: relative;
margin-bottom: 48rpx;
padding-bottom: 40rpx;
}
.customer-title {
padding: 0 40rpx;
line-height: 80rpx;
font-size: 26rpx;
}
.operation-cate-content {
height: 480rpx;
width: 690rpx;
margin: 0 auto;
}
.charts-box {
width: 100%;
height: 330rpx;
}
.operation-stock-content {
height: 440rpx;
width: 690rpx;
margin: 0 auto;
}
.operation-pie-content {
height: 500rpx;
width: 690rpx;
margin: 0 auto;
}
.tab-btn {
position: absolute;
color: #fff;
font-size: 24rpx;
width: 241rpx;
height: 52rpx;
line-height: 52rpx;
right: 0;
top: 0;
display: flex;
align-items: center;
justify-content: center;
background: url(../../../static/images/revenue/tab-bg.png) no-repeat right;
background-size: contain;
}
.tab-btn::before {
content: '';
background: url(../../../static/images/revenue/next.png) no-repeat center;
background-size: contain;
width: 40rpx;
height: 16rpx;
}
.analysis-text {
color: #9498A4;
display: flex;
align-items: flex-start;
font-size: 24rpx;
margin: 0 30rpx 0 30rpx;
}
.key-text {
min-width: 50rpx;
background: #EA7F56;
font-size: 22rpx;
text-align: center;
color: #ffffff;
background: #ea7f56;
border-radius: 5rpx;
margin-right: 16rpx;
height: 30rpx;
line-height: 30rpx;
margin-top: 4rpx;
}
.tab-unit {
padding-left: 40rpx;
position: relative;
}
.tab-unit+.tab-unit::before {
content: '';
height: 77rpx;
width: 2rpx;
background-color: #E6E6E6;
display: block;
position: absolute;
top: 65rpx;
left: -10rpx;
}
.tab-title {
margin-bottom: 20rpx;
font-size: 26rpx;
}
.tab-number {
font-size: 30rpx;
}
.tab-title,
.tab-desc {
color: #ADADAD;
margin-right: 16rpx;
}
.tab-desc,
.tab-rate {
font-size: 24rpx;
}
</style>