lcny-vue3-antd-admin/src/views/visualization/components/NYQK.vue

335 lines
8.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="w-314px">
<div
class="font-pmzd text-18px mt-19px text-center bg-clip-text text-transparent bg-gradient-to-t from-[#76E9F0] to-[#A7E6EE]"
>隆昌农业产业情况万元</div
>
<div class="w-full h-250px mx-auto mt-10px" ref="chartRef"> </div>
<div
class="font-bold text-18px bg-clip-text text-transparent bg-gradient-to-t from-[#76E9F0] to-[#A7E6EE] text-center mt-10px"
>
总产值
<CountTo
:startVal="0"
:endVal="countNumber"
class="font-bold text-18px bg-clip-text text-transparent bg-gradient-to-t from-[#76E9F0] to-[#A7E6EE]"
/>
万元
</div>
<div class="grid grid-cols-2 gap-y-18px gap-x-10px mx-10px mt-18px">
<div class="flex items-center" v-for="item in cityData" :key="item.slug">
<!-- <SvgIcon :name="item.slug" :size="40" color="transparent" /> -->
<img :src="item.icon" alt="" class="w-40px h-40px aim-spin" srcset="" />
<div class="text-white ml-6px">
<div class="text-12px font-bold">{{ item.name }}</div>
<div class="text-10px font-bold mt-4px">
<CountTo :startVal="0" :endVal="item.value" class="text-10px font-bold" />
<span>{{ item.unit }}</span>
</div>
</div>
</div>
</div>
<CModal v-model:visible="modelVisible" :footer="null" :name="currentData.name" />
</div>
</template>
<script lang="ts">
import {
Ref,
ref,
defineComponent,
onBeforeMount,
reactive,
toRefs,
watch,
computed,
onMounted,
} from 'vue'
import CModal from './CModal.vue'
import { useECharts } from '/@/hooks/web/useECharts'
import { getCitydataStatistics, getCropYieldCategoryStatics } from '/@/api/sys/other'
import { CountTo } from '/@/components/CountTo'
import { useVContext } from '../useVContext'
import { deepMerge } from '/@/utils'
import cityIcon1 from '/@/assets/images/city-1.png'
import cityIcon2 from '/@/assets/images/city-2.png'
import cityIcon3 from '/@/assets/images/city-3.png'
import cityIcon4 from '/@/assets/images/city-4.png'
import { useVisualizationStore } from '/@/store/modules/visualization'
var colorList = ['#73DDFF', '#73ACFF', '#FDD56A', '#FDB36A', '#FD866A', '#9E87FF', '#58D5FF']
interface cityDataType {
name: string
slug: string
unit: string
value: number
icon: string
}
const cityDefaultData = [
{
slug: 'city_data_area',
name: '',
value: '0',
unit: '',
icon: cityIcon1,
},
{
slug: 'city_data_population',
name: '',
value: '0',
unit: '',
icon: cityIcon2,
},
{
slug: 'city_data_street',
name: '',
value: '0',
unit: '',
icon: cityIcon3,
},
{
slug: 'city_data_cultivated_area',
name: '',
value: '0',
unit: '',
icon: cityIcon4,
},
]
export default defineComponent({
components: {
CountTo,
CModal,
},
setup() {
const modelVisible = ref(false)
const visualizationStore = useVisualizationStore()
const chartRef = ref<HTMLDivElement | null>(null)
const { setOptions, getInstance } = useECharts(chartRef as Ref<HTMLDivElement>)
const Data = reactive({
cityData: [] as cityDataType[],
lyqkData: [] as any,
})
const currentData = ref<any>({})
const { rootEmitter } = useVContext()
function chatInit() {
setOptions({
legend: {
show: true,
textStyle: {
color: '#fff',
},
orient: 'vertical',
right: 0,
top: 20,
bottom: 20,
},
tooltip: {
trigger: 'item',
// formatter: function (params) {
// return params.marker + params.name + ' ' + params.value + ' 万元'
// },
},
series: [
{
name: '隆昌农业产业情况',
type: 'pie',
radius: '80%',
center: ['40%', '50%'],
colorBy: 'data',
color: colorList,
itemStyle: {
color: function (params) {
return colorList[params.dataIndex]
},
},
label: {
show: false,
formatter: '{b}\n{d}%',
},
data: Data.lyqkData.map((item, index) => {
item.label = {
color: colorList[index],
}
return item
}),
},
],
})
chartAmi()
}
let timer: any = null
function chartAmi() {
let index = 0
timer && clearInterval(timer)
timer = setInterval(() => {
const currentIndex = index % Data.lyqkData.length
// getInstance()?.dispatchAction({
// type: 'legendUnSelect',
// name: legendData[currentIndex],
// })
// getInstance()?.dispatchAction({
// type: 'legendSelect',
// name: legendData[currentIndex],
// })
getInstance()?.dispatchAction({
type: 'showTip',
seriesIndex: 0,
dataIndex: currentIndex,
})
getInstance()?.dispatchAction({
type: 'downplay',
seriesIndex: 0,
dataIndex: currentIndex - 1,
})
getInstance()?.dispatchAction({
type: 'highlight',
seriesIndex: 0,
dataIndex: currentIndex,
})
index++
}, 3000)
}
async function getCropYieldCategory() {
const { list } = await getCropYieldCategoryStatics({
year: visualizationStore.getYear,
base_id: visualizationStore.getAddresId,
})
const arr = [] as { value: string | number; name: string }[]
for (const key in list) {
if (Object.prototype.hasOwnProperty.call(list, key)) {
arr.push({
value: (list[key] / 10000).toFixed(2),
name: key,
})
}
}
Data.lyqkData = arr
}
//获取所有
async function getCitydata() {
const resData = await getCitydataStatistics()
const temp = [] as cityDataType[]
cityDefaultData.forEach((e) => {
const obj = deepMerge({}, e)
const item: cityDataType = resData.find((r) => r.slug == e.slug)
if (item) {
obj.value = Number(item.value)
obj.unit = item.unit
}
temp.push(obj)
})
Data.cityData = temp
}
function onChangeMap(el) {
const keys = ['city_data_street']
const temp = [] as cityDataType[]
cityDefaultData.forEach((e) => {
const obj = deepMerge({}, e)
if (!keys.includes(e.slug)) {
//面积
if (e.slug == 'city_data_area') {
obj.value = Number(el.areas)
obj.unit = '亩'
} else if (e.slug == 'city_data_population') {
obj.value = el.workforce
} else if (e.slug == 'city_data_cultivated_area') {
obj.value = el.cultivated
}
temp.push(obj)
}
})
Data.cityData = temp
}
const countNumber = computed(() =>
Data.lyqkData.reduce((c, p) => {
c += Number(p.value)
return c
}, 0),
)
onMounted(() => {
getInstance()?.on('click', (e) => {
currentData.value = e.data
modelVisible.value = true
})
})
onBeforeMount(() => {
getCitydata()
getCropYieldCategory()
//地图点击
rootEmitter.on('map:click', (e) => {
onChangeMap(e)
getCropYieldCategory()
})
//地图返回
rootEmitter.on('map:back', () => {
getCitydata()
getCropYieldCategory()
})
rootEmitter.on('interval:auto', () => {
getCropYieldCategory()
})
})
watch(
() => Data.lyqkData,
() => {
chatInit()
},
)
watch(
() => visualizationStore.getYear,
() => {
getCropYieldCategory()
},
)
return {
modelVisible,
chartRef,
countNumber,
currentData,
...toRefs(Data),
}
},
})
</script>
<style scoped>
.aim-spin {
animation: spin 2s linear infinite;
}
@keyframes spin {
50% {
transform: scaleX(0);
}
100% {
transform: scaleX(1);
}
}
</style>