Files
EmailBill/Web/src/plugins/chartjs-pie-center-plugin.ts

61 lines
1.8 KiB
TypeScript
Raw Normal View History

2026-02-18 21:16:45 +08:00
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()
}
}