大屏页面布局

This commit is contained in:
2026-02-26 17:03:00 +08:00
parent 1ce4596b6a
commit 44f744010e

View File

@@ -8,30 +8,52 @@
</template> </template>
<script setup> <script setup>
import { ref, onMounted } from 'vue' import { ref, onMounted, nextTick, watch } from 'vue'
import * as echarts from 'echarts' import * as echarts from 'echarts'
import { getItemInfoList } from '@/api/itemInfo'
const vList = ref([])
const chartRef = ref(null) const chartRef = ref(null)
let chartInstance = null let chartInstance = null
const initBarLineChart = () => { async function getList() {
try {
const params = {
itemCode: 'ERP_YEARPSAV_M001',
reqParam: '2025'
}
const res = await getItemInfoList(params)
vList.value = res || []
} catch (error) {
console.error(error)
}
}
function initChart() {
const el = chartRef.value const el = chartRef.value
if (!el) return if (!el || vList.value.length === 0) return
if (chartInstance) {
chartInstance.dispose()
}
chartInstance = echarts.init(el) chartInstance = echarts.init(el)
// 收支数据 const xData = vList.value.map(item => {
const incomeData = [1200, 2000, 1500, 800, 700, 1100, 1300, 1800, 1600, 900, 1000, 1400] const xaxis = item.xaxis || ''
const expenseData = [800, 1500, 1000, 600, 500, 800, 900, 1200, 1100, 700, 800, 950] return xaxis.includes('月') ? xaxis : `${xaxis}`
// 计算支出占收入的比例保留1位小数
const ratioData = incomeData.map((income, index) => {
const expense = expenseData[index]
return income === 0 ? 0 : ((expense / income) * 100).toFixed(1)
}) })
const index01Yuan = vList.value.map(item => item.index01 || 0)
const index02Yuan = vList.value.map(item => item.index02 || 0)
const index03 = vList.value.map(item => item.index03 || 0)
const index01Wan = index01Yuan.map(val => (val / 10000).toFixed(2))
const index02Wan = index02Yuan.map(val => (val / 10000).toFixed(2))
const option = { const option = {
tooltip: { tooltip: {
trigger: 'axis', trigger: 'axis',
axisPointer: { type: 'cross' }, axisPointer: { type: 'cross' },
backgroundColor: 'rgba(145, 200, 255, 0.9)', backgroundColor: 'rgba(145, 200, 255, 0.9)',
borderColor: '#409EFF', borderColor: '#409EFF',
@@ -39,33 +61,48 @@ const initBarLineChart = () => {
textStyle: { color: '#0a3b70' }, textStyle: { color: '#0a3b70' },
padding: [8, 12], padding: [8, 12],
borderRadius: 6, borderRadius: 6,
formatter: function(params) { formatter: function (params) {
let res = `<b>${params[0].axisValue}</b>` const title = params[0].axisValue
params.forEach(item => { const idx = params[0].dataIndex
const unit = item.seriesName === '支出占收入比' ? '%' : '万元' const incomeVal = index01Yuan[idx]
res += `<br/>${item.seriesName}${item.value}${unit}` const expenseVal = index02Yuan[idx]
}) const rateVal = index03[idx]
return res
return `
<div style="text-align:center; font-weight:bold; margin-bottom:6px">${title}</div>
<table style="width:100%; border-collapse:collapse; text-align:center">
<tr>
<td style="border:1px solid #409EFF; padding:4px; font-weight:bold">收入(元)</td>
<td style="border:1px solid #409EFF; padding:4px; font-weight:bold">支出(元)</td>
<td style="border:1px solid #409EFF; padding:4px; font-weight:bold">存储率(%)</td>
</tr>
<tr>
<td style="border:1px solid #409EFF; padding:4px">${incomeVal}</td>
<td style="border:1px solid #409EFF; padding:4px">${expenseVal}</td>
<td style="border:1px solid #409EFF; padding:4px">${rateVal}</td>
</tr>
</table>
`
} }
}, },
legend: { legend: {
top: '10', top: '10',
left: 'center', left: 'center',
textStyle: { fontSize: 12, color: '#e0e6ff' } textStyle: { fontSize: 12, color: '#e0e6ff' }
}, },
grid: { grid: {
left: '5%', left: '5%',
right: '5%', right: '5%',
bottom: '10%', bottom: '10%',
top: '15%', top: '15%',
containLabel: true containLabel: true
}, },
xAxis: [ xAxis: [
{ {
type: 'category', type: 'category',
data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'], data: xData,
axisLabel: { axisLabel: {
fontSize: 11, fontSize: 11,
interval: 0, interval: 0,
color: '#b4c7e7' color: '#b4c7e7'
}, },
@@ -80,10 +117,7 @@ const initBarLineChart = () => {
nameTextStyle: { fontSize: 12, color: '#b4c7e7' }, nameTextStyle: { fontSize: 12, color: '#b4c7e7' },
axisLabel: { formatter: '{value}', color: '#b4c7e7' }, axisLabel: { formatter: '{value}', color: '#b4c7e7' },
axisLine: { lineStyle: { color: '#1a508b' } }, axisLine: { lineStyle: { color: '#1a508b' } },
splitLine: { lineStyle: { color: 'rgba(26, 80, 139, 0.3)' } }, splitLine: { lineStyle: { color: 'rgba(26, 80, 139, 0.3)' } }
nameLocation: 'end',
nameGap: 10,
nameRotate: 0
}, },
{ {
type: 'value', type: 'value',
@@ -91,10 +125,7 @@ const initBarLineChart = () => {
nameTextStyle: { fontSize: 12, color: '#b4c7e7' }, nameTextStyle: { fontSize: 12, color: '#b4c7e7' },
axisLabel: { formatter: '{value} %', color: '#b4c7e7' }, axisLabel: { formatter: '{value} %', color: '#b4c7e7' },
axisLine: { lineStyle: { color: '#1a508b' } }, axisLine: { lineStyle: { color: '#1a508b' } },
splitLine: { lineStyle: { color: 'rgba(26, 80, 139, 0.3)' } }, splitLine: { show: false },
nameLocation: 'end',
nameGap: 10,
nameRotate: 0,
min: 0, min: 0,
max: 100 max: 100
} }
@@ -104,46 +135,47 @@ const initBarLineChart = () => {
name: '收入', name: '收入',
type: 'bar', type: 'bar',
yAxisIndex: 0, yAxisIndex: 0,
data: incomeData, data: index01Wan,
itemStyle: { color: '#67C23A' }, // 绿色代表收入 itemStyle: { color: '#67C23A' },
barWidth: '12%', // 适配双柱宽度 barWidth: '12%',
label: { label: {
show: true, show: true,
position: 'top', position: 'top',
fontSize: 10, fontSize: 10,
color: '#fff' color: '#fff',
formatter: '{c}' // 移除万元单位,只显示数值
} }
}, },
{ {
name: '支出', name: '支出',
type: 'bar', type: 'bar',
yAxisIndex: 0, yAxisIndex: 0,
data: expenseData, data: index02Wan,
itemStyle: { color: '#F56C6C' }, // 红色代表支出 itemStyle: { color: '#F56C6C' },
barWidth: '12%', barWidth: '12%',
label: { label: {
show: true, show: true,
position: 'top', position: 'top',
fontSize: 10, fontSize: 10,
color: '#fff' color: '#fff',
formatter: '{c}' // 移除万元单位,只显示数值
} }
}, },
{ {
name: '支出占收入比', name: '存储率',
type: 'line', type: 'line',
yAxisIndex: 1, yAxisIndex: 1,
data: ratioData, data: index03,
smooth: true, smooth: true,
lineStyle: { width: 1.5, color: '#409EFF' }, // 蓝色代表占比曲线 lineStyle: { width: 1.5, color: '#409EFF' },
symbol: 'circle', symbol: 'circle',
symbolSize: 5, symbolSize: 5,
emphasis: { symbolSize: 7 },
label: { label: {
show: true, show: true,
position: 'top', position: 'top',
fontSize: 10, fontSize: 10,
color: '#409EFF', color: '#409EFF',
formatter: '{c}%' formatter: '{c}' // 移除%单位,只显示数值
}, },
areaStyle: { areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
@@ -156,10 +188,16 @@ const initBarLineChart = () => {
} }
chartInstance.setOption(option) chartInstance.setOption(option)
window.addEventListener('resize', () => chartInstance.resize()) window.addEventListener('resize', () => chartInstance?.resize())
} }
onMounted(() => initBarLineChart()) watch(vList, () => {
nextTick(() => initChart())
}, { deep: true })
onMounted(() => {
getList()
})
</script> </script>
<style scoped> <style scoped>
@@ -184,7 +222,7 @@ onMounted(() => initBarLineChart())
.chart-card-title { .chart-card-title {
font-size: 16px; font-size: 16px;
font-weight: 600; font-weight: 600;
color: '#409EFF'; color: #409EFF;
letter-spacing: 0.5px; letter-spacing: 0.5px;
} }
@@ -192,14 +230,5 @@ onMounted(() => initBarLineChart())
flex: 1; flex: 1;
width: 100%; width: 100%;
height: calc(100% - 40px); height: calc(100% - 40px);
margin: 0;
padding: 0;
}
:deep(.echarts-tooltip) {
background-color: rgba(145, 200, 255, 0.9) !important;
border-color: #409EFF !important;
color: #0a3b70 !important;
border-radius: 6px !important;
} }
</style> </style>