feat:完善功能
This commit is contained in:
48
src/components/Select/index.vue
Normal file
48
src/components/Select/index.vue
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<template>
|
||||||
|
<div class="select">
|
||||||
|
<el-select v-model="modelValue" clearable :placeholder="label" @change="onChange">
|
||||||
|
<el-option v-for="item in options" :key="item.id" :label="item.ssname" :value="item.id" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
defineProps({
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
default: '选择排队景区'
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let modelValue = defineModel()
|
||||||
|
let emit = defineEmits(['on-change'])
|
||||||
|
const onChange = (e) => {
|
||||||
|
emit('on-change', e)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.select {
|
||||||
|
:deep(.el-select__wrapper) {
|
||||||
|
width: vw(240);
|
||||||
|
padding: vh(10) vw(20);
|
||||||
|
border-radius: vw(54);
|
||||||
|
box-shadow: none;
|
||||||
|
border: 1px solid rgba(0, 114, 220, 0.3);
|
||||||
|
background: linear-gradient(270deg, rgba(8, 41, 86, 0.16) 0%, #0b61b4 100%);
|
||||||
|
}
|
||||||
|
:deep(.el-select__placeholder) {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: vw(20);
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: vw(24);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -13,58 +13,54 @@
|
|||||||
watch(
|
watch(
|
||||||
() => homeData.value?.userPortrait?.ageRate,
|
() => homeData.value?.userPortrait?.ageRate,
|
||||||
() => {
|
() => {
|
||||||
init()
|
setOption({
|
||||||
}
|
tooltip: {
|
||||||
)
|
trigger: 'item'
|
||||||
|
|
||||||
const init = () => {
|
|
||||||
setOption({
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'item'
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
orient: 'vertical',
|
|
||||||
left: '60%',
|
|
||||||
y: 'center',
|
|
||||||
itemHeight: fitChartSize(8),
|
|
||||||
itemWidth: fitChartSize(8),
|
|
||||||
itemGap: fitChartSize(10),
|
|
||||||
formatter: function (name) {
|
|
||||||
return '{name|' + name + '}'
|
|
||||||
},
|
},
|
||||||
textStyle: {
|
legend: {
|
||||||
rich: {
|
orient: 'vertical',
|
||||||
name: {
|
left: '60%',
|
||||||
color: '#fff',
|
y: 'center',
|
||||||
fontSize: fitChartSize(14)
|
itemHeight: fitChartSize(8),
|
||||||
},
|
itemWidth: fitChartSize(8),
|
||||||
value: {
|
itemGap: fitChartSize(10),
|
||||||
color: '#00D5F6',
|
formatter: function (name) {
|
||||||
fontSize: fitChartSize(14)
|
return '{name|' + name + '}'
|
||||||
|
},
|
||||||
|
textStyle: {
|
||||||
|
rich: {
|
||||||
|
name: {
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: fitChartSize(14)
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
color: '#00D5F6',
|
||||||
|
fontSize: fitChartSize(14)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
series: [
|
||||||
series: [
|
{
|
||||||
{
|
type: 'pie',
|
||||||
type: 'pie',
|
center: ['30%', '50%'],
|
||||||
center: ['30%', '50%'],
|
radius: ['50%', '70%'],
|
||||||
radius: ['50%', '70%'],
|
itemStyle: {
|
||||||
itemStyle: {
|
borderColor: 'transparent',
|
||||||
borderColor: 'transparent',
|
borderRadius: fitChartSize(2),
|
||||||
borderRadius: fitChartSize(2),
|
borderWidth: fitChartSize(2)
|
||||||
borderWidth: fitChartSize(2)
|
},
|
||||||
},
|
label: {
|
||||||
label: {
|
show: false,
|
||||||
show: false,
|
color: '#D3F0FE',
|
||||||
color: '#D3F0FE',
|
fontSize: fitChartSize(12)
|
||||||
fontSize: fitChartSize(12)
|
},
|
||||||
},
|
data: homeData.value?.userPortrait?.ageRate || []
|
||||||
data: homeData.value?.userPortrait?.ageRate || []
|
}
|
||||||
}
|
]
|
||||||
]
|
})
|
||||||
})
|
}
|
||||||
}
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -7,9 +7,10 @@
|
|||||||
</Title1>
|
</Title1>
|
||||||
<div class="flex pt-20">
|
<div class="flex pt-20">
|
||||||
<div
|
<div
|
||||||
v-for="(item, index) in homeData?.scenicSpot"
|
|
||||||
class="item"
|
class="item"
|
||||||
:class="{ core: index == 0, queue: index == 1, congestion: index == 2 }"
|
:class="{ core: index == 0, queue: index == 1, congestion: index == 2 }"
|
||||||
|
v-for="(item, index) in homeData?.scenicSpot"
|
||||||
|
:key="index"
|
||||||
>
|
>
|
||||||
<span class="label">{{ item.name }}</span>
|
<span class="label">{{ item.name }}</span>
|
||||||
<div class="flex align-end">
|
<div class="flex align-end">
|
||||||
@@ -146,9 +147,9 @@
|
|||||||
<Title2 title="景区购票数" />
|
<Title2 title="景区购票数" />
|
||||||
<div class="ticket-wrap">
|
<div class="ticket-wrap">
|
||||||
<img src="@/assets/images/ticket.png" />
|
<img src="@/assets/images/ticket.png" />
|
||||||
<div> <span class="label">当日购票量:</span><countup endVal="768578" /> </div>
|
<div v-for="(item, index) in homeData?.admission" :key="index">
|
||||||
<div> <span class="label">未来3天购票量:</span><countup endVal="768578" /> </div>
|
<span class="label">{{ item.name }}:</span><countup :end-val="item.value" />
|
||||||
<div> <span class="label">3天后购票量:</span><countup endVal="768578" /> </div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -157,8 +158,12 @@
|
|||||||
<div class="box-1">
|
<div class="box-1">
|
||||||
<Title3 title="年龄/性别占比" />
|
<Title3 title="年龄/性别占比" />
|
||||||
<age />
|
<age />
|
||||||
<div class="count">总人数:<countup endVal="124563" /></div>
|
<div class="count">总人数:<countup :end-val="ageRateTotal" /></div>
|
||||||
<div class="cell pt-20" v-for="item in homeData?.userPortrait.genderRate">
|
<div
|
||||||
|
class="cell pt-20"
|
||||||
|
v-for="(item, index) in homeData?.userPortrait.genderRate"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
<img class="icon" src="@/assets/images/man.png" />
|
<img class="icon" src="@/assets/images/man.png" />
|
||||||
<div class="bg">
|
<div class="bg">
|
||||||
<span class="text">{{ item.name }}性</span>
|
<span class="text">{{ item.name }}性</span>
|
||||||
@@ -181,7 +186,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="box-1">
|
<div class="box-1">
|
||||||
<Title3 title="购票来源" />
|
<Title3 title="购票来源" />
|
||||||
<div class="count">总人数:<countup endVal="124563" /></div>
|
<div class="count">总人数:<countup :end-val="channelTotal" /></div>
|
||||||
<ticket />
|
<ticket />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -196,6 +201,19 @@
|
|||||||
import ticket from './ticket.vue'
|
import ticket from './ticket.vue'
|
||||||
|
|
||||||
const homeData = inject('homeData')
|
const homeData = inject('homeData')
|
||||||
|
|
||||||
|
const ageRateTotal = computed(() => {
|
||||||
|
return homeData.value?.userPortrait.genderRate.reduce(
|
||||||
|
(total, current) => Number(current.count) + total,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
})
|
||||||
|
const channelTotal = computed(() => {
|
||||||
|
return homeData.value?.userPortrait.channel.reduce(
|
||||||
|
(total, current) => Number(current.count) + total,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -164,7 +164,7 @@
|
|||||||
<div class="box-1">
|
<div class="box-1">
|
||||||
<div class="pt-10">
|
<div class="pt-10">
|
||||||
<Title3 title="拥堵路段总数" />
|
<Title3 title="拥堵路段总数" />
|
||||||
<traffic-flow />
|
<traffic />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-1">
|
<div class="box-1">
|
||||||
@@ -188,7 +188,7 @@
|
|||||||
<div class="car">
|
<div class="car">
|
||||||
<div class="label">车总数</div>
|
<div class="label">车总数</div>
|
||||||
<div class="flex align-center">
|
<div class="flex align-center">
|
||||||
<countup class="value" :end-val="homeData?.carShipData.car.count" />
|
<countup class="value" :end-val="homeData?.carShipData?.car?.count || 0" />
|
||||||
<span class="unit">辆</span>
|
<span class="unit">辆</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -198,7 +198,7 @@
|
|||||||
<div>调度</div>
|
<div>调度</div>
|
||||||
<div>空余</div>
|
<div>空余</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="cell" v-for="item in homeData?.carShipData.car.info" :key="index">
|
<div class="cell" v-for="(item, index) in homeData?.carShipData?.car.info" :key="index">
|
||||||
<div>{{ item.scenic_area }}</div>
|
<div>{{ item.scenic_area }}</div>
|
||||||
<div>{{ item.started_count }}<span class="unit-1">辆</span></div>
|
<div>{{ item.started_count }}<span class="unit-1">辆</span></div>
|
||||||
<div>{{ item.not_started_count }}<span class="unit-1">辆</span></div>
|
<div>{{ item.not_started_count }}<span class="unit-1">辆</span></div>
|
||||||
@@ -209,7 +209,7 @@
|
|||||||
<div class="ship">
|
<div class="ship">
|
||||||
<div class="label">车总数</div>
|
<div class="label">车总数</div>
|
||||||
<div class="flex align-center">
|
<div class="flex align-center">
|
||||||
<countup class="value" :end-val="homeData?.carShipData.ship.count" />
|
<countup class="value" :end-val="homeData?.carShipData?.ship?.count || 0" />
|
||||||
<span class="unit">辆</span>
|
<span class="unit">辆</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="table">
|
<div class="table">
|
||||||
@@ -259,7 +259,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="lodging">
|
<div class="occupancy">
|
||||||
<Title3 title="酒店入住人数及入住率" />
|
<Title3 title="酒店入住人数及入住率" />
|
||||||
</div>
|
</div>
|
||||||
<occupancy />
|
<occupancy />
|
||||||
@@ -273,7 +273,7 @@
|
|||||||
import jam from './jam.vue'
|
import jam from './jam.vue'
|
||||||
import vacancy from './vacancy.vue'
|
import vacancy from './vacancy.vue'
|
||||||
import occupancy from './occupancy.vue'
|
import occupancy from './occupancy.vue'
|
||||||
import TrafficFlow from './traffic-flow.vue'
|
import traffic from './traffic.vue'
|
||||||
import countup from 'vue-countup-v3'
|
import countup from 'vue-countup-v3'
|
||||||
import icon1 from '@/assets/images/icon-1.png'
|
import icon1 from '@/assets/images/icon-1.png'
|
||||||
import icon2 from '@/assets/images/icon-2.png'
|
import icon2 from '@/assets/images/icon-2.png'
|
||||||
@@ -519,7 +519,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.lodging {
|
.occupancy {
|
||||||
:deep(.title-3) {
|
:deep(.title-3) {
|
||||||
margin-top: vh(10);
|
margin-top: vh(10);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,174 +1,161 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="lodging-ratio" id="lodging-ratio" />
|
<div class="lodging-ratio" :id="id" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { fitChartSize } from '@/utils/dataUtil'
|
import { fitChartSize } from '@/utils/dataUtil'
|
||||||
import * as echarts from 'echarts'
|
import { useEchart } from '@/hooks/echart'
|
||||||
|
|
||||||
let topChart = null
|
const { id, setOption } = useEchart()
|
||||||
let result = [
|
|
||||||
{ name: '酒店1', value: 86 },
|
const homeData = inject('homeData')
|
||||||
{ name: '酒店2', value: 83 },
|
watch(
|
||||||
{ name: '酒店3', value: 73 }
|
() => homeData.value?.hotelData?.list,
|
||||||
]
|
() => {
|
||||||
let option = {
|
setOption({
|
||||||
backgroundColor: 'transparent',
|
backgroundColor: 'transparent',
|
||||||
tooltip: {
|
tooltip: {
|
||||||
show: false
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
show: false
|
|
||||||
},
|
|
||||||
grid: {
|
|
||||||
left: '4%',
|
|
||||||
right: '4%',
|
|
||||||
top: '20%',
|
|
||||||
bottom: '-10%',
|
|
||||||
containLabel: true
|
|
||||||
},
|
|
||||||
xAxis: [{ max: 100, show: false }],
|
|
||||||
yAxis: [
|
|
||||||
{
|
|
||||||
splitLine: {
|
|
||||||
show: false
|
show: false
|
||||||
},
|
},
|
||||||
axisLine: {
|
legend: {
|
||||||
show: false
|
show: false
|
||||||
},
|
},
|
||||||
type: 'category',
|
grid: {
|
||||||
axisTick: {
|
left: '4%',
|
||||||
show: false
|
right: '4%',
|
||||||
|
top: '20%',
|
||||||
|
bottom: '-10%',
|
||||||
|
containLabel: true
|
||||||
},
|
},
|
||||||
data: result.map((item) => item.name),
|
xAxis: [{ max: 100, show: false }],
|
||||||
axisLabel: {
|
yAxis: [
|
||||||
show: false
|
{
|
||||||
}
|
splitLine: {
|
||||||
},
|
show: false
|
||||||
{
|
|
||||||
type: 'category',
|
|
||||||
axisTick: 'none',
|
|
||||||
axisLine: 'none',
|
|
||||||
show: true,
|
|
||||||
axisLabel: {
|
|
||||||
textStyle: {
|
|
||||||
color: '#fff',
|
|
||||||
fontSize: fitChartSize(12)
|
|
||||||
},
|
|
||||||
verticalAlign: 'bottom',
|
|
||||||
padding: [0, 0, fitChartSize(6), 0],
|
|
||||||
inside: true,
|
|
||||||
formatter: function (value) {
|
|
||||||
return `{value|${value}}`
|
|
||||||
},
|
|
||||||
rich: {
|
|
||||||
name: {
|
|
||||||
align: 'center',
|
|
||||||
color: '#D3E5FF',
|
|
||||||
fontSize: fitChartSize(14),
|
|
||||||
fontFamily: 'Source Han Sans CN'
|
|
||||||
},
|
},
|
||||||
value: {
|
axisLine: {
|
||||||
align: 'center',
|
show: false
|
||||||
color: '#fff',
|
},
|
||||||
fontSize: fitChartSize(14),
|
type: 'category',
|
||||||
fontFamily: 'Source Han Sans CN'
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
data: homeData.value?.hotelData?.list.map((item) => item.hotel_name),
|
||||||
|
axisLabel: {
|
||||||
|
show: false
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
{
|
||||||
data: result.map((item) => item.value)
|
type: 'category',
|
||||||
}
|
axisTick: 'none',
|
||||||
],
|
axisLine: 'none',
|
||||||
series: [
|
show: true,
|
||||||
{
|
axisLabel: {
|
||||||
name: '',
|
textStyle: {
|
||||||
type: 'bar',
|
color: '#fff',
|
||||||
barWidth: fitChartSize(4),
|
fontSize: fitChartSize(12)
|
||||||
MaxSize: 0,
|
},
|
||||||
showBackground: true,
|
verticalAlign: 'bottom',
|
||||||
barBorderRadius: [30, 0, 0, 30],
|
padding: [0, 0, fitChartSize(6), 0],
|
||||||
backgroundStyle: {
|
inside: true,
|
||||||
color: 'rgba(0, 150, 255, 0.15)'
|
formatter: function (value) {
|
||||||
},
|
return `{value|${value}}`
|
||||||
label: {
|
},
|
||||||
show: true,
|
rich: {
|
||||||
offset: [fitChartSize(10), -fitChartSize(20)],
|
name: {
|
||||||
color: '#D3E5FF',
|
align: 'center',
|
||||||
fontWeight: 500,
|
color: '#D3E5FF',
|
||||||
position: 'left',
|
fontSize: fitChartSize(14),
|
||||||
align: 'left',
|
fontFamily: 'Source Han Sans CN'
|
||||||
fontSize: fitChartSize(14),
|
},
|
||||||
fontFamily: 'Source Han Sans CN',
|
value: {
|
||||||
formatter: function (params) {
|
align: 'center',
|
||||||
return params.data.name
|
color: '#fff',
|
||||||
}
|
fontSize: fitChartSize(14),
|
||||||
},
|
fontFamily: 'Source Han Sans CN'
|
||||||
data: result.map((item, index) => {
|
}
|
||||||
return {
|
|
||||||
name: item.name,
|
|
||||||
value: item.value,
|
|
||||||
itemStyle: {
|
|
||||||
barBorderRadius: [3, 0, 0, 3],
|
|
||||||
color: {
|
|
||||||
type: 'linear',
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
x2: 1,
|
|
||||||
y2: 1,
|
|
||||||
colorStops: [
|
|
||||||
{
|
|
||||||
offset: 0,
|
|
||||||
color: 'rgba(255, 112, 33, 0)'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
offset: 1,
|
|
||||||
color: 'rgba(255, 112, 33, 1)'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
data: homeData.value?.hotelData?.list.map((item) => item.occupancy_rate)
|
||||||
}
|
}
|
||||||
})
|
],
|
||||||
},
|
series: [
|
||||||
{
|
{
|
||||||
name: '外圆',
|
name: '',
|
||||||
type: 'scatter',
|
type: 'bar',
|
||||||
emphasis: {
|
barWidth: fitChartSize(4),
|
||||||
scale: false
|
MaxSize: 0,
|
||||||
},
|
showBackground: true,
|
||||||
showSymbol: true,
|
barBorderRadius: [30, 0, 0, 30],
|
||||||
symbol: 'circle',
|
backgroundStyle: {
|
||||||
symbolSize: fitChartSize(10),
|
color: 'rgba(0, 150, 255, 0.15)'
|
||||||
z: 2,
|
},
|
||||||
data: result.map((item, index) => {
|
label: {
|
||||||
return {
|
show: true,
|
||||||
name: item.name,
|
offset: [fitChartSize(10), -fitChartSize(20)],
|
||||||
value: item.value,
|
color: '#D3E5FF',
|
||||||
itemStyle: {
|
fontWeight: 500,
|
||||||
color: '#fff',
|
position: 'left',
|
||||||
opacity: 1
|
align: 'left',
|
||||||
}
|
fontSize: fitChartSize(14),
|
||||||
|
fontFamily: 'Source Han Sans CN',
|
||||||
|
formatter: function (params) {
|
||||||
|
return params.data.name
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: homeData.value?.hotelData?.list.map((item) => {
|
||||||
|
return {
|
||||||
|
name: item.hotel_name,
|
||||||
|
value: item.occupancy_rate,
|
||||||
|
itemStyle: {
|
||||||
|
barBorderRadius: [3, 0, 0, 3],
|
||||||
|
color: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
x2: 1,
|
||||||
|
y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{
|
||||||
|
offset: 0,
|
||||||
|
color: 'rgba(255, 112, 33, 0)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 1,
|
||||||
|
color: 'rgba(255, 112, 33, 1)'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '外圆',
|
||||||
|
type: 'scatter',
|
||||||
|
emphasis: {
|
||||||
|
scale: false
|
||||||
|
},
|
||||||
|
showSymbol: true,
|
||||||
|
symbol: 'circle',
|
||||||
|
symbolSize: fitChartSize(10),
|
||||||
|
z: 2,
|
||||||
|
data: homeData.value?.hotelData?.list.map((item) => {
|
||||||
|
return {
|
||||||
|
name: item.hotel_name,
|
||||||
|
value: item.occupancy_rate,
|
||||||
|
itemStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
opacity: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
animationDelay: 500
|
||||||
}
|
}
|
||||||
}),
|
]
|
||||||
animationDelay: 500
|
})
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
const init = () => {
|
|
||||||
topChart = echarts.init(document.getElementById('lodging-ratio'))
|
|
||||||
topChart.setOption(option)
|
|
||||||
}
|
|
||||||
const resize = () => {
|
|
||||||
if (topChart) {
|
|
||||||
topChart.dispose()
|
|
||||||
topChart = null
|
|
||||||
init()
|
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
onMounted(() => {
|
|
||||||
init()
|
|
||||||
window.addEventListener('resize', resize)
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -1,190 +1,73 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="ticket" id="ticket" />
|
<div class="ticket" :id="id" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { fitChartSize } from '@/utils/dataUtil'
|
import { fitChartSize } from '@/utils/dataUtil'
|
||||||
import * as echarts from 'echarts'
|
import { useEchart } from '@/hooks/echart'
|
||||||
|
|
||||||
let ticketChart = null
|
const { id, setOption } = useEchart()
|
||||||
var qxzbData = [
|
|
||||||
{
|
const homeData = inject('homeData')
|
||||||
name: '处理中',
|
|
||||||
value: 500,
|
let x = 15
|
||||||
full: 1000 // 最大值
|
let y = 25
|
||||||
},
|
|
||||||
{
|
watch(
|
||||||
name: '超期中',
|
() => homeData.value?.userPortrait?.channel,
|
||||||
value: 756,
|
() => {
|
||||||
full: 1000
|
setOption({
|
||||||
},
|
backgroundColor: 'transparent',
|
||||||
{
|
legend: {
|
||||||
name: '延期中',
|
x: 'center',
|
||||||
value: 800,
|
y: 'bottom',
|
||||||
full: 1000
|
itemHeight: fitChartSize(8),
|
||||||
}
|
itemWidth: fitChartSize(8),
|
||||||
]
|
itemGap: fitChartSize(20),
|
||||||
var returnData = function (qxzbData, name) {
|
formatter: function (name) {
|
||||||
for (var a = 0; a < qxzbData.length; a++) {
|
return '{title|' + name + '}'
|
||||||
if (qxzbData[a].name == name) {
|
|
||||||
return qxzbData[a].value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let option = {
|
|
||||||
backgroundColor: 'transparent',
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'item',
|
|
||||||
formatter: function (rsp) {
|
|
||||||
if (rsp.name != '') {
|
|
||||||
return rsp.name + '<br/>' + rsp.marker + ' ' + rsp.value + ' (' + rsp.percent + ')'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
x: 'center',
|
|
||||||
y: 'bottom',
|
|
||||||
data: qxzbData,
|
|
||||||
itemHeight: fitChartSize(8),
|
|
||||||
itemWidth: fitChartSize(8),
|
|
||||||
itemGap: fitChartSize(20),
|
|
||||||
formatter: function (name) {
|
|
||||||
return '{title|' + name + '} {value|' + returnData(qxzbData, name) + '}'
|
|
||||||
},
|
|
||||||
textStyle: {
|
|
||||||
rich: {
|
|
||||||
title: {
|
|
||||||
color: '#fff',
|
|
||||||
fontSize: fitChartSize(14)
|
|
||||||
},
|
},
|
||||||
value: {
|
textStyle: {
|
||||||
color: '#00D5F6',
|
rich: {
|
||||||
fontSize: fitChartSize(14)
|
title: {
|
||||||
}
|
color: '#fff',
|
||||||
}
|
fontSize: fitChartSize(14)
|
||||||
}
|
},
|
||||||
},
|
value: {
|
||||||
color: ['#F15A25', '#01FEFE', '#12B5FD'],
|
color: '#00D5F6',
|
||||||
series: [
|
fontSize: fitChartSize(14)
|
||||||
{
|
|
||||||
name: qxzbData[0].name, //最里面的圈
|
|
||||||
type: 'pie',
|
|
||||||
clockWise: false, //顺时加载
|
|
||||||
radius: ['15%', '25%'],
|
|
||||||
center: ['50%', '40%'],
|
|
||||||
label: {
|
|
||||||
normal: {
|
|
||||||
show: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
labelLine: {
|
|
||||||
show: false
|
|
||||||
},
|
|
||||||
itemStyle: {
|
|
||||||
emphasis: {
|
|
||||||
show: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
value: qxzbData[0].value,
|
|
||||||
name: qxzbData[0].name
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: qxzbData[0].full,
|
|
||||||
itemStyle: {
|
|
||||||
normal: {
|
|
||||||
color: '#07439C'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: qxzbData[1].name, //第二个圈
|
|
||||||
type: 'pie',
|
|
||||||
clockWise: false, //顺时加载
|
|
||||||
radius: ['30%', '40%'],
|
|
||||||
center: ['50%', '40%'],
|
|
||||||
label: {
|
|
||||||
normal: {
|
|
||||||
show: false
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
labelLine: {
|
color: ['#F15A25', '#01FEFE', '#12B5FD'],
|
||||||
show: false
|
series: homeData.value?.userPortrait?.channel.map((item, index) => {
|
||||||
},
|
return {
|
||||||
itemStyle: {
|
name: item.name,
|
||||||
emphasis: {
|
type: 'pie',
|
||||||
show: false
|
clockwise: false, //顺时加载
|
||||||
}
|
radius: [`${x * (index + 1)}%`, `${y + index * 15}%`],
|
||||||
},
|
center: ['50%', '40%'],
|
||||||
data: [
|
label: { show: false },
|
||||||
{
|
labelLine: { show: false },
|
||||||
value: qxzbData[1].value,
|
emphasis: { show: false },
|
||||||
name: qxzbData[1].name
|
data: [
|
||||||
},
|
{
|
||||||
{
|
value: parseFloat(item.value),
|
||||||
value: qxzbData[1].full,
|
name: item.name
|
||||||
itemStyle: {
|
},
|
||||||
normal: {
|
{
|
||||||
color: '#07439C'
|
value: 100,
|
||||||
|
itemStyle: {
|
||||||
|
color: '#07439C'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
}
|
}
|
||||||
]
|
})
|
||||||
},
|
})
|
||||||
{
|
|
||||||
name: qxzbData[2].name, //最外层圈
|
|
||||||
type: 'pie',
|
|
||||||
clockWise: false, //顺时加载
|
|
||||||
radius: ['45%', '55%'],
|
|
||||||
center: ['50%', '40%'],
|
|
||||||
label: {
|
|
||||||
normal: {
|
|
||||||
show: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
labelLine: {
|
|
||||||
show: false
|
|
||||||
},
|
|
||||||
itemStyle: {
|
|
||||||
emphasis: {
|
|
||||||
show: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
value: qxzbData[2].value,
|
|
||||||
name: qxzbData[2].name
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: qxzbData[2].full,
|
|
||||||
itemStyle: {
|
|
||||||
normal: {
|
|
||||||
color: '#07439C'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
const init = () => {
|
|
||||||
ticketChart = echarts.init(document.getElementById('ticket'))
|
|
||||||
ticketChart.setOption(option)
|
|
||||||
window.addEventListener('resize', resize)
|
|
||||||
}
|
|
||||||
const resize = () => {
|
|
||||||
if (ticketChart) {
|
|
||||||
ticketChart.dispose()
|
|
||||||
ticketChart = null
|
|
||||||
init()
|
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
onMounted(() => {
|
|
||||||
init()
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -10,13 +10,6 @@
|
|||||||
|
|
||||||
const homeData = inject('homeData')
|
const homeData = inject('homeData')
|
||||||
|
|
||||||
watch(
|
|
||||||
() => homeData.value?.userPortrait?.provinceRate,
|
|
||||||
() => {
|
|
||||||
init()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const init = () => {
|
const init = () => {
|
||||||
setOption({
|
setOption({
|
||||||
backgroundColor: 'transparent',
|
backgroundColor: 'transparent',
|
||||||
@@ -138,6 +131,13 @@
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => homeData.value?.userPortrait?.provinceRate,
|
||||||
|
() => {
|
||||||
|
init()
|
||||||
|
}
|
||||||
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -1,54 +1,77 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<div class="select-box">
|
||||||
|
<Select v-model="params.id" :options="options" @on-change="initChart" />
|
||||||
|
</div>
|
||||||
<div class="area" :id="id" />
|
<div class="area" :id="id" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useEchart } from '@/hooks/echart'
|
import { useEchart } from '@/hooks/echart'
|
||||||
import { fitChartSize } from '@/utils/dataUtil'
|
import { fitChartSize } from '@/utils/dataUtil'
|
||||||
import { getAreaApi } from '@/api/sentiment.js'
|
import { getAreaApi, getSpotApi } from '@/api/sentiment.js'
|
||||||
|
|
||||||
const { id, setOption } = useEchart()
|
const { id, setOption } = useEchart()
|
||||||
|
|
||||||
|
let params = reactive({ id: '' })
|
||||||
|
let option = null
|
||||||
|
let options = ref([])
|
||||||
const initChart = async () => {
|
const initChart = async () => {
|
||||||
let res = await getAreaApi()
|
let res = await getAreaApi(params)
|
||||||
setOption({
|
if (option) {
|
||||||
legend: {
|
option.series[0].data = res.data
|
||||||
top: 'top',
|
} else {
|
||||||
itemWidth: fitChartSize(30),
|
option = {
|
||||||
itemHeight: fitChartSize(30),
|
legend: {
|
||||||
textStyle: {
|
top: '10%',
|
||||||
fontSize: fitChartSize(14),
|
itemWidth: fitChartSize(20),
|
||||||
color: '#fff'
|
itemHeight: fitChartSize(20),
|
||||||
}
|
textStyle: {
|
||||||
},
|
color: '#fff',
|
||||||
series: [
|
fontSize: fitChartSize(20)
|
||||||
{
|
}
|
||||||
name: 'Nightingale Chart',
|
},
|
||||||
type: 'pie',
|
series: [
|
||||||
radius: ['30%', '60%'],
|
{
|
||||||
center: ['50%', '56%'],
|
name: '',
|
||||||
roseType: 'area',
|
type: 'pie',
|
||||||
labelLine: {
|
radius: ['30%', '60%'],
|
||||||
normal: {
|
center: ['50%', '56%'],
|
||||||
show: true,
|
roseType: 'area',
|
||||||
length: 1
|
labelLine: {
|
||||||
}
|
normal: {
|
||||||
},
|
show: true,
|
||||||
itemStyle: {
|
length: 1
|
||||||
borderRadius: fitChartSize(10)
|
}
|
||||||
},
|
},
|
||||||
data: res.data
|
itemStyle: {
|
||||||
}
|
borderRadius: fitChartSize(10)
|
||||||
]
|
},
|
||||||
})
|
data: res.data
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setOption(option)
|
||||||
|
}
|
||||||
|
const getStop = async () => {
|
||||||
|
let res = await getSpotApi()
|
||||||
|
options.value = res.data
|
||||||
}
|
}
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
getStop()
|
||||||
initChart()
|
initChart()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
.select-box {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 9999;
|
||||||
|
top: vh(40);
|
||||||
|
right: vw(10);
|
||||||
|
}
|
||||||
.area {
|
.area {
|
||||||
width: vw(740);
|
width: vw(840);
|
||||||
height: vh(400);
|
height: vh(400);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -38,7 +38,9 @@
|
|||||||
<div class="flex mt-10">
|
<div class="flex mt-10">
|
||||||
<div class="box-2 mr-10 rela">
|
<div class="box-2 mr-10 rela">
|
||||||
<Title1 title="舆情指数" />
|
<Title1 title="舆情指数" />
|
||||||
<div class="dropdown"> <Dropdown :options="options" @on-change="onChange" /> </div>
|
<div class="select-box">
|
||||||
|
<Select v-model="params.id" :options="options" @on-change="getLineChart" />
|
||||||
|
</div>
|
||||||
<Line
|
<Line
|
||||||
:width="1560"
|
:width="1560"
|
||||||
:height="400"
|
:height="400"
|
||||||
@@ -47,7 +49,7 @@
|
|||||||
:seriesConfig="{ smooth: false, symbol: 'circle' }"
|
:seriesConfig="{ smooth: false, symbol: 'circle' }"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-1 mr-10">
|
<div class="box-1 mr-10 rela">
|
||||||
<Title1 title="地域分析" />
|
<Title1 title="地域分析" />
|
||||||
<Area />
|
<Area />
|
||||||
</div>
|
</div>
|
||||||
@@ -80,9 +82,8 @@
|
|||||||
let unsensitive = ref(0)
|
let unsensitive = ref(0)
|
||||||
let stateList = ref([])
|
let stateList = ref([])
|
||||||
let options = ref([])
|
let options = ref([])
|
||||||
const onChange = (e) => {
|
let params = reactive({ id: '' })
|
||||||
getLineChart(e.id)
|
|
||||||
}
|
|
||||||
const getStop = async () => {
|
const getStop = async () => {
|
||||||
let res = await getSpotApi()
|
let res = await getSpotApi()
|
||||||
options.value = res.data
|
options.value = res.data
|
||||||
@@ -97,8 +98,8 @@
|
|||||||
let res = await getStateApi()
|
let res = await getStateApi()
|
||||||
stateList.value = res.data
|
stateList.value = res.data
|
||||||
}
|
}
|
||||||
const getLineChart = async (id) => {
|
const getLineChart = async () => {
|
||||||
let res = await getLineChartApi({ id })
|
let res = await getLineChartApi(params)
|
||||||
xAxisData.value = res.data.data
|
xAxisData.value = res.data.data
|
||||||
seriesData.value = res.data.series
|
seriesData.value = res.data.series
|
||||||
}
|
}
|
||||||
@@ -116,9 +117,10 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.dropdown {
|
.select-box {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
|
top: vh(10);
|
||||||
right: vw(10);
|
right: vw(10);
|
||||||
}
|
}
|
||||||
.container {
|
.container {
|
||||||
|
|||||||
Reference in New Issue
Block a user