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() } }