246 lines
6.2 KiB
Vue
246 lines
6.2 KiB
Vue
<template>
|
|
<Box title="大宗物资(元/吨)">
|
|
<div class="h-full flex flex-col">
|
|
<div class="py-10px">
|
|
<ul class="flex items-center justify-center m-0">
|
|
<li
|
|
class="mx-11px text-white text-12px cursor-pointer"
|
|
:class="{ active: currentTab == item.key }"
|
|
@click="changeTab(item.key)"
|
|
v-for="item in tabList"
|
|
:key="item.key"
|
|
>{{ item.value }}</li
|
|
>
|
|
</ul>
|
|
</div>
|
|
<div class="flex-1" ref="chartRef"> </div>
|
|
</div>
|
|
</Box>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { defineComponent, reactive, ref, Ref, onBeforeMount, watch } from 'vue'
|
|
import Box from './Box.vue'
|
|
import { useECharts } from '/@/hooks/web/useECharts'
|
|
import { getMateriel } from '/@/api/sys/other'
|
|
import { useVisualizationStore } from '/@/store/modules/visualization'
|
|
import { chartBarColors } from './colors'
|
|
import { useVContext } from '../useVContext'
|
|
export default defineComponent({
|
|
components: {
|
|
Box,
|
|
},
|
|
setup() {
|
|
const { rootEmitter } = useVContext()
|
|
const tabList = reactive([
|
|
{
|
|
key: '1',
|
|
value: '饲料',
|
|
},
|
|
{
|
|
key: '2',
|
|
value: '肥料',
|
|
},
|
|
])
|
|
|
|
const Data = reactive({
|
|
x_axis: [],
|
|
series: [],
|
|
})
|
|
|
|
const currentTab = ref<String>('1')
|
|
|
|
const visualizationStore = useVisualizationStore()
|
|
|
|
const chartRef = ref<HTMLDivElement | null>(null)
|
|
|
|
const changeTab = (key: String) => {
|
|
if (currentTab.value == key) return
|
|
currentTab.value = key
|
|
getData()
|
|
}
|
|
|
|
const { setOptions, getInstance } = useECharts(chartRef as Ref<HTMLDivElement>)
|
|
|
|
async function getData() {
|
|
const resData = await getMateriel({
|
|
year: visualizationStore.getYear,
|
|
type: currentTab.value,
|
|
})
|
|
Data.x_axis = resData.x_axis
|
|
Data.series = resData.series
|
|
chartsInit()
|
|
}
|
|
|
|
let legendData = [] as any
|
|
|
|
const chartsInit = () => {
|
|
const obj = {
|
|
legendData: [] as any,
|
|
series: [] as any,
|
|
}
|
|
|
|
Data.series.forEach(({ name, data, diffs }, index) => {
|
|
const color = chartBarColors[index % chartBarColors.length]
|
|
obj.legendData.push(name)
|
|
|
|
obj.series.push({
|
|
name: 'Placeholder',
|
|
type: 'bar',
|
|
barGap: 0,
|
|
stack: 'Total' + index,
|
|
itemStyle: {
|
|
borderColor: 'transparent',
|
|
color: 'transparent',
|
|
},
|
|
data: data,
|
|
})
|
|
obj.series.push({
|
|
name: name,
|
|
type: 'bar',
|
|
stack: 'Total' + index,
|
|
itemStyle: {
|
|
color: color.itemColor1,
|
|
},
|
|
label: {
|
|
show: false,
|
|
position: 'inside',
|
|
color: '#fff',
|
|
},
|
|
data: diffs,
|
|
})
|
|
})
|
|
|
|
legendData = obj.legendData
|
|
|
|
setOptions({
|
|
grid: { left: '2%', right: '2%', top: '50px', bottom: '2%', containLabel: true },
|
|
legend: {
|
|
show: true,
|
|
data: obj.legendData,
|
|
textStyle: {
|
|
color: '#ffffff',
|
|
},
|
|
},
|
|
tooltip: {
|
|
trigger: 'axis',
|
|
axisPointer: {
|
|
lineStyle: {
|
|
width: 1,
|
|
color: '#019680',
|
|
},
|
|
},
|
|
formatter: function (params) {
|
|
let str = params[0]?.name + '<br/>'
|
|
params.forEach((e) => {
|
|
if (e.seriesName != 'Placeholder') {
|
|
const item: any = Data.series.find((el: any) => el.name == e.seriesName)
|
|
if (item) {
|
|
const min = item.data[e.dataIndex] ?? 0
|
|
const diff = item.diffs[e.dataIndex] ?? 0
|
|
const sum = min + diff
|
|
str += `${e.marker}<span style="width:50px;display: inline-block;">${e.seriesName}</span> ${min}-${sum}<br>`
|
|
}
|
|
}
|
|
})
|
|
return str
|
|
},
|
|
},
|
|
xAxis: {
|
|
type: 'category',
|
|
data: Data.x_axis,
|
|
axisTick: {
|
|
show: false,
|
|
},
|
|
axisLine: {
|
|
show: false,
|
|
},
|
|
axisLabel: {
|
|
color: '#fff',
|
|
},
|
|
},
|
|
yAxis: [
|
|
{
|
|
position: 'left',
|
|
alignTicks: true,
|
|
nameTextStyle: {
|
|
color: '#fff',
|
|
},
|
|
type: 'value',
|
|
axisTick: {
|
|
show: false,
|
|
},
|
|
splitLine: {
|
|
lineStyle: {
|
|
type: 'solid',
|
|
color: '#8EEEFF',
|
|
opacity: 0.3,
|
|
},
|
|
},
|
|
axisLabel: {
|
|
color: '#fff',
|
|
},
|
|
},
|
|
],
|
|
series: obj.series,
|
|
})
|
|
|
|
chartAmi()
|
|
}
|
|
|
|
let timer: any = null
|
|
function chartAmi() {
|
|
let index = 0
|
|
timer && clearInterval(timer)
|
|
timer = setInterval(() => {
|
|
const currentIndex = index % legendData.length
|
|
// getInstance()?.dispatchAction({
|
|
// type: 'legendUnSelect',
|
|
// name: legendData[currentIndex],
|
|
// })
|
|
|
|
// getInstance()?.dispatchAction({
|
|
// type: 'legendSelect',
|
|
// name: legendData[currentIndex],
|
|
// })
|
|
|
|
getInstance()?.dispatchAction({
|
|
type: 'showTip',
|
|
seriesIndex: 0,
|
|
dataIndex: currentIndex,
|
|
})
|
|
|
|
index++
|
|
}, 3000)
|
|
}
|
|
|
|
watch(
|
|
() => visualizationStore.getYear,
|
|
() => {
|
|
getData()
|
|
},
|
|
)
|
|
|
|
onBeforeMount(() => {
|
|
getData()
|
|
rootEmitter.on('interval:auto', () => {
|
|
getData()
|
|
})
|
|
})
|
|
|
|
return {
|
|
tabList,
|
|
currentTab,
|
|
chartRef,
|
|
changeTab,
|
|
}
|
|
},
|
|
})
|
|
</script>
|
|
|
|
<style scoped lang="less">
|
|
.active {
|
|
@apply font-bold text-15px text-[#76E9F0];
|
|
}
|
|
</style>
|