Files
EmailBill/Web/src/plugins/chartjs-pie-center-plugin.ts
SunCheng c49f66757e
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
1
2026-02-18 21:16:45 +08:00

61 lines
1.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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()
}
}