Some checks failed
Docker Build & Deploy / Build Docker Image (push) Waiting to run
Docker Build & Deploy / Deploy to Production (push) Has been cancelled
Docker Build & Deploy / Cleanup Dangling Images (push) Has been cancelled
Docker Build & Deploy / WeChat Notification (push) Has been cancelled
61 lines
1.8 KiB
TypeScript
61 lines
1.8 KiB
TypeScript
import { Plugin } from 'chart.js'
|
||
|
||
/**
|
||
* 饼图中心文本插件
|
||
* 在 Doughnut/Pie 图表中心显示总金额
|
||
*/
|
||
|
||
export interface PieCenterTextOptions {
|
||
text?: string
|
||
subtext?: string
|
||
textColor?: string
|
||
subtextColor?: string
|
||
fontSize?: number
|
||
subFontSize?: number
|
||
}
|
||
|
||
export const pieCenterTextPlugin: Plugin = {
|
||
id: 'pieCenterText',
|
||
afterDraw: (chart: any) => {
|
||
const { ctx, chartArea } = chart
|
||
|
||
if (!chartArea) return
|
||
|
||
// 计算中心点
|
||
const centerX = (chartArea.left + chartArea.right) / 2
|
||
const centerY = (chartArea.top + chartArea.bottom) / 2
|
||
|
||
// 从图表配置中获取插件选项
|
||
const pluginOptions = chart.options.plugins?.pieCenterText as PieCenterTextOptions | undefined
|
||
|
||
if (!pluginOptions) return
|
||
|
||
const { text, subtext, textColor, subtextColor, fontSize, subFontSize } = pluginOptions
|
||
|
||
ctx.save()
|
||
ctx.textAlign = 'center'
|
||
ctx.textBaseline = 'middle'
|
||
|
||
// 计算字体大小(基于图表高度)
|
||
const chartHeight = chartArea.bottom - chartArea.top
|
||
const defaultFontSize = Math.max(14, Math.min(32, chartHeight * 0.2))
|
||
const defaultSubFontSize = Math.max(10, Math.min(16, chartHeight * 0.12))
|
||
|
||
// 绘制主文本(金额)
|
||
if (text) {
|
||
ctx.font = `bold ${fontSize || defaultFontSize}px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`
|
||
ctx.fillStyle = textColor || '#323233'
|
||
ctx.fillText(text, centerX, centerY - 5)
|
||
}
|
||
|
||
// 绘制副文本(标签,如"总支出")
|
||
if (subtext) {
|
||
ctx.font = `${subFontSize || defaultSubFontSize}px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`
|
||
ctx.fillStyle = subtextColor || '#969799'
|
||
ctx.fillText(subtext, centerX, centerY + (fontSize || defaultFontSize) * 0.6)
|
||
}
|
||
|
||
ctx.restore()
|
||
}
|
||
}
|