268 lines
6.6 KiB
Vue
268 lines
6.6 KiB
Vue
<template>
|
|
<Box title="土壤监测数据">
|
|
<template #center>
|
|
<div
|
|
class="text-center bg-clip-text text-transparent bg-gradient-to-t from-[#76E9F0] to-[#A7E6EE] text-15px font-bold"
|
|
>
|
|
{{ currentTabValue }}
|
|
</div>
|
|
</template>
|
|
<template #right>
|
|
<div class="py-10px relative">
|
|
<div class="" v-if="tabList.length > 1">
|
|
<Dropdown
|
|
overlayClassName="dropdownClass"
|
|
placement="bottomRight"
|
|
trigger="click"
|
|
:style="{ height: '300px' }"
|
|
>
|
|
<div class="cursor-pointer">
|
|
<span class="text-white text-12px">更多</span>
|
|
<DownOutlined :style="{ fontSize: '12px', color: '#FFF' }" />
|
|
</div>
|
|
<template #overlay>
|
|
<Menu @click="onMenuClick">
|
|
<menu-item v-for="item in tabList" :key="item.id">
|
|
<div>{{ item.name }}</div>
|
|
</menu-item>
|
|
</Menu>
|
|
</template>
|
|
</Dropdown>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<div class="h-full flex flex-col">
|
|
<div class="h-30px flex items-center px-10px">
|
|
<div
|
|
class="text-white mx-5px text-12px cursor-pointer"
|
|
:class="{ active: item.key == currentMenu }"
|
|
v-for="(item, index) in menu"
|
|
@click="onChangeMenu(item)"
|
|
:key="index"
|
|
>
|
|
{{ item.name }}
|
|
</div>
|
|
</div>
|
|
<div class="flex-1" ref="chartRef"> </div>
|
|
</div>
|
|
</Box>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { defineComponent, reactive, ref, Ref, onBeforeMount, computed, toRefs } from 'vue'
|
|
import Box from './Box.vue'
|
|
import { useECharts } from '/@/hooks/web/useECharts'
|
|
import { getAgriculturalDeviceBasic, getDeviceBaseDataStatics } from '/@/api/sys/other'
|
|
import { DownOutlined } from '@ant-design/icons-vue'
|
|
import { Dropdown, Menu } from 'ant-design-vue'
|
|
import { cloneDeep } from 'lodash'
|
|
import { dateUtil } from '/@/utils/dateUtil'
|
|
import { chartLineColors } from './colors'
|
|
|
|
const desList = [
|
|
{
|
|
key: 'temperature',
|
|
unit: ' ℃',
|
|
name: '温度',
|
|
},
|
|
{
|
|
key: 'conductivity',
|
|
unit: 'us/cm',
|
|
name: '电导率 ',
|
|
},
|
|
{
|
|
key: 'humidity',
|
|
unit: '%',
|
|
name: '湿度',
|
|
},
|
|
{
|
|
key: 'n',
|
|
unit: 'mg/kg',
|
|
name: '氮',
|
|
},
|
|
{
|
|
key: 'p',
|
|
unit: 'mg/kg',
|
|
name: '磷',
|
|
},
|
|
{
|
|
key: 'k',
|
|
unit: 'mg/kg',
|
|
name: '钾',
|
|
},
|
|
]
|
|
export default defineComponent({
|
|
components: {
|
|
Box,
|
|
Dropdown,
|
|
DownOutlined,
|
|
Menu,
|
|
MenuItem: Menu.Item,
|
|
},
|
|
props: ['baseId'],
|
|
setup(props) {
|
|
console.log('===TRJCSJ')
|
|
console.log(props.baseId)
|
|
const Data = reactive({
|
|
tabList: ref<any>([]),
|
|
menu: cloneDeep(desList),
|
|
currentMenu: 'temperature',
|
|
currentTab: ref<number | string>(''),
|
|
list: [] as any,
|
|
})
|
|
|
|
const chartRef = ref<HTMLDivElement | null>(null)
|
|
|
|
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>)
|
|
|
|
const currentTabValue = computed(
|
|
() => Data.tabList.find((e) => e.id == Data.currentTab)?.name ?? '',
|
|
)
|
|
|
|
function onMenuClick({ key }) {
|
|
if (Data.currentTab == key) return
|
|
Data.currentTab = key
|
|
}
|
|
|
|
async function getTabs() {
|
|
const resData = await getAgriculturalDeviceBasic({
|
|
device_type: 2,
|
|
})
|
|
Data.tabList = resData
|
|
if (resData.length) Data.currentTab = resData[0].id
|
|
getData()
|
|
}
|
|
|
|
async function getData() {
|
|
const resData = await getDeviceBaseDataStatics({
|
|
base_id: Data.currentTab,
|
|
device_type: 2,
|
|
device_column: Data.currentMenu,
|
|
})
|
|
|
|
const arr = [] as any
|
|
|
|
for (const key in resData) {
|
|
if (Object.prototype.hasOwnProperty.call(resData, key)) {
|
|
arr.push({
|
|
name: key,
|
|
data: Object.keys(resData[key]).map((e) => {
|
|
return {
|
|
key: e,
|
|
value: resData[key][e],
|
|
}
|
|
}),
|
|
})
|
|
}
|
|
}
|
|
Data.list = arr
|
|
chartsInit()
|
|
}
|
|
|
|
function onChangeMenu({ key }) {
|
|
if (Data.currentMenu == key) return
|
|
Data.currentMenu = key
|
|
getData()
|
|
}
|
|
|
|
const isBase = computed(() => !!props.baseId)
|
|
|
|
onBeforeMount(() => {
|
|
if (isBase.value) {
|
|
getData()
|
|
} else {
|
|
getTabs()
|
|
}
|
|
})
|
|
|
|
const chartsInit = () => {
|
|
const data = Data.list.map((e, index) => {
|
|
const color = chartLineColors[index % chartLineColors.length]
|
|
return {
|
|
axis: e.data.map((e) => dateUtil(e.key).format('HH:mm')),
|
|
name: e.name,
|
|
series: {
|
|
name: e.name,
|
|
data: e.data.map((e) => e.value),
|
|
type: 'line',
|
|
symbol: 'none',
|
|
itemStyle: {
|
|
color: color.itemColor,
|
|
},
|
|
areaStyle: {
|
|
color: color.areaColor,
|
|
},
|
|
},
|
|
}
|
|
})
|
|
|
|
setOptions({
|
|
grid: { left: '2%', right: '2%', top: '20px', bottom: '2%', containLabel: true },
|
|
legend: {
|
|
data: data.map((e) => e.name),
|
|
top: '0%',
|
|
right: '0',
|
|
textStyle: {
|
|
color: '#ffffff',
|
|
},
|
|
},
|
|
tooltip: {
|
|
trigger: 'axis',
|
|
axisPointer: {
|
|
lineStyle: {
|
|
width: 1,
|
|
color: '#019680',
|
|
},
|
|
},
|
|
},
|
|
xAxis: {
|
|
type: 'category',
|
|
data: data[0]?.axis ?? [],
|
|
axisTick: {
|
|
show: false,
|
|
},
|
|
axisLine: {
|
|
show: false,
|
|
},
|
|
axisLabel: {
|
|
color: '#fff',
|
|
},
|
|
},
|
|
yAxis: [
|
|
{
|
|
type: 'value',
|
|
axisTick: {
|
|
show: false,
|
|
},
|
|
splitLine: {
|
|
lineStyle: {
|
|
type: 'solid',
|
|
color: '#8EEEFF',
|
|
opacity: 0.3,
|
|
},
|
|
},
|
|
axisLabel: {
|
|
color: '#fff',
|
|
},
|
|
},
|
|
],
|
|
series: data.map((e) => e.series),
|
|
})
|
|
}
|
|
|
|
return {
|
|
...toRefs(Data),
|
|
currentTabValue,
|
|
onMenuClick,
|
|
onChangeMenu,
|
|
chartRef,
|
|
}
|
|
},
|
|
})
|
|
</script>
|
|
<style scoped>
|
|
.active {
|
|
color: #76e9f0;
|
|
}
|
|
</style>
|