251 lines
5.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="supply-chart-container">
<!-- 柱状图 -->
<EChart :options="barOption" :height="height" />
</div>
</template>
<script setup lang="ts">
import type { EChartsOption } from 'echarts'
// @ts-ignore
import EChart from '@/components/Echart/src/Echart.vue'
import { computed, watch } from 'vue'
defineOptions({ name: 'BarChart' })
interface ChartDataItem {
category: string
monthlyStandard: number
perCapita: number
}
interface CardData {
inProgress: number
toWarehouse: number
outWarehouse: number
}
const props = withDefaults(
defineProps<{
width?: number
height?: string
data?: ChartDataItem[]
cardData?: CardData
}>(),
{
width: 400,
height: '300px',
data: () => [],
cardData: () => ({
inProgress: 5,
toWarehouse: 5,
outWarehouse: 5
})
}
)
// 创建图表配置
const createChartOption = (): EChartsOption => {
const categories = props.data.map((item) => item.category)
const monthlyStandardData = props.data.map((item) => item.monthlyStandard)
const perCapitaData = props.data.map((item) => item.perCapita)
// 创建底色数据最大值50
const maxValue = 50
const monthlyStandardBgData = categories.map((_, index) => maxValue - monthlyStandardData[index])
const perCapitaBgData = categories.map((_, index) => maxValue - perCapitaData[index])
return {
backgroundColor: 'transparent',
grid: {
left: '10%',
right: '15%',
top: '20%',
bottom: '15%',
containLabel: false
},
xAxis: {
type: 'category',
data: categories,
axisLine: {
lineStyle: {
color: '#38668D50'
}
},
axisLabel: {
color: '#D8F0FF',
fontSize: 10,
interval: 0,
rotate: 0
},
axisTick: {
show: false
}
},
yAxis: {
type: 'value',
min: 0,
max: 50,
interval: 10,
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
color: '#D8F0FF',
fontSize: 10
},
splitLine: {
lineStyle: {
color: '#38668D20',
type: 'dashed'
}
}
},
legend: {
data: ['支出', '收入'],
top: '5%',
right: '10%',
textStyle: {
color: '#6D869A',
fontSize: 9
},
itemWidth: 9,
itemHeight: 9,
itemGap: 25
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
},
backgroundColor: 'rgba(0, 0, 0, 0.8)',
borderColor: 'rgba(0, 167, 255, 0.5)',
textStyle: {
color: '#D8F0FF',
fontSize: 10
},
formatter: function (params: any) {
let result = params[0].name + '<br/>'
// 只显示数据系列,不显示底色系列
params.forEach((param: any) => {
if (param.seriesName === '支出' || param.seriesName === '收入') {
result += param.marker + param.seriesName + ': ' + param.value + '<br/>'
}
})
return result
}
},
series: [
// 支出数据(渐变)- 先绘制,作为底层
{
name: '支出',
type: 'bar',
stack: 'monthly',
data: monthlyStandardData,
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: '#10A0F2'
},
{
offset: 1,
color: 'rgba(0, 82, 184, 0)'
}
]
}
},
barWidth: '20%',
barGap: '20%'
},
// 支出底色 - 后绘制,堆叠在数据上方
{
name: '支出底色',
type: 'bar',
stack: 'monthly',
data: monthlyStandardBgData,
itemStyle: {
color: '#38668D70'
},
barWidth: '20%',
barGap: '20%',
silent: true,
tooltip: {
show: false
}
},
// 收入数据(渐变)
{
name: '收入',
type: 'bar',
stack: 'perCapita',
data: perCapitaData,
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: '#FFA58D'
},
{
offset: 1,
color: 'rgba(87, 140, 205, 0)'
}
]
}
},
barWidth: '20%',
barGap: '80%'
},
{
name: '收入底色',
type: 'bar',
stack: 'perCapita',
data: perCapitaBgData,
itemStyle: {
color: '#38668D70'
},
barWidth: '20%',
barGap: '80%',
silent: true,
tooltip: {
show: false
}
}
]
}
}
// 柱状图配置
const barOption = computed(() => createChartOption())
// 监听数据变化,更新图表
watch(
() => [props.data, props.cardData],
() => {
// 数据变化时computed 会自动更新
},
{ deep: true }
)
</script>
<style scoped lang="scss">
.supply-chart-container {
width: 100%;
}
</style>