171 lines
4.3 KiB
Plaintext
171 lines
4.3 KiB
Plaintext
<template>
|
||
<view class="chart-wrap" :style="{ height: heightPx }">
|
||
<EChartsView :option="chartOption" class="chart" />
|
||
</view>
|
||
</template>
|
||
|
||
<script lang="uts">
|
||
import EChartsView from '@/uni_modules/charts/EChartsView.vue'
|
||
|
||
export default {
|
||
components: {
|
||
EChartsView
|
||
},
|
||
props: {
|
||
xLabels: { type: Array, default: () => [] },
|
||
gmv: { type: Array, default: () => [] },
|
||
orders: { type: Array, default: () => [] },
|
||
height: { type: Number, default: 320 }
|
||
},
|
||
|
||
data() {
|
||
return {
|
||
heightPx: '320px',
|
||
chartOption: {} as any
|
||
}
|
||
},
|
||
|
||
watch: {
|
||
xLabels: { handler() { this.updateOption() }, deep: true },
|
||
gmv: { handler() { this.updateOption() }, deep: true },
|
||
orders: { handler() { this.updateOption() }, deep: true },
|
||
height: {
|
||
handler() {
|
||
this.heightPx = `${this.height}px`
|
||
}
|
||
}
|
||
},
|
||
|
||
mounted() {
|
||
this.heightPx = `${this.height}px`
|
||
this.updateOption()
|
||
},
|
||
|
||
methods: {
|
||
updateOption() {
|
||
const x = (this.xLabels as Array<any>).map((s) => String(s))
|
||
const bar = (this.gmv as Array<any>).map((v) => {
|
||
const n = Number(v)
|
||
return isFinite(n) ? n : 0
|
||
})
|
||
const line = (this.orders as Array<any>).map((v) => {
|
||
const n = Number(v)
|
||
return isFinite(n) ? n : 0
|
||
})
|
||
|
||
this.chartOption = {
|
||
grid: { left: 60, right: 60, top: 70, bottom: 40 },
|
||
tooltip: {
|
||
trigger: 'axis',
|
||
axisPointer: { type: 'shadow' },
|
||
formatter: (params: any) => {
|
||
let result = params[0].name + '<br/>'
|
||
for (let i = 0; i < params.length; i++) {
|
||
const p = params[i]
|
||
if (p.seriesName === 'GMV') {
|
||
const val = Number(p.value)
|
||
const formatted = val >= 10000 ? (val / 10000).toFixed(1) + '万' : val.toFixed(0)
|
||
result += `${p.marker} ${p.seriesName}: ¥${formatted}<br/>`
|
||
} else {
|
||
result += `${p.marker} ${p.seriesName}: ${p.value}<br/>`
|
||
}
|
||
}
|
||
return result
|
||
}
|
||
},
|
||
legend: {
|
||
top: 8,
|
||
left: 8,
|
||
itemWidth: 10,
|
||
itemHeight: 10,
|
||
textStyle: { fontSize: 12 },
|
||
data: ['GMV', '订单数'],
|
||
bottom: 'auto'
|
||
},
|
||
xAxis: {
|
||
type: 'category',
|
||
data: x,
|
||
axisTick: { alignWithLabel: true },
|
||
axisLine: { lineStyle: { color: 'rgba(0,0,0,0.12)' } },
|
||
axisLabel: {
|
||
color: 'rgba(0,0,0,0.55)',
|
||
rotate: x.length > 12 ? 45 : 0,
|
||
interval: 0
|
||
}
|
||
},
|
||
yAxis: [
|
||
{
|
||
type: 'value',
|
||
name: 'GMV(元)',
|
||
position: 'left',
|
||
axisLine: { show: false },
|
||
splitLine: { lineStyle: { color: 'rgba(0,0,0,0.06)' } },
|
||
axisLabel: {
|
||
color: 'rgba(0,0,0,0.55)',
|
||
formatter: (value: number) => {
|
||
if (value >= 10000) {
|
||
return (value / 10000).toFixed(1) + '万'
|
||
}
|
||
return String(Math.round(value))
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'value',
|
||
name: '订单数',
|
||
position: 'right',
|
||
alignTicks: true,
|
||
axisLine: { show: false },
|
||
splitLine: { show: false },
|
||
axisLabel: {
|
||
color: 'rgba(0,0,0,0.55)',
|
||
formatter: (value: number) => String(Math.round(value))
|
||
}
|
||
}
|
||
],
|
||
series: [
|
||
{
|
||
name: 'GMV',
|
||
type: 'bar',
|
||
yAxisIndex: 0,
|
||
data: bar,
|
||
barMaxWidth: 14,
|
||
barCategoryGap: '35%',
|
||
itemStyle: {
|
||
borderRadius: [6, 6, 0, 0],
|
||
color: '#3b82f6'
|
||
}
|
||
},
|
||
{
|
||
name: '订单数',
|
||
type: 'line',
|
||
yAxisIndex: 1,
|
||
data: line,
|
||
smooth: true,
|
||
symbol: 'circle',
|
||
symbolSize: 6,
|
||
lineStyle: {
|
||
width: 2,
|
||
color: '#10b981'
|
||
},
|
||
itemStyle: {
|
||
color: '#10b981'
|
||
}
|
||
}
|
||
]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style>
|
||
.chart-wrap {
|
||
width: 100%;
|
||
}
|
||
.chart {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
</style>
|