Files
admin-vben5/apps/web-antd/src/utils/threeDBarOption.ts
2025-07-10 17:52:54 +08:00

129 lines
4.4 KiB
TypeScript

import * as echarts from 'echarts'
interface ThreeDBarOptionConfig {
xData: string[]
yData: number[]
barWidth?: number
colorConfig?: {
left0?: string
left08?: string
top03?: string
top1?: string
}
}
export function getThreeDBarOption({ xData, yData, barWidth = 30, colorConfig = {} }: ThreeDBarOptionConfig) {
// 注册 shape 只需一次,防止多次注册报错
if (!(echarts.graphic as any).registered3DBar) {
const leftShape = echarts.graphic.extendShape({
buildPath(ctx: any, shape: any) {
const { topBasicsYAxis, bottomYAxis, basicsXAxis } = shape
const WIDTH = 15
const OBLIQUE_ANGLE_HEIGHT = 8
const p1 = [basicsXAxis - WIDTH, topBasicsYAxis - OBLIQUE_ANGLE_HEIGHT]
const p2 = [basicsXAxis - WIDTH, bottomYAxis]
const p3 = [basicsXAxis, bottomYAxis]
const p4 = [basicsXAxis, topBasicsYAxis]
ctx.moveTo(p1[0], p1[1])
ctx.lineTo(p2[0], p2[1])
ctx.lineTo(p3[0], p3[1])
ctx.lineTo(p4[0], p4[1])
}
})
const rightShape = echarts.graphic.extendShape({
buildPath(ctx: any, shape: any) {
const { topBasicsYAxis, bottomYAxis, basicsXAxis } = shape
const WIDTH = 15
const OBLIQUE_ANGLE_HEIGHT = 2
const p1 = [basicsXAxis, topBasicsYAxis]
const p2 = [basicsXAxis, bottomYAxis]
const p3 = [basicsXAxis + WIDTH, bottomYAxis]
const p4 = [basicsXAxis + WIDTH, topBasicsYAxis - OBLIQUE_ANGLE_HEIGHT]
ctx.moveTo(p1[0], p1[1])
ctx.lineTo(p2[0], p2[1])
ctx.lineTo(p3[0], p3[1])
ctx.lineTo(p4[0], p4[1])
}
})
const topShape = echarts.graphic.extendShape({
buildPath(ctx: any, shape: any) {
const { topBasicsYAxis, basicsXAxis } = shape
const WIDTH = 15
const OBLIQUE_ANGLE_HEIGHT = 8
const p1 = [basicsXAxis, topBasicsYAxis]
const p2 = [basicsXAxis + WIDTH, topBasicsYAxis - OBLIQUE_ANGLE_HEIGHT]
const p3 = [basicsXAxis, topBasicsYAxis - OBLIQUE_ANGLE_HEIGHT * 2]
const p4 = [basicsXAxis - WIDTH, topBasicsYAxis - OBLIQUE_ANGLE_HEIGHT]
ctx.moveTo(p1[0], p1[1])
ctx.lineTo(p2[0], p2[1])
ctx.lineTo(p3[0], p3[1])
ctx.lineTo(p4[0], p4[1])
}
})
echarts.graphic.registerShape('leftShape', leftShape)
echarts.graphic.registerShape('rightShape', rightShape)
echarts.graphic.registerShape('topShape', topShape)
;(echarts.graphic as any).registered3DBar = true
}
return {
tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
grid: { left: '3%', right: '4%', bottom: '3%', top: "12%", containLabel: true },
xAxis: [{
type: 'category',
data: xData,
axisTick: { alignWithLabel: true },
axisLine: { lineStyle: { color: '#3ec6ff' } },
axisLabel: { color: '#fff' }
}],
yAxis: [{
type: 'value',
axisLine: { show: false },
splitLine: { lineStyle: { color: '#1b4a7a' } },
axisLabel: { color: '#fff' }
}],
series: [{
type: 'custom',
data: yData,
barWidth,
renderItem(params: any, api: any) {
const basicsCoord = api.coord([api.value(0), api.value(1)])
const topBasicsYAxis = basicsCoord[1]
const basicsXAxis = basicsCoord[0]
const bottomYAxis = api.coord([api.value(0), 0])[1]
return {
type: 'group',
children: [
{
type: 'leftShape',
shape: { topBasicsYAxis, basicsXAxis, bottomYAxis },
style: {
fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: colorConfig.left0 || '#2ADBEF' },
{ offset: 1, color: colorConfig.left08 || '#2677F9 ' },
])
}
},
{
type: 'rightShape',
shape: { topBasicsYAxis, basicsXAxis, bottomYAxis },
style: {
fill: '#114EAD '
}
},
{
type: 'topShape',
shape: { topBasicsYAxis, basicsXAxis, bottomYAxis },
style: {
fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0.3, color: colorConfig.top03 || '#6DF0FF' },
{ offset: 1, color: colorConfig.top1 || '#6DF0FF' }
])
}
}
]
}
}
}]
}
}