大屏页面布局

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

View File

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